-
-
[原创]KCTF2021第2题通关分析(穷举)
-
2021-11-17 14:03 10603
-
分析上述算法,密码为长度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,遂穷举
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 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); } } } } } } } } } |
穷举结果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
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界