ByteCTF2024 Reverse wps
碎碎念
好久没打 CTF 感觉能力退化了不少,遇到不是 Android 的题都有点不会做了,甚至卡了一题光荣成为战犯(?)。想了半天为什么 10 解的题我都不会做,后来发现原来现在还有可以直接去除的 ollvm 混淆…. 平时看到的 ollvm 混淆基本都是加强过的根本没法直接跑轮子去除就根本没往这方面想,还是有点太唐了。
babyAPK
上来肯定是先把 Android 秒了(x
经典 flutter,直接跑一下 blutter。 main.dart 里可以看到一个明显的相关逻辑:
|
|
大概就是 check 了一下 flag 格式和长度 45,直接进入[package:babyapk/src/rust/api/simple.dart] ::m3N4B5V6
执行校验逻辑。这里可以看到是使用了一个 flutter 和 rust 结合的框架 https://github.com/fzyzcjy/flutter_rust_bridge
直接找源码来看,大概的逻辑是对所有的 rust 函数做一个中间层,大概的调用顺序如下:
|
|
示例工程里的调用代码:https://github.com/fzyzcjy/flutter_rust_bridge/blob/fffbb1f9ab7e4586ec2e3cd7f1f0b94219161ee1/frb_example/dart_minimal/lib/src/rust/frb_generated.dart#L96
|
|
可以看到是调用 pdeCallFfi 后根据函数 ID 来调用函数。根据官方文档,序列化的一些东西只给 rust 访问 dart 对象的能力,所以可以不管他。
在 ida 里经过一系列 F7 分析后可以发现跳过一些异步的操作后直接走到了 CallNativeThroughSafepointStub_1815ac 来进行一个统一的调用,最后跳入 librust_lib_babyapk.so+0x350b8
再根据函数ID执行具体的函数逻辑。
出题人在这个 so 里留了一个 m3N4B5V6
的字符串,感觉之前的努力全部都像小丑,还好我起床的时候血都没了不然肯定要红温…
后面的逻辑是先 check 了 uuid 格式,然后 8 个一组解方程,感觉这 rust 和没有也一样。
|
|
ByteBuffer
不知道什么是 flatbuffer,但是一看有边有点多半就是画图,那么需要的信息就是边连接的两个点和点的坐标。直接大眼观察一下哪个像就可以了。大概内存布局:
|
|
直接画图。
|
|
|
|
这题之所以放在 Reverse 标签内大概是因为最后需要把图翻转 180 度再水平翻转吧。
ByteKit
给了一个 qemu 镜像和 bios,先看看 getflag.sh
|
|
根据题目描述,运行这个脚本设置了 ByteCTFIn 之后重启,根据有没有 ByteCTFOut 来判定 flag 是否正确。这里写的是 /efi/efivars,可以判断和 uefi 相关,应该是在 bios.bin 里做的校验。用 UEFI Tools 解包了一下可以发现下面两个有趣的东西:
|
|
dump 出 ByteKitLoaderDxe 之后直接逆向分析,有 ollvm 混淆,crc32 和 smc 的异或混在一起,已经逆了两个题神志不清的我直接忽略了 smc 的那个异或干瞪了好一会啥都没看出来,又因为完全没有接触过 uefi 相关的东西根本不会调试,遂躺床上昏迷成为战犯。赛后经好心人提点知道这个 ollvm 可以直接用 d810 去除(真没想到 2024 年了还有能被完美去除的 ollvm 混淆…)
去除混淆后可以发现是一个简单的异或解密了另一个 module 然后 load 进来执行,里面的逻辑也是简单异或。
|
|