-
-
[原创]看雪CTF TSRC 2018团队赛第八题
-
2018-12-17 12:07 3179
-
又是一个控制台的程序,所以很容易找到sn的验证处。在把sn转换到16后,进行验证。这里有两个关键的函数需要分析
sub_401AC0和sub_401710
首先分析sub_401AC0,参数为我们输入的sn的16进制形式。ida反编译的代码看起来很复杂。首先调用了sub_402890获取前16个字节,然后进行了位置变换,可以当做4X4的二维数组的操作看待。
接下来在一个while循环里有一个stl模板库中vector的痕迹
通过比较stl的源码和动态调试分析发现,这是一个vector的push_back操作,操作的元素是一个复数,这个在后面的复数乘法运算中可以确定出来。这个while循环的作用就是把前面获取的16个字节转换到复数保存到vector对象,然后在进行复数的乘法运算,之后调用了sub_402D80。
在sub_402D80函数里也有vector的操作,配合动态分析发现。通过循环对每一列做快速傅里叶变换FFT,这个函数对应的是sub_402B90,然后再对每一行做FFT。回到
sub_401AC0函数继续分析,又进行了复数的乘法。调用sub_4033D0函数进行每一列和每一行的快速傅里叶逆变换。
最后进行运算结果的比较
因为这些操作都是可逆的所以可以编写相应的逆向算法来解密,相应的代码我会放到附件里,解密出前32个字节如下:
进入sub_401710函数进行分析。
sub_403A30这个函数里调用sub_4038E0进行XXTEA的解密运算
把XXTEA解密运算后的数据在进行AES-256的解密,解密函数为sub_401330,AES被混淆了,其中的算法也进行了部分改变,S盒和标准的也不一样。s盒可以通过sub_4011F0密钥扩展函数得到S盒byte_418000。然后动态调试分析,对相应的数据下内存访问断点。可以找到MixColumns函数为sub_401080,代码如下:
signed int __cdecl sub_401080(int a1) { int v1; // eax@2 char *v2; // ecx@2 signed int v3; // esi@2 int *v4; // eax@4 char *v5; // edi@5 int *array_v27; // esi@5 unsigned __int8 v7; // dl@6 char v8; // cl@6 char v9; // bl@6 char v10; // al@9 bool v11; // zf@13 int v12; // ecx@14 char *v13; // eax@14 signed int v14; // esi@14 signed int result; // eax@16 signed int v16; // [sp+Ch] [bp-70h]@1 signed int v17; // [sp+10h] [bp-6Ch]@6 signed int v18; // [sp+14h] [bp-68h]@4 signed int v19; // [sp+18h] [bp-64h]@5 char *v20; // [sp+1Ch] [bp-60h]@4 int v21; // [sp+20h] [bp-5Ch]@1 char v22; // [sp+27h] [bp-55h]@5 char v23; // [sp+28h] [bp-54h]@5 char v24; // [sp+2Ch] [bp-50h]@2 char v25; // [sp+30h] [bp-4Ch]@4 char v26; // [sp+34h] [bp-48h]@14 int v27; // [sp+38h] [bp-44h]@1 int v28; // [sp+3Ch] [bp-40h]@1 int v29; // [sp+40h] [bp-3Ch]@1 int v30; // [sp+44h] [bp-38h]@1 int v31; // [sp+48h] [bp-34h]@1 int v32; // [sp+4Ch] [bp-30h]@1 int v33; // [sp+50h] [bp-2Ch]@1 int v34; // [sp+54h] [bp-28h]@1 int v35; // [sp+58h] [bp-24h]@1 int v36; // [sp+5Ch] [bp-20h]@1 int v37; // [sp+60h] [bp-1Ch]@1 int v38; // [sp+64h] [bp-18h]@1 int v39; // [sp+68h] [bp-14h]@1 int v40; // [sp+6Ch] [bp-10h]@1 int v41; // [sp+70h] [bp-Ch]@1 int v42; // [sp+74h] [bp-8h]@1 v27 = 84281355; v28 = 117506820; v29 = 100993800; v30 = 17236995; v31 = 134939910; v32 = 50595585; v33 = 185075205; v34 = 67305735; v35 = 117506820; v36 = 84281355; v37 = 17236995; v38 = 100993800; v39 = 50595585; v40 = 134939910; v41 = 67305735; v42 = 185075205; v21 = a1; v16 = 2; do { v1 = v21; v2 = &v24; v3 = 4; do { *(v2 - 4) = *(_BYTE *)v1; *v2 = *(_BYTE *)(v1 + 2); v1 += 4; ++v2; --v3; } while ( v3 ); v20 = &v25; v4 = &v27; v18 = 8; do { *v20 = 0; v22 = 0; v5 = &v23; array_v27 = v4; v19 = 8; do { v7 = *v5; v8 = *(_BYTE *)array_v27; v9 = 0; v17 = 8; do { if ( v7 & 1 ) v9 ^= v8; v10 = v8; v8 *= 2; if ( v10 & 0x80 ) v8 ^= 0x1Bu; v7 >>= 1; --v17; } while ( v17 ); v22 ^= v9; ++v5; array_v27 = (int *)((char *)array_v27 + 1); --v19; } while ( v19 ); *v20 = v22; v11 = v18-- == 1; ++v20; v4 = array_v27; } while ( !v11 ); v12 = v21; // v21=a1 v13 = &v26; v14 = 4; do { *(_BYTE *)v12 = *(v13 - 4); *(_BYTE *)(v12 + 2) = *v13++; v12 += 4; --v14; } while ( v14 ); result = 1; ++v21; --v16; } while ( v16 ); return result; }
分别对state状态数组的1,3列和2,4列进行相应矩阵的乘法,MDS矩阵如下:
11, 8, 6, 5, 4, 3, 1, 7, 8, 11, 5, 6, 3, 4, 7, 1, 6, 5, 11, 8, 1, 7, 4, 3, 5, 6, 8, 11, 7, 1, 3, 4, 4, 3, 1, 7, 11, 8, 6, 5, 3, 4, 7, 1, 8, 11, 5, 6, 1, 7, 4, 3, 6, 5, 11, 8, 7, 1, 3, 4, 5, 6, 8, 11
这个矩阵的逆为其自身。ShiftRows层跟踪如下:
对state状态数组的第一列不变,第二列和第三列循环下移2位,第四列为3位,行移位变成列移位了...。之后在进行轮密钥加操作前对state和轮密钥进行了矩阵的转置。最后根据网上的源码改了改,得到相应的XXTEA和AES的加密算法。对面后面验证的数据进行加密得到后面的sn如下:
所以sn为76474B2B1926009C452B00627200190268740438FDCC641665D0EA735F2739B3EE7B315A
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
[原创]vmp trace的优化处理
16903
[原创]基于LSTM的二进制代码相似性检测
19722
[原创]混合布尔算术运算的混淆及反混淆
18767
[原创]利用机器学习分析vmp的思路
17339
谁下载
无
谁下载
无
谁下载
看原图