雷池waf绕过之前奏
众所周知,在现代化中的waf中,长亭的雷池waf、阿里的伏魔、以及宝塔的waf,在这众多的waf中,雷池waf和宝塔waf比较受欢迎,因为他免费。那么免费的东西真的就一定是最安全的产品嘛?这可不一定,那么让我们来进行尝试绕过waf的限制。在进行绕waf的前提下,我们要进行环境的搭建和一些基础知识的探讨,以下便是我们对雷池waf绕过的前奏。此篇文章仅仅是环境搭建和绕过waf的原理基础只是。
一、环境搭建
1.1靶场部署
自行找两台虚拟机进行演练,一台为我们的服务器,另一台为我们的雷池waf,靶场的部署我们使用sqli-labs的靶场为基础,进行使用雷池waf绕过。此靶场的环境以及下载包自行可在网上寻找,部署环境一大推,在此省略此部分的部署,主要讲雷池waf的部署。
1.2雷池安装
安装雷池的链接如下:https://help.waf-ce.chaitin.cn/node/01973fc6-df0f-7650-bafa-8ed8d2fc2bc1
安装时,直接进行安装,在安装的过程中出现的问题大概可能因为你的内存原因导致的,遇到这种情况下进行扩容,从而来顺利的安装雷池waf。在安装完雷池waf后,进行相应的配置,我这里使用劫持域名来到雷池waf的流量,具体的配置如下:
在雷池waf安装后,点击防护应用进行添加应用,因为我们没有SSL证书,所以去掉443端口,使用80进行访问。在雷池waf中,所谓的上游服务器就是我们数据的来源,也就是我们的另一台服务器。这这里顺便解释一下上下游和上下行链路的问题,这个问题花了好长时间进行解决。
上游:就是我们的数据的源头
下游:是数据从源头出来的地方
上行链路:类似上传的问题,数据到达的服务器的方向
下行链路:从服务器出来,到达主句的方向
在进行劫持后,将域名填写到windows的host文件中和雷池waf的中,上游服务器就填写自己的虚拟机的服务器。如下图1-1所示:

图1-1(waf配置图)
1.3代码改写
在如今的环境下,雷池waf在get传参已经不可能进行绕过了,但是在post的情况下存在一定的可能性,我们将sqli靶场中的11关进行修改,使得消除一下不必要的因素,删除所有这关的password,以及去数据库传输的password,使用用户名亦可以进行查询,具体修改后的代码如下:
html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Less-11- Error Based- String</title>
</head>
<body bgcolor="#000000">
<div style=" margin-top:20px;color:#FFF; font-size:24px; text-align:center"> Welcome <font color="#FF0000"> Dhakkan </font><br></div>
<div align="center" style="margin:40px 0px 0px 520px;border:20px; background-color:#0CF; text-align:center; width:400px; height:150px;">
<div style="padding-top:10px; font-size:15px;">
<!--Form to post the data for sql injections Error based SQL Injection-->
<form action="" name="form1" method="post">
<div style="margin-top:15px; height:30px;">Username :
<input type="text" name="uname" value=""/>
</div>
<div style=" margin-top:9px;margin-left:90px;">
<input type="submit" name="submit" value="Submit" />
</div>
</form>
</div></div>
<div style=" margin-top:10px;color:#FFF; font-size:23px; text-align:center">
<font size="6" color="#FFFF00">
<?php
include("../sql-connections/sqli-connect.php");
error_reporting(0);
if(isset($_POST['uname']))
{
$uname=$_POST['uname'];
$fp=fopen('result.txt','a');
fwrite($fp,'User Name:'.$uname);
fclose($fp);
@$sql="SELECT username, password FROM users WHERE username='$uname'";
$result=mysqli_query($con1, $sql);
$row = mysqli_fetch_array($result, MYSQLI_BOTH);
if($row)
{
echo "<br>";
echo '<font color= "#FFFF00" font size = 4>';
//echo " You Have successfully logged in\n\n " ;
echo '<font size="3" color="#0000ff">';
echo "<br>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo "</font>";
echo "<br>";
echo "<br>";
echo '<img src="../images/flag.jpg" />';
echo "</font>";
}
else
{
echo '<font color= "#0000ff" font size="3">';
//echo "Try again looser";
print_r(mysqli_error($con1));
echo "</br>";
echo "</br>";
echo "</br>";
echo '<img src="../images/slap.jpg" />';
echo "</font>";
}
}
?>
</font>
</div>
</body>
</html>
修改代码之后我们进行测试,看我们的waf和服务器是否已经开始连接,使用铭感数据进行测试,如下图1-2所示,那么你的waf将会部署成功。

