一次sm4参数加密下的sql盲注

  • A+
所属分类:安全文章

本文转自公众号:https://xz.aliyun.com/t/8071

0x00 前言


  在一次授权渗透测试中,应用在前端使用sql语句拼接方式传送参数,很明显存在sql注入,提交漏洞后,用户大概不想重构项目,于是将前端参数传输前均进行加密,但是通过JS找到加密密钥后,结合py脚本还是注入了;后续用户再次升级将设计加密的JS也加密混淆了,不过还有办法找到密钥,借此分享,过程中踩坑绕弯,欢迎大表哥们交流指导。

0x01 第一次常规测试

  1. 如下图点击功能抓数据包,可以发现参数中明显有SQL语句,后使用1=1 和 1=2 确定了注入点,但是没有返回值,只能盲注了。
    一次sm4参数加密下的sql盲注

  2. py写个脚本,简单爆破了一下数据库长度、数据库名等信息
    一次sm4参数加密下的sql盲注


0x02 第二次参数使用SM4加密

  1. 接到复测通知,看了下系统,发现参数被加密了,如下图
    一次sm4参数加密下的sql盲注

  2. 这里找加密方法的图没截,大概就是找到对应的ajax方法,可以看到md5_bean参数的生成通过base.js的encryptData_ECB方法生成,打开base.js清晰可见sm4字样以及secretkey和iv,如下图
    一次sm4参数加密下的sql盲注

  3. 接下来是如何注入,本来想构造一个sqlmap的tamper脚本,但是发现这个是把所有参数一起加密了,没得思路了,于是还是用py写盲注脚本吧,但是网上找的python实现sm4加密的结果都不一样,考虑到这个后台是java的,肯定是java做的解密,于是找了java的sm4实现,试了一下,结果可以了,于是尝试用py调用打包好的jar包进行注入(这里绕了一个大圈,实际上使用py调用js就行,第三次测试的时候更新了)

一次sm4参数加密下的sql盲注

import requests   import json   import os   from urllib.parse import quote
header = { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" } pay = '01[email protected]#$%^&*()'
proxies = { 'http':'http://127.0.0.1:8080' } #request构造请求,传入data中的_searchWhere
def attack(payload): url = "http://" data = "{"_searchWhere":" %s","title":"","paramsFlag":"false","parVar":"","frameId":"=","readOnly":"","extWhere":","type":"","parWhere":"","dataFlag":""}" % payload data = quote(data,'utf-8') command = "java -Dmoudle=e -Dstr=%s -jar sm4Decode.jar" % data data_sm4 = "".join(os.popen(command).readlines()) data_send = {"md5_bean":data_sm4} cookies = {"": ""} result = requests.post(url=url, data=data_send, cookies=cookies, headers=header ,proxies=proxies) return len(result.text) if __name__ == '__main__': # 判断数据库 for i in range(1,20): payload = "and (select length(name) from v$database)=%s" % str(i) print(payload) lenstr = attack(payload) if lenstr > 3000: print(lenstr) print("数据库长度是%s"% str(i)) break else: print(lenstr)


4.此时客户疑问,这个sql注入1=1 1=2返回结果是不同、暴露一个数据库版本等信息又有什么用,于是多注了一点信息,证明危害,获取用户表名的过程比较啰嗦,这里只有是结果图。
a. 用户表数据

一次sm4参数加密下的sql盲注

b. owner表数量
一次sm4参数加密下的sql盲注


0x03 第三次JS加密混淆隐藏密钥

  1. 最后一次复测,用户表示已经没问题了,让再看一下,由于时间有点长,重新找一下加密算法位置

    使用抓包抓到的URL,在chrome调试工具中search一下位置,打下断点,点击功能看一下是否触发断点。

    一次sm4参数加密下的sql盲注

    一次sm4参数加密下的sql盲注

  2. 接下来一步一步跟下去,找到参数构造md5_bean参数的位置
    一次sm4参数加密下的sql盲注

  3. next找到base64.js,发现代码已经压缩而且加密了。
    一次sm4参数加密下的sql盲注

  4. 遇到JS加密了如果有实力的大佬可以解密js或者 https://www.sojson.com/jsobfuscator.html 付费解密,不过只是想得到密钥和iv的话,可以在断点进入base64.js后,调试窗口肯定会显示密钥和iv值,因为不管怎么混淆,代码还是要被正常执行的。

    一次sm4参数加密下的sql盲注

  5. 接下来又是注入了,之前用的脚本思路太麻烦了,这次简单点,直接调SM4加密的js,由于这段js已经混淆了,于是从网上找来base64.js的源码简单改了一下,使用python的execjs调用加密。

a. java解开加密内容如图

一次sm4参数加密下的sql盲注

b. python调用js加密明文内容,对比结果(调用js的代码如图,上面没有了,因此没有粘过来,感觉内容有点啰嗦了)
一次sm4参数加密下的sql盲注

6.如此便不用java介入了,之后的操作就是利用之前的盲注脚本,修改一下data参数的加密获取就行了,重复的盲注过程。

0x04 总结

  1. 实际上现在得web框架中很少这种前端传js的了,但是在很多老企业中还是有部分网站不想重构,这样的例子有很多,第一次开发说出这种修复sql注入的方法时,还很犹豫的回答,还可以注入吧。。。,没想到真的有人这样修复,随着一次一次的治标不治本,自己也在不断探索学习。

  2. 有的时候感觉除非大厂,很多网站如果一抓包看到把参数一起加密了,很有可能是在想隐藏什么漏洞。。。

  3. 还有一个小坑,加密js在JavaScript中需要手动new一个对象,再用py调用对象+方法。


一次sm4参数加密下的sql盲注

相关实验:

SQL盲注 

https://www.hetianlab.com/expc.do?ec=ECID172.19.104.182015060917014100001

(本实验以PHP和mysql为环境,简单展示了SQL的发生原理和利用过程,通过显错注入和盲注的对比,更直观展现注入的不同利用方法。)


欢迎投稿至邮箱:[email protected]

有才能的你快来投稿吧!

投稿细则都在里面了,点击查看哦

重金悬赏 | 合天原创投稿涨稿费啦!

一次sm4参数加密下的sql盲注




点击这里提升自己

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: