title: Mitmproxy精华笔记
copyright: true
top: 0
date: 2019-05-12 22:41:37
tags:
categories: 爬虫笔记
permalink:
password:
keywords:
description: Mitmproxy一些常用的方法实践

是啊,世界那么残酷,无论你怎么反抗它,它都沉默无声地运转着,根本不管你会怎么想。你在大使的沙拉里放入了鱼胆,苦得他落荒而逃,可他选中的小羊还是被宰杀了,剥了皮泡在胡椒和香叶汤里;你吓得那些红男绿女落荒而逃,可不久之后他们又会聚在你家的舞厅里,就着靡靡之音跳贴面舞,喝醉的男男女女搂在一起,在午夜里高声调笑;你吓走了种马老爹带回来的女明星,可是几天之后卧室里换了新的画作,又有新的女人从老爹的豪车上下来,袅袅婷婷地踏入你家的房门,袅袅婷婷地跟着他走向卧室,流水般的裸女在老爹的大床上滚过。那么多年过去了你还是那么弱小,你自以为足够叛逆了,可你根本不曾改变这个世界,你只是躲开不去看它那残酷的一面。现在你回想起来了吧?你那被愤怒和不甘支配的童年。

介绍

中间代理抓包处理库~类似与burpsuite,fidder,wireshark

安装方法:

pip3 install mitmproxy

安装好后,会有mitmproxy、mitmdump、mitmweb三个使用方法,在cmd命令下输入:

mitmdump --version

出现如下结果表示安装成功:

Mitmproxy: 4.0.4
Python:    3.6.3
OpenSSL:   OpenSSL 1.1.0g  2 Nov 2017
Platform:  Windows-10-10.0.16299-SP0

注意mitmproxy是不支持windos的噢~mitmweb是web界面的管理器。分别介绍他们的功能:

mitmproxy:提供一个命令行界面,实时显示发生的请求
mitmweb:web页面的获取发生的请求,可视乎查看过滤内容
mitmdump:没有界面,程序默默运行,所以 mitmdump 无法提供过滤请求、查看数据的功能,只能结合自定义脚本,默默工作。

基础使用

首先要开启抓包,使用命令:

mitmdump -p 1080
# 流量走本地代理的1080端口

如果发现需证书有问题,我们还需要安装 mitmproxy 提供的证书,要不抓包失败。打开网址 http://mitm.it , 选择匹配的平台,下载 HTTPS 证书。并按照对应的步骤进行安装

注意不要有端口冲突!!

当启动mitmproxy后,会在根目录下生成证书

C:\Users\langzi\.mitmproxy

这个时候安装证书即可mitmproxy-ca-cert.p12

资料来自 碳基体

要捕获https证书,就得解决证书认证的问题,因此需要在通信发生的客户端安装证书,并且设置为受信任的根证书颁布机构。下面介绍6种客户端的安装方法。当我们初次运行mitmproxy或mitmdump时,会在当前目录下生成 ~/.mitmproxy文件夹,其中该文件下包含4个文件,这就是我们要的证书了。mitmproxy-ca.pem 私钥mitmproxy-ca-cert.pem 非windows平台使用mitmproxy-ca-cert.p12 windows上使用mitmproxy-ca-cert.cer 与mitmproxy-ca-cert.pem相同,android上使用1. Firefox上安装preferences-Advanced-Encryption-View Certificates-Import (mitmproxy-ca-cert.pem)-trust this CA to identify web sites2. chrome上安装设置-高级设置-HTTPS/SSL-管理证书-受信任的根证书颁发机构-导入mitmproxy-ca-cert.pem2. osx上安装双击mitmproxy-ca-cert.pem - always trust3.windows7上安装双击mitmproxy-ca-cert.p12-next-next-将所有的证书放入下列存储-受信任的根证书发布机构4.iOS上安装将mitmproxy-ca-cert.pem发送到iphone邮箱里,通过浏览器访问/邮件附件我将证书放在了vps上以供下载http://tanjiti.com/crt/mitmproxy-ca-cert.pem mitmproxy iOShttp://tanjiti.com/crt/mitmproxy-ca-cert.cer mitmproxy androidhttp://tanjiti.com/crt/mitmproxy-ca-cert.p12 windowshttp://tanjiti.com/crt/PortSwigger.cer BurpSuite (burpsuite的证书,随便附上)5.iOS模拟器上安装git clone https://github.com/ADVTOOLS/ADVTrustStore.gitcd ADVTrustStore/DANI-LEE-2:ADVTrustStore danqingdani$ python iosCertTrustManager.py -a ~/iostools/mitmproxy-ca-cert.pemsubject= CN = mitmproxy, O = mitmproxyImport certificate to iPhone/iPad simulator v5.1 [y/N] yImporting to /Users/danqingdani/Library/Application Support/iPhone Simulator/5.1/Library/Keychains/TrustStore.sqlite3 Certificate added实际上上面的操作就是给 ~/Library/Application\ Support/iPhone\ Simulator/5.1/Library/Keychains/TrustStore.sqlite3 数据库中表tsettings表中插入证书数据6.Android上安装将mitmproxy-ca-cert.cer 放到sdcard根目录下选择设置-安全和隐私-从存储设备安装证书