图1-2(waf响应图)
二、绕过waf原理
以前的waf有的是将正则写入,底层还是通过正则来进行控制,但是这中杀的太死而且规则很死板,面对这些正则所写的,使用正则回溯来进行绕过,那么雷池的waf怎么绕过呢?是换函数?还是通过大小写来进行绕过?这些都不是,这些放在以前可能会进行绕过,但是现在,NO!NO!NO!,那么我们到底是怎么进行绕过的?绕过的思路是啥?这是我们进行讨论的,雷池的waf是语义化的,背后有大模型进行拦截。所以我们唯一的方法就是骗过waf,数据从而到达后端进行执行。这是我们主流的思想。
对于一个HTTP请求,Nginx解析了啥内容?交给后端又解析了啥内容、ASP又解析了啥,针对这个我们进行本机测试。
使用php为例,进行测试,查看后端的处理代码是如何进行处理。使用php为后端代码进行测试,php后端的代码如下:
php
<?php
echo "<pre>"; // 加上这一行,瞬间整齐
echo "--- 原始输入 (非 multipart 时有效) ---\n";
echo file_get_contents("php://input") . "\n\n";
echo "--- POST 数据 ---\n";
print_r($_POST);
echo "\n";
echo "--- FILES 数据 ---\n";
print_r($_FILES);
echo "</pre>";
?>
文件上传的代码如下:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="demo.php" method="post" enctype="application/x-www-form-urlencoded">
<input type="text" name="username">
<input type="submit">
</form>
</body>
</html>
POST提交的代码如下所示:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="demo.php" method="post" enctype="multipart/form-data">
<input type="text" name="username">
<input type="submit">
</form>
</body>
</html>
以上的准备工作已经做好,那么我们为啥需要进行一个上传功能和正常的POST提交参数呢?你可以这样来想,你只有上传接口,但是你要存在拼接自己的语句进行后端查询,那么这样怎么做呢?上传接口只是上传接口嘛?他能不能通过修改一些字段来进行提交我们的post数据呢?这样不仅绕过了waf的检测,而且到后端查询数据使用post提交数据的格式,这样会存在嘛?答案是。下面让我们来进行模拟。
使用正常的Post进行提交数据,查看后端是怎么接受数据的。打开post.html进行测试。如下图所示1-3:

图1-3(正常POST提交)
如上图所示,我们正常提交的为POST参数,后端接受的便是POST的,那么。我们将包的类型改了呢?改为上传包的情况下,那么数据的传输到后端是啥来进行解析,如下图1-4。

图1-4(异常的提交结果)
可以清晰的看到,不论是请求包还是上传包,我们的数据都是存在后端的POST来进行提交。那么使用上传文件的类型呢?如下图所示1-5所示:

图1-5(正常上传接口)
可以清晰的看到,我们的正常上传数据包在后端是使用文件协议的情况下来解析,那么不正常呢?有没有不正常的数据包从而导致进行POST来处理呢?
经过测试,确实存在这样的情况,在上传的请求包中,我们通过修改filename的名字来通过提交,导致我们的参数会存在后端POST进行处理,那么假如只有上传接口,只能进行上传嘛?如下图1-6所示,

图1-6(异常上传导致POST进行处理)
那么我们就可以进行在上传的情况下可以进行绕过waf,导致后端处理的是我们的参数,使用POST进行处理。以上便是我们绕过雷池的前奏。