配合mitmproxy使用自动化工具测试阿里云API网关接口
对阿里云API网关接口(ali api gateway)的每次请求都需要校验签名,url和body变动都会导致签名变化。这就导致在渗透测试过程中,无法使用SQLMAP这样的自动化工具来测试api gateway接口的sql注入漏洞。
mitmproxy(https://mitmproxy.readthedocs.io/en/v2.0.2/mitmproxy.htm) 顾名思义,mitmproxy 就是用于 MITM 的 proxy,MITM 即中间人攻击(Man-in-the-middle attack)。
用于中间人攻击的代理首先会向正常的代理一样转发请求,也可以查、记录其截获的数据,或篡改数据,引发服务端或客户端特定的行为。
同理,可以将一个没有签名header的request接获,添加签名头,再发给api服务器,从而让自动化测试工具只需要配置一个代理即可正常工作。
签名代码如下,修改了部分签名代码,将url和data作为参数,方便在mitm.py里面调用:
# -*- coding: UTF-8 -*-
import json
import requests
from sdk.util import UUIDUtil, DateUtil
from sdk.auth import md5_tool, signature_composer, sha_hmac256
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
appKey = "xxx"
appSecret = "xx"
def signreq(data,aurl):
u = urlparse(aurl)
host = u.scheme + '://' + u.netloc
url = u.path
timestamp = DateUtil.get_timestamp()
Datet = DateUtil.get_rfc_2616_date()
accept = '*/*'
request_method = "POST"
xcanonce = UUIDUtil.get_uuid()
contentmd5 = md5_tool.get_md5_base64_str(json.dumps(data))
str_to_sign = ''
headers = {
'Content-MD5': contentmd5,
'User-Agent':'Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.12(0x17000c2d) NetType/WIFI Language/zh_CN',
#'Content-Length':'',
'Content-Type': 'application/json',
"Accept": '*/*',
"Date": Datet
}
headers['x-ca-signaturemethod'] = 'HmacSHA356'
headers['x-ca-nonce'] = xcanonce
headers['x-ca-key']= appKey
headers['X-ca-stage']= 'RELEASE'
str_to_sign = signature_composer.build_sign_str(uri=url, method=request_method,
headers=headers)
xcasignature = sha_hmac256.sign(str_to_sign, appSecret)
headers['X-Ca-Signature'] = xcasignature
headers['X-Ca-Signature-headers'] = "x-ca-key,x-ca-nonce,x-ca-signaturemethod"
tstr_to_sign = str_to_sign.replace('\n','#',100)
#print(100*'-'+ tstr_to_sign + 100*'-')
headers['x-ca-signature'] = xcasignature
#print(headers)
return headers
if __name__ == '__main__':
data = {"xxxx": "xxxx"}
url = 'https://api.xx.xxx.cn/tier/get'
head = signreq(data,url)
r = requests.post(url, data=json.dumps(data), headers=head, verify=False)
print(r.headers, r.text)
mitm.py 代码
"""
./mitmproxy --listen-host 0.0.0.0 --listen-port -s mitm.py
"""
import json
from signreq import signreq
from mitmproxy import ctx
def request(flow):
# 获取
req= flow.request
#print(req.headers)
#print(dir(req))
print(flow.request.pretty_url)
url = flow.request.pretty_url
body = req.content.decode('UTF-8')
data = json.loads(body)
print(url)
print(data)
new_headers = signreq(data,url)
#print(new_headers)
for k,v in new_headers.items():
req.headers[k] = v
def response(flow):
response = flow.response
print(response.text)
ctx.log.info(str(response.status_code))
运行mitmweb或者mitmproxy,-s指定自己写得脚本mitm.py, 默认mitmproxy监听0.0.0.0:8080。
mitmweb -v -s mitm.py
可以使用proxychain跑个sqlmap测试是否配置成功:
:
proxychains sqlmap -u https://xxx.cn/xx/xx/xx--data \{\"xxx\":\"xx\",\"xx\":\"xx*\"\} --ignore-code=400 -v 7
跑burpsuite的话可以通过配置burpsuite upstream为mitmproxy的监听地址,这样所有burpsuite发出去的包都会经过mitmproxy添加签名头再发出去,这样有个缺点是在burp里面看不到mitmproxy修改后的包。
举一反三,也可以让burpsuite作为mitmproxy的upstream,192.168.137.1:8080是burp监听地址端口,这样所有的包都会先发到mitmproxy添加signature头,再发到burpsuite:
mitmproxy -s mitm.py --mode upstream:192.168.137.1:8080 --ssl-insecure
文中所有代码在
https://github.com/xiaoxiaoleo/mitmproxy_alicloud_api_gateway