對阿里雲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
