首页
社区
课程
招聘
[原创]CTF2019-Q3- 第三题:庄周梦蝶 设计思路
2019-8-9 15:31 2672

[原创]CTF2019-Q3- 第三题:庄周梦蝶 设计思路

2019-8-9 15:31
2672
战队名称:兔斯基保护协会

参赛题目:基因编辑(Gene Hacking)

题目答案: 45621456375897443042931429304290



crackme程序见附件



题目设计:

(如有需要,可以联系我提供源代码)

本题的设计理念是题目即游戏。游戏分为两关,不同答案会根据通关情况给出不同的反馈,从而降低玩家的枯燥感。

正确序列号可以通过两关,程序显示:Right! You are very clever!
不正确但过了第一关,程序显示:Wrong! You are close to the result!
一关都没过,程序显示:Wrong!

第一关直接可以得到32的字节的key,不过这个key恐怕在小范围内有多解的可能,所以再由第二关从第一关的解中筛选中正确的唯一解。

(如果最终多解,我女装自拍发到比赛群里)

第一关:

本题限定用户的正确输入必须是正好32个字节。

本人搞了包含10个指令的指令集,把用户的输入转换为指令序列,然后开始跑如下程序:

void Sort()
{
int loop = 1;
LOOP: // 第一层循环
g_i = 1;
while (g_i < g_a_count) // 第二层循环
{
int pos = 0;
while (pos < 32)
{
跑用户指令
}
}
loop = (loop + 1) % 128;
if (loop)
goto LOOP;
}

这个程序就是个排序算法,排序需要的两层循环都已经限定死了,用户只需要填充每次比较和交换的逻辑即可。

我会用256位乱序数据来测试排序算法的有效性。

由于指令集非常基础而繁琐,用户所能达成目的有需要在32个字节之内,所以用户几乎只能使用冒泡算法:

void DefaultSort()
{
两层循环
{
// user code starts
if (g_box[g_a[i]] > g_box[g_a[i + 1]])
{
int temp = g_a[i];
g_a[i] = g_a[i + 1];
g_a[i + 1] = temp;
}
// user code ends
}
}

一种巧妙压缩后的算法如下:(正好32字节,不需要空操作,我本人没有想到更短的写法)
F代表指令集解释函数,只支持10种指令。

void Sort()
{
int loop = 1;
LOOP:
g_i = 1;
while (g_i < g_a_count)
{
// code starts

// (g_box[g_a[i]]
// block A1 starts (4 bytes)
F(4);
F(5);
F(6);
F(2);
// block A1 ends

// g_box[g_a[i + 1]]
// block A2 starts (5 bytes)
F(1);
F(4);
F(5);
F(6);
F(3);
// block A2 ends

// if (g_box[g_a[i]] > g_box[g_a[i + 1]]) 
// block A3 starts (4 bytes)
F(7, OP_TEST);
F(8);
F(9);
// block A3 ends

// do exchange g_a[i] and g_a[i + 1] if needed

// set operation
// block B1 starts (2 bytes)
F(7, OP_XOR);
// block B1 starts

// exchange g_a[i] and g_a[i + 1] if needed
// block B2 starts (16 bytes)
F(4);
F(3);
F(0);
F(4);
F(2);
F(9);
F(3);
F(1);
F(4);
F(2);
F(9);
F(3);
F(0);
F(4);
F(2);
F(9);
// block B2 ends

// i++
// block C starts (1 bytes)
F(0);
// block C ends

// code ends
}
loop = (loop + 1) % 128;
if (loop)
goto LOOP;
}

这个算法的一些部分有变体,少部分可以交换顺序,比如A1和A2。但B、C部分已经极度压缩,变体会撑爆32字节的限制。(也许存在更多的变体,但总体可能性很少)

按照交换和规律,和变体的候选集,用户无论是人工操作,还是写个自动程序,穷尽之都不算复杂。


第二关:

第一关把用户的输入限制到了很小的范围。直接在第二关过一下标准的sha2,都可以验证唯一解了。

用户所需要做的就是第一关把可能的解列出来,人工还是自动程序看用户口味。我觉得直接人工更省力。



[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2019-9-25 10:38 被kanxue编辑 ,原因:
上传的附件:
收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回