|

‘乱码’ 的情况应该也有不少人遇到过。刚刚我也遇到了,貌似我也没发过,所以也就发一波。
APP: 配音阁。
首先看登录的抓包结果 :
源包
POST http://m.peiyinge.com/api-mobile/user_login HTTP/1.1
base_param: {"imei":"864731935151261","csid":"0e838dc763cd4af4966bada969be73f0","mac":"08:00:27:a7:05:3a","net":2,"osversion":"4.4.4","version":"1.6.05.11","channelid":"10010016","osid":"1","time":1499312215880,"adid":"7037048824597863","device":"1","ssid":"\"MEmuWiFi\"","ua":"Xiaomi|MI 5|MI 5|ANDROID4.4.4","tid":"27fcc0b63e354ea480ebe7bf459e5cbc","imsi":"460007783975782"}
token: CqhE4ZEsnXRqQfw551LEQwRyh7NsG+zygNZxK7oMk+2h3tgps3yqd5onIy60QoQUDqQfGxzEefmlv8eVBecKjBy2gvDY8sYD/HRqJqUQ4A14gVu6/bG/FqMPOGc2vnN6
If-Modified-Since: Thu, 06 Jul 2017 03:35:39 GMT+00:00
Content-Type: multipart/form-data; boundary=MZZ4xx6-W1TSRhmnuizjQUxZZqbJOG3C0Yq7sxI; charset=UTF-8
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.4; MI 5 Build/KTU84P)
Host: m.peiyinge.com
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 841
--MZZ4xx6-W1TSRhmnuizjQUxZZqbJOG3C0Yq7sxI
Content-Disposition: form-data; name="version"
1.0
--MZZ4xx6-W1TSRhmnuizjQUxZZqbJOG3C0Yq7sxI
Content-Disposition: form-data; name="appid"
UV010001
--MZZ4xx6-W1TSRhmnuizjQUxZZqbJOG3C0Yq7sxI
Content-Disposition: form-data; name="time"
1499312215883
--MZZ4xx6-W1TSRhmnuizjQUxZZqbJOG3C0Yq7sxI
Content-Disposition: form-data; name="salt"
73b221ff8924453cbb4b9e50e52323dc
--MZZ4xx6-W1TSRhmnuizjQUxZZqbJOG3C0Yq7sxI
Content-Disposition: form-data; name="sign"
bb611b1e7ccb3f384d4f0fdf512dd4f0
--MZZ4xx6-W1TSRhmnuizjQUxZZqbJOG3C0Yq7sxI
Content-Disposition: form-data; name="data"
aVI29u37SX63CbrL87iobUM3fnOaflDzjzvl3Zdc9qvFtH04QoFV1rk2QC8oY/cPPQL+obcr3bTAheLthKHJNj+psziWQ1gZ1+BNjtOYWf7mGpgtTSRSFVNtkTuIbfpFeJVbdqDCAq+LZeJzSB1DpA==
--MZZ4xx6-W1TSRhmnuizjQUxZZqbJOG3C0Yq7sxI--
表单提交的POST,加密处均以标记。
在其它包内,我看到了返回 token 字符串的包,但是它是“乱码”。
PS: 所谓“乱码”其实是包体被压缩或被加密。。。。所以你得看包体的HEX数据也就是十六进制数据。把HEX数据还原为字节集再用字节集的方式提交即可。。。。。
HEX数据是有值的,长度为128,使用FD直接重新发包,证明这个包确实是有数据,而且可以被操作的。
那么问题就来了。。。如何解码 这个包呢???
还是老样子,反编译APP,这里我通过URL的关键字 “exchange”定位到一处看起来有点像包体加密得地方。
因为我看到了 InputStream = 流
用易语言的方式解读一下。
public static byte[] a(Context context, String str) throws Exception {
String str2 = HTTP.UTF_8;
Object bytes = str.getBytes(str2); //bytes = 到字节集(p1的UTF8值)
Object bytes2 = c.b.getBytes(str2); //bytes2 = 到字节集(字符串 c.b的UTF8值)
byte[] bytes3 = n.a().getBytes(str2); //bytes3 = 到字节集(n.a()函数的UTF8值)
Object a = a.a(str, bytes3); //bytes a = 函数:a.a (p1的值,bytes3的值)
byte[] bArr = new byte[((((bytes.length + bytes2.length) + 1) + bytes3.length) + a.length)]; //bArr = 取空白字节集(bytes.length + bytes2.length + 1 + bytes3.length + bytes a.length)
System.arraycopy(bytes, 0, bArr, 0, bytes.length);// 拷贝数组
bArr[bytes.length] = (byte) bytes2.length; //赋值
System.arraycopy(bytes2, 0, bArr, bytes.length + 1, bytes2.length);// 拷贝数组
System.arraycopy(bytes3, 0, bArr, (bytes.length + 1) + bytes2.length, bytes3.length);// 拷贝数组
System.arraycopy(a, 0, bArr, bytes3.length + ((bytes.length + 1) + bytes2.length), a.length);// 拷贝数组
InputStream openRawResource = context.getResources().openRawResource(com.iflytek.domain.a.b.adsring); //打开文件流的句柄,也就是 类似于易语言的 打开内存文件() 命令
byte[] a2 = a.a(bArr, openRawResource); //通过a.a函数得到最后得字节集结果
openRawResource.close();//也就是 类似于易语言的 关闭文件() 命令
return a2;//返回最后字节集结果
}
大致的观察一下。
Object bytes = str.getBytes(str2);
str = n.a().substring(0, 16); // 取文本左边(UUID,16)
n.a() = UUID
*****************************************
Object bytes2 = c.b.getBytes(str2);
包内就有APPID的值。
c.b= appid = ”UV010001“
**************************************
byte[] bytes3 = n.a().getBytes(str2);
n.a() = UUID
*******************************************
Object a = a.a(str, bytes3);
a.a函数 = AES加密
byte[] a2 = a.a(bArr, openRawResource);
a.a函数 = 从证书加载RSA算法。
那我来看看证书,因为是从流( getResources().openRawResource() )里面读取证书,所以证书肯定在APP包得资源目录,也就是res/raw,这个会android编程的人应该都知道。
证书确实在。最简单的办法:使用linux转为pem格式,这样就可以拿到公钥。RsaPublicKey
但是我现在没有linux???那我只能调试了。。。
****************************************************
至此我们已经大概知道整个加密流程,我觉得应该就是这个地方加密出了”乱码“包。
为了验证想法,我打算动态调试此处,继续操作APK,看看是否会断下,但是发现这个APK只有刚刚启动的时候会发这个“乱码“包,
于是我在APP创建进程时挂起等待调试。不过APP直接挂了。那就只能hook了。
于是我在UUID , AES , RsaGetPublickey 处hook。
重新运行APP查看logcat.
07-06 12:55:05.132 29709-29709/? D/QQ805123809: 配音阁,UUID结果: 2532d3c7f29f4dbba95025c199fd01c9
07-06 12:55:05.132 29709-29709/? D/QQ805123809: 配音阁,UUID结果: d33bf6cbaeea46b7b011f903278a1e81
07-06 12:55:05.132 29709-29709/? D/QQ805123809: ----开始拦截a方法-------
07-06 12:55:05.132 29709-29709/? D/QQ805123809: 配音阁,AES p0=2532d3c7f29f4dbb p1=6433336266366362616565613436623762303131663930333237386131653831
07-06 12:55:05.132 29709-29709/? D/QQ805123809: 配音阁,AES 加密结果: 38bde673a40563116930b085cd8a4ee3ce7d045b241bd45673aa501dc6f3929c514d52db5b2449d9ccc12c87438d6689
07-06 12:55:05.132 29709-29709/? D/QQ805123809: ----开始拦截A方法-------
07-06 12:55:05.132 29709-29709/? D/QQ805123809: 配音阁,最后A的 p0=32353332643363376632396634646262085556303130303031643333626636636261656561343662376230313166393033323738613165383138bde673a40563116930b085cd8a4ee3ce7d045b241bd45673aa501dc6f3929c514d52db5b2449d9ccc12c87438d6689
07-06 12:55:05.136 29709-29709/? D/QQ805123809: 配音阁,A读取的OpenSSLRSAPublicKey: OpenSSLRSAPublicKey{modulus=84bb6668b9c069293043bb81661374c6e7f332961a1466525b0d0041d6a5754a4dec1b2aa14d86b7aa6e000655c26e2e8d8d516bd5f6e941ca2bdc6dcbcef8a7bc23ad1f20db46bba09d394248436dd47000cc3584e1d5c9a0a0d7132aa61058e0e3cfb623648849654fdebb2cf671ee35dbcbad7c947864f124a96a9ca4c395,publicExponent=10001}
07-06 12:55:05.136 29709-29709/? D/QQ805123809: 配音阁,A读取的PublicKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCEu2ZoucBpKTBDu4FmE3TG5/MylhoUZlJbDQBB
1qV1Sk3sGyqhTYa3qm4ABlXCbi6NjVFr1fbpQcor3G3LzvinvCOtHyDbRrugnTlCSENt1HAAzDWE
4dXJoKDXEyqmEFjg48+2I2SISWVP3rss9nHuNdvLrXyUeGTxJKlqnKTDlQIDAQAB
07-06 12:55:05.140 29709-29709/? D/QQ805123809: 配音阁,最后A加密: 288166d46c21d0fca0315111bf1420b75f514eab46c6ab1dc357a40b9e5ad664ce32b74b1a4d3a2485672f8f8e6f2849b629744bdac3a6ed640defb351e39a2b8947b85d016662414538b849a1f7eeec547d8236e632c24dc6f39eeefc9285f5ad4098f9f8255900560e8a871542c24891c413b531d6382644886e3ade10624a
为了方便数据一致和观察,我把Java的byte[]转到了hex。因为BYTE也就是字节集是万能的通用型数据
再看刚刚APP启动发包抓包得结果 HEX数据
抓包得Hex数据:
byte[] arrOutput = { 0x28, 0x81, 0x66, 0xD4, 0x6C, 0x21, 0xD0, 0xFC, 0xA0, 0x31, 0x51, 0x11, 0xBF, 0x14, 0x20, 0xB7, 0x5F, 0x51, 0x4E, 0xAB, 0x46, 0xC6, 0xAB, 0x1D, 0xC3, 0x57, 0xA4, 0x0B, 0x9E, 0x5A, 0xD6, 0x64, 0xCE, 0x32, 0xB7, 0x4B, 0x1A, 0x4D, 0x3A, 0x24, 0x85, 0x67, 0x2F, 0x8F, 0x8E, 0x6F, 0x28, 0x49, 0xB6, 0x29, 0x74, 0x4B, 0xDA, 0xC3, 0xA6, 0xED, 0x64, 0x0D, 0xEF, 0xB3, 0x51, 0xE3, 0x9A, 0x2B, 0x89, 0x47, 0xB8, 0x5D, 0x01, 0x66, 0x62, 0x41, 0x45, 0x38, 0xB8, 0x49, 0xA1, 0xF7, 0xEE, 0xEC, 0x54, 0x7D, 0x82, 0x36, 0xE6, 0x32, 0xC2, 0x4D, 0xC6, 0xF3, 0x9E, 0xEE, 0xFC, 0x92, 0x85, 0xF5, 0xAD, 0x40, 0x98, 0xF9, 0xF8, 0x25, 0x59, 0x00, 0x56, 0x0E, 0x8A, 0x87, 0x15, 0x42, 0xC2, 0x48, 0x91, 0xC4, 0x13, 0xB5, 0x31, 0xD6, 0x38, 0x26, 0x44, 0x88, 0x6E, 0x3A, 0xDE, 0x10, 0x62, 0x4A };
从证书加载RSA算法最后加密得结果:
288166d46c21d0fca0315111bf1420b75f514eab46c6ab1dc357a40b9e5ad664ce32b74b1a4d3a2485672f8f8e6f2849b629744bdac3a6ed640defb351e39a2b8947b85d016662414538b849a1f7eeec547d8236e632c24dc6f39eeefc9285f5ad4098f9f8255900560e8a871542c24891c413b531d6382644886e3ade10624a
一模一样。。。那么至此我已经对这个”乱码”得包完成了”解包”的过程。
现在,用易语言来写这个“乱码”包。。。
生成UUID: 这里我用了JS生成。你也可以用E写。都一样。
也把Java的arrayCopy函数用E来表示一下,拷贝数组函数。arrayCopy
我不知道为什么易语言的数组索引是从1开始。。写一些算法的时候好JJ蛋疼。。。这很不科学。。。
因为这个AES密钥是这个a函数来的。动态的。我也还原一下。这里有一个a是全局字节集变量。。转到HEX即可。
全局aHexString = “052d59deb435613a1eb99ec47b2db2d93fdabb303b4a3a2c2759524a252a594b561b023922082b4b59034f234d1d0802080202522753075d064f540861095305490957032b3559070636494f5906503808060761085a17fb”
然后就可以还原整个算法
易语言正解:
测试改包后返回异常。
测试多次发包都返回了不同得token,这样就完成了这个“乱码“包得还原过程和写包过程。
应该也是首发吧。能精否?
@冰点 @精易客服
置入广告{ QQ群: 327680147}
PS:有些人遇到证书很蛋疼。这个就得看这个证书到底是干嘛得。一般就3种。常见处理方式:
1.通讯数据加密解密: hook,动态调试,注入 。
2.通讯加密解密: 代理,提取证书->使用OpenSSL通讯,反射。
3.PFX这类可以找它的密码。直接在winhttp当中使用。
|
评分
-
查看全部评分
|