考察知识点
- dex文件头修复
- onCreate修复
前置参考
http://eternalsakura13.com/2018/02/10/dex/
赛题链接
https://github.com/eternalsakura/ctf_pwn/blob/master/android逆向/misc.apk
分析
直接反编译apk,然后得到算法:输入用户名和密码,长度要想等,用户名和密码的逆序串相等则输出字符串,返回flag。
这当然是不可能的,这题可是道misc!
实际上,检查apk解压文件发现,下图的abc大小刚好为112字节也就是70h,是一个dex头的大小。
用010editor打开后发现确实是dex头。
而CERT.RSA这个不正常的大,其实就是因为把dex主体藏在这了。
用010editor打开观察
关键信息就是KEY和aes-128-cbc这个加密方式,KEY后面有一个DEX=…
我们知道dex头后面紧接着就是字符串索引项,应该是很整齐的四字节四字节,现在明显是被加密过了。
首先把DEX=…后面的数据拷贝出来,保存成文件。
再把数据直接复制粘贴在新建的文件里就行了。
用openssl或者其他工具解密这个文件。openssl aes-128-cbc -d -k "Misc@inf0#fjhx11" -nosalt -in encfile -out decfile
-in encfile是被加密的文件,-out decfile是解密后的文件。
打开解密后的文件,现在就很整齐了。
再把文件头拷贝到前面,就拼接出了一个dex文件,嗯,就叫flag好了。
修复dex
用010 editor打开拼接好的flag文件,执行dex解析脚本,报错。
检查后发现是因为索引区各索引分区的size(其实就是索引项的项数)为0,需要填补。
关于怎么计算,了解dex文件格式的应该很easy,我举个例子。type_id_off
为A8h,string_ids_off
偏移为70h,因为每个项的大小为4字节,所以(A8-70)/4=E
string_ids size = (0x000091DC - 0x00000070) / 4 = 0x0000245B
type_ids size = (0x0000A3EC - 0x000091DC) / 4 = 0x00000484
proto_ids size = (0x0000EF28 - 0x0000A3EC) / 12 = 0x00000645
field_ids size = (0x00015DB8 - 0x0000EF28) / 8 = 0x00000DD2
method_ids size = (0x00026DC8 - 0x00015DB8) / 8 = 0x00002202
这样就算完,填入进行修补。
重新解析一下,我们的dex文件就修复好了。
修复onCreate
用jadx反编译拼接好的dex文件,发现onCreate()方法反编译失败,用IDA打开后发现全被nop掉了(抽空)
可以想到运行时动态恢复指令,但是这里没有so,明显不是(这真是道misc……)
所以藏在哪里呢?实际上被抽空的onCreate指令就在下图的y中。
用IDA打开搜索onCreate,找到nop的起始地址,CODE:00097390
用010editor找到对应空白
将y的数据拷贝进去,刚好完全填补
再次用jadx反编译修复好的dex。
解密
修复好的onCreate
1 | public class MainActivity extends ActionBarActivity { |
1 | public StringBuilder replace(int start, int end, String str) |
- start − This is the beginning index, inclusive.
- end − This is the ending index, exclusive.
- str − This is the String that will replace previous contents.
查阅文档,然后手动换了一下,得到flag是h3ll02_GetfLag
我修复好的dex文件链接
https://github.com/eternalsakura/ctf_pwn/blob/master/android%E9%80%86%E5%90%91/flag.dex