• flutter逆向 ACTF native app


    前言

    算了一下好长时间没打过CTF了,前两天看到ACTF逆向有道flutter逆向题就过来玩玩啦,花了一个下午做完了.说来也巧,我给DASCTF十月赛出的逆向题其中一道也是flutter,不过那题我难度降的相当之低啦,不知道有多少人做出来了呢~

    还原函数名

    flutter逆向的一大难点就是不知道libapp.so的函数名,虽然有工具reflutter可以帮助我们得到其中的符号,但是我个人认为基于对libflutter.so源码插桩后重编译再重打包apk的方式具有极大的不可预料性,极有可能导致apk闪退,这一题便出现了这种情况,所以接下来我将介绍的工具blutter是纯静态分析来还原函数名,更令人惊喜的是它提供了IDApython脚本来让我们可以在IDA中对函数进行重命名,而这个项目中提供的其他文件也相当好用

    blutter的编译及使用

    blutter项目地址

    1

    https://github.com/worawit/blutter

    在各个平台如何编译在这个项目的README.md中写的已经相当详细了,这里我就简单介绍一下Windows上的编译过程吧,注意一下这些命令需要全程运行在代理环境否则会导致无法下载

    首先clone项目

    1

    git clone https://github.com/worawit/blutter --depth=1

    随后运行初始化脚本

    1

    2

    cd .\blutter\

    python .\scripts\init_env_win.py

    请注意,接下来我们需要打开x64 Native Tools Command Prompt,它可以在Visual Studio文件夹中找到

    image-20231031182720564

    然后运行blutter.py并提供libapp.solibflutter.so的文件夹路径以及输出文件夹路径

    1

    python .\blutter.py ..\chall\lib\arm64-v8a\ .\output

    image-20231031183050383

    输出文件夹目录如下

    image-20231031183135453

    随后我们用ida反编译libapp.so,并运行输出文件夹中的IDApython脚本ida_script/addNames.py,符号就被全部恢复出来啦

    image-20231031183441477

    hook关键函数 获取函数参数

    这里我们需要关注的函数是flutter_application_1_main__LongPressDemoState::_onTap,因为在flutter的开发中,onTap函数是按钮点击之后的响应函数

    image-20231031183702090

    随后我们进入sub_1DE500,在该函数中双击sub_1DE59C进入

    image-20231031183814522

    在这个函数中我们发现了256,%,^这些特征,合理猜测一下算法可能是RC4

    image-20231031185252569

    image-20231031185414233

    image-20231031185438467

    接下来我们使用输出文件夹中的blutter_frida.jshook一下sub_1DE59C看看情况

    image-20231031185604019

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    PS D:\hgame\ACTF\native app\work\blutter> frida -U -f "com.example.flutter_application_1" -l .\output\blutter_frida.js

    [Pixel 3::com.example.flutter_application_1 ]->

    Unhandle class id: 46, TypeArguments

    GrowableList@6d00488c29 = [

      188676,

      0,

      {

        "key": "Unhandle class id: 46, TypeArguments"

      },

      34,

      {

        "key": [

          184,

          132,

          137,

          215,

          146,

          65,

          86,

          157,

          123,

          100,

          179,

          131,

          112,

          170,

          97,

          210,

          163,

          179,

          17,

          171,

          245,

          30,

          194,

          144,

          37,

          41,

          235,

          121,

          146,

          210,

          174,

          92,

          204,

          22

        ]

      },

      0,

      0,

      0

    ]

    这里我们只hook到一个数组的值,另一个数组的类型是TypeArguments,研究了一下blutter_frida.js后发现作者还没有对这种数据类型格式提供hook支持

    image-20231031185952753

    IDA动态调试libapp.so

    现在我们得到了一个数组,我们就暂时认为它就是flag经过加密之后得到的结果,接下来我们在IDA中对sub_1DE59C下断点动态调试来更加深入的研究一下

    首先我们需要将IDA文件夹中的dbgsrv/android_server64 push到手机上面,然后运行一下并且指定端口

    1

    2

    3

    blueline:/data/local/tmp # ./as64 -p 11112

    IDA Android 64-bit remote debug server(ST) v7.7.27. Hex-Rays (c) 2004-2022

    Listening on 0.0.0.0:11112...

    随后端口转发一下

    1

    2

    PS C:\Users\oacia> adb forward tcp:11112 tcp:11112

    11112

    在IDA中选择调试器为Android debugger

    image-20231031190502580

    随后点击Debugger->Debugger options...选择如下配置

    image-20231031190621711

    点击Debugger->Process options...,Hostname修改为127.0.0.1,Port修改为11112

    image-20231031190653343

    然后点击Debugger->Attach to process...,附加到我们目标包名的进程上面

    image-20231031190932527

    弹出该弹窗选择Same即可

    image-20231031191001330

    在手机上点击按钮,然后在IDA中点击这个绿色的剪头,就可以动态调试啦

    image-20231031191049306

    image-20231031191123141

    在动态调试之后,未知的变量也逐渐浮现了出来,这里我们发现了v28>=256,那么很有可能就是RC4了哦

    image-20231031191544680

    既然这样,那么直接在这里唯一的异或的地方用IDA去trace一下,把异或的数组dump下来不就行了:)

    image-20231031192301154

    于是我们得到了被异或的数组了

    image-20231031193001825

    但是在异或运算的地方下断点之后,我输入的数全都是1,这里被异或的数也全是0xce

    image-20231031194118997

    所以莫非不是RC4?让0xce和0x31异或一下看看,竟然是0xff这么有意义的数字

    image-20231031194218233

    所以exp也就能写出来啦~

    1

    2

    3

    4

    5

    6

    7

    8

    final = [184, 132, 137, 215, 146, 65, 86, 157, 123, 100, 179, 131, 112, 170, 97, 210, 163, 179, 17, 171, 245, 30, 194,

             144, 37, 41, 235, 121, 146, 210, 174, 92, 204, 22]

    xor = [14, 14, 68, 80, 29, 201, 241, 46, 197, 208, 123, 79, 187, 55, 234, 104, 40, 117, 133, 12, 67, 137, 91, 31, 136,

           177, 64, 234, 24, 27, 26, 214, 122, 217]

    flag = [chr(xor[i]^final[i]^0xff) for i in range(len(final))]

    print(''.join(flag))

    # Iu2xpwXLAK734btEt9kXIhfpRgTlu6KuI0

  • 相关阅读:
    Ubuntu20.04安装ROS
    计算机网络学习笔记(II)——应用层(二)
    Python编程中的数据结构
    为 Visual Paradigm 的应用程序收集 JVM 线程转储
    微软Edge浏览器的辅助功能设置:提升用户体验的指南
    ESP32通过ali的C LINK4.0接入aliyun阿里云
    十年测试老鸟带你玩转-测试用例
    大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介
    基础的正则表达式
    leetcode145--二叉树的后序遍历
  • 原文地址:https://blog.csdn.net/wei_java144/article/details/134367219