当前位置: 首页 > 后端技术 > PHP

从一个有趣的漏洞分析到一个有趣的PHP后门

时间:2023-03-29 16:12:27 PHP

事件的起因非常有趣。前几天对着电脑发呆的时候,突然安全交流群的一群小伙伴来找我交流一个问题,就是说他在挖SRC的时候,发现了一个目录遍历漏洞资产。通过这个漏洞,他用一个叫phpmailer的中间件(应该是类似中间件)找到了目标资产,问我有没有办法利用,我查了这个组件的漏洞信息。不幸的是,最新的漏洞似乎是在6.5.0版本之前。可惜群友的版本是6.5.1,就是不能用。找不到与版本匹配的孔也没关系。抱着学习的心态,还是看了看。历史漏洞的成因,不看是不会知道的。看完之后,你会学到一些有趣的新知识,这也是有这篇文章的原因。CVE-2016-10033简单分析CVE-2016-10033是Phpmailer见过的最经典的漏洞。在本文正式开始之前,我们先简单分析一下这个漏洞。读者可以到:https://github.com/opsxcq/exp...查看phpmailer的代码。让我们在这里开门见山。漏洞的起因其实是mail()函数的第五个参数。只要控制好第五个参数,我们就可以进行RCE、文件读取等操作。所以让我们先回到mail()函数:这样我们就可以首先找到mailPassthru()方法。可以看到这个方法内部使用了mail(),maill的第五个参数也是mailPassthru()参数的第五个参数。【----帮助学习网络安全,在以下所有学习资料中添加vx:yj009991,获得备注“ThoughtNo”!】①网络安全学习成长路径思维导图②60+经典网络安全工具包③100+SRC漏洞分析报告④150+在线安全攻防实战技术电子书⑤最权威的CISSP认证考试指南+题库⑥1800多页CTF实战技巧手册⑦网络安全公司最新面试题(含答案)合集⑧APP客户端安全检测指南(安卓+IOS)所以我们看看其他地方是否使用了mailPassthru(),可以找到这个maillSend()方法中使用了mailPassthru()方法,第五个参数$params来自于当前类中的Sender属性###然后我们回到Sender属性,看看Sender属性在什么地方可以控制。这里可以看出在setFrom方法中,可以赋值Sender属性。当然,该漏洞的另一个关键点是validateAddress()方法的绕过,这也是CVE-2016-10033的精彩之处。但这与本文的重点不符,因此我们不对此进行深入分析。有兴趣的读者可以阅读更多:https://paper.seebug.org/161/知道了Sender的key属性是如何赋值的,继续接下来,我们继续分析mailSend()方法的调用链。我们可以找到postSend()方法,继续看postSend()。最后,我们可以找到send()方法。至此,我们就分析完了整个漏洞参数传递过程。一般来说,只要我们使用setFrom()方法给Sender属性赋值,然后调用send()方法即可。那么Sender属性的值就会进入mail()函数的第五个参数,从而实现RCE。看到这里,想必很多读者对开头提到的mail()函数的第五个参数产生了兴趣。为什么RCE能被控制就可以实现?这是关于php中mail()函数的实现原理。有意思的mail()mail()函数是php定义的一个发送邮件的函数,它支持的参数如下:为什么一个发送邮件的函数会引发RCE?前人的安全研究经验已经告诉了我们答案。Php的mail()函数底层其实就是调用了linux下的sendmail命令。由于sendmail支持一些有趣的参数,这可能会造成更大的损害。①写日志引起的RCE继上面的内容,我们先介绍一下sendmaill的X和O参数,它们的作用是:-Xlogfile:指定一个文件来记录邮件发送的详细日志。-Ooption=value:临时设置邮件存储的临时位置。看到这里,大部分读者应该都能第一时间反应过来。我们可以指定一个文件来存放邮件发送的日志,那么我们可以写loggetshell吗?这是真的。了解了这些信息,我们再回头看看mail()函数支持的第五个参数:是的,我们可以通过这个第五个参数来控制sendmail的附加参数,所以我们可以控制X参数的值。向上?我们可以使用下面的demo来测试:';//任何你想执行的php代码$message='';//同上$headers='';$addtionparam='-fLa2uR1te@1-OQueueDirectory=/tmp/-X/var/www/html/1.php';//假设我们知道目标站点的绝对路径mail($to,$subject,$message,$headers,$param);?>比如我在我的服务器上运行下面的代码,我们假设网站的根目录是/root/,我们运行上面的代码,看看会发生什么。(复现时一定要安装sendmail,否则没用)。运行之后,我们确实在根目录下找到了一个名为testmail.php的文件。我们看看它的内容是什么:其实它有很多内容,就是日志文件。但是看箭头所指的地方,毫无疑问我们的代码已经写成功了。这个时候如果我们用php来执行这个testmail.php,注意前后的区别。当前用户为root,当前目录下只有testmail.php和test.php。毫无疑问,我们的恶意代码已经成功执行。综上所述,如果我们知道目标网站的绝对路径,目标网站是linux环境,PHP底层使用sendmail发送邮件(默认),那么我们就可以使用mail()函数执行写好的GETSHELL到日志文件。②读取配置文件导致的任意文件读取这个功能的乐趣还不止于此,它还可以用于任意文件读取。我们修改一下上面的demo,注意这里,我们用的是-C参数,后面是我们要读取的文件。这样就可以直接读取任何文件了!如下图,直接用飞梭读取文件③进阶技巧:使用配置文件来执行代码想象一下这样变态的情况,整个网站,假设我们只有一点写文件,而且有一个很严格的筛选。这时候是不是可以用mail()来操作呢?让我们回到sendmail命令的特性。默认情况下,sendmail-mta将用于解析要发送的邮件的内容。我们其实有办法覆盖sendmail的解析配置,让它使用php来解析我们要发送的邮件内容,从而直接完成命令执行。我们首先转到/etc/mail/sendmail.cg并复制其内容。然后在其内容末尾添加如下配置:Mlocal,P=/usr/bin/php,F=lsDFMAw5:/|@qPn9S,S=EnvFromL/HdrFromL,R=EnvToL/HdrToL,T=DNS/RFC822/X-Unix,A=php--$u$h${client_addr}把这个新文件命名为sendmail_cf然后我们执行下面的命令,因为这个东西不能回显,所以我们让它新建几个文件:(恭喜各位高手FaCaiHappyNewYearha)执行以上代码后。可以看到tmp目录下多了一个xnklgxfc(提前祝各位高手新年快乐,恭喜发财)④进阶技巧:Exim4mail()函数运行的情况下,环境没有配置好,所以演示不成功,所以我会用其他的作为高手的结果,虽然mail()函数的底层是sendmail命令,但有时也可能是exim4命令。假设在ubuntu/debain中,sendmail实际上符号链接到exim4。也就是说,我们有了新的姿势(exim4的各种参数和可以玩的操作都不一样)。这里我们介绍一个,-be参数。该参数是exim4中的运行扩展模式参数。该参数支持我们进行很多操作,例如:-be${run{}{}{}}//执行命令,返回string1成功,失败返回string2-be${substr{}{}{}}//字符串截取,从string3中的string1开始截取string2字符-be${readfile{}{}}//读取文件名,按eolstring分割-be${readsocket{}{}{}{}{}}//发送socket消息,消息内容是request,没错,你可以发现除了直接执行命令(不用写日志文件getshell),虽然不能回显,打一个shell也是简单的。而且它仍然可以读取任何文件。而且最骚的是substr可以用来进行字符串拦截,支持我们进行很多绕过WAF的操作。使用mail()创建一个简单的后门。上面说的各种mail()操作,除了在学习和复现的过程中觉得NB之外,我无话可说。它的各种特性让我思考它是否有成为后门的潜力。可以在普通Linux环境下实现loggetshell和读取任意文件。它还可以在其他特定情况下执行不带回显的命令。而且是一个很正常的功能,一般的开发和安全人员可能不会想到这样一个无害的邮件发送功能会造成什么危害。抱着这种心态,我简单的实现了这样一个功能:$e的明文内容是:-fLa2uR1te@1-OQueueDirectory=/tmp/-X/root/mailshell.php和$a/$b/$c的内容/$d都是phpshell。下面我们将其带到实际环境中,看看能否成功实现刚才演示的效果。如果运行成功,如图所示,在根目录下应该会生成mailshell.php,成功生成的mailshell.php内容是一段php。所以我们继续修改这个后门,让它更可控。根据上面的总结,我们可以知道我们只需要控制第五个参数,所以我们的改造也很简单:这个后门最终可以达到的效果包括但不限于:①在linux环境下写入任意文件(可以getshell)②linux环境下③特定环境下没有echo命令执行和代码执行(比如mail()使用exim4或者底层软链接到exim4)。截至本文发表,这个极其简单的后门依然具备不错的反杀能力:后记这篇文章之所以被说成是炒饭,是因为安全圈至少已经知道了mail()函数带来的危害2016年之前。而更深入的使用姿势在17年和18年被高手总结过(绿盟高手和安衡高手)。对于我这个新人来说,真是大开眼界,惊艳不已。果然,漏洞再现一定要及时,不然很容易错过很多有趣的知识。更多网络安全技能在线实战练习,请点击这里>>