因为在处理反爬的过程中遇到了一些动态JS,但是由于服务端会返回一些参数参与本地加密,不能用固定的JS进行AST还原替换调试。所以才有了这个思路,本文只讲思路不涉及具体网站处理。
先记录下mitmproxy基本的api:
针对http,常用的API
http.HTTPFlow 实例 flow
flow.request.headers #获取所有头信息,包含Host、User-Agent、Content-type等字段
flow.request.url #完整的请求地址,包含域名及请求参数,但是不包含放在body里面的请求参数
flow.request.pretty_url #同flow.request.url目前没看出什么差别
flow.request.host #域名
flow.request.method #请求方式。POST、GET等
flow.request.scheme #什么请求 ,如https
flow.request.path # 请求的路径,url除域名之外的内容
flow.request.get_text() #请求中body内容,有一些http会把请求参数放在body里面,那么可通过此方法获取,返回字典类型
flow.request.query #返回MultiDictView类型的数据,url直接带的键值参数
flow.request.get_content()#bytes,结果如flow.request.get_text()
flow.request.raw_content #bytes,结果如flow.request.get_content()
flow.request.urlencoded_form #MultiDictView,content-type:application/x-www-form-urlencoded时的请求参数,不包含url直接带的键值参数
flow.request.multipart_form #MultiDictView,content-type:multipart/form-data
时的请求参数,不包含url直接带的键值参数
以上均为获取request信息的一些常用方法,对于response,同理
flow.response.status_code #状态码
flow.response.text#返回内容,已解码
flow.response.content #返回内容,二进制
flow.response.setText()#修改返回内容,不需要转码
先给需要反混淆的JS文件写个AST,通过express启动作为服务端,伪代码如下:
const parser = require("@babel/parser"); const { visitors } = require("@babel/traverse"); const traverse = require("@babel/traverse").default; const t = require("@babel/types"); const generator = require("@babel/generator").default; const express = require('express'); var bodyParser = require('body-parser'); const app = express(); app.listen(9091,function(){ console.log('Express server running at http://127.0.0.1') }) app.use(bodyParser.json({limit: '50mb'})); app.post('/', (req, sendReq) => { visitor = { ... }; let ast = parser.parse(req.body["content"]); traverse(ast, visitor); let {code} = generator(ast); sendReq.send(code); })
编写mitmproxy代码拦截response对象,然后把获取到的JS代码交给我们上面启动的服务端进行反混淆,随便我们可以在反混淆完了后可以添加Hook代码。伪代码如下:
class intercept_: def response(self, flow): if flow.request.url == 'https://www.baidu.com/123.js' and flow.request.method == "GET": #'https://www.baidu.com/123.js'为需要反混淆js的网址 content = flow.response.text decrypt_response = requests.post("http://127.0.0.1:9091", json={"content": content}).text flow.response.text = """此处加上需要Hook的代码,没有可以不加""" + decrypt_response addons = [ intercept_() ]
命令行启动mitmproxy脚本:
mitmdump -s .\mimt.py u www.baidu.com #www.baidu.com为js所在域名
命令行启动chrome浏览器:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --proxy-server=127.0.0.1:8080 --ignore-certificate-errors
现在可以随便调试了。