Part1 前言
在日常的渗透测试、红队项目、攻防比赛中,sql注入仍是广泛存在的一种漏洞,只要花时间仔细找,注入漏洞总会有的。sqlmap是目前最常用的注入工具,但是sqlmap也不是万能的,也有不足之处。
1. 对于SQL Server注入,sqlmap没法自动枚举网站目录,读取文件和执行命令功能方法单一,不够完善,不能通过opendatasource和openrowset函数快速出数据等。
2. 对于Oracle注入,提权功能与执行命令功能都有欠缺;对于Access注入,不支持爆路径及特殊情况下的命令执行。
但是相反有很多古老的注入工具,整体功能虽然不如sqlmap强大,但是却很好的实现了上述功能,但是毕竟是古老工具了,由于各种原因,不适合当前的网站环境了,必须加以改造,有什么方法实现对这些注入工具的改造呢,接下来听我慢慢讲。
Part2 古老的注入工具介绍
为了照顾一些新手,先介绍几款上古时代强大的注入工具,那时候的很多工具还是比较经典的。
- Data Thief注入工具
Data Thief V1.0 这款国外的注入工具距今19年了。专门针对SQLServer注入漏洞,通过opendatasource或者openrowset函数来实现快速出数据。需要事先在外网准备一个sqlserver数据库,配置之后可以实现对于一些盲注点快速获取结果。
- CADT v1.0注入工具
这款工具是黑哥和xiaolu写的,18年前的工具了,功能与Data Thief差不多,可以实现执行命令、列目录等功能。
- 管中窥豹Liqidis注入工具
这款商业版的注入工具距今有10几年了吧,细化了很多注入漏洞利用功能,对于SQLServer可以实现执行命令、列目录、上传二进制文件等等。
- Safe3的注入工具
经常可以应对一些奇葩的注入点,也增加了很多执行目录、列目录等辅助功能。
- 古老工具无法使用的原因
遗憾的是,这些10几年前的工具放到现在几乎都用不了了,不适用于现在的网站环境了,原因大致有以下几点:
1 在10几年前,注入点的利用方式都集中在GET型上,对于Post型注入和Cookie注入支持的都不是太好。
2 对于Json数据包中的注入、XML包的注入等等都不支持,也没法对Header头进行设置,比如说设置一个content-type:application/json等,导致一些网站不能正常使用。
3 对于一些复杂的数据包,无法像Sqlmap那样指定一个*星号去使用,极大限制了这些工具的发挥。
4 如果遇到了waf,这些古老的注入工具没法进行绕waf规则替换。
Part3 技术研究过程
那有没有一种方法,一劳永逸解决这些问题,让这些古老的工具继续发挥作用呢?
- 注入中转生成器
为此我踩了很多坑,我想到了一个15年前的工具,“寂寞的刺猬”用VB写的“注入中转生成器”工具,这个工具巧妙地把POST型注入、Cookie型注入中转到了url上面,变成了GET型注入。但是这个工具放到现在,适用范围很窄了,因为它依赖于asp代码编写,asp代码实现一些功能是非常麻烦的。
点击“生成ASP”后,这个工具会生成一个asp文件,大致原理如下:工具在本地启动了一个http服务器,asp代码承担了把注入工具的发来的GET请求转为网站能用的POST型请求或者Cookie型请求。
- Go语言的HandleFunc函数
后续经过一系列探索,发现了go语言的这个HandleFunc函数比较适合做这个“注入中转”功能。该方法接收两个参数,一个是路由匹配的字符串,另外一个是 func(ResponseWriter, *Request) 类型的函数:
如下图所示,这段代码先利用http.HandleFunc在根路由/上注册了一个httpFunction, 然后利用http.ListenAndServe启动服务器并监听本地的 8888端口。当有请求过来时,则根据路由执行对应的handler函数。
httpFunction代码实现如下:如果有绕waf需求,还可以在这里面进行关键字替换,比如把=替换成like,把空格替换成TAB或者/***?id=1***/等。
Go语言的强大,使得实现“注入中转”功能非常简单,不用多少行代码就可以搞定。启动程序之后,访问如下url:http://127.0.0.1:8888/?sql=1,发现可以正常返回原有网站页面。证明功能没问题,接下来就可以让那些古老工具成功注入了。
- 实战测试
来看一下Safe3的注入工具,成功以GET请求方法对这个POST型注入点利用,并且成功枚举当前目录。
再看一下管中窥豹LiQiDiS工具,以GET请求方法,对POST型注入点成功利用,并且可以直接一键列出目录。
执行命令也是没问题的。
BSQLHacker支持深盲注入的工具,也是可以成功的。
至此,通过go语言的一个函数HandleFunc使用,完美解决了这一问题,这个HandleFunc函数还有很多妙用,后续我们再举例分享。
专注于网络安全技术分享,包括红队攻防、蓝队分析、渗透测试、代码审计等
每周一篇,99%原创,敬请关注