首页
社区
课程
招聘
[原创]flutter逆向 ACTF native app
2023-10-31 20:01 18442

[原创]flutter逆向 ACTF native app

2023-10-31 20:01
18442

前言

算了一下好长时间没打过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,%,^这些特征,合理猜测一下算法可能是RC4image-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

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
点赞21
打赏
分享
最新回复 (32)
雪    币: 221
活跃值: (839)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
果冻大砍刀 2023-10-31 23:01
2
0
好贴,火钳刘明,明天试试手动复现一下
雪    币: 19734
活跃值: (29369)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-11-1 09:50
3
1
感谢分享
雪    币: 226
活跃值: (1299)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hpphpp 2023-11-1 10:58
4
0
flutter IDA动态调试断下一段时间后经常会无法恢复运行,然后报错
雪    币: 3512
活跃值: (4073)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
oacia 2 2023-11-1 11:34
5
0
hpphpp flutter IDA动态调试断下一段时间后经常会无法恢复运行,然后报错
先在输入框中输入字符串之后再点按钮,然后到IDA中点击绿色的箭头来动态调试,要是在IDA运行的时候弹出小键盘的话会有概率导致无法运行的
雪    币: 461
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_eiaothcj 2023-11-1 16:44
6
0
oacia 先在输入框中输入字符串之后再点按钮,然后到IDA中点击绿色的箭头来动态调试,要是在IDA运行的时候弹出小键盘的话会有概率导致无法运行的
楼主,现在flutter app的抓包有什么工具么,最近遇到的几个只要一抓包就直接掉登录,之前的hook方法不起效果,wireshark抓包走的是https,直接尬住了
雪    币: 244
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
wugming 2023-11-2 18:06
7
0


1、作者源码中只有这两种架构:EM_AARCH64、EM_IA_64,而我的so文件是em_arm架构,走到这里就报错了。


2、修改了一下问题一里的架构判断,先绕了过去,后边又出现了报错,经过调试发现:executable为None,导致系统找不到要启动的进程



希望能够得到帮助。。。

雪    币: 2
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
zx_958536 2023-11-4 18:49
8
0
感谢分享
雪    币: 226
活跃值: (1299)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hpphpp 2023-11-6 11:59
9
0
oacia 先在输入框中输入字符串之后再点按钮,然后到IDA中点击绿色的箭头来动态调试,要是在IDA运行的时候弹出小键盘的话会有概率导致无法运行的
即使调试自己的app,不涉及输入,断下分析一段时间后也会无法恢复,不知道怎么回事. 
雪    币: 212
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_ezphxtar 2023-11-6 14:24
10
0
mb_eiaothcj 楼主,现在flutter app的抓包有什么工具么,最近遇到的几个只要一抓包就直接掉登录,之前的hook方法不起效果,wireshark抓包走的是https[em_47],直接尬住了
hookssl无效么?
雪    币: 461
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_eiaothcj 2023-11-9 00:36
11
0
mb_ezphxtar hookssl无效么?
不是一定要走ssl的,而且那个方法都出来多久了,老早不管用了
雪    币: 212
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_ezphxtar 2023-11-9 09:38
12
0
mb_eiaothcj 不是一定要走ssl的,而且那个方法都出来多久了,老早不管用了
可否分享下app研究下?
雪    币: 62
活跃值: (572)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
万里星河 2023-11-10 22:21
13
0
支持一下 大佬的文章属实精彩
雪    币: 1770
活跃值: (8914)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
你瞒我瞒 2023-11-13 15:49
14
0
大佬你的博客崩溃了
雪    币: 3512
活跃值: (4073)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
oacia 2 2023-11-13 16:39
15
1
你瞒我瞒 大佬你的博客崩溃了
不是崩了是域名过期了这个月比较忙,下个月初我把域名重新买回来
雪    币: 313
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_pweuvgeh 2023-11-20 17:03
16
0
[1/22] Building CXX object CMakeFiles/blutte...vm2.19.2_android_arm64.dir/cmake_pch.hxx.gch
FAILED: CMakeFiles/blutter_dartvm2.19.2_android_arm64.dir/cmake_pch.hxx.gch 
/usr/bin/c++ -DDART_COMPRESSED_POINTERS -DDART_PRECOMPILED_RUNTIME -DDART_TARGET_OS_ANDROID -DDART_TARGET_OS_WINDOWS_UWP -DEXCLUDE_CFE_AND_KERNEL_PLATFORM -DFRIDA_TEMPLATE_DIR=\"/root/blutter/scripts\" -DHAS_TYPE_REF -DNDEBUG -DPRODUCT -DTARGET_ARCH_ARM64 -DU_USING_ICU_NAMESPACE=0 -D_HAS_EXCEPTIONS=0 -I/usr/include/capstone -isystem /root/blutter/packages/include/dartvm2.19.2 -O3 -DNDEBUG -O3 -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden -fno-omit-frame-pointer -std=c++20 -Winvalid-pch -x c++-header -include /root/blutter/build/blutter_dartvm2.19.2_android_arm64/CMakeFiles/blutter_dartvm2.19.2_android_arm64.dir/cmake_pch.hxx -MD -MT CMakeFiles/blutter_dartvm2.19.2_android_arm64.dir/cmake_pch.hxx.gch -MF CMakeFiles/blutter_dartvm2.19.2_android_arm64.dir/cmake_pch.hxx.gch.d -o CMakeFiles/blutter_dartvm2.19.2_android_arm64.dir/cmake_pch.hxx.gch -c /root/blutter/build/blutter_dartvm2.19.2_android_arm64/CMakeFiles/blutter_dartvm2.19.2_android_arm64.dir/cmake_pch.hxx.cxx
In file included from /root/blutter/build/blutter_dartvm2.19.2_android_arm64/CMakeFiles/blutter_dartvm2.19.2_android_arm64.dir/cmake_pch.hxx:5,
                 from <command-line>:
