-
-
[原创]CTF2017第6题分析
-
发表于: 2017-6-13 10:53 4896
-
之前看这题的要求是要android 5.1以上系统,手上没这种手机,PC跑arm模拟器又慢,准备放弃的,后来发现竟然能在我的华为3C (android 4.2)上运行。
1. 静态分析
用ApkIDE反编译,直接浏览MainActivity.smali,流程很清晰。
invoke-static {v0}, Lcom/miss/rfchen/utils;->check(Ljava/lang/String;)Z
整个验证逻辑就是调用so中的check完成的.
把lib中的librf-chen.so拖到IDA中,可以直接索引check函数
简单浏览了下,发现一些字符串相关的操作,估计跟逻辑有关.
.text:0000295C STRH.W R0, [SP,#arg_22]
.text:00002960 PUSH.W {R4-R10,LR}
.text:000029C6 STRH.W R1, [SP,#arg_24]
.text:000029CA MOVS R1, #0x75
.text:00002A32 STRH.W R1, [SP,#arg_26]
.text:00002A36 MOVS R1, #0x33
.text:00002A9A SUB.W R1, R1, #1
.text:00002A9E STRH.W R1, [SP,#arg_28]
.text:00002AA2 MOVS R1, #0x43
.text:00002B0A STRH.W R1, [SP,#arg_2A]
.text:00002B0E PUSH.W {R4-R10,LR}
后面代码混淆比较多,准备动态调试了.
这里本来想修改这里的跳转逻辑验证下的,发现只要smali文件有修改,就打包不回去了,看到android.support下有个包名是符号,估计跟这个有关,具体不了解,考虑到时间关系,没继续研究这个了,后面有空了再看看.
改smali不行,但是修改AndroidManifest.xml可以,直接加上android:debuggable="true",当然手上有修改参数自己刷过机的调试环境的,可以不用这步.
2. 动态调试
先挂起app (具体的调试步骤,论坛网上都有很详细的介绍):
adb shell am start -D -n com.miss.rfchen/.MainActivity
然后使用IDA附加,跟踪check函数,相比PC,这个又带混淆,调试手段还是少很多,感觉就是单步,然后配合静态IDA看流程,能跳过的函数先跳过,先弄清楚大致流程.
首先是前面拼接了一个字符串JPyjup3eCyJjlkV6DmSmGHQ=,先记录下来。
base: 776A4000
librf_chen.so:776A76C4 BLX R3
librf_chen.so:776A76C6 PUSH.W {R4-R10,LR}
librf_chen.so:776A76CA POP.W {R4-R10,LR}
librf_chen.so:776A76CE B unk_776A76F8 这里r0:指向输入的字符串
后面可以逐步看到对输入字符串的处理,到下面函数,通过看逻辑发现就是base64,
.text:00005AFC my_base64 ; CODE XREF: sub_1A188+9Ep
.text:00005AFC PUSH.W {R4-R10,LR}
.text:00005B00 ADD R7, SP, #0xC
.text:00005B02 MOV R9, R0
.text:00005B04 MOVW R0, #0x5556
.text:00005B08 MOV R10, R1
.text:00005B0A MOVT.W R0, #0x5555
.text:00005B0E SMMUL.W R0, R10, R0
.text:00005B12 ADD.W R0, R0, R0,LSR#31
.text:00005B16 ADD.W R1, R0, R0,LSL#1
.text:00005B1A SUB.W R1, R10, R1
.text:00005B1E CMP R1, #0
然后就是结果和之前的JPyjup3eCyJjlkV6DmSmGHQ=这个串比较.
之前为了快速弄清楚流程,有的函数跳过了,到base64这,发现输入字符串不是app上输入的原始字符串,看来是之前又有变换操作,不过这里发现长度和原始串是一致的.
后面就单独跟踪了base64之前的操作,大概就是查表,
.text:000047EA ADD R10, R4
.text:000047EC UXTB.W R7, R10
.text:000047F0 LDR.W R8, [R6,R7,LSL#2] ; r6: 0x100个int的表,查表操作
.text:000047F4 STR.W R8, [R6,R5,LSL#2]
.text:000047F8 STR.W R4, [R6,R7,LSL#2]
.text:000047FC ADD R4, R8
.text:000047FE UXTB R4, R4
.text:00004800 LDRB.W R5, [R11] ; 读取app中的输入串,单个字符
.text:00004804 LDR.W R4, [R6,R4,LSL#2]
.text:00004808 EOR.W R4, R4, R5
.text:0000480C STRB R4, [R3]
这里涉及到混淆,后来又跟踪了后续处理,基本确定是rc4了,然后就是回溯表的生成,发现8字节的输入key:
70 D6 CB 74 40 B2 A8 72
base: 77461000
librf_chen.so:7747B0BC POP.W {R0,R4,R5,R7,LR}
librf_chen.so:7747B0C0 ADD.W R1, R1, #1
librf_chen.so:7747B0C4 SUB.W R1, R1, #1
librf_chen.so:7747B0C8 BL unk_774665E4 生成rc4表
librf_chen.so:7747B0CC MOV R0, R4
librf_chen.so:7747B0CE MOV R1, R6
librf_chen.so:7747B0D0 MOV R2, R9
不过这里遇到个问题,我用程序生成的表和这个不同,已经int转byte后的,考虑比较晚了,第二天还上班,没跟踪具体逻辑了,直接把表数据扣出来了。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课