首页
社区
课程
招聘
[原创]KCTF2021第2题通关分析(穷举)
发表于: 2021-11-17 14:03 11485

[原创]KCTF2021第2题通关分析(穷举)

2021-11-17 14:03
11485



分析上述算法,密码为长度32字符串,且字符只能包含0123456789ABCDEF
如:0123456789ABCDEF0123456789ABCDEF

简化后为2个16byte的字节数组
算法1 长度为8字节的数组 byte key1[8] //0123456789ABCDEF 变为{0x10,0x32,0x54,0x76,0x98,0xBA,0xDC,0xFE}
算法2 长度为8字节的数组 byte key2[8] //7923456789ABCDEF 变为{0x97,0x32,0x54,0x76,0x98,0xBA,0xDC,0xFE}

分析后拆分为两个算法
算法1:
密码表为0x100字节,前8位为key1填入
一系列计算后生成一个数组:tmparr[0x100][0x100]
然后遍历0x100次,每次取4个固定索引的值,不为0则计次+1

v21、v22、v23、v23为计次
if (v21 == 0xA9 && v22 == 0xAC && v23 == 0xA7 && v24 > 0xC8u)
{
//成功
}

算法2:
将key2的8个字节,每个字节计算每一位为单数或双数,进而将key1的值++或改为从密码表取
计算后key1的值是字符串"GoodJob~" 则为成功

破解步骤
1、分析算法2逻辑,发现在循环遍历密码表和索引值打乱,拷贝出密码表发现缺少8个字节的密码,判断出密钥在其中且不能重复。

密钥1的8个字节为0x1E,0x28,0x4B,0x6D,0x8C,0xA3,0xD2,0xFB,遂穷举

穷举结果key1为0x4b,0x6d,0x28,0x8c,0xfb,0xd2,0x1e,0xa3
也就是32位序列号前16位为B4D682C8BF2DE13A

算法2分析
修改key2值并调试,发现单个索引只改变单个字节的值,遂穷举key[0]-key[7]
都穷举0-0xff,判断算法后的字符是否相等

穷举后得出结果密钥为0x9d,0x6b,0xea,0x2f,0xa4,0x08,0xbc,0x22
也就是32位序列号后16位为D9B6AEF24A80CB22

拼接key1和key2,得出完整结果B4D682C8BF2DE13AD9B6AEF24A80CB22

 
 
 
 
 
 
for (size_t i0 = 0; i0 < 8; i0++)
{
    g_404000[0] = key[i0];
    for (size_t i1 = 0; i1 < 8; i1++)
    {
        g_404000[1] = key[i1];
        for (size_t i2 = 0; i2 < 8; i2++)
        {
            g_404000[2] = key[i2];
            for (size_t i3 = 0; i3 < 8; i3++)
            {
                g_404000[3] = key[i3];
                for (size_t i4 = 0; i4 < 8; i4++)
                {
                    g_404000[4] = key[i4];
                    for (size_t i5 = 0; i5 < 8; i5++)
                    {
                        g_404000[5] = key[i5];
                        for (size_t i6 = 0; i6 < 8; i6++)
                        {
                            g_404000[6] = key[i6];
                            for (size_t i7 = 0; i7 < 8; i7++)
                            {
                                g_404000[7] = key[i7];
 
                                bool isRepeat = false;
                                for (size_t iii = 0; iii < 8; iii++)
                                {
                                    for (size_t jjj = 0; jjj < 8; jjj++)
                                    {
                                        if (iii != jjj && g_404000[iii] == g_404000[jjj])
                                        {
                                            isRepeat = true;
                                        }
                                    }
                                }
                                if (isRepeat)continue;
 
                                int nRet = sync_1();
                                //printf("nRet[%d]\n", nRet);
                                static int aaa = 0;
                                if (aaa++ % 10000 == 0)
                                {
                                    printf("%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x  find\n", i0, i1, i2, i3, i4, i5, i6, i7);
                                }
                                if (nRet == 1)
                                {
                                    static int oknum = 0;
                                    //printf("%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x  ok\n", i0, i1, i2, i3, i4, i5, i6, i7);
                                    printf("0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x  oknum[%d]\n", key[i0], key[i1], key[i2], key[i3], key[i4], key[i5], key[i6], key[i7], ++oknum);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
for (size_t i0 = 0; i0 < 8; i0++)
{
    g_404000[0] = key[i0];
    for (size_t i1 = 0; i1 < 8; i1++)
    {
        g_404000[1] = key[i1];
        for (size_t i2 = 0; i2 < 8; i2++)
        {
            g_404000[2] = key[i2];
            for (size_t i3 = 0; i3 < 8; i3++)
            {
                g_404000[3] = key[i3];
                for (size_t i4 = 0; i4 < 8; i4++)
                {
                    g_404000[4] = key[i4];
                    for (size_t i5 = 0; i5 < 8; i5++)
                    {
                        g_404000[5] = key[i5];
                        for (size_t i6 = 0; i6 < 8; i6++)
                        {
                            g_404000[6] = key[i6];
                            for (size_t i7 = 0; i7 < 8; i7++)
                            {

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

收藏
免费 4
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//