例题

以攻防世界moblie easy-so为例

链接:https://pan.baidu.com/s/1Rd6XHnaewK4HCPyQEwATIQ 提取码:jcc0

运行app

拿到apk之后 当然是先安装到我们的安卓虚拟机上

这里我用win11自带的安卓子系统直接安装到了物理机上
在这里插入图片描述

可以看到有文本输入框和check机制

随意输入数值进行检测试试
在这里插入图片描述

不出所料验证失败
我们可以猜测如果我们输入的数值如果是正确的话 应该会输出 验证成功
大部分的check机制 是将你的输入与内置字符串进行比较

然后输出正确或者错误的结果 就像这道例题一样

Androidkiller

将文件拖入到Androidkiller中进行静态分析
在这里插入图片描述

这里选否即可

在工程管理中就可以看到我们想要的信息
在这里插入图片描述

所涉及的文件需要了解apk的文件结构

Apk 文件结构

APK 文件也是一种 ZIP 文件。因此,我们可以使用解压 zip 的工具来对其进行解压。一个典型的 APK 文件的结构如下图所示。其中,关于每一部分的介绍如下
在这里插入图片描述

AndroidManifest.xml

  • 该文件主要用于声明应用程序的名称,组件,权限等基本信息。

class.dex

  • 该文件是 dalvik 虚拟机对应的可执行文件,包含应用程序的可执行代码。
  • resource.arsc该文件主要是应用程序编译后的二进制资源以及资源位置与资源 id 之间的映射关系,如字符串。
  • assets该文件夹一般用于包含应用程序的原始资源文件,例如字体和音乐文件。程序在运行的时候,可以通过 API 获取这些信息。
  • lib/lib 目录下主要用于存储通过 JNI(Java Native Interface)机制使用的本地库文件,并且会按照其支持的架构,分别创建对应的子目录。
  • res/该目录主要包含了 Android 应用引用的资源,并且会按照资源类型进行存储,如图片,动画,菜单等。主要还有一个 value 文件夹,包含了各类属性资源
    • colors.xml→颜色资源
      dimens.xml—> 尺寸资源
      strings—> 字符串资源
      styles.xml→样式资源

META-INF/类似于 JAR 文件,APK 文件中也包含了 META-INF 目录,用于存放代码签名等文件,以便于用来确保 APK 文件不会被人随意修改。

Smali

介绍

在执行 Android Java 层的代码时,其实就是 Dalvik(ART) 虚拟机(使用 C 或 C++ 代码实现)在解析 Dalvik 字节码,从而模拟程序的执行过程。
自然,Dalvik 字节码晦涩难懂,研究人员们给出了 Dalvik 字节码的一种助记方式:smali 语法。通过一些工具(如 apktool),我们可以把已有的 dex 文件转化为若干个 smali 文件(一般而言,一个 smali 文件对应着一个类),然后进行阅读。对于不同的工具来说,其转换后的 smali 代码一般都不一样,毕竟这个语法不是官方的标准。这里我们介绍比较通用的语法。值得注意的是,在 smali 语法中,使用的都是寄存器,但是其在解释执行的时候,很多都会映射到栈中。

语法

smali有属于自己的语法标准
在这里就不细讲了
在这里插入图片描述

apk的文件结构在做题时一般除了查找字符串资源其他很少涉及到

但是smali中大部分会有我们想要的信息

一般路径为:smali > com > 作者定义的文件夹
正如这道题来说com中的testjava就是题目想要给我们的信息

我们依次点开文件夹后找到我们的主函数(MainActivity)
这里有我们想要的主要运行逻辑
在这里插入图片描述

右边部分就是smali语法 因和寄存器有关所以想要对我们来说是比较难读的

基于smali我们可以直接在此上进行修改
修改之后我们利用Androidkiller的编译工具将其重新打包生成一个新的apk文件
就可以执行我们想要的运行结果
这道题目没有涉及就不多谈了