然后再浏览器中设置本地代理,方法如下:

这个时候浏览器的请求都会被mitmproxy捕获噢~

mitmdump 命令最大的特点就是可以自定义脚本,你可以在脚本中对请求或者响应内容通过编程的方式来控制,实现数据的解析、修改、存储等工作

使用方法为:

mitmdump -p 1080 -s script.py

你的script.py 的文件内容为:

import mitmproxy.http
from mitmproxy import ctxclass Counter:def __init__(self):self.num = 0def request(self, flow: mitmproxy.http.HTTPFlow):self.num = self.num + 1ctx.log.info("We've seen %d flows" % self.num)addons = [Counter()
]

然后在浏览器打开网站,浏览页面,这个时候显示数据如下:!

说明捕获到数据了噢~

还能这样这样写script.py,获取每次请求头:

def request(flow): print(flow.request.headers) # 打印请求头

这里我会重点说说自定义脚本的使用方法与功能

生命周期

即发起一次http请求的全部过程,从发起连接http_connect到获取到发起连接的响应头requestheaders,然后获取到想要发起连接的内容request。

发起连接后,得到获取内容的响应头responseheaders,然后获取到返回相应的内容response。

上面的script文件中的函数名,request都是mitm定义好的了函数名,我们每次要写对应功能的脚本时候,需要找到相关功能提供的函数名即可。

http_connect

def http_connect(self, flow: mitmproxy.http.HTTPFlow):

(Called when) 收到了来自客户端的 HTTP CONNECT 请求。在 flow 上设置非 2xx 响应将返回该响应并断开连接。CONNECT 不是常用的 HTTP 请求方法,目的是与服务器建立代理连接,仅是 client 与 proxy 的之间的交流,所以 CONNECT 请求不会触发 request、response 等其他常规的 HTTP 事件。

requestheaders

def requestheaders(self, flow: mitmproxy.http.HTTPFlow):

(Called when) 来自客户端的 HTTP 请求的头部被成功读取。此时 flow 中的 request 的 body 是空的。

request

def request(self, flow: mitmproxy.http.HTTPFlow):

(Called when) 来自客户端的 HTTP 请求被成功完整读取。

responseheaders

def responseheaders(self, flow: mitmproxy.http.HTTPFlow):

(Called when) 来自服务端的 HTTP 响应的头部被成功读取。此时 flow 中的 response 的 body 是空的。

response

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

(Called when) 来自服务端端的 HTTP 响应被成功完整读取。

通用周期

即每次发起连接或者收到相应内容,都可以使用下面的函数

error

def error(self, flow: mitmproxy.http.HTTPFlow):

(Called when) 发生了一个 HTTP 错误。比如无效的服务端响应、连接断开等。注意与“有效的 HTTP 错误返回”不是一回事,后者是一个正确的服务端响应,只是 HTTP code 表示错误而已。

configure

def configure(self, updated: typing.Set[str]):

