我正在尝试在 mitmproxy 中开发一个插件,它将分析来自端点服务器/网站的一些 HTTPS/HTTP 响应并对收到的特定响应做出反应。 然后,我会阻止响应访问客户端,而是从 mitmproxy 向端点服务器发送 GET 请求,然后从同一端点服务器接收响应,然后对其进行分析,发回 GET 请求,而无需先前的响应到达客户端,一旦我从端点得到正确答案,我会将其转发给客户端。
换句话说,我想实现这个:
Client Mitmproxy CorporateProxy Endpoint Server/Website [Internet]
GET_Request1 --> GET_Request1 --> GET_Request1 -----> GET_Request1
Answer1 <-- Answer1 <----- Answer1
GET_Request2 --> GET_Request2 -----> GET_Request2
Answer2 <-- Answer2 <----- Answer2
GET_Request3 --> GET_Request3 -----> GET_Request3
Answer3 <-- Answer3 <-- Answer3 <----- Answer3
GET_Request4 --> GET_Request4 --> GET_Request4 -----> GET_Request4
Answer4 <-- Answer4 <-- Answer4 <----- Answer4
[etc.]
请注意,我使用的是上游模式,因为我位于拥有自己的 SSL 证书的企业 HTTP 代理服务器后面,因此 mitmproxy 通过冒充具有自签名 SSL 证书的客户端背后的 CA 机构来解码此处的流量非常有用.
我在文档中没有看到如何使用提供的 API 从 mitmproxy 插件“生成”新颖的 GET 请求。我主要看到修改请求/响应的插件,所以我不确定如何正确执行它。
由于 mitmproxy 已经有一个到端点的 HTTP 连接,所以使用例如 似乎(也许我错了)是多余的urllib3 来生成这些 GET 请求(添加新的依赖项),此外,我需要对 GET 请求的响应通过 mitmproxy。
TL;DR 如何使用现有的 mitmproxy 设施生成全新的 GET 请求,这是客户端上游的请求,该请求将由无法到达客户端的响应来应答?
这对OP来说已经太晚了,但也许对其他人有用,包括我未来的自己。
我发现了两种有效的方法:一种是使用
urllib.request.urlopen
,另一种是使用 302 重定向。第一个更准确地满足OP的要求,第二个以更自然的方式使用mitmdump,让客户端(浏览器)进行后续查询,直到找到合适的答案。
这是第一种方式的片段,使用响应的长度来指示它是“正确”(长于1个字节)还是“错误”:
answer = flow.response.content
while len(answer.rstrip()) < 2:
flow.request.path = flow.request.path
logging.warning('making followup request to %s',
flow.request.path)
with urlopen(flow.request.url) as instream:
answer = instream.read()
flow.response.content = answer
第二种方式:
redirect = flow.request.path
flow.response = http.Response.make(
HTTPStatus.FOUND,
('<a href="%s">%s</a>' % (redirect, redirect)).encode(),
{'content-type': 'text/html', 'location': redirect}
)
我也尝试过
flow.copy()
,但找不到一种干净的方法(或实际上是任何方法)来“丢弃”“错误”响应而不同时终止客户端连接。我用于测试的完整代码,包括一个简单的测试服务器,位于:https://github.com/jcomeauictx/stackoverflow/tree/master/77252251