pythonmitmproxy⽂档
1、顾名思义,mitmproxy 就是⽤于 MITM 的 proxy,MITM 即[中间⼈攻击],⽤于中间⼈攻击的代理⾸先会向正常的代理⼀样转发请求,保障服务端与客户端的通信,其次,会适时的查、记录其截获的数据,或篡改数据,引发服务端或客户端特定的⾏为。
2、不同于 fiddler 或 wireshark 等抓包⼯具,mitmproxy 不仅可以截获请求帮助开发者查看、分析,更可以通过⾃定义脚本进⾏⼆次开发。举例来说,利⽤ fiddler 可以过滤出浏览器对某个特定 url 的请求,并查看、分析其数据,但实现不了⾼度定制化的需求,类似于:“截获对浏览器对该 url 的请求,将返回内容置空,并将真实的返回内容存到某个数据库,出现异常时发出邮件通知”。⽽对于 mitmproxy,这样的需求可以通过载⼊⾃定义 python 脚本轻松实现。
3、但 mitmproxy 并不会真的对⽆辜的⼈发起中间⼈攻击,由于 mitmproxy ⼯作在 HTTP 层,⽽当前 HTTPS 的普及让客户端拥有了检测并规避中间⼈攻击的能⼒,所以要让 mitmproxy 能够正常⼯作,必须要让客户端(APP 或浏览器)主动信任 mitmproxy 的 SSL 证书,或忽略证书异常,这也就意味着 APP 或浏览器是属于开发者本⼈的——显⽽易见,这不是在做⿊产,⽽是在做开发或测试。
4、那这样的⼯具有什么实际意义呢?据我所知⽬前⽐较⼴泛的应⽤是做仿真爬⾍,即利⽤⼿机模拟器、⽆头浏览器来爬取 APP 或⽹站的数
据,mitmproxy 作为代理可以拦截、存储爬⾍获取到的数据,或修改数据调整爬⾍的⾏为。
事实上,以上说的仅是 mitmproxy 以正向代理模式⼯作的情况,通过调整配置,mitmproxy 还可以作为透明代理、反向代理、上游代理、SOCKS 代理等,但这些⼯作模式针对 mitmproxy 来说似乎不⼤常⽤,故本⽂仅讨论正向代理模式。
5、python脚本不要⼩于3.6
6、安装完后,mitmdump 是命令⾏⼯具,mitmweb是⼀个web界⾯。
image.png
7、第⼀个套路是,编写⼀个 py ⽂件供 mitmproxy 加载,⽂件中定义了若⼲函数,这些函数实现了某些 mitmproxy 提供的事
件,mitmproxy 会在某个事件发⽣时调⽤对应的函数,形如:
import mitmproxy.http
from mitmproxy import ctx
num = 0
def request(flow: mitmproxy.http.HTTPFlow):
global num
num = num + 1
ctx.log.info("We've seen %d flows" % num)
第⼆个套路是,编写⼀个 py ⽂件供 mitmproxy 加载,⽂件定义了变量 addons,addons 是个数组,每个元素是⼀个类实例,这些类有若⼲⽅法,这些⽅法实现了某些 mitmproxy 提供的事件,mitmproxy 会在某个事件发⽣时调⽤对应的⽅法。这些类,称为⼀个个 addon,⽐如⼀
import counter
import joker
addons = [
counter.Counter(),
joker.Joker(),
]
mitmweb -s addons.py
18、def tcp_start(self, flow: p.TCPFlow):
(Called when) 建⽴了⼀个 TCP 连接。
def tcp_message(self, flow: p.TCPFlow):
(Called when) TCP 连接收到了⼀条消息,最近⼀条消息存于 ssages[-1]。消息是可修改的。
def tcp_error(self, flow: p.TCPFlow):
(Called when) 发⽣了 TCP 错误。
def tcp_end(self, flow: p.TCPFlow):
(Called when) TCP 连接关闭。
19、def websocket_handshake(self, flow: mitmproxy.http.HTTPFlow):
(Called when) 客户端试图建⽴⼀个 websocket 连接。可以通过控制 HTTP 头部中针对 websocket 的条⽬来改变握⼿⾏为。flow 的request 属性保证是⾮空的的。
def websocket_start(self, flow: mitmproxy.websocket.WebSocketFlow):
(Called when) 建⽴了⼀个 websocket 连接。
def websocket_message(self, flow: mitmproxy.websocket.WebSocketFlow):
(Called when) 收到⼀条来⾃客户端或服务端的 websocket 消息。最近⼀条消息存于 ssages[-1]。消息是可修改的。⽬前有两种消息类型,对应 BINARY 类型的 frame 或 TEXT 类型
的 frame。
def websocket_error(self, flow: mitmproxy.websocket.WebSocketFlow):
(Called when) 发⽣了 websocket 错误。
def websocket_end(self, flow: mitmproxy.websocket.WebSocketFlow):
python在线模拟器(Called when) websocket 连接关闭。
20、def clientconnect(self, layer: mitmproxy.proxy.protocol.Layer):
(Called when) 客户端连接到了 mitmproxy。注意⼀条连接可能对应多个 HTTP 请求。
def clientdisconnect(self, layer: mitmproxy.proxy.protocol.Layer):
(Called when) 客户端断开了和 mitmproxy 的连接。
def serverconnect(self, conn: tions.ServerConnection):
(Called when) mitmproxy 连接到了服务端。注意⼀条连接可能对应多个 HTTP 请求。
def serverdisconnect(self, conn: tions.ServerConnection):
(Called when) mitmproxy 断开了和服务端的连接。
def next_layer(self, layer: mitmproxy.proxy.protocol.Layer):
(Called when) ⽹络 layer 发⽣切换。你可以通过返回⼀个新的 layer 对象来改变将被使⽤的 layer。
21、
def configure(self, updated: typing.Set[str]):
(Called when) 配置发⽣变化。updated 参数是⼀个类似集合的对象,包含了所有变化了的选项。在 mitmproxy 启动时,该事件也会触发,且updated 包含所有选项。
def done(self):
(Called when) addon 关闭或被移除,⼜或者 mitmproxy 本⾝关闭。由于会先等事件循环终⽌后再触发该事件,所以这是⼀个 addon 可以看见的最后⼀个事件。由于此时 log 也已经关闭,所以此时调⽤ log 函数没有任何输出。
def load(self, entry: mitmproxy.addonmanager.Loader):
(Called when) addon 第⼀次加载时。entry 参数是⼀个 Loader 对象,包含有添加选项、命令的⽅法。这⾥是 addon 配置它⾃⼰的地⽅。def log(self, entry: mitmproxy.log.LogEntry):
(Called when) 通过 log 产⽣了⼀条新⽇志。⼩⼼不要在这个事件内打⽇志,否则会造成死循环。
def running(self):
(Called when) mitmproxy 完全启动并开始运⾏。此时,mitmproxy 已经绑定了端⼝,所有的 addon 都被加载了。
def update(self, flows: typing.Sequence[mitmproxy.flow.Flow]):
(Called when) ⼀个或多个 flow 对象被修改了,通常是来⾃⼀个不同的 addon。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论