关于RCE,在学习过程中其实已经接触到了很多,但在学习的时候都是这儿那儿一点一点的拼接起来的,所以看了很多大佬的博客,总结了一下,打算写一篇博客,好好的整理一下自己学习RCE所学到的东西。
RCE概述
RCE,即remote command/code execute,远程代码执行(eval),远程命令执行(ping)。
在Web应用开发中为了灵活性、简洁性等时,会让应用调用代码执行函数或系统命令执行函数进行处理,如PHP中的system,exec,shell_exec,popen等,当应用开发人员对用户的输入参数过滤不严,并且用户可以控制这些函数的参数时,就可以将恶意命令拼接到正常的命令,造成攻击,或者控制后台系统。简单一点来说的话,RCE就是远程命令执行漏洞。
举个例子:我们常见的路由器、防火墙、入侵检测等设备的web管理界面上,一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。其实这就是一个接口,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统,这就是RCE漏洞
RCE漏洞是非常严重的安全漏洞,一旦出现,就意味着攻击者可以获取服务器的命令执行权限,从而对服务器安全造成极大的影响。
关于代码执行和命令执行的区别:一个是执行的脚本代码,一个是执行的系统命令。
利用条件:
1.开发人员调用了能够执行系统命令的函数
2.这个函数的参数可控(即用户能够控制)
3.开发人员没有对该函数的参数进行过滤或过滤不严
#当然,过滤程度取决于我们自己的绕过能力,哈哈哈
常见的RCE利用函数
系统命令执行函数
system():能将字符串作为OS命令执行,且返回命令执行结果;如:ls,cat,ifconfig等
system("ls");
system("ls /");
system("cat /flag");
exec():能将字符串作为OS命令执行,但是只返回执行结果的最后一行(约等于无回显);直接执行命令,或者间接使用其它函数达到执行命令的目的
shell_exec():能将字符串作为OS命令执行,与``的作用相同,也没有回显,需要使用echo或者其他函数达到回显的目的
passthru():能将字符串作为OS命令执行,只调用命令不返回任何结果,但把命令的运行结果原样输出到标准输出设备上;与system()差不多,在system被过滤时可以使用这个函数
popen():打开进程文件指针
proc_open():与popen()类似
pcntl_exec():在当前进程空间执行指定程序;
反引号``:反引号``内的字符串会被解析为OS命令;
代码执行函数
eval():算是RCE中最常见的函数,将你需要执行的某些东西作为php代码执行,达到利用一些未被禁用的危险函数来达到执行命令的目的。官方的说明:
assert()断言函数:它会将字符串作为php代码执行;跟eval()相似。官方说明:
preg_replace():正则匹配替换字符串;
create_function():主要创建匿名函数;
call_user_func():回调函数,第一个参数为函数名,第二个参数为函数的参数;
call_user_func_array():回调函数,第一个参数为函数名,第二个参数为函数参数的数组;
call_user_func()和call_user_func_array()相同,只是它两个的传参不同
RCE的绕过
过滤空格
%09(url传递)(cat%09flag.php)
${IFS}(cat${IFS}flag) #个人觉得是最好用的
$IFS$9
<>(cat<>/flag) #还未使用过,重定向符代替空格
<(cat</flag) #还未使用过,重定向符代替空格
{cat,flag}%0a (cat%0aflag)
过滤了cat,cat的替换
more:LInux命令(逐项查看文件,按空格继续,最后自己退出)一页一页的显示档案内容
less:与 more 类似,LInux命令(逐行查看文件,按方向键继续,不可主动退出,按Q退出)
head:查看前十行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看后十行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,可以查看
vim:一种编辑器,可以查看
sort:可以查看(还未使用过)
uniq:可以查看(还未使用过)
一些常见的绕过
\绕过,'"单引号双引号绕过,`反撇号绕过
在写题的时候,当cat,ls,flag等过滤时,使用\绕过,或者',",`都可以进行绕过
ca\t flag
l\s
ca''t flag
ca``t falg
变量绕过,拆分绕过
两个其实差不多,例如当cat被过滤时,我们可以将c赋值给变量a,将a赋值给变量b,将c赋值给变量c,然后输出
a=c;b=a;c=a;echo $a$b$c flag;
当flag被过滤时,也是同样的道理
a=fl;b=ag;echo $a%b;
进制编码绕过
base64
cat flag 的base64编码为 Y2F0IGZsYWc=,
16进制,base家族,hex编码等都可以进行绕过
正则绕过
当文件名,例如flag被过滤时,我们可以使用正则绕过
cat /f*
cat /fl* #*相当于正则匹配
cat /f[a-z]{} #在a-z里匹配字母,匹配3个字母
无回显RCE
一般会有shell_exec等无回显函数。我们执行命令之后,它并不会回显出我们想要的内容,我学到的方法是,可以将执行结果输出到一个文件里,再访问文件即可,例:执行tee命令创建一个文件,将我们执行命令想要得到的内容放在这个文件里,然后再访问这个文件得到我们需要的内容
例:
Rceeee(web)
无回显RCE,
Url:?cmd=ls /|tee a.txt
然后访问a.txt,看到flag
直接:?cmd=cat /f*|a.txt
然后再访问得到flag