首页
社区
课程
招聘
bytectf2024 babyapk wp(flutte逆向)
发表于: 2024-9-24 16:04 3066

bytectf2024 babyapk wp(flutte逆向)

2024-9-24 16:04
3066

jadx打开,我们可以发现是flutter逆向,然后打包出资源,用blutter来搞(因为reflutter和flutter逆向助手都已经停止更新),

可以直接从github上面git下来(代理环境下),windows或者linux都可以,但因为我的linux上面的g++版本小于13,所以我用的是windows,下面是项目源码

GitHub - worawit/blutter: Flutter Mobile Application Reverse Engineering Tool

然后在readme.md上面也说了怎么使用,这里我就只说一下一些可能遇到的报错,

这个报错是说cmake的命令的执行返回了非零状态码,也就是遇到了一些环境依赖问题

所以可以用vs2022的命令行来执行脚本,这样cmake和ninja就不会出现问题,

打开x64 Native Tools Command Prompt,直接搜索就行,

然后blutter.py运行后,会出现下图的文件

然后先打开asm文件夹里面babyapk文件夹的main.dart,用vscord打开就行

首先就是审到这个,看到了用户输入后的逻辑,是先验证是否是’ByteCTF{’开头以及’}’结尾,继续审计代码可以发现字符串长度为43,并且通过frida hook几个地址时,会发现在m3N4B5V6这个函数这里有一些输出,

ida9(可以反汇编arm架构)打开libapp.so

运行重命名脚本后,恢复符号表,搜索m3N4B5V6

发现逻辑混乱,但还是出现了许多simple或者src的字符

于是回去看dart

然后会发现具体m3N4B5V6的实现需要在[package:babyapk/src/rust/api/simple.dart] ::m3N4B5V6这个里面去找,还是vscord打开simple.dart,

又发现提示这个dart文件,

这个dart主要实现一个与 Rust 库的交互接口,并且还有一些utf8编码解码函数,猜测加密会在flutter与rust交互的so里面,

也就是librust_lib_babyapk.so里面,于是ida打开,又出现了src/api/simple的字样,直接点进去

发现了一段数据,猜测密文,直接交叉引用,

果然是加密逻辑,审一审,先是一长串的判断’-’的位置是否在输入字符串的指定位置,然后是检查去掉了‘-’的字符串是否满足一系列条件,所以可以先z3解出未带’-’的字符串,然后再抄一下逻辑,爆破出‘-’的位置,反正只有4个‘-’,也许猜也可以,完整脚本如下:

from z3 import *
import itertools
 
char=['']*4
for j in range(4):
    flag = [BitVec(f'flag[{i}]',32)for i in range(8)]
    data = [0x0001EE59, 0x0000022A, 0x00001415, 0x00040714, 0x000013E0, 0x000008B8, 0xFFFDCEA0, 0x0000313B, 0x0003D798, 0xFFFFFE6B, 0x00000C4E, 0x00023884, 0x0000008D, 0x00001DB4, 0xFFFC1328, 0x00001EAC, 0x00043C64, 0x0000142B, 0xFFFFF622, 0x00023941, 0xFFFFEF6D, 0x0000120C, 0xFFFBD30F, 0x00001EBE, 0x00045158, 0xFFFFEF66, 0x00001D3F, 0x0004C46B, 0xFFFFF97A, 0x00001BFD, 0xFFFBA235, 0x00001ED2]
    s=Solver()
    for i in range(8):
        s.add(flag[i]>=0,flag[i]<=0x10FFFF)
    v45 = flag[2]
    v44 = flag[3]
    v46 = flag[0]
    v47 = flag[1]
    v48 = flag[4]
    v49 = flag[5]
    v50 = flag[6]
    v51 = flag[7]
    v52 = v46 * v49
    v53 = v48 * v46
    v54 = v44 - v51 - (v47 + v49)
    s.add(v51 + v47 * v44 * v49 - (v46 + v50 + v45 * v48) == data[0+j*8])
    s.add(v44 - v48 - v46 * v49 + v51 * v47 + v45 + v50 == data[1+j*8])
    s.add(v52 - (v48 + v51 * v47) + v45 + v50 * v44 == data[2+j*8])
    s.add(v47 + v48 * v46 - (v51 + v45) + v50 * v49 * v44 ==data[3+j*8])
    s.add(v49 * v44 + v47 + v45 * v48 - (v50 + v51 * v46) == data[4+j*8])
    s.add(v52 + v47 * v44 + v45 - (v50 + v48 * v51) == data[5+j*8])
    s.add(v51 - v47 + v45 * v49 + v50 - v53 * v44 == data[6+j*8])
    s.add(v54 + v53 + v50 * v45 ==data[7+j*8])
    if s.check()==sat:
        m=s.model()
        inp = [m.evaluate(flag[i]).as_long() for i in range(8)]
        char[j]= ''.join([chr(inp[i]) for i in range(8)])
    #     print(inp)
byte_18E46 = [
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
]
 
