exploit-db-mirror/exploits/multiple/local/39595.txt
Offensive Security ed0e1e4d44 DB: 2018-09-25
1979 changes to exploits/shellcodes

Couchdb 1.5.0 - 'uuids' Denial of Service
Apache CouchDB 1.5.0 - 'uuids' Denial of Service

Beyond Remote 2.2.5.3 - Denial of Service (PoC)
udisks2 2.8.0 - Denial of Service (PoC)
Termite 3.4 - Denial of Service (PoC)
SoftX FTP Client 3.3 - Denial of Service (PoC)

Silverstripe 2.3.5 - Cross-Site Request Forgery / Open redirection
SilverStripe CMS 2.3.5 - Cross-Site Request Forgery / Open Redirection

Silverstripe CMS 3.0.2 - Multiple Vulnerabilities
SilverStripe CMS 3.0.2 - Multiple Vulnerabilities

Silverstripe CMS 2.4 - File Renaming Security Bypass
SilverStripe CMS 2.4 - File Renaming Security Bypass

Silverstripe CMS 2.4.5 - Multiple Cross-Site Scripting Vulnerabilities
SilverStripe CMS 2.4.5 - Multiple Cross-Site Scripting Vulnerabilities

Silverstripe CMS 2.4.7 - 'install.php' PHP Code Injection
SilverStripe CMS 2.4.7 - 'install.php' PHP Code Injection

Silverstripe Pixlr Image Editor - 'upload.php' Arbitrary File Upload
SilverStripe CMS Pixlr Image Editor - 'upload.php' Arbitrary File Upload

Silverstripe CMS 2.4.x - 'BackURL' Open Redirection
SilverStripe CMS 2.4.x - 'BackURL' Open Redirection

Silverstripe CMS - 'MemberLoginForm.php' Information Disclosure
SilverStripe CMS - 'MemberLoginForm.php' Information Disclosure

Silverstripe CMS - Multiple HTML Injection Vulnerabilities
SilverStripe CMS - Multiple HTML Injection Vulnerabilities

Apache CouchDB 1.7.0 and 2.x before 2.1.1 - Remote Privilege Escalation
Apache CouchDB 1.7.0 / 2.x < 2.1.1 - Remote Privilege Escalation

Monstra CMS before 3.0.4 - Cross-Site Scripting
Monstra CMS < 3.0.4 - Cross-Site Scripting (2)

Monstra CMS < 3.0.4 - Cross-Site Scripting
Monstra CMS < 3.0.4 - Cross-Site Scripting (1)
Navigate CMS 2.8 - Cross-Site Scripting
Collectric CMU 1.0 - 'lang' SQL injection
Joomla! Component CW Article Attachments 1.0.6 - 'id' SQL Injection
LG SuperSign EZ CMS 2.5 - Remote Code Execution
MyBB Visual Editor 1.8.18 - Cross-Site Scripting
Joomla! Component AMGallery 1.2.3 - 'filter_category_id' SQL Injection
Joomla! Component Micro Deal Factory 2.4.0 - 'id' SQL Injection
RICOH Aficio MP 301 Printer - Cross-Site Scripting
Joomla! Component Auction Factory 4.5.5 - 'filter_order' SQL Injection
RICOH MP C6003 Printer - Cross-Site Scripting

Linux/ARM - Egghunter (PWN!) + execve(_/bin/sh__ NULL_ NULL) Shellcode (28 Bytes)
Linux/ARM - sigaction() Based Egghunter (PWN!) + execve(_/bin/sh__ NULL_ NULL) Shellcode (52 Bytes)
2018-09-25 05:01:51 +00:00

107 lines
No EOL
4.5 KiB
Text

Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=676
tl;dr
The code responsible for loading a suid-binary following a call to the execve syscall invalidates
the task port after first swapping the new vm_map into the old task object leaving a short race window
where we can manipulate the memory of the euid(0) process before the old task port is destroyed.
******************
__mac_execve calls exec_activate_image which calls exec_mach_imgact via the image activator table execsw.
If we were called from a regular execve (not after a vfork or via posix_spawn) then this calls load_machfile
with a NULL map argument indicating to load_machfile that it should create a new vm_map for this process:
if (new_map == VM_MAP_NULL) {
create_map = TRUE;
old_task = current_task();
}
it then creates a new pmap and wraps that in a vm_map, but doesn't yet assign it to the task:
pmap = pmap_create(get_task_ledger(ledger_task),
(vm_map_size_t) 0,
((imgp->ip_flags & IMGPF_IS_64BIT) != 0));
pal_switch_pmap(thread, pmap, imgp->ip_flags & IMGPF_IS_64BIT);
map = vm_map_create(pmap,
0,
vm_compute_max_offset(((imgp->ip_flags & IMGPF_IS_64BIT) == IMGPF_IS_64BIT)),
TRUE)
the code then goes ahead and does the actual load of the binary into that vm_map:
lret = parse_machfile(vp, map, thread, header, file_offset, macho_size,
0, (int64_t)aslr_offset, (int64_t)dyld_aslr_offset, result);
if the load was successful then that new map will we swapped with the task's current map so that the task now has the
vm for the new binary:
old_map = swap_task_map(old_task, thread, map, !spawn);
vm_map_t
swap_task_map(task_t task, thread_t thread, vm_map_t map, boolean_t doswitch)
{
vm_map_t old_map;
if (task != thread->task)
panic("swap_task_map");
task_lock(task);
mp_disable_preemption();
old_map = task->map;
thread->map = task->map = map;
we then return from load_machfile back to exec_mach_imgact:
lret = load_machfile(imgp, mach_header, thread, map, &load_result);
if (lret != LOAD_SUCCESS) {
error = load_return_to_errno(lret);
goto badtoolate;
}
...
error = exec_handle_sugid(imgp);
after dealing with stuff like CLOEXEC fds we call exec_handle_sugid.
If this is indeed an exec of a suid binary then we reach here before actually setting
the euid:
* Have mach reset the task and thread ports.
* We don't want anyone who had the ports before
* a setuid exec to be able to access/control the
* task/thread after.
ipc_task_reset(p->task);
ipc_thread_reset((imgp->ip_new_thread != NULL) ?
imgp->ip_new_thread : current_thread());
As this comment points out, it probably is quite a good idea to reset the thread, task and exception ports, and
that's exactly what they do:
...
ipc_port_dealloc_kernel(old_kport);
etc for the ports
...
The problem is that between the call to swap_task_map and ipc_port_dealloc_kernel the old task port is still valid, even though the task isn't running.
This means that we can use the mach_vm_* API's to manipulate the task's new vm_map in the interval between those two calls. This window is long enough
for us to easily find the load address of the suid-root binary, change its page protections and overwrite its code with shellcode.
This PoC demonstrates this issue by targetting the /usr/sbin/traceroute6 binary which is suid-root. Everything is tested on OS X El Capitan 10.11.2.
In our parent process we register a port with launchd and fork a child. This child sends us back its task port, and once we ack that we've got
its task port it execve's the suid-root binary.
In the parent process we use mach_vm_region to work out when the task's map gets switched, which also convieniently tells us the target binary's load
address. We then mach_vm_protect the page containing the binary entrypoint to be rwx and use mach_vm_write to overwrite it with some shellcode which
execve's /bin/zsh (because bash drops privs) try running id in the shell and note your euid.
Everything is quite hardcoded for the exact version of traceroute6 on 10.11.2 but it would be easy to make this into a very universal priv-esc :)
Note that the race window is still quite tight so you may have to try a few times.
Proof of Concept:
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/39595.zip