建行生活请求解密

建行生活请求解密

image-20231116112624538

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
|----|----|----|----|----entered--com.ccb.common.safe.EbsSafeManager.tranEncrypt
|----|----|----|----|----arg[0]: {"regionCode":"510100","ENTITY":"{\"TXCODE\":\"FTFQ02\",\"FT_TILEID\":\"01LSSFQ02\",\"FT_SCENARIO\":\"FTC_CCBLIFE01LSSFQ02001\",\"FT_ORDERNO\":\"YSM2022021628625361700104272875\",\"FT_CORPID\":\"FTC_CCBLIFE\",\"BRANCHID\":\"441000000\",\"resType\":\"JSON\",\"Ed_Crd_Prty_Idr_CD\":\"105290000010422\",\"Cnter_ID\":\"002633255\",\"POS_ID\":\"\",\"EdCrdMchn_Tmnl_Idr_CD\":\"\",\"Clrg_Txn_CD\":\"100801000\",\"TxCh_TpCd\":\"00020000\",\"BRANCHID_MER\":\"310000000\"}","chnlType":"1","APPEND_PARAM":"0ee5b8a25c77c75e|@|171.88.21.93|@|Mobile|@|104.095884|@|30.561436|@|01|@|10|@|M2007J3SC|@|3E:E1:C1:6F:98:A8|@|510100|@|510100|@|B0E5326A5EC9E41ACC7E889076F8D2A3CFBF7AF2|@|2.1.3.002","USER_ID":"YSM202202162862536","SKEY":"bZVGAV"}
--> Bypassing Trustmanager (Android < 7) request
|----|----|----|----|----|----entered--com.ccb.common.safe.EbsSafeManager.getSafeLib
|----|----|----|----|----|----retval: com.ccb.crypto.tp.tool.eSafeLib@eef5187
|----|----|----|----|----|----exiting--com.ccb.common.safe.EbsSafeManager.getSafeLib
|----|----|----|----|----retval: i0+OJkcWPbFDK6cM/bQDXnLLGZsS6R7XicH3SRY75Vy/4EPskJ2r/HJbufq+jqzC3A7mNMiU2V0D5b2MM6V80YfEDExT0I9gyIjukxWkvITv8qZfvFDL2YoQhE6edelnz6kdcDUGAZoSkAv0DkMEAdaD7QVu5j+c7Mixw3jGDh06iFrXqjKCCnS6US6Z06bzXQAnKi5fLWff7KDN8G6RGgDalcLerBVn720gIudWlKIsBXMMbzef0Oxm69UuzJUSWGhzG6Br5ivHD4r7TeR+Ee9k2lj0Ins0waJOwbi7DAnhykUvAX4hIHgq6hRsBACtwLryqxgH/z1czYZ53B5PghFKwQMrWHFUmuYtcqRW36HRTwbVhTN3pfYYg7o5Mg/EuNr4qGD/A0qbhW6dVhoAG04jgI6qNhCDE2iuEmVCzCAmGeO499ASe8n6n3hWD5+JmJ+616USKGGVPnBD1kI3dZTgww2ED+3W/ns+mHuvKc1V90/6jqVmAx79JI4u1FoCLs5Ci2a/dCAl0Ds4kIshXA6U4u4Xn+6RqwO4ysYDqmE3c0pduGXsKORSbGPI70xpWn9WtJ2RVvWvICaEzxF77wJL8GuEfZJfEuzQOCxZKCkvK8uPtFXECScaOQ1SfuXJzWzTQqr16TYWAyiUZb1snLiMLWIIgjXmRd8demtI33z+JsZcCCoh6tOmWHZ4VHwZm0D2AaYof2p7jXw5VDEYE88pdEhtqjzZvswbjdDpNfS1z2HKU4xgti4oM8oVYQ6XS38h4XhUPl4qewBWqAeElflPs/Lz31dq5yQbCZpHjowPk1ZZ3mv54OYG0tcndde0xj89BkO7i3VLL5OxmsxdbJgpWYLpqZbVrGU3FHET5uQaV3jrFIfFhQTxgLGyG3AYwh/f6dBToOtCoP2NvILsf0D5G4467lC7Fra934j/U0M3CSz3CONMSxkGxWP8ROFNJ04BPcewWWs=
|----|----|----|----|----exiting--com.ccb.common.safe.EbsSafeManager.tranEncrypt
|----|----|----|----|----entered--com.ccb.common.safe.EbsSafeManager.calc_HMAC
|----|----|----|----|----arg[0]: {"regionCode":"510100","ENTITY":"{\"TXCODE\":\"FTFQ02\",\"FT_TILEID\":\"01LSSFQ02\",\"FT_SCENARIO\":\"FTC_CCBLIFE01LSSFQ02001\",\"FT_ORDERNO\":\"YSM2022021628625361700104272875\",\"FT_CORPID\":\"FTC_CCBLIFE\",\"BRANCHID\":\"441000000\",\"resType\":\"JSON\",\"Ed_Crd_Prty_Idr_CD\":\"105290000010422\",\"Cnter_ID\":\"002633255\",\"POS_ID\":\"\",\"EdCrdMchn_Tmnl_Idr_CD\":\"\",\"Clrg_Txn_CD\":\"100801000\",\"TxCh_TpCd\":\"00020000\",\"BRANCHID_MER\":\"310000000\"}","chnlType":"1","APPEND_PARAM":"0ee5b8a25c77c75e|@|171.88.21.93|@|Mobile|@|104.095884|@|30.561436|@|01|@|10|@|M2007J3SC|@|3E:E1:C1:6F:98:A8|@|510100|@|510100|@|B0E5326A5EC9E41ACC7E889076F8D2A3CFBF7AF2|@|2.1.3.002","USER_ID":"YSM202202162862536","SKEY":"bZVGAV"}
|----|----|----|----|----|----entered--com.ccb.common.safe.EbsSafeManager.getSafeLib
|----|----|----|----|----|----retval: com.ccb.crypto.tp.tool.eSafeLib@eef5187
|----|----|----|----|----|----exiting--com.ccb.common.safe.EbsSafeManager.getSafeLib
|----|----|----|----|----retval: xwCRJgW1XZfppVWPAwgBLeUtgTE=
|----|----|----|----|----exiting--com.ccb.common.safe.EbsSafeManager.calc_HMAC
--> Bypassing Trustmanager (Android < 7) request
com.nantian.nthttptool.okhttp3.internal.tls.OkHostnameVerifie.verify("java.lang.String", "javax.net.ssl.SSLSession")
com.nantian.nthttptool.okhttp3.CertificatePinner.check()1
com.nantian.nthttptool.okhttp3.internal.tls.OkHostnameVerifie.verify("java.lang.String", "javax.net.ssl.SSLSession")
com.nantian.nthttptool.okhttp3.CertificatePinner.check()1
com.nantian.nthttptool.okhttp3.internal.tls.OkHostnameVerifie.verify("java.lang.String", "javax.net.ssl.SSLSession")
com.nantian.nthttptool.okhttp3.CertificatePinner.check()1
com.nantian.nthttptool.okhttp3.internal.tls.OkHostnameVerifie.verify("java.lang.String", "javax.net.ssl.SSLSession")
com.nantian.nthttptool.okhttp3.CertificatePinner.check()1
|----|----|----|----|----entered--com.ccb.common.safe.EbsSafeManager.tranDecrypt
|----|----|----|----|----arg[0]: kumy2nOG3ZwBzwwW0lIHuoNvgAl6+0IWaA0CWpRLCC31WzATMl/InB3HFGVB2sODjlKB335Xkb8FMzUS4FaLtaIkdm/fg21PxEYRSLvOJcUJwzTdwh84/dbtpbN4miGlcmb3Oz/TdjCTl86SHxfJJJ3l7hd6HRc4TyNEUAhtwdnyLUvzv/zVphMtJk4gzT16H6ytXUgWhYLKy0ri3mwlCWDErX3mdA8MnIrgEoosScY58gxboasibG5ByG5g8uCOb6lljFXQMKnn0I1ZArs6+H6AC9ejWAXy/18IKUq5z55pKrLx44ZZDhJDofH4ML6eaXVn1JZTDffrNMm5MM+JgbclMU9Cf0YY0VhVedHaDZYDVFb2mxzuvzAySjbm5J1hfI8U3xhqUJ1G3kG2dFbpv6HQDrHs7hCgdq9nxNLp2Dg8cU49ZPLSbgtfOdiaf4i1cAn9E1jJcASMxBbmrAOQJ0xACdbtlS/+pIFkcaqJp3V/qLGQTRhR2PzIAgpcBTcMs+XseqoFogLsoqkURxftouLiIB01SyR3lJwtEQwlpnbYcztMQWyvSUKs/9lgTS4iODEDV6CKf3C412WJWobfJAvymEC1wIC6ZpnjB4c9sSBMxkIRQvIzg3skOBaqaExdgvNjN1OKGpczzTat1J+gSvT21KRaOf0fK8PwtItSrcCFTxBXYAhxFQiNMmwwHTXc8gZC7vPgEZZiLbbhYQTaQfu89dhn0Lzp2UWtnWSuXKTspVaU+FKI64dAgomGZKIl86C8aqYHuFqMURIB/haicH+5snpOu2hz4lm3pZ25Ztk=
|----|----|----|----|----|----entered--com.ccb.common.safe.EbsSafeManager.getSafeLib
|----|----|----|----|----|----retval: com.ccb.crypto.tp.tool.eSafeLib@eef5187
|----|----|----|----|----|----exiting--com.ccb.common.safe.EbsSafeManager.getSafeLib
|----|----|----|----|----retval: {"data":{"RESP_ENTITY":{"POS_ID":"1052900000104220001","SUCCESS":"true","Mrch_Blng_Dept_Cd":"1","Acq_Clrg_InsNo":"310280000","OnlnPcsgInd_1_Bmp_ECD":"1111000000001000000","SYS_EVT_TRACE_ID":"1010114691700104273659896","Ed_Crd_Prty_Nm_Adr":"建行优惠券","MTTC":"","EdCrdMchn_Tmnl_Idr_CD":"00291596","Qot_Ctrl_Bmp_Dsc":"00000000","Mrch_Tp_ECD":"7399","Wbt_Cnter_Nm":"浦东分行(建行客户回馈专用户)","Cnter_ID":"002633255","Mrch_GBnk_InsNo":"310613640","OnlnPcsgInd_2_Bmp_ECD":"00000000000000000000000","Ed_Crd_Prty_Idr_CD":"105290000010422","TXCODE":"FTZF01"}},"errCode":"0","errMsg":""}
|----|----|----|----|----exiting--com.ccb.common.safe.EbsSafeManager.tranDecrypt
|----|----|----|----|----entered--com.ccb.common.safe.EbsSafeManager.tranDecrypt