(Called when) 配置发生变化。updated 参数是一个类似集合的对象,包含了所有变化了的选项。在 mitmproxy 启动时,该事件也会触发,且 updated 包含所有选项。

done

def done(self):

(Called when) addon 关闭或被移除,又或者 mitmproxy 本身关闭。由于会先等事件循环终止后再触发该事件,所以这是一个 addon 可以看见的最后一个事件。由于此时 log 也已经关闭,所以此时调用 log 函数没有任何输出。

load

def load(self, entry: mitmproxy.addonmanager.Loader):

(Called when) addon 第一次加载时。entry 参数是一个 Loader 对象,包含有添加选项、命令的方法。这里是 addon 配置它自己的地方。

log

def log(self, entry: mitmproxy.log.LogEntry):

(Called when) 通过 mitmproxy.ctx.log 产生了一条新日志。小心不要在这个事件内打日志,否则会造成死循环。

running

def running(self):

(Called when) mitmproxy 完全启动并开始运行。此时,mitmproxy 已经绑定了端口,所有的 addon 都被加载了。

update

def update(self, flows: typing.Sequence[mitmproxy.flow.Flow]):

(Called when) 一个或多个 flow 对象被修改了,通常是来自一个不同的 addon。

功能使用

response 1

获取返回信息

from mitmproxy import http
def response(flow:http.HTTPResponse)->None:print('-'*30)print(flow.request)# Request(GET langzi.fun:80/upload/TIM%E6%88%AA%E5%9B%BE20190422162029.png)# 请求发送 请求的urlprint(flow.response)# Response(200 OK, image/png, 61.29k)# 返回状态码 返回的信息类型 返回的文件大小print(flow.client_conn)# <ClientConnection: 127.0.0.1:28055># 本地发起连接print(flow.server_conn)# <ServerConnection: langzi.fun:80># 服务器端口print('-'*30)

response 2

获取请求头,主机,查询

import mitmproxy
def response(flow: mitmproxy.http.HTTPFlow)->None:print(flow.request.headers)# Headers[(b'Host', b'www.syztfj.com'), (b'User-Agent', b'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0'), (b'Accept', b'*/*'), (b'Accept-Language', b'zh-CN,zh;q=0.8,en-US;q=0.5,en;q# =0.3'), (b'Accept-Encoding', b'gzip, deflate'), (b'Referer', b'http://www.syztfj.com/css/stylelunbo_nei.css'), (b'Cookie', b'online_service_status=1; ASPSESSIONIDCQTTRCBC=HDPJBKAAAFJOACLEDEGCNDAF'), (b'DNT',# b'1'), (b'X-Forwarded-For', b'8.8.8.8'), (b'Connection', b'keep-alive')]print(flow.request.host)# www.syztfj.comprint(flow.request.query)# 访问网址 http://c.cnzz.com/core.php?web_id=1271804123&t=z ,返回的结果如下:# MultiDictView[('web_id', '1271804123'), ('t', 'z')]# 可以使用flow.request.query.keys()获取所有的键

resnose 3

获取url动态链接

from mitmproxy import http
import re
from urllib.parse import urljoin
def response(flow:http.HTTPFlow):if "Content-Type" in flow.response.headers and flow.response.headers["Content-Type"].find("text/html") != -1:pageUrl = flow.request.urlpageText = flow.response.textpattern = (r"<a\s+(?:[^>]*?\s+)?href=(?P<delimiter>[\"'])"r"(?P<link>(?!https?:\/\/|ftps?:\/\/|\/\/|#|javascript:|mailto:).*?)(?P=delimiter)")rel_matcher = re.compile(pattern, flags=re.IGNORECASE)rel_matches = rel_matcher.finditer(pageText)for match_num, match in enumerate(rel_matches):(delimiter, rel_link) = match.group("delimiter", "link")abs_link = urljoin(pageUrl, rel_link)print('LINKS:'+abs_link)# LINKS:http://bbs.kjj.com/space.php?username=%BB%F9%BD%F0%CA%D6# LINKS:http://bbs.kjj.com/redirect.php?tid=655201&amp;goto=lastpost#lastpost# LINKS:http://bbs.kjj.com/space-username-gtthc.html# LINKS:http://bbs.kjj.com/forum-154-1.html# LINKS:http://bbs.kjj.com/forum-154-1.html# LINKS:http://bbs.kjj.com/space.php?username=%B4%BA%C8%D5%D4%D8%D1%F4# LINKS:http://bbs.kjj.com/redirect.php?tid=968702&amp;goto=lastpost#lastpost# LINKS:http://bbs.kjj.com/space-username-%C0%B6%CC%EC%B7%E3.html# LINKS:http://bbs.kjj.com/forum-144-1.html# LINKS:http://bbs.kjj.com/forum-144-1.html# LINKS:http://bbs.kjj.com/space.php?username=%D4%C2%D7%ED%BB%A8%D2%F5

