首页
论坛
专栏
课程

[原创]MSC解题报告

2015-1-26 19:17 17681

[原创]MSC解题报告

2015-1-26 19:17
17681
第一题
看代码是从logo.png这张图片的最后,读取一个映射表,和最终比较的密码,然后通过输入的字符的转换,去比较是否和最终密码相等。但注意到每段下面都有log输出。因此直接装手机上跑一跑,果然点击按键之后会有中文的表和所需正确密码的中文输出,尝试输入几个字符查看对应的中文后,可以找到对应关系,得到最后的密码。

第二题
Java层没做什么,直接把输入放到底层的libcrackme.so里做了判断。发现JNI_Onload里做了些处理,接着securityCheck里面最后有判断,将输入和一个wojiushidaan做比较。输入后发现密码错误,因此可以猜测前面一大段逻辑的作用就是会把这个最终的字符串改掉。其实只需要知道最终判断时候那个地址上的值就行了,先尝试了调试,发现一旦attach就退出,做了反调试。注意到比较之前有个android_log_print函数,因此可以直接利用这个函数做打印。我选择patch方法是直接把这个函数往下移,因为在0x12A4地址处正好有需要的数据给了R2,所以我把从0x1284到0x129C的地方都NOP了,在0x12AC的地方调用log函数。把patch好的so直接放回去,随便输入就能看到最终比较的密码了。

第三题
看代码很明显加过壳了,用的是整体的DEX加密方案。使用之前自己开发过的Dalvik的动态分析框架来做动态分析时的解析。参见CIT 2014的论文:
DIAS:Automated Online Analysis for Android Applications
使用的思想大概就是直接修改dalvik源代码,在解释器层面去获取程序动态运行时的信息。脱壳的话也可以使用这个思想,程序一定会在解释执行时被解密,只需要在解释器上去获取DexFile这个结构体的信息就可以了,我直接用了dexdump的代码。运行以后直接可以得到脱壳后的dexdump结果。后面是dex逆向,比较简单,就是dexdump的文本没有反编译成Java的好看,不过程序不大,关键逻辑不多也关系不大。后面唯一的问题是在后一个比较中需要对某个类的annotation做比较,dexdump里没有做annotation的dump。不过问题不大,因为在DIAS解释器层面我依然可以监控到这个getAnnotation函数的返回值,因此直接得到后,换成莫尔斯电码输入就是password了。

第四题
第一步一样是脱壳,和上一题一样,直接脱出来后发现程序会再去调用M$j方法,是个native的。看了下so,这题lib目录看上去和上一题差不多,libmobisecy.so解压是个内容都是空的dex,想必另一个mobisecz就是解密以后填充进去的代码,脱壳已经脱出来了,就不用管,因此可以判断native方法调用应该是在libmobisec.so中。这个so做了混淆,各种头被破坏得难以修复,所以采用动态的方法。运行程序以后随便输内容,点击出现错误后,直接去dd进程的内存。这样这个so就是已经执行过的了。接着是去找M$j的地址,因为JNI方法一定会出现在常量字符串表里,找了下M$j,发现没有,想必使用了RegiterNative做了变换的。因此继续使用DIAS系统,在调用这个方法的时候去打印insns的值,就是地址了。结果发现被映射到了个很奇怪的内存区域,不过那块正好也是rwx的,所以输入结果应该没错。Dd那一段,根据地址找到指令,又LOAD PC指回了dump出来的libmobisec里,到那个地方就能直接看代码了。这里有个技巧,就是看dump出来的so时,需要先用IDA载入libc,在载入这个dump后的so,根据内存分布调整偏移,这样就能让IDA辨认出so中的libc函数了。程序做了些控制流的混淆,正常流程被转成了类似状态转移的几层死循环,另外就是普通的一些字符串加解密操作也做了混淆,一个简单的异或也被展开成一个很长的等价与和或操作等等。不过关系不大,因为这个so是dd出来的,执行过的关键的字符串都解密了,甚至可以直接跳到那段区域去看解密的所有字符串,可以看到接下来会调用的bh类的a方法,以及之后会调用的一系列函数的字符串如sendEmptyMessage以及参数类型等字符串,值得注意的是由两个非常可疑的base64字符串。先不急,先回上去看Java层的bh类的a方法,发现是经过了几个Java层的函数变换,再经过几个native层的函数变换。大概可以猜到整个程序的逻辑,就是输入经过native和java层函数的来回传递,最终做比较,比较在native层。JAVA层的代码比较简单,不多说。Native的变换需要去逆向另外两个函数M$d和M$z。不过当使用DIAS监控这两个方法的输入输出时,我们发现参数本身并没有做复杂的变换,通过变换输入,发现这几个native的方法只有M$d对第四个字节做了个固定的变换,其他复杂的变换都在dex里。唯一的问题是得不到最后比较的字符串。脑洞一开,直接用之前观察到的两个base64字符串试了下,其中一个经过逆变换直接可以变成有意义的字符串,可以肯定是password了。

