PHP代码审计之WEB安全系列基础文章(三)之命令执行篇
【如需转载,请详细表明来源,请勿设置原创】
嗨,大家好,我是闪石星曜CyberSecurity创始人Power7089。
欢迎大家扫描下方二维码关注 “闪石星曜CyberSecurity” 公众号,这里专注分享渗透测试,Java代码审计,PHP代码审计等内容,都是非常干的干货哦。

今天为大家带来PHP代码审计基础系列文章第三篇之命令执行篇。
这是【炼石计划@PHP代码审计】知识星球第二阶段的原创基础系列文章,拿出部分课程分享给零基础的朋友学习。本系列原创基础文章涵盖了PHP代码审计中常见的十余种WEB漏洞,是匹夫老师精心的创作,欢迎关注我的公众号跟着一起学习。
【炼石计划@PHP代码审计】是一个系统化从入门到提升学习PHP代码审计的成长型知识星球。这里不仅注重夯实基础,更加专注实战进阶。强烈推荐加入我们,一起来实战提升PHP代码审计。

PHP代码审计之命令执行
1.命令执行原理
通过调用PHP中命令执行函数,且函数中的参数可控就会造成命令执行。以Web中一句话木马为例,常见的PHP一句话木马<?php system($_REQUEST['value']); ?>,这里通过system()函数将前端传入的值当做系统命令执行,其中value参数由前端传入。
1.1 命令执行示例代码
cmd.php
下面示例代码将前端传入的value参数值带到system()命令执行函数中去执行,值得注意的是system()函数自带回显,不用使用echo或者var_dump()进行输出。
1 | |
value传入calc.exe即可调用system()函数弹出计算器。

2.命令执行相关函数
exec()、shell_exec()、system()、popen()、passthru()、proc_open()、pcntl_exec()、 反引号``实际上是使用shell_exec()函数。
exec()
该函数无回显需使用echo进行输出,且只返回执行后的最后一行结果。
示例代码:
1 | |
我们执行ipconfig只返回了结果中最后一行结果

执行whoami结果将不受影响,因为返回结果只有一行

shell_exec()
该函数无回显需使用echo或者var_dump进行输出,但返回结果所有内容。
示例代码:
1 | |
我们传入系统命令ipconfig则会输出所有结果

``反引号
反引号其实调用的是shell_exec()函数,当反引号中的变量可控时就会造成命令执行,且无回显。
示例代码:
1 | |
我们传入系统命令ipconfig则会输出所有结果

system()
该函数会将输入的参数当做命令执行,有回显且返回所有内容。在实战中也是最常见的造成命令执行漏洞的函数之一。
这里注意:如果目标是LInux则执行Bash命令,如果是Windows则执行cmd命令。
passthru()
该函数与上述system()函数类似,也可将输入的参数当做命令执行,且函数执行后有回显。
示例代码:
1 | |
我们传入系统命令dir则会输出所有结果

popen()
该函数通常用于打开进程文件指针,但如果传入的参数可控也可造成命令执行,且该函数无回显,通过echo不回直接返回执行的结果,而是返回的是文件指针。

示例代码:
1 | |
这里调用我们的popen()函数执行calc.exe打开了计算器。

proc_open()
执行一个命令,并且打开用来输入/输出的文件指针。 类似 popen()函数,但是 proc_open() 所需参数更多,且处理数据能力更强。
3.系统命令执行
在很多IoT设备如路由器中会存在如下类似的代码,本来设计的功能点是测试网络通信情况,但由于传入的参数没有进行严格的过滤就传入到命令执行函数中,最终导致命令执行。
ping.html
1 | |
ping.php
1 | |
我们使用|来分割前面的ping命令,将我们的ipconfig命令单独分割出来造成命令执行。

由于|会直接执行后面的命令,所以直接输出了ipconfig的内容。

4.命令执行漏洞利用姿势
常见管道符
由于Linux和Windows中命令执行的方式不同,Linux中执行的是bash命令,而Windows执行的是cmd命令。常见的管道符如下:
Windows:
| 直接执行后面的语句

|| 如果前面执行的语句出错,那么才执行后面的语句

& 前面和后面的语句都会被执行

&& 前面语句出错后面的语句也不执行,只有前面的语句成功执行才执行后面的语句

Linux:
Linux中除了上面的管道符外还有一个;
; 前面的语句执行完成后,继续执行后面的语句。

1 | |
5.命令执行代码审计总结
1 | |