点击“简说Python”,选择“星标公众号”
福利干货,第一时间送达!
图片by@unsplash
作者:小帅b
阅读文本大概需要 7 分钟。
有一天,小明问小黑说:
“世界上最帅的人是谁?”
正文开始
不知道你有没有听过一个词叫做:MITM, 也就是 man in the middle〔attack〕,意思就是中间人攻击。
比如你在跟你另一半(单身狗,暂时假设你有另一半)网上聊天的时候,本来你们聊得好好的,哥们聊得挺嗨啊。突然间,小帅b在走进了你们两的网络通讯之间,并且跟你们两同时建立了联系,这时候,你原本要发给你另一半的信息,被我拦截下来了,而这时候我还可以对你要发的数据进行篡改,然后再发给你的另一半。你们两还全然不知,以为就是对方说的话。
这就是中间的人,坏坏,这时候你可能想到了 mitmproxy,它不止是可以像 直接使用 Python 写一些脚本进行中间操控。
那么,怎么玩呢?
正是因为 mitmproxy 这种比较牛逼的请求拦截定制化骚操作,使得它又一不小心成了我们爬虫的一个工具,使用它我们可以更加方便的爬取一些 APP 上面的数据。
安装起来特别简单,pip install 下就可以了,使用如下命令安装:
pip install mitmproxy
就是这么一顿下载之后,你就成为了中间的人了,这时候你的电脑就有了 mitmproxy、mitmdump、mitmweb 这三个牛逼的东西,其实它们本质都一样,只是交互的方式不同:
mitmproxy 主要是以控制台的方式交互
mitmdump 主要是以命令行的方式交互
mitmweb 就是以 web 的形式进行交互
反正都差不多的,你用哪个都行:
这时候你想要启动 mitm ,只需要直接输入名称就可以了,比如我这里要启动 mitmweb:
可以看到它就绑定了 8080 的端口,用来监听,这时候我们如果使用 8080 端口进行代理上网,就可以直接获取到请求数据了。
而 8081 这个端口就是用来运行 mitm 交互界面的,浏览器打开 127.0.0.1:8081 就是这个样子:
想要使用 Chrome 以及 8080 端口代理运行,你可以使用命令行打开:
google-chrome --proxy-server=127.0.0.1:8080 --ignore-certificate-errors
如果你用的是 windows 系统的话,上面命令的 google-chrome 换成你的 chrome.exe 路径,后面的 --ignore-certificate-errors 主要是忽略一下证书,打开之后我们输入百度:
这个时候我们就可以在中间人(mitmweb)那里看到百度的请求了:
点进去一个具体的请求,你会发现右边的面板很清晰的给你展示了请求和返回的数据:
看到这里,我知道你又想坏坏了,篡改一下请求和返回的数据?
简单,在这里定义你要修改的地方,比如我要对百度的请求的数据进行修改,那就在这里输入 baidu:
这时候我们重新在 8080 代理的 Chrome 请求一下百度,你会发现,中间人这边先拦截了请求了:
这时候我们点击右边那支笔,就可以直接修改请求数据了:
因为我这里只是直接请求首页,没有表单数据,我就不修改了,直接让它去请求百度的服务器,我们可以点击上面 Flow 菜单下的 resume 按钮就可以直接执行了:
服务器返回数据的时候,又被我们(中间人)拦截下来了,此时我们又可以修改服务器返回的数据了:
你看这标题:
我们改成:帅b老仙,法力无边
写完之后,右上角打个勾,然后再点击一下上面的 resume :
可以看到浏览器的标题变了:
可能你看到这里会想,这...和 fiddler 差不多嘛,好吧,接下来就给你展示一下,它真正厉害的地方,把 Python 当做中间人,对请求和返回数据进行操控。
开始撸一下代码,我们创建一个 mitm_shuaib.py
在这里我们把 mitmproxy 导进来,接着定义了 addons ,在这个列表里面我可以定义一些实例,每个实例都可以自己去定义想要的中间操作。
实例里面的定义的方法是和 mitmproxy 内部的机制挂钩的,比如请求时会调用到 requests , 响应时会调用 response 方法,我们的脚本逻辑主要就是在这些地方实现的。
比如我们这里用到了 request 方法,也就是当我们进行请求的时候,中间人在这里就可以拦截到请求,每次访问我们就 +1 ,然后打印一下。
保存好我们的脚本,然后使用 mitmweb 来执行:
mitmweb -s mitm_shuaib.py
这时候脚本就运行了,开了 8080 端口代理:
老样子,我们开个 8080 端口代理的浏览器来访问,这时候每次请求就被我知道了,看以下就是每次请求被我发现后打印的数据:
这就说明,我们的脚本已经可以了,但是这样玩有点不过瘾,我们继续玩下 Python 脚本,在请求的时候,和数据返回的时候,来搞点事情怎么样?
来玩个有趣的,就是让对方在百度搜索的时候,不管搜什么内容,我们都把它改成搜 “世界上最帅的男人” ,然后把百度返回的结果改成“世界上最帅的男人是小帅b”。
哈哈哈哈,先让我笑一会~
我们先定义一个帅b实例:
然后我们再拦截一下百度的搜索请求,在这里我们简单的判断一下,如果不是百度的请求我们就放行,如果是的话,我们就把搜索的关键词给改了,不管他搜什么,我们都改成去搜索:世界上最帅的人!
接着就是数据的返回,很简单,把返回含有 “世界上最帅的人” 臭不要脸的改为 “世界上最帅的人是小帅b”。
也就是这样:
好了,我们来运行一波吧,执行脚本:
执行代理访问,然后随便搜索一下:
可以看到,本来搜索的是“hahah”,但都直接被改成搜索 “世界上最帅的人”,并且返回的是 “世界上最帅的人是小帅b” 了,哈哈哈。
好吧,小帅b最帅~
这就是 mitmproxy 的牛逼之处,可以让我们使用 Python 直接操作上网数据,可能你会问了:“如何操作手机上的请求数据呢?”、“怎么使用它来爬取手机上的数据呢?”