response 4

获取相关结果

def parser_data(self):result = dict()result['url'] = self.flow.request.url# 当前网址result['path'] = '/{}'.format('/'.join(self.flow.request.path_components))# 当前路径result['host'] = self.flow.request.host# 当前主机result['port'] = self.flow.request.port# 主机端口result['scheme'] = self.flow.request.scheme# http or httpsresult['method'] = self.flow.request.method# 请求方式result['status_code'] = self.flow.response.status_code# 状态码result['content_length'] = int(self.flow.response.headers.get('Content-Length', 0))# 返回内容长度result['request_header'] = self.parser_header(self.flow.request.headers)# 请求头result['request_content'] = self.flow.request.content# 返回内容result['query'] = self.flow.request.query# 查询参数return result

重定向

from mitmproxy import http
def request(flow: http.HTTPFlow) -> None:if flow.request.pretty_host == "example.org":flow.request.host = "mitmproxy.org"# 在这里把提交的主机地址修改成Mitmproxy.org

使用日志

使用日志的时候,不能再print,因为log.xxx自动输出内容

from mitmproxy import ctx
def load(l):ctx.log.info("This is some informative text.")ctx.log.warn("This is a warning.")ctx.log.error("This is an error.")

写入文件

import random
import sys
from mitmproxy import io, http
import typing  # noqaclass Writer:def __init__(self, path: str) -> None:self.f: typing.IO[bytes] = open(path, "wb")self.w = io.FlowWriter(self.f)def response(self, flow: http.HTTPFlow) -> None:if random.choice([True, False]):self.w.add(flow)def done(self):self.f.close()addons = [Writer(sys.argv[1])]

读取文件

from mitmproxy import io
from mitmproxy.exceptions import FlowReadException
import pprint
import syswith open(sys.argv[1], "rb") as logfile:freader = io.FlowReader(logfile)pp = pprint.PrettyPrinter(indent=4)try:for f in freader.stream():print(f)print(f.request.host)pp.pprint(f.get_state())print("")except FlowReadException as e:print("Flow file corrupted: {}".format(e))

获取路径

from pathod import pathocp = pathoc.Pathoc(("google.com", 80))
p.connect()
print(p.request("get:/"))
print(p.request("get:/foo"))

使用案例

官方文档

参考链接 1

参考连接 2

欢迎关注公众号:【安全研发】获取更多相关工具,课程,资料分享哦~