第五题
Java层没做加壳,也没什么内容,直接把输入字符串给了native方法,返回就是1或0。第一个想法是把so抠出来,自己写个程序去调用。So又被破坏,IDA辨认不出,继续使用dd大法。由于在自己进程里,因此可以通过修改地址来做代码注入,使用adbi工具来监控函数的输入输出,发现里面经过一些简单可逆的逻辑后,有个复杂算法,没有能力逆向算法,但可以使用暴力破解。最终运行了两个多小时后爆出结果。

非常幸运这次比赛可以得奖,这次比赛运气非常好,一方面得益于本次比赛题目使用动态分析能够很快理出头绪,另一方面得益于本人之前的积淀,自己科研使用的工具能够直接派上用场也是非常幸运,因为单纯的静态分析和逆向能力本人肯定比不过看雪上的多数工业界的前辈。最后感谢我所在的上海交通大学密码与计算机安全实验室的老师的培养和知识传授,以及同学的技术交流和讨论。

[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最新回复 (50)
tomtory 2015-1-26 19:22
2
0
前排 恭喜得奖!
Romangol 2015-1-26 19:22
3
0
天才少年啊~~

帮你贴一个以前的作品~
http://loccs.sjtu.edu.cn/typecho/index.php/archives/236/
jiavjiav 2015-1-26 19:39
4
0
围观大牛,最后一个直接“爆”结果也真是暴力呀
轩野 1 2015-1-26 19:58
5
0
学习了.
bjhrwzh 2015-1-26 20:03
6
0
围观大牛啊~~只有拜膜。 然后接着努力学习
習生 1 2015-1-26 20:07
7
0
Hi,你好 请问DD大法是什么?能详细一点吗?谢谢了!
peterchen 2015-1-26 20:07
8
0
骚年果然很牛X...
君君寒 2015-1-26 20:08
9
0
从第三题开始就不太知道说的是什么
可否提问下?
自己开发过的Dalvik的动态分析框架 -------------可否共享一下 ,只是想见识一下
DIAS:Automated Online Analysis for Android Applications ------可不可以发下 这个pdf 或者word文档 这个百度不到。
希望大牛可以满足 小菜鸟的小愿望,谢谢了。
suwey 2015-1-26 20:09
10
0
积累很深厚啊。。第一题jd-gui关键的两段代码反不出来。。我试着对着字节码还原代码。。没成功。。放弃了。。哦。。我不是搞安全的。。我就是试试
猫狗大战 2015-1-26 20:37
11
0
jeb直接出源码……
然后拿着源码在eclipse直接算出来的……
上传的附件:
QEver 5 2015-1-26 20:44
12
0
最后一题爆破的想法不错。
做法和楼主的差别还是很大的,稍等一下也发帖吐槽一下
qihuan风云 2015-1-26 20:44
13
0
怎么感觉,别人的工具早就等待阿里的题目了啊 ...
lcweik 1 2015-1-26 20:45
14
0
暴破字典怎么来的呀
天易love 18 2015-1-26 20:52
15
0
oops的博士大牛不得不服!
JoyFei 2 2015-1-26 20:52
16
0
赞! 思路真不错
我是土匪 4 2015-1-26 21:11
17
0
来看大牛解体思路,受教了。
uaien 2015-1-26 21:49
18
0
受教,还是需要去积累啊
小鸡炖蘑菇 2015-1-26 21:50
19
0
确实厉害。
upcwuyu 2015-1-26 22:29
20
0
围观大牛思路
EvlixZ 2015-1-26 23:11
21
0
厉害厉害~~
DIAS:Automated Online Analysis for Android Applications
这个论文可否分享一下?
Hippocrate 2015-1-26 23:14
22
0
前2题跟我的解法一样,后面的能不能详细介绍一下呀
JoenChen 4 2015-1-26 23:21
23
0
确实很牛, 楼主谦虚了. 楼主的方法很好, 对的, 为什么我们不改个自己的rom出来呢! 这样应该就简单多了!
JackJoker 2015-1-26 23:56
24
0
前来学习大牛总结
熊猫正正 9 2015-1-27 09:36
25
0
确实厉害,不得不服,希望楼主有时间,多在看雪上发一些学习资料,供大家学习参考
sudami 25 2015-1-27 10:33
26
0
牛鼻,android大牛,学习了
ThomasKing 6 2015-1-27 11:08
27
0
跪拜博士大牛!
riusksk 41 2015-1-27 11:14
28
0
常备武器库,结合动态分析,果然高效啊
waylife 2015-1-27 11:55
29
0
厉害,各种奇淫技巧
deadxing 2015-1-27 12:00
30
0
前来学习!!!
dratiger 2015-1-27 12:02
31
0
大牛真是神啊!第三题我也是把进程的内存dump出来的,不过里面搜索出来的dex都不正确。不知道问题出在哪里?
中流 2015-1-27 12:24
32
0
围观一下,恭喜楼主
kwanhua 2015-1-27 14:41
33
0
谢谢大牛分享....能给下apk吗?我等渣渣拿不到后几题的apk
heartbeast 2015-1-27 15:07
34
0
别用百度了,用Google
heartbeast 2015-1-27 15:08
35
0
DIAS:Automated Online Analysis for Android Applications PDF在这里,不知道你们能不能看:
http://xplorebcpaz.ieee.org/stamp/stamp.jsp?tp=&arnumber=6984671
Matrix 2015-1-27 16:16
36
0
第三题算法相关的代码:

http://akana.mobiseclab.org/index.jsp?type=result&md5=HW27879e3820a3ca5487e66e7b3417f6a170f0dcb5d9ccf4a4c619b24bbc6e3ab080dad30f2c3bffe1def2bd74749ce23b

给大家参考
Litche 2015-1-27 17:05
37
0
apk能不能发出来下
Matrix 2015-1-27 18:08
38
0
apk不是原版的啊。

另外,第四题的那个libmobisec.so保护的挺好,ida,甚至包括我们的解析工具,都完全失效了。比如说动态节区的打印的信息如下,完全是我们之前没遇到,值得学习。

index        d_tag        d_val_or_d_ptr
0        0x60198899        -1988738981
1        0x74389238        -1039113264
2        0xe4194519        -594982116
3        0x12a1cca9        1285437848
4        0xc89c6495        -935030432
5        0xc6d4c35f        -1848102621
6        0x50950898        1684645620
7        0x8a90424        943252561
8        0x431073c        -1862184825
9        0xbeccb25c        572517296
10        0xd4894c1c        -863408356
11        0xc489721c        -1131834596
12        0x47349122        1205084888
13        0xe3090390        -991386749
14        0xd02c2430        672402664
15        0x9bdc4241        -386939863
16        0x4a9c8482        -363248496
17        0xfa140bb4        -32548080
18        0x8dc2f063        -795603891
19        0x9f29a80d        -1541829864
chenwitch 2015-1-27 19:00
39
0
DIAS论文是收费的啊
君君寒 2015-1-27 19:10
40
0
大家可能需要的论文
就是文中提及到的
希望有人翻译一下。
thx
上传的附件:
jieniruyan 2015-1-28 11:25
41
0
好像不是同一篇
http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=6984671
Romangol 2015-1-29 11:25
42
0
论文原作者表示放一个更为完整的版本吧

见附件
上传的附件:
学编程 1 2015-1-30 17:17
43
0
所以我把从0x1284到0x129C的地方都NOP了,在0x12AC的地方调用log函数。

这个arm汇编,nop指令对应的机器码是啥哈
学编程 1 2015-1-30 18:02
44
0
我采用    指令所在地址+4+偏移量=跳转目标地址

这个偏移量算出来不对。
正确的公式是?
rexdf 2015-1-30 19:16
45
0
感觉很高端的样子啊
hmbhmb 2015-2-1 00:17
46
0
麻弊,简直是膜拜!!学霸太强了!有你一半功力就不得了了。
学编程 1 2015-2-4 17:58
47
0
arm汇编的BL 比较好算
指令所在地址A ,目标地址B
(B-(A+8))/4

Thumb就比较复杂了,目前没找到通用的公式。
学编程 1 2015-2-5 15:34
48
0
第二题
Java层没做什么,直接把输入放到底层的libcrackme.so里做了判断。发现JNI_Onload里做了些处理,接着securityCheck里面最后有判断,将输入和一个wojiushidaan做比较。输入后发现密码错误,因此可以猜测前面一大段逻辑的作用就是会把这个最终的字符串改掉。其实只需要知道最终判断时候那个地址上的值就行了,先尝试了调试,发现一旦attach就退出,做了反调试。注意到比较之前有个android_log_print函数,因此可以直接利用这个函数做打印。我选择patch方法是直接把这个函数往下移,因为在0x12A4地址处正好有需要的数据给了R2,所以我把从0x1284到0x129C的地方都NOP了,在0x12AC的地方调用log函数。把patch好的so直接放回去,随便输入就能看到最终比较的密码了。

原版的汇编

.text:00001284 92 FF FF EB                             BL      __android_log_print
.text:00001288 00 00 95 E5                             LDR     R0, [R5]
.text:0000128C 04 10 A0 E1                             MOV     R1, R4
.text:00001290 00 20 A0 E3                             MOV     R2, #0
.text:00001294 A4 32 90 E5                             LDR     R3, [R0,#JNINativeInterface.GetStringUTFChars]
.text:00001298 05 00 A0 E1                             MOV     R0, R5
.text:0000129C 33 FF 2F E1                             BLX     R3
.text:000012A0 60 10 9F E5                             LDR     R1, =(CheckPassword - 0x5FBC)
.text:000012A4 07 20 91 E7                             LDR     R2, [R1,R7] ; CheckPassword
.text:000012A8
.text:000012A8                         loc_12A8                                ; CODE XREF: Java_com_yaotong_crackme_MainActivity_securityCheck+120j
.text:000012A8 00 30 D2 E5                             LDRB    R3, [R2]
.text:000012AC 00 10 D0 E5                             LDRB    R1, [R0]
.text:000012B0 01 00 53 E1                             CMP     R3, R1

我改之后的汇编

.text:00001284 00 00 A0 E1                             NOP
.text:00001288 00 00 95 E5                             LDR     R0, [R5]
.text:0000128C 00 00 A0 E1                             NOP
.text:00001290 00 00 A0 E1                             NOP
.text:00001294 00 00 A0 E1                             NOP
.text:00001298 00 00 A0 E1                             NOP
.text:0000129C 00 00 A0 E1                             NOP
.text:000012A0 60 10 9F E5                             LDR     R1, =(off_628C - 0x5FBC)
.text:000012A4 07 20 91 E7                             LDR     R2, [R1,R7] ; off_628C
.text:000012A8
.text:000012A8                         loc_12A8                                ; CODE XREF: Java_com_yaotong_crackme_MainActivity_securityCheck+120j
.text:000012A8 04 00 A0 E3                             MOV     R0, #4
.text:000012AC 02 10 A0 E1                             MOV     R1, R2
.text:000012B0 87 FF FF EB                             BL      __android_log_print
.text:000012B4 05 00 00 1A                             BNE     loc_12D0

在修改当中,发现.text:00001288 00 00 95 E5                             LDR     R0, [R5]
改为00 00 A0 E1,程序在没进入函数前,程序就会崩溃。
DDMS的提示为:
02-05 06:39:32.430: A/libc(2490): Fatal signal 11 (SIGSEGV) at 0x00000004 (code=1), thread 2490 (yaotong.crackme)

为什么会崩溃呢?
NISL 2015-4-23 19:50
49
0
菜鸟问一句,拜读了那篇论文,是将下载那个Indroid压缩文件直接用第三方recovery刷,还是要单独编译啊,是用mmm吗?
zhengweird 2015-4-28 14:17
50
0
第五题的话我做了。。感觉就那个复杂的算法不知道怎么搞?楼主说暴力破解。可我看了算法复杂度有2^128呢。不知如何处理。
游客
登录 | 注册 方可回帖
返回