def check(input_str):
    a1=[ord(i) for i in input_str]
    v2 = byte_18E46[a1[0]]
    if v2 == 36:
        return 0
    v3 = byte_18E46[a1[v2]] + v2
    if v3 == 36:
        return 0
    v4 = v3 + byte_18E46[a1[v3]]
    if v4 == 36:
        return 0
    v5 = v4 + byte_18E46[a1[v4]]
    if v5 == 36:
        return 0
    v6 = v5 + byte_18E46[a1[v5]]
    if v6 == 36:
        return 0
    v7 = v6 + byte_18E46[a1[v6]]
    if v7 == 36:
        return 0
    v8 = v7 + byte_18E46[a1[v7]]
    if v8 == 36:
        return 0
    v9 = v8 + byte_18E46[a1[v8]]
    if v9 == 36:
        return 0
     
    v10 = a1[v9]
    if v10 != ord('-'):
        return 0
 
    v12 = v9 + byte_18E46[a1[v9]]
    if v12 == 36:
        return 0
    v13 = v12 + byte_18E46[a1[v12]]
    if v13 == 36:
        return 0
    v14 = v13 + byte_18E46[a1[v13]]
    if v14 == 36:
        return 0
    v15 = v14 + byte_18E46[a1[v14]]
    if v15 == 36:
        return 0
    v16 = v15 + byte_18E46[a1[v15]]
    if v16 == 36:
        return 0
     
    v18 = a1[v16]
    if v18 != ord('-'):
        return 0
 
    v20 = v16 + byte_18E46[a1[v16]]
    if v20 == 36:
        return 0
    v21 = v20 + byte_18E46[a1[v20]]
    if v21 == 36:
        return 0
    v22 = v21 + byte_18E46[a1[v21]]
    if v22 == 36:
        return 0
    v23 = v22 + byte_18E46[a1[v22]]
    if v23 == 36:
        return 0
    v24 = v23 + byte_18E46[a1[v23]]
    if v24 == 36:
        return 0
 
    v25 = a1[v24]
    if v25 != ord('-'):
        return 0
 
    v27 = v24 + byte_18E46[a1[v24]]
    if v27 == 36:
        return 0
    v28 = v27 + byte_18E46[a1[v27]]
    if v28 == 36:
        return 0
    v29 = v28 + byte_18E46[a1[v28]]
    if v29 == 36:
        return 0
    v30 = v29 + byte_18E46[a1[v29]]
    if v30 == 36:
        return 0
    v31 = v30 + byte_18E46[a1[v30]]
    if v31 == 36:
        return 0
 
    v32 = a1[v31]
    if v32 != ord('-'):
        return 0
    return 1
     
str=char[0]+char[1]+char[2]+char[3]
table = list(itertools.combinations(range(len(str)+1),4))
 
c=0
success=0
for i in table:
    tmp = str
    for i,j in enumerate(i):
        tmp  = tmp[:j+i]+'-' + tmp[j+i:]
    if check(tmp):
        print("ByteCTF{"+f"{tmp}"+"}")
 
        
from z3 import *
import itertools
 
char=['']*4
for j in range(4):
    flag = [BitVec(f'flag[{i}]',32)for i in range(8)]
    data = [0x0001EE59, 0x0000022A, 0x00001415, 0x00040714, 0x000013E0, 0x000008B8, 0xFFFDCEA0, 0x0000313B, 0x0003D798, 0xFFFFFE6B, 0x00000C4E, 0x00023884, 0x0000008D, 0x00001DB4, 0xFFFC1328, 0x00001EAC, 0x00043C64, 0x0000142B, 0xFFFFF622, 0x00023941, 0xFFFFEF6D, 0x0000120C, 0xFFFBD30F, 0x00001EBE, 0x00045158, 0xFFFFEF66, 0x00001D3F, 0x0004C46B, 0xFFFFF97A, 0x00001BFD, 0xFFFBA235, 0x00001ED2]
    s=Solver()
    for i in range(8):
        s.add(flag[i]>=0,flag[i]<=0x10FFFF)
    v45 = flag[2]
    v44 = flag[3]
    v46 = flag[0]
    v47 = flag[1]
    v48 = flag[4]
    v49 = flag[5]
    v50 = flag[6]
    v51 = flag[7]
    v52 = v46 * v49
    v53 = v48 * v46
    v54 = v44 - v51 - (v47 + v49)
    s.add(v51 + v47 * v44 * v49 - (v46 + v50 + v45 * v48) == data[0+j*8])
    s.add(v44 - v48 - v46 * v49 + v51 * v47 + v45 + v50 == data[1+j*8])
    s.add(v52 - (v48 + v51 * v47) + v45 + v50 * v44 == data[2+j*8])
    s.add(v47 + v48 * v46 - (v51 + v45) + v50 * v49 * v44 ==data[3+j*8])
    s.add(v49 * v44 + v47 + v45 * v48 - (v50 + v51 * v46) == data[4+j*8])
    s.add(v52 + v47 * v44 + v45 - (v50 + v48 * v51) == data[5+j*8])
    s.add(v51 - v47 + v45 * v49 + v50 - v53 * v44 == data[6+j*8])
    s.add(v54 + v53 + v50 * v45 ==data[7+j*8])
    if s.check()==sat:
        m=s.model()
        inp = [m.evaluate(flag[i]).as_long() for i in range(8)]
        char[j]= ''.join([chr(inp[i]) for i in range(8)])
    #     print(inp)
byte_18E46 = [
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
]
 
def check(input_str):
    a1=[ord(i) for i in input_str]
    v2 = byte_18E46[a1[0]]
    if v2 == 36:
        return 0
    v3 = byte_18E46[a1[v2]] + v2
    if v3 == 36:
        return 0
    v4 = v3 + byte_18E46[a1[v3]]

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 300
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
有遇到flutter的问题 能有偿帮忙解决么
1天前
0
游客
登录 | 注册 方可回帖
返回
//