涉及工具
- JEB
- DDMS
- frida
- frida-dexdump
- burpy
过程
又是喜闻乐见的加密流量!搞它。
APP是加壳的,先上frida-dexdump
脱壳。
这么多有encrypt
关键字的,不好找,我们上DDMS
:
通过profilling
,我们很容易就能定位到加密函数:
上JEB
,打开我们已经脱掉的dex
文件:
恩,剩下的就是写脚本了。
- 为方便测试,我们使用burpy,这样就能直接在burpsuite上操作加密解密了。
- 为方便burpy调用加密和解密,需要把hook写成rpc的形式。
Talk is cheap, show me the code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import frida import sys import os import json
class Burpy: def __init__(self): device = self._get_android_usb_device() pid = device.spawn("xxxx") self.session = device.attach(pid) device.resume(pid) self.rpc = self._load_rpc()
def _get_android_usb_device(self): for x in frida.get_device_manager().enumerate_devices(): if "AOSP" in x.name: return x
def _load_rpc(self): with open("/run/media/m0nst3r/SSD/work/scripts/xxxx.js") as f: myScript = self.session.create_script(f.read()) myScript.load() return myScript.exports
def decrypt(self,header,body): body_json = json.loads(body) if body.startswith('{"request"'): data = body_json.get('request').get('body') dec_data = self.rpc.dec(data) body_json.get('request').update({"body":dec_data}) else: data = body_json.get('response') dec_data = self.rpc.dec(data) body_json.update({"response":dec_data}) body = json.dumps(body_json) return header,body
def encrypt(self,header,body): body_json = json.loads(body) data = body_json.get('request').get('body') enc_data = self.rpc.enc(data) body_json.get('request').update({"body":enc_data}) body = json.dumps(body_json) return header,body
|
上面是burpy脚本,主要提供frida脚本的加载和加解密功能函数,主要实现在下面的frida hook的js代码中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| setTimeout(()=>{
rpc.exports = { dec: function(data) { let res = null Java.perform(()=>{ let instance = null Java.choose("xxxx.SecurityManager", { onMatch: function(x) { console.log("GetAESKey", x.getAesKey()) instance = x }, onComplete: function(x) {} }) res = instance.decypt(data) }) return res }, enc: function(data) { let res = null Java.perform(()=>{ let instance = null Java.choose("xxxx.SecurityManager", { onMatch: function(x) { console.log("GetAESKey", x.getAesKey()) instance = x }, onComplete: function(x) {} }) res = instance.encrypt(data) }) return res }, }; },5000)
|
由于目标函数是非静态函数,为了避免类实例化时会随机生成密钥,我们使用Java.choose
从内存中查找已经实例化的对象。
另外,使用setTimeout
的方式进行hook是为了给壳一些时间,不然会提示找不到目标类。
成果
配置好Burpy:
可以愉快的渗透了: