【PoRE】Lab5: Reversing and Repacking

回到目录

内容总结

  • 本Lab以及课件的内容在之前对Smali逆向的基础之上,引入了一些更深入的话题,例如对于固定结构的Smali代码的模式匹配的话题等等。之后,介绍了一些反汇编器(Decompiler),例如JEB、jadx等等……

  由于JEB对JDK版本有一些要求,而课程建议的JDK版本中,我安装了不适合JEB的那个版本……【笑哭】于是之后的所有有关Java反汇编器的操作,都以jadx为主要工具。

  • 这一次Lab中需要我们进行重打包(Repacking)的操作,这需要使用到apktool。此外,由于对于apk本身重打包攻击的难度不高,也有不少针对重打包攻击的措施。可以对apk本身进行加固,对关键代码进行加密或隐藏;也可以对签名文件的哈希值等进行校验。

  不过我个人非常赞同张老师的说法:当讨论到apk的防御措施时,上面的这些操作或许只能拦住水平有限的逆向人员,究其原因在于apk文件在于逆向人员和使用者手中。尤其是基于这次Lab的重打包攻击,这也会成为之后PJ和一部分Lab的可选策略。(如果不出意外的话,3个PJ其一是同学之间互相攻防的CrackMe。这是个很有趣的PJ。)

Lab简介与参考

  • 这个Lab将分为三个Task,分别展示了部分Java代码和攻击的特性。我们依次来看看。

  我并不会展示所有的key是什么,而是聚焦于具体的解题过程,也希望看到这篇文章的读者,也能够亲历一遍。抛开课程Lab的难度和数量,至少我个人觉得还是很享受这个过程的。

  • Task 1: Give me your key
      一条金科玉律是,看Java代码总会比看Smali代码好得多,尽管这个代码是由并不完全聪明的反汇编器得到的。在之后的一些Lab中,可能会遇到jadx读错代码,甚至无法分析代码的情境。
      回到这个apk,使用jadx反汇编得到代码如图所示。
    【PoRE】Lab5: Reversing and Repacking
      可以看到,在buttonClick这个方法中有对key.booleanValue()的条件判断,分析一下这应该是在判断输入的内容是否正确。那么接下去就是查看HappyTime.getKey()的逻辑。

  在逆向处理和分析代码的时候,要格外关注一些Android SDK中的一些固定的类,比如这里的View,以及需要重写的buttonClick及对应的接口等等。这些“关键词”,在之前的Lab 2中可以逐渐熟悉。而这一条规则,在之后的Lab 6中发现会起到大作用。

【PoRE】Lab5: Reversing and Repacking
  输入的内容是str,会根据res数组、str1和输入内容(str)进行一系列位异或操作,需要结果相同。这个就可以通过写一段代码来帮助我们“智能”地计算异或运算的结果了。

  • Task2: Play a game
      在完成Task 1之后,就进入了playGame()的函数的逻辑。大概地阅读一下这段代码,每次需要猜一个[0, 10000)的随机数。很明显,想要猜对这个数字之难度极大,更何况要连续猜对12次。
    【PoRE】Lab5: Reversing and Repacking
      可以有很多策略克服这个问题。其一,是想方设法借助Toast等可以展示数据的类,把这个随机生成的数字展示出来;其二,可以将这个“随机数”换成一个固定的值,那只需要机械地输入12次固定的数字就可以完成一个“猜数字”的操作。
    【PoRE】Lab5: Reversing and Repacking
      这里修改了MainActivity中的playGame()函数,其中将随机生成的数字(v0寄存器)修改为了0这么一个常数(图中选中的那一行代码是新加的)。之后只需要连续输入12次0就可以顺利地进入下一关了。

  • Task 3: Get the flag
      这个Task的问题是似乎在Java代码中并没有找到有关于生成flag的逻辑。不过反复查找,可以发现这里有一个本地方法(native method),名为show()。那么这个应该就是需要调用的方法,关于如何查看这个方法的逻辑,在之后有关Native Code的逆向的Lab和课程中会有介绍,在此不表。
      那么思路就是,想方设法在函数的行进流程中插入对这个show方法的调用。
    【PoRE】Lab5: Reversing and Repacking
      随后就可以看到flag了!

写在最后

  • 其实这个Lab是第一次有十足的操作性的逆向类的Lab,而且每个Task几乎可以有自己的思路进行破解。这里只记录了我个人的思路。
上一篇:MIT6.830 Lab 3 查询优化 学习笔记


下一篇:c++Lab-进程间通信的几种方式