/root/blutter/blutter/src/pch.h:12:10: fatal error: format: No such file or directory
   12 | #include <format>
      |          ^~~~~~~~
compilation terminated.
ninja: build stopped: subcommand failed.
Traceback (most recent call last):
  File "/root/blutter/blutter.py", line 138, in <module>
    main(args.indir, args.outdir, args.rebuild, args.vs_sln)
  File "/root/blutter/blutter.py", line 120, in main
    cmake_blutter(blutter_name, dartlib_name, macros)
  File "/root/blutter/blutter.py", line 76, in cmake_blutter
    subprocess.run([NINJA_CMD], cwd=builddir, check=True)
  File "/usr/lib/python3.11/subprocess.py", line 571, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['ninja']' returned non-zero exit status 1.
我己经安装 g++13 了
雪    币: 514
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
aqingadmin 2023-12-17 01:22
17
0
C:\Users\Administrator\Desktop\blutter-main>python blutter.py ./app ./output
Dart version: 2.17.5, Snapshot: 1441d6b13b8623fa7fbf61433abebd31, Target: android arm64
libapp is loaded at 0x236e1a40000
Dart heap at 0x23700000000
Analyzing the application
C:\Users\Administrator\Desktop\blutter-main\blutter\src\CodeAnalyzer_arm64.cpp: 124: error: expected: dartCls->Id() >= dart::kNumPredefinedCids

C:\Users\Administrator\Desktop\blutter-main> 失败了
雪    币: 1
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
xzy____ 2023-12-21 16:35
18
0
https://segmentfault.com/a/1190000044464286
这个文章是搬运的吗?
雪    币: 3512
活跃值: (4073)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
oacia 2 2023-12-21 18:37
19
0
xzy____ https://segmentfault.com/a/1190000044464286 这个文章是搬运的吗?
看了一下应该是别的师傅参考这里的文章复现了ACTF的这题,说明我写的内容还是有意义的:)
雪    币: 422
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
zxk1ng 2023-12-21 22:00
20
0
师傅,我运行那个blutter_frida脚本,然后let报语法错误,您知道如何解决吗,对这个还不是很熟悉

雪    币: 1027
活跃值: (182)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
浮虚千年 1 2023-12-28 21:57
21
0
师傅我trace有问题,一直打印出14,具体的步骤可以教一下吗
雪    币: 3512
活跃值: (4073)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
oacia 2 2023-12-29 19:44
22
0
mb_ykhckzcr 师傅我trace有问题,一直打印出14,具体的步骤可以教一下吗

你需要点一下这个勾号确认文本框的提交 ,

点击提交之后在"submitted:"后面出现你输入的字符串才算是正确的把输入给输进去了,不然你的输入就是空字符串

雪    币: 0
活跃值: (393)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Light紫星 2024-1-23 13:20
23
0
感谢分享,遇到了一个flutter app,按照步骤试一下
雪    币: 2098
活跃值: (3139)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
shmilyaxy 2024-1-29 16:59
24
0
请问以下使用blutter时候提示找不到dartsdk\v3.0.2该如何处理?
C:\Users\TDTX001\Downloads\blutter-main\blutter\dartsdk\v3.0.2
Traceback (most recent call last):
  File "C:\Users\TDTX001\Downloads\blutter-main\blutter\blutter.py", line 169, in <module>
    main(args.indir, args.outdir, args.rebuild, args.vs_sln, args.no_analysis)
  File "C:\Users\TDTX001\Downloads\blutter-main\blutter\blutter.py", line 131, in main
    fetch_and_build(dart_version, arch, os_name, has_compressed_ptrs, snapshot_hash)
  File "C:\Users\TDTX001\Downloads\blutter-main\blutter\dartvm_fetch_build.py", line 122, in fetch_and_build
    outdir = checkout_dart(ver, snapshot_hash)
  File "C:\Users\TDTX001\Downloads\blutter-main\blutter\dartvm_fetch_build.py", line 53, in checkout_dart
    subprocess.run([GIT_CMD, '-c', 'advice.detachedHead=false', 'clone', '-b', ver, '--depth', '1', '--filter=blob:none', '--sparse', '--progress', DART_GIT_URL, clonedir], check=True)
  File "C:\Users\TDTX001\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 501, in run
    with Popen(*popenargs, **kwargs) as process:
  File "C:\Users\TDTX001\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 969, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Users\TDTX001\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1438, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] 系统找不到指定的文件。
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_wizwlvbj 2024-4-1 14:12
25
0

这是什么问题?

游客
登录 | 注册 方可回帖
返回