|
第一次发教程 出现问题请见谅
5 J6 C w- {( q' g% Y这次是最新版本的4399游戏盒登陆密码加密讲解和两个sign的讲解
* y0 r# E7 j( E/ C% D. |- Z# k g
由于我测试的时候是无法对这个APP进行IDA调试的 所以就静态分析了一下, S2 I9 n- X3 R7 P" c
# W4 M" j" O. r/ d! D! \8 b6 L" U
1 y! M+ ?* f5 a
- POST https://mapi.4399api.net/user/box/android/v1.0/log-in.html HTTP/1.1& R- b8 k. j* F( g1 l7 m8 y3 P
- User-Agent: 4399GameCenter/5.2.0.39 (android;Nexus 6P;6.0;1440x2392;WIFI;1376.416;yaoqing)
% T! x7 o1 Z3 L - mareacode: 350100- d* B) Q' W0 i* [ b7 J
- a-id: decd74ca59799d58
* }# b( l$ [% e l& m - e-id: 867981022896164
; p2 z) e7 D3 r7 X6 G! ]: W - m-id: D4%3A61%3A4E%3A13%3A10%3A1F3 J; {, M- Z* \$ H9 F; p/ t- @8 M
- s-id:! u6 @ [9 d5 }
- mauth:
! Z5 [( T0 r; H - mudid: 1085glt3vuUywD5g808eZb67a
2 p+ s7 W& v9 ?% }5 }7 ?" Y - pauth:5 D# S% C$ ^, Y5 M1 M0 ?: w' ?
- SM-DEVICEID: 2019101514035076086dc3e7e2dc00afe0043881a46e18018036cbcdd51ca5
$ i- L; W1 e, }+ m - mdeviceId: 867981022896164
b$ L# B. ^- Z* k% |7 u - mauthcode:
7 \5 o+ F! C1 R W R. {8 a- I - Content-Type: application/x-www-form-urlencoded
3 Y5 X/ P( g; D6 P3 w, a - Content-Length: 161
% q1 \- n& ]" i. c, O - Host: mapi.4399api.net- } X7 o8 n1 z7 H/ B; L
- Connection: Keep-Alive
9 p% ?- A: L3 p% T, H3 C% r/ ]7 {9 c - Accept-Encoding: gzip# T Z5 X8 y$ g* p( q
- password=JE%2FYTsyiLwE%3D&deviceIdentifier=867981022896164&dateline=1571863440&sign=c80c8c800fa61cccc02e12e87da33620&model=Nexus%206P&username=13665098754&info=1
复制代码 这是抓到的登陆包
2 g: m, u% Z1 x9 z; V3 k. F大概能看到两个参数需要处理 一个password 一个sign- a1 U; D( D- J( p5 j
8 d' B1 X5 X5 G' j反编译4 {: c: Y/ t4 e$ I& b5 Q+ F3 i# G
" O/ K/ Z# ?+ i; m+ ~/ ^
找到关键点
) G0 {7 u4 E5 y% B# u; @
7 w! b; I+ Y3 d1 ~跟进以后就是Native函数了 这里我们从名字就能大概知道password是一个DESCBC类型的加密(不排除重写) 我们也只是猜测
6 `1 Q6 Y& F1 N2 K) a- Y# D. {5 L3 y
: e: S$ {3 ~7 e/ {1 O: Z* `# Z1 [: A: q ?6 N+ i. a
- public class AppNativeHelper {; w8 f4 s8 a: p0 `$ }
- static {: ^+ o7 X0 J4 c' ]# ]1 _) T
- try {
* l/ x4 ^: @: [/ S c - SoFix.loadLibrary (BaseApplication.getApplication (), "m4399");
; C; `) `3 y# }2 T& f- p5 P. ?3 t - Log.d ("AppNativeHelper", "load libm4399.so");1 Z# W! y- l! j$ \
- }
" q5 Y& D* w- V$ b% a, G/ l - catch (SoLoadFailureException v0) {
! z( T2 Z& _# A7 ^0 V0 X - v0.printStackTrace ();
' z# e6 H4 C2 E2 l2 h% I - }4 f0 [5 @) J/ _# V
- }
; M& t% c4 J( ?7 o( x( ~9 l' R2 r - public AppNativeHelper () {
% x: R d& I4 O - super ();. \7 J7 J; S) o0 p. P# N
- }" U1 |6 P. w7 ]7 L
- public static native int applyPatch (String arg0, String arg1, String arg2) {
* z: A+ Z! Q8 C8 j2 x K7 ?3 B - }( T; {) s+ J6 \# _4 O: m
- public static native int delayRestartProcess (String arg0, String arg1, long arg2) {
3 c6 O. Y9 A( y* I" p: D - }
1 e* s+ x$ F# n' r' d* O" T) ~6 O& m - public static final native String desCbcDecrypt (String arg0) {
, h; s1 b Y/ [$ {# l4 _ - }- u- Z- J9 R( F& y, r" v# T
- public static final native String desCbcEncrypt (String arg0) {
4 u# M6 B0 ]( T - }
复制代码 拿出libm4399.so拖进IDA进行处理 ) R I/ _1 n' [# m
" }4 q2 B: h4 q5 u9 _这个So是动态注册函数/ _6 w- \9 y1 d m5 N) Y
/ R" b' A0 } u所以我们进入Jni_onload 导入头文件 找到RegisterNatives函数
$ M3 O9 V; @) c; DRegisterNatives中第三个参数就是我们注册Java函数的实际地址8 }0 B: z6 ?6 `8 p; ~+ Z N9 F
; n. h. |& a: ]2 I G: ~
3 A$ N' y7 t) S" W
6 f' W# u" s! l( I
进去以后是DCD格式的 第一项是函数名 第二项好像是格式还是啥 重要的是第三项 这就是我们的函数地址了 找到我们要的函数 然后找到函数地址: q! b0 M1 Z( W
4 D* j5 `* J: F% A
5 U' Z5 D% T7 O9 W" u0 D+ d; e* [
然后进来这个函数
2 c% L: g u1 F+ r6 i/ [' j, y d Y; m: T# V; M* q+ t# f/ I
7 B: D) x7 z6 D2 N- int __fastcall sub_17024(int a1, int a2)% {: p2 \! W* ~5 w8 H' N2 W' L* B
- {
7 f( k. p& a. p6 K! v" H - int v2; // r4
1 I0 }+ I: O+ ` - int v3; // r5
6 @% `) J8 x% O0 e - char *v4; // r6: n. L% i+ r/ V, `% x5 a
- int v5; // r0
: d4 g1 j: N3 }$ J - int v6; // r3
. G6 s# E; K! A& p% L6 s" q" L4 i - char v7; // r2( n* U5 H, n; q8 }5 c; o
- int v8; // r4
* `8 `' w: w+ }& Y1 z! z
- R7 S9 @* J' [% B- v2 = a2;' A" m% Z" z$ ]2 a/ K R5 _- N- I
- v3 = a1;
- t2 a" Y! y; Z+ [* [ - v4 = sub_17274(9, 1);
! L& i) L# `2 d1 W5 Y7 t0 U - v5 = 0;
- H) o: c5 [" H# X; D - do
3 Z- ], P' K6 { - {
, \/ y3 M+ ]# T6 l0 o) N - v6 = (dword_1B040[-v5] + 101) >> 15;. f6 y" K8 x5 B+ l: U" E
- v7 = v6 ^ 151;6 a# V% n K! k
- if ( v6 >= 102 )
: h$ ^5 p' c% p. Z# x8 \' i - v7 = v6;
7 u( G* c0 y- V3 { B - v4[-v5--] = v7;: u' H" t# U; r3 c) @
- }( t1 s+ k$ p5 l$ ]' Z
- while ( v5 != -8 ); // 循环8次 获取DESkey
1 W# R! \$ ]/ C; N, c+ m% W - v8 = sub_64B8(v3, v2, v4); // //进入加密函数
, _6 t% J1 q7 T* |' I - sub_17284(v4);
3 b$ ?; c( H* j# z, x9 G9 Y$ K0 N% U - return v8;0 m0 n. J- M" m" d* e8 b% j; Z
- }
复制代码
9 {1 `/ v/ X, `2 x/ u s/ f- {/ ]9 X& A* Z" @& p
通过前前后后的分析 这里就是获取Key的重要地方了 从一个地址里面取值出来 然后循环处理8次 然后我们进入dword_1B040看% r- _, t, c3 n
$ }' i1 [+ w: b% j8 w( n% B
; g3 `7 i/ P) b+ q3 v
4 Y( K# g' m- Y) `$ Q' {1 A) O- {6 N# w8 d% `5 j
看不出什么猫腻 我们转换一下格式 先转Double再转为array IDA右键就有
9 }5 e1 U& ~1 a+ H
( @' c: A2 x: O' _3 p1 N) _7 v
8 Q- U# c& u v, N6 h1 Q9 Z
2 v; T1 M. c1 F& y+ R+ @然后我用js翻译了这小段so逻辑理清楚后一下子就明白了
& A' Q% C9 r5 V6 y1 A+ w" H7 n
6 O1 [5 K. K, g2 C3 X5 t8 [( q* @' l4 R
- function get(a) {
5 r2 ~- S5 q+ A; c$ J$ y3 s4 j - v6 = (a + 101) >> 15;& B7 |+ H( k. Y7 k. e2 u& r4 [
- v7 = v6 ^ 151;; V* [- K/ {# w* U# ~0 R
- if (v6 >= 102) {- M+ e5 }' F. D1 Y3 P
- v7 = v6;( u+ l" p+ ~$ G% x2 z7 Z2 J
- }
! N" G+ v' L( F - return v7: d1 P, I3 _* b/ O, s% b
- }% D3 S! ~ U2 A4 u- | W1 {+ t
- function a() {( ^7 k1 N3 q( m: i( ^0 `
- arr = [0x3A7F9B, 0xFFDAFF9B, 0x3EFF9B, 0xFFD9FF9B, 0xFFCFFF9B, 0xFFEB7F9B, 0x3B7F9B, 0xFFD37F9B];3 z* Q s( }2 o% D9 ~- |
- var aa = new Array();
* n' b" e& G7 _' p$ k% q" O# D9 h) h - for (var i = 0; i < 8; i++) {
4 E/ u& T" x8 b" q+ h6 z - aa.push(get(arr[i]))
( l, ]+ Z' ^; Q5 T2 H/ j! v" S0 L - }, }# U3 L3 k& P, N. N; d
- return aa6 A/ S: q$ D4 F/ @; r4 U
- }
复制代码 # P. u* t+ r b
% k) s4 W4 c3 v. Y# n这里返回的就应该是key数组了 {117,-223,126,-221,-201,-192,119,-208}
& Z$ Q7 x! r3 n然后转换到易语言的字节集就是{117,33,126,35,55,64,119,48}文本为u!~#7@w0 (这里的转换就是由于其他语言的byte取值范围 -128~ 127) 易语言好像没上限 所以我们只需要把-的给他加上256就能变成易语言的字节集了), d8 {5 ^0 n/ I# X% {! I8 p
* I" _( }& D0 z5 s/ g
到这一步我们已经拿到了KEY了7 f0 ]) _$ u; k# ^$ c
9 _4 t! a8 r' L1 J现在就差一步IV了: X9 o4 K1 v$ x% e0 y
& b% |% Z+ F& v; {9 }( g
前面一直没说) m# {6 u' O! s( j6 ^
) _$ F. C# P0 _$ U因为这个so函数名全是匿名的 所以在分析的时候很难去判断这个函数到底是干嘛的 这种so分析起来就需要自己花点时间和结合经验来操作了
/ m/ ^3 c4 }/ E: R O' ?
$ e! ]9 L/ i2 S/ v这里我都给大家分析完了" B) v- j I# J* G( h
: T" M8 N- ~( y7 C) L& K, U; F
3 }3 _. J" b1 _4 @0 }0 M3 ^4 [, [6 E7 K# `, q( Z/ |% i, R. `% y9 G
5 R3 m8 Q- i7 a
0 s) Q: C4 e" X" \我们已经找到了最关键的加密点了 而且我们现在key也有了 只差IV了" l3 J( h+ M- x Q6 ?
& b1 ?( j* U/ u# u* Wsub_4720这个匿名函数其实就是DES_cbc_encrypt
/ g: f: C( l( t0 b" J
D* h1 W+ H1 z; r$ Svoid DES_ncbc_encrypt(const unsigned char *input,unsigned char *output,# h5 ]2 u2 L# s; g j* t
long length,DES_key_schedule *schedule,DES_cblock *ivec,+ H9 A6 {8 p9 Q* ^. p3 d! ^
int enc);
, f' o# b3 I! H. O( S- ]$ @" e6 z
$ b7 `, d# P5 R1 L. T: U$ n- j2 ]0 x这是DES_cbc_encrypt参数的定义1 j. _! o8 \4 _0 {: d
7 |& U* L5 H: v y依次是输入流 输出流 长度 key iv flag/ y! p/ ^! Z/ G' W0 x/ V* o
$ P }% |+ P6 s恰好能 对应上我们的函数 所以 iv应该就是我们&v11所指向的值了1 R( n) ?: a( w2 ]
" D( W3 u" w- X! R
9 u; L/ j8 O( z5 f3 }8 k3 v+ q- .text:00006618 ; 20: v12 = 0xEFCDAB90;
( O, K* S" O9 k9 C; P0 {& f' H - .text:00006618 LDR R0, =0xEFCDAB902 T# W8 K O$ [. \& F6 e
- .text:0000661A STR R0, [SP,#0xB0+var_9C]5 }. ~% y/ U; E) w
- .text:0000661C ; 21: v11 = 0x78563412;
$ ^) d/ a" T Y. s0 x7 W - .text:0000661C LDR R0, =0x78563412
2 }# k e8 H! x! a* G0 V4 b - .text:0000661E STR R0, [SP,#0xB0+var_A0]
复制代码 这里V11在我们的伪C代码中只赋值了0x78563412 但在汇编里面他实际是赋值了0xEFCDAB90 和0x78563412的 所以我们的iv应该就是0x1234567890ABCDEF
+ X6 a6 S M9 w1 I; x, v# G6 q6 C" @" T5 e6 d# W) j& P: G; S
在我们运行的时候 取值事从后往前取得 两个一组 这个我确实也不太明白具体原因 也是在无名侠前辈哪里学得 也就是 EF CD AB 90 78 56 34 12 这样来拼接得! X* w- i) x" \
3 D: A6 R9 `! u9 K/ k
好了 现在我们key iv都有了 我们在不排除有变异得情况下可以来测试一下能不能解开密文5 a8 {( S3 ~* ^5 P
; P0 |1 f% I2 v$ y* R/ o0 A
7 k# u, ^6 y$ @4 D* Q+ ~9 \
5 b1 t6 x8 ~4 }- x( t m0 H; ?. O6 s& t1 I
成功解开
E( @6 K- @. m* \
# Q/ z. M& w$ R3 e6 m这次so分析得难点其实就在于无法动态调试获取key或者IV 每一步逻辑都需要自己去看
# T% R6 F, ^& B6 L0 g6 F其次就是全是匿名函数 需要自己花点时间去查看每个函数的功能
' X; s+ Z5 b& [" q
+ L7 M/ j; A! ?0 B9 \但总统上还是不算难得 只是需要慢慢琢磨一下得! f' w* _' E7 n2 s K9 h
! `3 [! `0 ]% H5 ?, \" ?3 q
实在是太累了 如果大家对登陆得sign和签到得sign有想法我下次再给大家写文章把( D9 V6 v; K+ Q- J1 G
% S3 r2 M0 W. S3 R6 G
/ U" A8 N) \7 X5 P- g6 {; ]1 t4 \2 k" G( X) B
$ Y9 A. ^9 k$ s1 F; X
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|