模拟器
Nox(夜神)的6.x版本,可以使用52大佬的去广告绿化生成器,旧版本的模拟器可以在夜神的论坛下载,可以忍受广告的也可以直接官网下载最新版。
推荐分辨率设置到2k480dpi,不然可能会出现无法点击的错位ui。
因为Android7.0+的证书信任问题,选择5.0版本的模拟器。
mitmproxy
mitmproxy的原理是中间人攻击,名字就是中间人(Man-In-The-Middle)的缩写,感觉目前大部分的能抓https包的都是用的中间人攻击,其他的比如Charles,阿里的anyproxy等。
第一次安装用了scoop,之后为了生成文档又用pip装了一次。
官方文档非常不全,只推荐用pdoc自己生成,pdoc建议安装pdoc3,不然可能出现依赖markdown版本过低导致的错误。
pip install pdoc3
pdoc3 --html mitmproxy
安装完成之后就是常规操作,尝试先直接抓一下模拟器的包。
模拟器代理设置
设置→wlan→长按修改网络→代理:手动
主机名设置为物理机的内网IP,可使用ipconfig
命令查看。
端口设置为mitmproxy的端口8080
。
安装证书抓取HTTPS流量
mitmproxy把安装时生成的证书放在C:\Users\USERNAME\.mitmproxy
下,所有系统版本的均有,也可设置代理后访问mitm.it来可视化地选择下载。
设置→安全→从SD卡安装
选择对应的证书即可。
mitmweb抓包
mitmweb --set allow_hosts='(.*)-app-xxxx\.xxxxxx\.com' --set termlog_verbosity='warn'
由于该游戏的实名认证应该是使用了固定证书,不过滤可能会出现反复要求实名认证的问题。
因为要抓的包很明确,直接使用白名单模式过滤。
Wiki中的ignore-hosts
说明:
Ignore host and forward all traffic without processing it. In transparent mode, it is recommended to use an IP address (range), not the hostname. In regular mode, only SSL traffic is ignored and the hostname should be used. The supplied value is interpreted as a regular expression and matched on the ip or the hostname.
Default: []
简要意思就是说在透明代理模式下推荐使用ip代替域名,以及参数使用正则匹配。
这个名单只对SSL流量生效,并不会过滤http请求,需要过滤http流请求可以使用filter。
包处理
由于需要显示UI界面,不使用mitmproxy的脚本模式,而是在Python中后台开启mitmproxy。
#Build with tkinter
class Application(Frame):
def __init__(self, master=None):
self.m=None
Frame.__init__(self, master)
self.grid()
self.createUI()
def createUI(self):
# put UI here
def startDump(self):
# dump
self.m = DumpMaster(opts, with_termlog=False, with_dumper=True)
self.m.server = proxy.server.ProxyServer(pconf)
self.m.addons.add(PrintResponse())
# start mitmdump in a new thread
loop = asyncio.get_event_loop()
t = threading.Thread( target=loop_in_thread, args=(loop,self.m) )
t.start()
def close(self):
self.m.shutdown()
def showData(self):
#show dump data
app = Application()
# dump option
opts = options.Options(listen_port=8888)
opts.add_option("body_size_limit", int, 0, "")
opts.add_option("console_eventlog_verbosity", str, "warn", "")
opts.add_option("allow_hosts", list, ["(.*)-app-xxxx\\.xxxxxx\\.com"], "")
pconf = proxy.config.ProxyConfig(opts)
def loop_in_thread(loop, m):
asyncio.set_event_loop(loop)
m.run_loop(loop.run_forever)
class PrintResponse:
def __init__(self):
#set flowfilter
self.game_host = flowfilter.parse('~d "(.*)-app-xxxx\\.xxxxxx\\.com"')
def response(self, flow):
if(flowfilter.match(self.game_host,flow)):
resdict=json.loads(flow.response.content) #Parse the content as json
app.showData(resdict)
if __name__ == '__main__':
app.mainloop()
上次修改於 2021-01-20