首页
社区
课程
招聘
[原创] 第三题 寻踪觅源 WP
发表于: 2020-4-18 09:03 4059

[原创] 第三题 寻踪觅源 WP

2020-4-18 09:03
4059

注意:本篇 wp 不涉及对题目校验算法的完整分析,请关注我正在抱着的大腿以获得最佳题解。

题目用 quickjs 实现,本人由于过菜,并不会逆其虚拟机字节码。好在作者并没有丧心病狂到将符号去除,通过把在 main 函数内被注册了的 js 函数中看着嫌疑比较大的都稍微下断点调一调跑一跑跟一跟,我们可以发现校验算法与 quickjs 的大整数运算相关。这样一来我将关注重点放在了 BigInt(Float) 的相关函数上,例如 bf_mul / bf_cmp 等等,关注程序在哪些地方、以何种顺序调用了这些函数。

有了源码之后我便失去了在 IDA 中打标记的动力,因为可以直接在 quickjs 库中找到 bf_mul / bf_cmp 的声明:

可以发现这些函数操作对象是 bf_t 数据类型,它的结构如下:

它是以 hexadecimal floating number(这瞎编的名字是什么?)的形式存储的,limb_t 在我的机器上其实就是一个 DWORD,存的是十六进制的小数有效值部分,len 是 tab 数组的长度。既然打算去跟踪这些函数调用,自然会想到在每一次调用的时候输出调用的参数(比方说打印出 mul 、cmp 的两个操作数),因为已经清楚 bf_t 的结构,我们已经可以直接打印出这个 bf_t。

因为懒惰,写代码之前我在源码中报着期望的目光一瞧瞧二看看,果然在 libbf.c 里我发现了:

于是乎写了个调试器,hook 了 bf_mul / bf_cmp ,顺便把 quickjs 的源码拉进来用,在被 hook 函数 hit 的时候输出相应的调用参数:

值得夸奖的是 binary 里面这些函数的头部都留有类似 lea edi, [edi+0] 这样又长又没用的废话指令方便我们进行 hook。

把给的 UserName / SN 拿来跑跑:

经过几轮观察,猜测 UserName 的作用除了计算出一个 BigInt1 之外还对某种形式的表进行了搅乱,这个表用来将 SN 的每 2 个 bytes 置换为一个 100 内的十进制数,然后这些十进制数会被不断拼接成一个 BigInt2,进而与 BigInt1 进行比较。于是我在 UserName 固定时将验证算法简单地抽象成了 assert(f(UserName)==g(SN)),其中 f、g 互不相干,固定 UserName 为 KCTF 后可以得到 BigInt1 为:

现在需要将这个数转换为十进制,Python 直接处理这种数据会丢失精度,因才疏学浅不了解其它更好的方法,我手糊了一个脚本用来生成算式:

然后把输出丢给科学家们用的 Mathematica 求解:

简单地划分一下这个结果得到:02 43 37 77 98 92 55 56 02 64 77 31 43 60

接下来便是跑表的过程了,同样因为没有什么好办法,我开始了手动跑表,跑了一会儿发现在每个段(用 --- 隔开的部分)内 in-out 的映射关系是有规律的:

于是后续阶段里每个段只需要跑一个结果即可推出剩余的部分。

得到表之后,把 02 43 37 77 98 92 55 56 02 64 77 31 43 60 映射回来,即为本题的 flag: 40017535dad01714402635730122

PS. 我在手动跑表的过程中得知附件被换掉了,内心顿时受到 1w+ 的暴击伤害并直接回到了泉水(指床)开始了为期一晚的挂机疗养,后经美味 pizza 与强壮大腿的滋润才得以康复。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2020-4-18 23:46 被yypEx编辑 ,原因: pizzatql
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//