加密流量APP的渗透准备

涉及工具

  • JEB
  • DDMS
  • frida
  • frida-dexdump
  • burpy

过程

又是喜闻乐见的加密流量!搞它。

APP是加壳的,先上frida-dexdump脱壳。

这么多有encrypt关键字的,不好找,我们上DDMS

通过profilling,我们很容易就能定位到加密函数:

JEB,打开我们已经脱掉的dex文件:

恩,剩下的就是写脚本了。

  1. 为方便测试,我们使用burpy,这样就能直接在burpsuite上操作加密解密了。
  2. 为方便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:

可以愉快的渗透了: