从一次有趣的漏洞分析到一个有趣的PHP后门
起因事情的起因很有趣,前几天我正对着电脑发呆的时候,突然有个安全交流群的群友来找我交流一个问题
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519119.png
大概的意思就是,他在挖SRC的时候,发现一处资产存在目录遍历漏洞,它通过这个漏洞,找到目标资产使用了一个名为phpmailer的中间件(应该类似于中间件吧),问我有没有办法利用,我查了一下这个组件的漏洞信息。最新的洞似乎截止到6.5.0版本以前
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519120.png
很不幸,群友这个版本是6.5.1,刚好就不能利用了
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519121.png
找不到符合版本的洞没关系,抱着学习的心态,我还是看了一下它的历史漏洞成因,不看不知道,看了之后就学到一些好玩的新知识了,这也就是为什么会有这篇文章的原因。
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519122.png
CVE-2016-10033的简单分析
CVE-2016-10033是Phpmailer出现过的最经典的的漏洞,在本文正式开始之前,我们先来简单分析一下这个漏洞。读者可以到:
https://github.com/opsxcq/exploit-CVE-2016-10033/blob/master/src/class.phpmailer.php
看到phpmailer的代码。这里先开门见山地说,漏洞的成因其实就在mail()函数的第五个参数,只要控制了第五个参数,我们就能进行RCE、文件读取等操作。因此我们先追溯mail()函数:
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519123.png
因此我们可以先定位到mailPassthru()这一方法,可以看到,这个方法内部就使用了mail(),maill的第五个参数也就是mailPassthru()的第五个参数。
【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC漏洞分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)
因此,我们再查看有没有别的地方使用了mailPassthru(),可以找到这个maillSend()方法中使用了mailPassthru()方法,并且第五个参数$params是来自于当前类中的Sender属性
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519124.png
那我们回溯Sender属性,看看有什么地方可以控制Sender属性。
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519125.png
这里可以看到,setFrom方法当中,就可以对Sender属性进行赋值
当然,这个漏洞还有一个重点就是对validateAddress()这一方法的绕过,这也是CVE-2016-10033的精彩部分。
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519126.png
但是它和本文的重点不符,所以我们就不深入分析这块。
既然知道了Sender这个关键属性是怎么赋值的,接下来我们继续分析mailSend()方法的调用链,可以找到postSend()方法
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519127.png
继续看postSend(),最终可以找到send()方法
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519129.png
自此,整个漏洞的传参流程我们就已经分析完了。大体上来说,只要我们用setFrom()方法对Sender属性赋值,再调用send()方法。那么Sender属性的值就会进入到mail()函数的第五个参数中,从而实现RCE。看到这想必很多读者已经对开篇提到的这个mail()函数的第五个参数提起兴趣了,为什么控制了它就能实现RCE呢?这就要提到php中 mail()函数的实现原理了。
有趣的mail()
mail()函数是php定义的用来发送邮件的函数,其支持的参数如下:
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519130.png
为什么一个发送邮件的函数能造成RCE?前人的安研经验已经告诉了我们答案。Php的mail()函数,其底层其实是调用了linux下的sendmail命令。由于sendmail支持一些有趣的参数,这就会造成更大的危害。
①日志写入导致的RCE
接着上面提到的内容来说,我们首先要介绍的是sendmaill的X和O参数,其效果分别为:
-X logfile :指定一个文件来记录邮件发送的详细日志。
-O option=value :临时设置一个邮件储存的临时位置。
看到这大部分读者应该马上能反应过来,我们能指定文件来储存邮件发送的日志,那不就可以写日志getshell了吗?事实也的确如此。了解这个信息之后,我们再回过头看mail()函数支持的第五个参数:
https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202302141519131.png
没错,我们可以用这个第五个参数来控制sendmail的额外参数,那我们控制X的参数值不就拿下了?我们可以使用如下demo进行测试:
页:
[1]