2024-12-11 update

请求体的加密和响应体的解密对应的方法分别是:

1
2
com.ccb.common.safe.EbsSafeManager.tranEncrypt()
com.ccb.common.safe.EbsSafeManager.tranDecrypt()

这两个方法都是native方法,加密算法的实现在libEsafeexptp.so中。

tranEncrypt实际上是TriDesCBC.

tranDecryptAES-128-ECB.

只不过他们的密钥是在调用白盒解密后才能拿到,但从逆向的角度,根本不需要去死磕白盒加密,只需要在TriDesCBC和AES解密时候拿到对应的密钥就行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Interceptor.attach(Module.findExportByName("libEsafeexptp.so", "_Z9TriDesCBCiPhjS_S_S_"), {
onEnter: function (args) {
console.log('_Z9TriDesCBCiPhjS_S_S_...')
this.arg2 = args[4]
console.log('TriDesCBC key:', Memory.readCString(args[1]))
console.log('TriDesCBC iv:', Memory.readCString(args[5]))

}
});

Interceptor.attach(Module.findExportByName("libEsafeexptp.so", "AES_set_encrypt_key"), {
onEnter: function (args) {
console.log('AES_set_encrypt_key:', Memory.readCString(args[0]))
}
});

新版本中没有了函数符号,不过可以根据特征码找到对应的偏移。

