阿里移动安全挑战赛第二题writeup

题目链接

https://github.com/eternalsakura/ctf_pwn/blob/master/android逆向/AliCrackme_2.apk

反调试原理

ptrace

ptrace提供了一种使父进程得以监视和控制其它进程的方式,它还能够改变子进程中的寄存器和内核映像,因而可以实现断点调试和系统调用的跟踪。
在执行系统调用之前,内核会先检查当前进程是否处于被“跟踪”(traced)的状态。如果是的话,内核暂停当前进程并将控制权交给跟踪进程,使跟踪进程得以察看或者修改被跟踪进程的寄存器。

反调试

用fopen打开/proc//status文件读取其中的TracerPid值来检测自己的进程是否被attach,
TracerPid如果为0说明没有别的进程在调试这个进程,如果不为0说明有程序在调试

反调试程序执行时机

  • .init_array是一个so最先加载的一个段信息,时机最早,现在一般so解密操作都是在这里做的
  • JNI_OnLoad是so被System.loadLibrary调用的时候执行,它的时机要早于哪些native方法执行,但是没有.init_array时机早

动态调试

连接到实体机,打开监听

./android_server

这里开始监听设备的23946端口。

端口转发

如果要想让IDA和这个android_server进行通信,那么必须让PC端的IDA也连上这个端口
adb forward tcp:远端设备端口号(进行调试程序端) tcp:本地设备端口(被调试程序端)
adb forward tcp:23946 tcp:23946

打开要调试的apk,找到入口

adb shell dumpsys activity top

打开monitor

启动apk

adb shell am start -D -n com.yaotong.crackme/.MainActivity
设备将处于一个Waiting For Debugger的状态

在要调试的函数下断点,这里我们在JNI_OnLoad下断。

设置IDA


attach进程



断在libc.so

tips:这里为什么会断在libc.so中呢
android系统中libc是c层中最基本的函数库,libc中封装了io、文件、socket等基本系统调用。所有上层的调用都需要经过libc封装层。所以libc.so是最基本的,所以会断在这里,而且我们还需要知道一些常用的系统so,比如linker

在控制台使用jdb恢复进程运行

jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700

按下F9执行程序
弹出窗口,这里是问apk里的so文件和我们正在调试的是否是同一个,当然是same

正常情况会出现:

报错处理:

  • 打开ddms尝试.
  • 检查调试的app配置文件中是否有android:debuggable=”true”,导致不能调试。若无则在清单文件的application中加上,重新打包即可.

    JNI_OnLoad中单步调试找到check点

    函数顺利断下

    F8单步找到Check点

    执行BLX R7之后就跳入libc中断

    分析



    反编译一下,找到BLX R7那行函数,这个函数就是pthread_create,它调用sub_16A4

进入sub_16A4,它调用sub_130C,在这里进行反调试,所以我们只需要把它nop即可

另外的一些分析

在module list里找到libc.so,再从中找到fopen函数



在fopen断下之后,查看hex窗口
(在这之前需要先设置hex数据与R0同步)


查看一下这个8358进程是什么,果然是我们的crack apk,再看看它的status,发现被trace了

这个trace的进程就是我们的android_server

patch so

arm中对应的nop指令是:00 00 00 00
我们可以选择nop掉BL sub_130C,或者直接nop掉BLX R7,这里我们nop后者

数据窗口中跟随,按F2去编辑

修改并保存



感觉IDA的patch并不是很好用,所以我们记下地址后用010editor打开修改更好

将原apk中的so文件替换为此so文件,重新打包签名安装,现在直接打开app调试就不会退出了. Success!

securityCheck

找到securityCheck函数下断


输入密码后断下

剩下的就是很简单的比较

直接找到密码,over~
flag是aiyou,bucuoo