既然smali语法这么难读 有其他办法可以帮助我们读懂这些代码吗
当然可以 我们可以将它转换为jar文件 再利用我们jd-gui进行反编译
这样可读性大大提高
这就涉及到了dex文件 转 jar文件

dex to jar

一键转换

dex文件转jar文件方式很多
最简单的就是在Androidkiller中直接点击jd-gui(小茶杯)即可
在这里插入图片描述

当第一种方式无法进行转换的时候 可以考虑第二种方式

手动转换

另一种方式就是利用dextojar插件手动去转换成我们想要的jar文件

首先获取我们的dex文件
dex文件的获取方式很简单
只需要将apk后缀名改为zip后解压就可以得到文件的dex文件
在这里插入图片描述

然后找到我们的dextojar插件所在路径
将我们的dex文件移动到dextojar插件的同一目录
当前目录打开cmd 输入

d2j-dex2jar classes.dex

生成的文件就是当前部分classes的jar信息
但是只有部分信息明显不是我们想要的结果

还有一种方法可以直接将我们的apk文件移动到dextojar插件的同一目录
当前目录打开cmd 输入

d2j-dex2jar.bat org.apk

在这里插入图片描述

可以看到出现了

dex2jar org.apk -> .\org-dex2jar.jar

说明已经成功了
在这里插入图片描述

将我们的org-dex2jar.jar文件拖入到jd-gui中就可以看到所有的信息了

静态分析

在这里插入图片描述

还是找到我们的主函数 可以看到关键字 验证失败 验证成功
那么最关键的就是找到我们check机制
在这里插入图片描述

当我们的if语句成立的时候就会输出验证成功

if(cyberpeace.CheckString(((EditText)MainActivity.this.findViewById(2131165233)).getText().toString()) == 1)

可以看到最后会有一个函数(cyberpeace)将我们的字符串进行了加密
我们点击这个函数的位置继续跟进
在这里插入图片描述

我们发现了关键语句 System.loadLibrary(“cyberpeace”)

这里又要引入一个新的概念.so文件

so文件

简介

so文件是unix(一个系统的名字)的动态连接库,是二进制文件,作用相当于windows下的.dll文件。

加载方法

  • System.loadLibrary如果加载的文件名是 xxx ,那么其实加载的是项目中 libs 目录下的 libxxx.so 文件。
  • System.load对应 lib 的绝对路径。

主要使用第一种方式,第二种方式主要用于在插件中加载 so 文件。

补充

在Android中调用动态库文件(*.so)都是通过jni的方式。
Android中加载so文件的提供的API:
void System.load(String pathName);
说明:pathName:文件名+文件路径;
也就是说Java层的代码太容易被逆向或者破解了,由于一些底层的算法,
比如说账号登陆的算法,不想被外界看到就需要这种底层的SO文件,在SO层内部对密码进行加密,
然后对内外都留有接口,方便SO层跟Java层之间互相通信,或者是互相调用。

so文件路径

一般都存在于lib文件路径下
在这里插入图片描述

ida静态分析

拿到了so文件我们继续使用ida进行静态分析
在这里插入图片描述

很轻松就可以找到我们所需要的函数信息

算法分析

这个比较容易就不多说了
脚本梭哈

解题脚本

key = 'f72c5a36569418a20907b55be5bf95ad'
key = list(key)
flag = ''
v8 =0
a = 0
while (len(key)>v8):
    flag = key[v8]
    key[v8] = key[v8+1]
    key[v8+1] = flag
    v8 += 2
while (len(key)>a+16):
    flag = key[a]
    key[a] = key[a+16]
    key[a+16] = flag
    a += 1
for i in range(len(key)):
    print(key[i],end='')
    

#90705bb55efb59daf7c2a5636549812a

可以将我们得出的结果输入进行检测
在这里插入图片描述

flag{90705bb55efb59daf7c2a5636549812a}

have a good time!!!

参考:Android 开发基础 - CTF Wiki (ctf-wiki.org)

参考:什么是安卓SO文件 - 简书 (jianshu.com)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