Mitmproxy精华笔记相关推荐

  1. 互联网电商大数据环境 ——大数飓数据分析实践培训精华笔记(一)——简介入门

    互联网电商大数据环境 --数据分析实践培训精华笔记(一) 工作内容 项目:DW数据库建设/经分/客户精准营销/推荐系统需求/移动端数据分析 数据:流量数据/交易数据B2C/会员与活动数据/物流与配送数 ...

  2. 基于百度时空大数据的城市计算(讲座精华笔记)

    基于百度时空大数据的城市计算(讲座精华笔记) THU数据派 2017-05-27 23:24 [导读]本文整理自2017年5月24日,百度自动驾驶事业部创始团队成员.高级技术顾问秦伟俊博士在清华大数据 ...

  3. 福利 | 精选大咖演讲干货、精华笔记、课件分享(附PPT/视频)

    数据派一直致力于打造数据科学人才聚集地,传播数据科学知识,分享前沿科技动态,分析应用案例,组织线下活动.本文通过梳理往期内容,挑选出数据派独家讲座干货,做成了合集. 再也不怕错过精彩内容 点点感觉自己 ...

  4. 福利 | 16场精选活动干货、精华笔记、课件分享:数据派独家讲座干货大合集

    数据派一直致力于打造数据科学人才聚集地,传播数据科学知识,分享前沿科技动态,分析应用案例,组织线下活动.近期数据派开设"福利"专栏,将在每周日晚推送往期文章干货大合集,欢迎关注.本 ...

  5. Algorithms, 4th Edition 算法4精华笔记,通俗理解,算法收集与强化

    JVM 是 java 程序员永远的考题,算法是所有程序员永久的考题.这应该是很多人的共识,不管是谁,学习的路上我们时常遇到迷茫阶段,抓住最根本的东西你永远不会觉得迷失. 年假之前,我就规定自己要完成多 ...

  6. 独家 | Michael I.Jordan:大数据时代下的安全实时决策堆栈与增强学习(视频+精华笔记)

    金秋九月,2017国际大数据产业技术创新高峰论坛暨大数据系统软件国家工程实验室第一次会议盛大开幕,大数据系统软件国家工程实验室作为大数据系统软件技术研发与工程化的国家级创新平台,将通过大数据系统软件技 ...

  7. 大数据视觉智能实践及医学影像智能诊断探索(讲座精华笔记)

    [导读]本文整理自2017年6月20日,阿里巴巴iDST算法专家行湘在清华-青岛数据科学研究院.阿里云和零氪科技共同举办的天池医疗AI大赛之"医学影像在肿瘤诊断中的应用及智能诊断探索&quo ...

  8. 人工智能必备数学基础--精华笔记

    人工智能必备数学基础--笔记 废话 笔记 高等数学基础 函数 极限 函数的连续性 导数 偏导数 方向导数 梯度 微积分 求曲边面积 定积分 第一中值定理 牛顿-莱布尼茨公式 泰勒公式与拉格朗日 泰勒公 ...

  9. 8086汇编语言精华笔记总结~

    目录 第一章 汇编语言的基础知识 1.计算机系统概述 硬件(Handware) 软件(Software) 2.汇编语言介绍 3.数据表示 1. BCD码 2. ASCII码 3. 真值和机器数 4. ...

最新文章

  1. 逐步转向自己主动化測试
  2. debug assertion failed!报错
  3. 亮相LiveVideoStackCon 2021,网易云信分享QoS优化之道
  4. 沪江日语电台首度在线直播后续花絮(附直播片段)
  5. linux下查看中断请求记录 IRQ
  6. pytorch得到梯度计算结果
  7. Memcached原理与应用
  8. Hadoop YARN最近几个新特性
  9. 40亿个手机号码如何去重?
  10. java session超时判断_详解SpringBoot中Session超时原理说明
  11. 数位板的主要参数解析
  12. 魔百盒CM201-1、CM211-1朝歌ZG_支持UWE5621WiFi驱动_免拆卡刷固件包
  13. 视频转GIF+GIF录制
  14. 车机蓝牙通话流程分析的流程分析
  15. 高仿微信6.5.7(融云版)
  16. 圆、椭圆和三角形的代码画法
  17. 打包时出现的异常。XXXXXXX-1.0-SNAPSHOT.jar中没有主清单属性的解决办法
  18. 线性表(小白,如有错误还望海涵)
  19. java+springboot的大学生心理健康测试测评系统vue
  20. 【C++】求解一元二次方程的根

热门文章

  1. 一万了解 Gateway 知识点
  2. 计算机语言dial,Go语言DialTCP():网络通信
  3. 不同进程log占有量分析
  4. 快手卖画怎么引流?快手直播卖货效果怎么样?
  5. 入门运动蓝牙耳机,必买的蓝牙耳机品牌
  6. 开机出现OEM7GRUB命令框
  7. idea git branches更新
  8. Ubuntu22.04篇---安装微信,QQ,企业微信
  9. redis的发布/订阅和mq消息队列的区别,该如何选择?
  10. android webview 自动点击事件,Android中的WebView布局点击事件的方法