-
-
[原创]看雪CTF.TSRC 2018 团队赛 第八题 二向箔
-
发表于:
2018-12-17 11:22
3287
-
[原创]看雪CTF.TSRC 2018 团队赛 第八题 二向箔
没什么时间,暂时先写点,如果有空的话。。。。
##初识
初看程序很“正常”,主流程清晰,输入72字节,unhex后的36字节分两个部分进行分别校验,这种明了的控制台程序让人看了感觉很舒服,典型做题人的懒人心理,如下:
这部分校验是通过复数计算实现的,背后的数学意义不知,也别再和我谈数学,头疼。
代码比较乱,就不上了。大致过程是:16字节输入矩阵点乘包含16个复数元素的常量矩阵A后进行变换,接着再点乘常量矩阵B后进行变换,结果与常量比较,可以参照反解代码。
这部分流程如下:
似乎过程也很明了。经过unhex后的20字节,先进行魔改tea解密,再进行魔改aes解密,最后进行常量校验。
但是做题做到aes_decrypt
函数里,发现里面有函数调用被非常大量的混淆代码替代了,有点痛苦。暂且不说。先把魔改tea搞定。
魔改tea解密后还有个细节,解密后第5个int数在[14,16]
范围内,对应长度的解密结果被copy加填充后进行后面的魔改aes解密。魔改tea的加密解用py实现如下:
魔改aes的识别主要靠猜,依据是密钥扩展和解密过程中的字节替换
及S盒和逆S盒的关系。
在aes解密的主函数中,第一次轮密钥加,循环中的行变换、字节替换和最后一轮的操作过程都清晰可见,循环中的轮密钥加和列混合变换函数调用被混淆代码填充了,编译后修改痕迹比较明显。
4013B0
-401508
本是一个循环。这个混淆也挺有意思,有个统一的业务流程跳转处理。不过对于做题这部分不要细看。直接上动态,跟踪数据写入。很容易就发现混淆在分散处理的功能就是轮密钥加,写入位置为421621
,而列混合变换是完整函数实现401080
。通过动态跟踪比对,发现了所有魔改之处,包括:
具体过程见代码(代码也是网上copy来的):
最后结果为:76474B2B1926009C452B00627200190268740438FDCC641665D0EA735F2739B3EE7B315A
。
int mainroutine()
{
char l_input[260]; // [esp+0h] [ebp-130h]
char l_unhex_input[36]; // [esp+104h] [ebp-2Ch]
char v3; // [esp+128h] [ebp-8h]
while ( 1 )
{
*(_DWORD *)l_unhex_input = 0;
*(_DWORD *)&l_unhex_input[4] = 0;
*(_DWORD *)&l_unhex_input[8] = 0;
*(_DWORD *)&l_unhex_input[12] = 0;
*(_DWORD *)&l_unhex_input[16] = 0;
*(_DWORD *)&l_unhex_input[20] = 0;
*(_DWORD *)&l_unhex_input[24] = 0;
*(_DWORD *)&l_unhex_input[28] = 0;
*(_DWORD *)&l_unhex_input[32] = 0;
v3 = 0;
printf("\nInput RegCode:");
memset(l_input, 0, 0x101u);
scanf("%245s", l_input);
if ( check_format_and_unhex(l_input, l_unhex_input) == 36
&& check_part1((int)l_unhex_input)
&& check_part2((unsigned int *)&l_unhex_input[16]) )
{
break;
}
printf("\n Wrong, Plz Try Again...\n");
}
printf("\n Good!\n");
return getch();
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-12-17 11:38
被poyoten编辑
,原因: