配合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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM