App逆向百例|07|找出CrackMe的Flag

admin 2022年7月13日19:28:06评论243 views字数 2728阅读9分5秒阅读模式


观前提示:

本文章仅供学习交流,切勿用于非法通途,如有侵犯贵司请及时联系删除

App逆向百例|07|找出CrackMe的Flag

样本:aHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMVVTYXk1S2pPUkdfQy1NWjhjWWdLUnc/cHdkPWxpbm4=

0x1 脱壳

网上冲浪的时候看到一个CrackMe样本 拿下来把玩把玩App逆向百例|07|找出CrackMe的Flag

界面很简单 只需要输入正确的Flag即可

将APK拖入JADX中 可以发现是360加固

App逆向百例|07|找出CrackMe的Flag

那就上FRIDA-DEXDUMP脚本脱个壳先

不出意外 就出意外了

App逆向百例|07|找出CrackMe的Flag

一运行FRIDA-DEXDUMP 样本App马上就崩了 排除了其他问题 那么就是App有Frida反调

这里我尝试使用葫芦娃大佬魔改过的Frida来测试

https://github.com/hzzheyang/strongR-frida-android

果然用了魔改的Frida 脱壳都顺畅了

App逆向百例|07|找出CrackMe的Flag

把脱下来的dex拉进jadx

App逆向百例|07|找出CrackMe的Flag

可以看到 flag并非在java层进行校验 还得到native-lib.so去分析

直接解压APK

App逆向百例|07|找出CrackMe的Flag

能看到只有一个so文件 盲猜frida的反调也是在里面的 待会做个验证

0x2 Frida反调

用大姐姐打开native-lib.so

先看导出表

App逆向百例|07|找出CrackMe的Flag

看到.datadiv_decode巴拉巴拉的 ollvm没跑了

因为frida反调的代码一般较早加载 所以直接进入.init_proc

sub_10E0这里创建了一个线程

App逆向百例|07|找出CrackMe的Flag

继续进入sub_E80

手动还原字符串

function get_str(ptr{
    var so_addr = Module.findBaseAddress("libnative-lib.so");
    console.log(hexdump(so_addr.add(ptr)))
}
App逆向百例|07|找出CrackMe的Flag

就能看得出来就是在sub_E80进行的frida字段检测 如果有问题 就killApp逆向百例|07|找出CrackMe的Flag

Pass的方法多种多样 可以hook住strstr sscanf 甚至可以不让它启动这个线程

参考文章:https://bbs.pediy.com/thread-217482.htm

0x3 寻找Flag

从导出表没有找到check 那猜是动态注册的

老规矩 用lasting-yang大佬的hook_RegisterNatives

https://github.com/lasting-yang/frida_hook_libart

hook到一个动态注册 就是我们需要的check方法

[RegisterNatives] java_class: com.kanxue.reflectiontest.MainActivity name: check sig: (Ljava/lang/Object;)Z fnPtr: 0xcd8344c9  fnOffset: 0x14c9  callee: 0xea4c7ba1 libart.so!_ZN3art8CheckJNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi+0x1e0

上大姐姐跳转0x14c9

App逆向百例|07|找出CrackMe的Flag

这里我已经将字符串还原备注好了

从伪代码上可以看到 拿到我们输入的flag后 先进行长度判断 不为20则返回0

接着往下看 下面又动态注册了一次App逆向百例|07|找出CrackMe的Flag

strcmp(s1, aSyvM)

App逆向百例|07|找出CrackMe的Flag

aSyvM对应的字符是kanxueApp逆向百例|07|找出CrackMe的Flag

所以 字符串里面应该包含kanxue

随便输入kanxue12345678901234App逆向百例|07|找出CrackMe的Flag果然 事情不会那么简单 前面看到check又被动态注册了一次 所以继续看RegisterNatives

[RegisterNatives] java_class: com.kanxue.reflectiontest.MainActivity name: check sig: (Ljava/lang/Object;)Z fnPtr: 0xcd8344c9  fnOffset: 0x14c9  callee: 0xea4c7ba1 libart.so!_ZN3art8CheckJNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi+0x1e0
[RegisterNatives] java_class: com.kanxue.reflectiontest.MainActivity name: check sig: (Ljava/lang/Object;)Z fnPtr: 0xcd834235  fnOffset: 0x1235  callee: 0xea4c7ba1 libart.so!_ZN3art8CheckJNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi+0x1e0
[RegisterNatives] java_class: com.kanxue.reflectiontest.MainActivity name: check sig: (Ljava/lang/Object;)Z fnPtr: 0xcd834149  fnOffset: 0x1149  callee: 0xea4c7ba1 libart.so!_ZN3art8CheckJNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi+0x1e0

这里居然在0x14c9之后又注册了一次0x1235 最后又注册了0x1149 且名字同样是check

在判断strcmp(s1, aSyvM)存在后继续往下走 然后取了输入flag的后14位作为参数继续call前面注册的sub_1234的方法App逆向百例|07|找出CrackMe的Flag

跳转到0x1235

这里的代码逻辑几乎和前面的一致

App逆向百例|07|找出CrackMe的Flag

其中aFSU2对应training

跳转到0x1149

这里代码逻辑短了许多 也没有再去注册方法了

App逆向百例|07|找出CrackMe的Flag

其中byte_5096对应course 判断取反为真则返回1 也就是验证成功

一共动态注册了三次分别检测了kanxue training course

所以Flag即为kanxuetrainingcourse

0x4流程梳理

  • 输入kanxuetrainingcourse 点击验证
  • 判断长度是否为20
  • 判断是否包含kanxue
  • 截取字符串trainingcourse再次调用check
  • 判断长度是否为14
  • 判断是否包含training
  • 截取字符串course再次调用check
  • 判断长度是否为6
  • 判断是否包含course
  • 验证成功返回1App逆向百例|07|找出CrackMe的Flag





感谢各位大佬观看

感谢大佬们的文章分享

 如有错误 还请海涵

共同进步


[完]



点赞 在看 分享是你对我最大的支持

逆向lin狗


原文始发于微信公众号(逆向lin狗):App逆向百例|07|找出CrackMe的Flag

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年7月13日19:28:06
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   App逆向百例|07|找出CrackMe的Flaghttps://cn-sec.com/archives/1175744.html

发表评论

匿名网友 填写信息