mintproxy跳坑集锦

mitmproxy出现Cannot establish TLS with client 错误,及解决办法错误详情:<< Cannot establish TLS with client (sni: app.1hai.cn): TlsException(“SSL handshake error: Error([(‘SSL routines’, ‘ssl3_read_bytes’, ‘sslv3 alert certificate unknown’)],)”,)这个错误可以理解为mitmproxy缺少https的证书问题,解析ssl协议出错。解决办法: 把tls_passthrough.py中的代码整合进我们的监听代码即可。 mitmproxy -s tls_passthrough.pytls_passthrough.py 脚本在github上直接可以下载。下载地址:tls_passthrough.py下载地址下面是tls_passthrough.py的全部内容"““This inline script allows conditional TLS Interception basedon a user-defined strategy.Example: > mitmdump -s tls_passthrough.py 1. curl –proxy http://localhost:8080 https://example.com –insecure // works - we’ll also see the contents in mitmproxy 2. curl –proxy http://localhost:8080 https://example.com –insecure // still works - we’ll also see the contents in mitmproxy 3. curl –proxy http://localhost:8080 https://example.com // fails with a certificate error, which we will also see in mitmproxy 4. curl –proxy http://localhost:8080 https://example.com // works again, but mitmproxy does not intercept and we do not see the contentsAuthors: Maximilian Hils, Matthew Tuusberg”““import collectionsimport randomfrom enum import Enumimport mitmproxyfrom mitmproxy import ctxfrom mitmproxy.exceptions import TlsProtocolExceptionfrom mitmproxy.proxy.protocol import TlsLayer, RawTCPLayerclass InterceptionResult(Enum): success = True failure = False skipped = Noneclass _TlsStrategy: "”” Abstract base class for interception strategies. "”" def init(self): # A server_address -> interception results mapping self.history = collections.defaultdict(lambda: collections.deque(maxlen=500)) def should_intercept(self, server_address): """ Returns: True, if we should attempt to intercept the connection. False, if we want to employ pass-through instead. """ raise NotImplementedError() def record_success(self, server_address): self.history[server_address].append(InterceptionResult.success) def record_failure(self, server_address): self.history[server_address].append(InterceptionResult.failure) def record_skipped(self, server_address): self.history[server_address].append(InterceptionResult.skipped)class ConservativeStrategy(_TlsStrategy): """ Conservative Interception Strategy - only intercept if there haven’t been any failed attempts in the history. """ def should_intercept(self, server_address): if InterceptionResult.failure in self.history[server_address]: return False return Trueclass ProbabilisticStrategy(_TlsStrategy): """ Fixed probability that we intercept a given connection. """ def init(self, p): self.p = p super(ProbabilisticStrategy, self).init() def should_intercept(self, server_address): return random.uniform(0, 1) < self.pclass TlsFeedback(TlsLayer): """ Monkey-patch _establish_tls_with_client to get feedback if TLS could be established successfully on the client connection (which may fail due to cert pinning). """ def _establish_tls_with_client(self): server_address = self.server_conn.address try: super(TlsFeedback, self)._establish_tls_with_client() except TlsProtocolException as e: tls_strategy.record_failure(server_address) raise e else: tls_strategy.record_success(server_address)# inline script hooks below.tls_strategy = Nonedef load(l): l.add_option( “tlsstrat”, int, 0, “TLS passthrough strategy (0-100)”, )def configure(updated): global tls_strategy if ctx.options.tlsstrat > 0: tls_strategy = ProbabilisticStrategy(float(ctx.options.tlsstrat) / 100.0) else: tls_strategy = ConservativeStrategy()def next_layer(next_layer): """ This hook does the actual magic - if the next layer is planned to be a TLS layer, we check if we want to enter pass-through mode instead. """ if isinstance(next_layer, TlsLayer) and next_layer._client_tls: server_address = next_layer.server_conn.address if tls_strategy.should_intercept(server_address): # We try to intercept. # Monkey-Patch the layer to get feedback from the TLSLayer if interception worked. next_layer.class = TlsFeedback else: # We don’t intercept - reply with a pass-through layer and add a “skipped” entry. mitmproxy.ctx.log(“TLS passthrough for %s” % repr(next_layer.server_conn.address), “info”) next_layer_replacement = RawTCPLayer(next_layer.ctx, ignore=True) next_layer.reply.send(next_layer_replacement) tls_strategy.record_skipped(server_address)整合示例import sysimport collectionsimport randomfrom enum import Enumimport requestsimport loggingimport jsonimport mitmproxyfrom mitmproxy import ctx,httpfrom mitmproxy.exceptions import TlsProtocolExceptionfrom mitmproxy.proxy.protocol import TlsLayer, RawTCPLayerfrom MongoTool import MongoToolclass Listener: def init(self): #self.logger =logging.getLogger(’listener’) #self.logger.setLevel(logging.INFO) #logger_handler=logging.FileHandler(‘D:/log/shop_detail_listener.log’) #formatter =logging.Formatter(’%(asctime)s - %(name)s - %(levelname)s - %(message)s’) #logger_handler.setFormatter(formatter) #self.logger.addHandler(logger_handler) self.mongo_client=MongoTool() def request(self,flow:http.HTTPFlow): url =flow.request.url if ‘base/storeList.do’ in url: try: ctx.log.info(‘flow request:’ + url) print(‘intercept shenzhou shop detail request,%s’ % (url)) except Exception as e: ctx.log.error(‘mitmproxy intercept http error:’ + repr(e)) def response(self,flow): response=flow.response response_text=response.text log_info = ctx.log.info if ‘storeList’ in response_text: self.insert_mongo(response_text) pass def insert_mongo(self,item): shop_item_json=json.loads(item) if shop_item_json[‘msg’] not in ‘成功’: pass for shop in shop_item_json[‘result’][‘storeList’]: print(shop) self.mongo_client.insert_item(shop,‘shenzhou_shop’)addons=[ Listener()]class InterceptionResult(Enum): success = True failure = False skipped = Noneclass _TlsStrategy: """ Abstract base class for interception strategies. """ def init(self): # A server_address -> interception results mapping self.history = collections.defaultdict(lambda: collections.deque(maxlen=500)) def should_intercept(self, server_address): """ Returns: True, if we should attempt to intercept the connection. False, if we want to employ pass-through instead. """ raise NotImplementedError() def record_success(self, server_address): self.history[server_address].append(InterceptionResult.success) def record_failure(self, server_address): self.history[server_address].append(InterceptionResult.failure) def record_skipped(self, server_address): self.history[server_address].append(InterceptionResult.skipped)class ConservativeStrategy(_TlsStrategy): """ Conservative Interception Strategy - only intercept if there haven’t been any failed attempts in the history. """ def should_intercept(self, server_address): if InterceptionResult.failure in self.history[server_address]: return False return Trueclass ProbabilisticStrategy(_TlsStrategy): """ Fixed probability that we intercept a given connection. """ def init(self, p): self.p = p super(ProbabilisticStrategy, self).init() def should_intercept(self, server_address): return random.uniform(0, 1) < self.pclass TlsFeedback(TlsLayer): """ Monkey-patch _establish_tls_with_client to get feedback if TLS could be established successfully on the client connection (which may fail due to cert pinning). """ def _establish_tls_with_client(self): server_address = self.server_conn.address try: super(TlsFeedback, self)._establish_tls_with_client() except TlsProtocolException as e: tls_strategy.record_failure(server_address) raise e else: tls_strategy.record_success(server_address)# inline script hooks below.tls_strategy = Nonedef load(l): l.add_option( “tlsstrat”, int, 0, “TLS passthrough strategy (0-100)”, )def configure(updated): global tls_strategy if ctx.options.tlsstrat > 0: tls_strategy = ProbabilisticStrategy(float(ctx.options.tlsstrat) / 100.0) else: tls_strategy = ConservativeStrategy()def next_layer(next_layer): """ This hook does the actual magic - if the next layer is planned to be a TLS layer, we check if we want to enter pass-through mode instead. """ if isinstance(next_layer, TlsLayer) and next_layer._client_tls: server_address = next_layer.server_conn.address if tls_strategy.should_intercept(server_address): # We try to intercept. # Monkey-Patch the layer to get feedback from the TLSLayer if interception worked. next_layer.class = TlsFeedback else: # We don’t intercept - reply with a pass-through layer and add a “skipped” entry. mitmproxy.ctx.log(“TLS passthrough for %s” % repr(next_layer.server_conn.address), “info”) next_layer_replacement = RawTCPLayer(next_layer.ctx, ignore=True) next_layer.reply.send(next_layer_replacement) tls_strategy.record_skipped(server_address) ...

