逆向攻防世界CTF系列16-IgniteMe-100 32位无壳
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 int __cdecl main (int argc, const char **argv, const char **envp) { size_t i; char v5[8 ]; char Str[128 ]; sub_402B30(&unk_446360, "Give me your flag:" ); sub_4013F0(sub_403670); sub_401440(Str, 127 ); if ( strlen (Str) < 0x1E && strlen (Str) > 4 ){ strcpy (v5, "EIS{" ); for ( i = 0 ; i < strlen (v5); ++i ) { if ( Str[i] != v5[i] ) goto LABEL_7; } if ( Str[28 ] != 125 ) { LABEL_7: sub_402B30(&unk_446360, "Sorry, keep trying! " ); sub_4013F0(sub_403670); return 0 ; } if ( (unsigned __int8)sub_4011C0(Str) ) sub_402B30(&unk_446360, "Congratulations! " ); else sub_402B30(&unk_446360, "Sorry, keep trying! " ); sub_4013F0(sub_403670); return 0 ; } else { sub_402B30(&unk_446360, "Sorry, keep trying!" ); sub_4013F0(sub_403670); return 0 ; } }
从下面这段代码可以看出,前几位一定是EIS{,否则就gotolable7,那边有个Return 0会退出。且str的第29位上一定是}。(}的asc是125)
1 2 3 4 5 6 strcpy (v5, "EIS{" ); for ( i = 0 ; i < strlen (v5); ++i ) { if ( Str[i] != v5[i] ) goto LABEL_7; } if ( Str[28 ] != 125 )
可得EIS{xxx},在看到Congratulations,应该是成功了,看看上面那个方法ifsub_4011C0
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 bool __cdecl sub_4011C0 (char *Str) int v2; char Str2[32 ]; int v4; int v5; size_t i; char v7[128 ]; if ( strlen (Str) <= 4 ) return 0 ; i = 4 ; v5 = 0 ; while ( i < strlen (Str) - 1 ) v7[v5++] = Str[i++]; v7[v5] = 0 ; v4 = 0 ; v2 = 0 ; memset (Str2, 0 , sizeof (Str2)); for ( i = 0 ; i < strlen (v7); ++i ) { if ( v7[i] >= 97 && v7[i] <= 122 ) { v7[i] -= 32 ; v2 = 1 ; } if ( !v2 && v7[i] >= 65 && v7[i] <= 90 ) v7[i] += 32 ; Str2[i] = byte_4420B0[i] ^ sub_4013C0(v7[i]); v2 = 0 ; } return strcmp "GONDPHyGjPEKruv{{pj]X@rF" , Str2) == 0 ; }
可以看出Str2一定要跟GON….相等,Str2中间可能做了一些变化,我们继续看看
1 2 3 4 5 6 7 8 9 10 if ( strlen (Str) <= 4 ) return 0 ; i = 4 ; v5 = 0 ; while ( i < strlen (Str) - 1 ) v7[v5++] = Str[i++]; v7[v5] = 0 ; v4 = 0 ; v2 = 0 ; memset (Str2, 0 , sizeof (Str2))
这段代码其实就是一个把str{}中间的部分赋值给v7
1 2 3 4 5 6 7 8 9 10 11 12 for ( i = 0 ; i < strlen (v7); ++i ) { if ( v7[i] >= 97 && v7[i] <= 122 ) { v7[i] -= 32 ; v2 = 1 ; } if ( !v2 && v7[i] >= 65 && v7[i] <= 90 ) v7[i] += 32 ; Str2[i] = byte_4420B0[i] ^ sub_4013C0(v7[i]); v2 = 0 ; }
这段代码就是大写转小写,小写转大写,byte_4420B0在下图
shift+e导出
sub_4013C0是
1 2 3 int __cdecl sub_4013C0 (int a1) { return (a1 ^ 0x55 ) + 72 ; }
Str2[i] = a[i] ^ ((v7[i] ^ 0x55)+72)
Str2[i] ^ a[i] = a[i] ^ a[i] ^ ((v7[i] ^ 0x55)+72) = 0 ^ ((v7[i] ^ 0x55)+72) = (v7[i] ^ 0x55)+72
(Str2[i] ^ a[i]) - 72 = v7[i] ^ 85
((Str2[i] ^ a[i]) - 72) ^ 85 = v7[i]
最后转化出来的要是GONDPHyGjPEKruv…
我们要逆着转换回去,写脚本吧,0x55=85
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 chars =[ 0x0D , 0x13 , 0x17 , 0x11 , 0x02 , 0x01 , 0x20 , 0x1D , 0x0C , 0x02 , 0x19 , 0x2F , 0x17 , 0x2B , 0x24 , 0x1F , 0x1E , 0x16 , 0x09 , 0x0F , 0x15 , 0x27 , 0x13 , 0x26 , 0x0A , 0x2F , 0x1E , 0x1A , 0x2D , 0x0C , 0x22 , 0x04 ] string = "GONDPHyGjPEKruv{{pj]X@rF" for c in range (0 , len (string)): a = ord (string[c]) a = ((chars[c] ^ a) - 72 ) ^ 0x55 if a >= 65 and a <= 90 : a += 32 elif a >= 97 and a <= 122 : a -= 32 print (chr (a), end="" )
得到答案