image-20241211194300218

image-20241211201529256

2.3.1 hook代码:

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
var lib_base = Module.findBaseAddress("libEsafeexptp.so");
Interceptor.attach(lib_base.add(0x6CA54), {
onEnter: function (args) {
console.log('_Z9TriDesCBCiPhjS_S_S_...')
this.arg2 = args[4]
console.log('TriDesCBC key:', Memory.readCString(args[1]))
console.log('TriDesCBC iv:', Memory.readCString(args[5]))

}
});


Interceptor.attach(lib_base.add(0x6A64C), {
onEnter: function (args) {
console.log('AES_set_encrypt_key: ', Memory.readCString(args[0]))
}
});

Java.perform(function () {
var EbsSafeManager = Java.use('com.ccb.common.safe.EbsSafeManager')
var plain = EbsSafeManager.tranEncrypt('11110000')
console.log(plain)

var s = '2pmLObLbD5LftuUBmsj3+MtJ04DFw6BfqjDHwMnRVS7VPLCS/CjRTqWd5BSr5kyrgFnsuvaiMKbylNAnnZghee458HNpOsJHbij/RYR5NUsBT0wCgrr3JncnjBFnEB9lcqHM3HYJIn8kh0FwN6KrmMa1MmPPjzR3LL8mrdDOet4enSCvWZlgJshCFZH94AwnrL5HSP5+uLZjqsasBb8MN2a3e+e/Da0NrmVOCbCJsZA='
var plain = EbsSafeManager.tranDecrypt(s)
console.log(plain)
});