April 17, 2019 · 4 min · jiezi

安装mitmproxy以及遇到的坑和简单用法

mitmproxy 是一款工具,也可以说是 python 的一个包,在命令行操作的工具。MITM 即中间人攻击(Man-in-the-middle attack)使用这个工具可以在命令行上进行抓包,还可以对所抓到的包进行脚本处理,非常有用。安装 mitmproxy安装这个我们必须先安装了 pip。 pip 在安装了 python之后自带的,如果你安装了 python 就可以忽略了,如何安装这里就不说了,只说安装 mitmproxy打开命令行,输入 pip install mitmproxy 即可按下回车即可下载但是到最后下载失败error: Microsoft Visual C++ 14.0 is required. Get it with “Microsoft Visual C++ Build Tools”: http://landinghub.visualstudio.com/visual-cpp-build-tools是因为安装这个包的 window 系统需要首先安装 Microsoft Visual C++ V14.0以上 才行。可以在https://visualstudio.microsof… 直接下载即可,安装之后需要把 c++ de 库之类的东西都安装了,然后再在命令行进行安装 mitmproxy即可。安装完之后查看 mitmproxy版本命令行输入 mitmproxy –version显示错误,这是因为 window操作系统不支持使用 mitmproxy 这个命令,我们可以使用 mitmdump 或 mitmweb 代替。这样就成功了。如何使用 mitmproxy抓包开启抓包:mitmdump这样子就是开始抓包了,监听了所有的地址,端口是 8080,如果需要改端口号,可以按 ctrl + c 退出抓包,然后输入下列命令:mitmdump -p 8889这样子就把端口号改成 8889 了如果需要抓手机的包的话,就需要在你连接的 wifi 修改代理上面的主机名字是 你电脑抓包的 ip 地址,端口号是刚才设置的端口号。设置完了打开浏览器查看。发现需证书有问题,我们还需要安装 mitmproxy 提供的证书,要不抓包失败。安装证书:浏览器输入 mitm.it然后根据你的手机系统进行安装即可。然后就可以进行抓包了。在浏览器输入 baidu.com 就可以看到下面内容了。电脑端的也是这样差不多,都是设置代理后安装证书,这里就不多说了。抓包之后的操作由于在 window上操作,只能使用 mitmdump 和 mitmweb这两个命令,mitmdump 命令是没有界面,只能进行默默地抓包,不能进行数据包的查看和过滤。而 mitmweb 和在一个网页上进行抓包的调试。所以下面我们用 mitmweb 来进行调试。1.开始抓包mitmweb -p 8889在你输入 baidu.com 的时候就会看到这些包了。查看包的请求信息和响应信息只需要点击相对应的包即可。其他的就不多说了。在 mitmproxy 上运行 python脚本mitmproxy 的强大之处就在于它能够运行 python 脚本来处理相关的请求,现在就来看看如何处理吧。mitmdump -p 889 -s mitm.py这个就是在抓包的同时运行了 mitm.py 的脚本了,代码是:# 必须这样写 def request(flow): print(flow.request.headers) # 打印请求头这个是打印抓到的请求头,方法名和参数的名称是固定的,写错了就运行不了这个脚本。这样子就开始了,然后在手机上打开网页。这样子就把他们的请求头给输出了。但是输出并不明显,我们可以使用里面的一个日志模块来输出,这样子就会显示出不同的颜色了。命令行上显示这样:这样子就清楚多了。除了上面的请求头,我们还可以访问他们的请求方法,请求路径等。响应的请求也可以获取:同样,这里的方法名和参数也是固定的,不写这个会捕捉不到。本文完。 ...

January 20, 2019 · 1 min · jiezi