簡體   English   中英

mitmproxy:用重新提交的請求替換響應

[英]mitmproxy: Replace response by resubmitted request

我嘗試通過再次重新提交相同請求的結果替換 mitmproxy 中的響應。 這是我當前的腳本:

from mitmproxy import http
from mitmproxy import ctx

import requests
import re

class ReplaceToken:

    nextToken = ""

    def response(self, flow: http.HTTPFlow):

        m = re.search('localhost.local:8085/test/index.php/(.+?)" method=', str(flow.response.content))
        if m:
            self.nextToken = m.group(1)
            ctx.log.info("Next token: " + self.nextToken)
        
        m = re.search('Wrong token!<br>', str(flow.response.content))
        if m:
        
            flow = flow.copy()
            request = flow.request.copy()
        
            ctx.log.info("Found wrong token! Resend request with correct token...")
            request.path = re.sub("/[^/]*$", "/" + self.nextToken, flow.request.path)
            
            playback = ctx.master.addons.get('clientplayback')
            flow.request = request
            
            playback.start_replay([flow])

addons = [ReplaceToken()]

在響應中,我想檢測錯誤情況(例如錯誤的 CSRF 令牌)。 如果存在這種情況,我想使用正確的令牌重新發送請求,等待正確的響應並用正確的令牌替換原始響應數據。

但是,在上面的腳本中,響應不會被替換。 並且正確的請求只在 mitmprox 內部發出。

一種可能的解決方法是使用$random-http-lib繞過 mitmproxy 發出 HTTP 請求。 就像下面的 PoC:

import requests
def response(self, flow: http.HTTPFlow):
    r = requests.get("http://www.example.com")
    ctx.log.info(r.text)
    flow.response.text = r.text

但是,這需要手動將每個方面從原始請求(HTTP 方法、路徑、標頭、正文等)“復制”到外部 HTTP 庫——我想避免這種情況。

有沒有辦法只使用 mitmproxy 本身來實現這一點?

意外地(或多或少)我在 github 上找到了一個 OAuth 插件的基本概念,這正是我想要的: oauth-mitmproxy

所以代碼看起來像這樣:

def response(self, flow: http.HTTPFlow):

    m = re.search('localhost.local:8085/test/index.php/(.+?)" method=', str(flow.response.content))
    if m:
        self.nextToken = m.group(1)
        ctx.log.info("Next token: " + self.nextToken)
        
    if flow.is_replay:
        self.postponed_flow.response = flow.response
        self.postponed_flow.resume()
        return
    
    m = re.search('Wrong token!<br>', str(flow.response.content))
    if m:
    
        ctx.log.info("Found wrong token! Resend request with correct token...")
        
        resend_flow = flow.copy()
        resend_flow.request.path = re.sub("/[^/]*$", "/" + self.nextToken, flow.request.path)
        ctx.master.commands.call("replay.client", [resend_flow])

        flow.intercept()
        self.postponed_flow = flow

這里的“技巧”是攔截和存儲錯誤狀態流( self.postponed_flow )。 然后克隆、改編和重放整個流程。 如果檢測到重放流,則將響應復制到原始流並恢復流。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM