测试文件:https://adworld.xctf.org.cn/media/task/attachments/088c3bd10de44fa988a3601dc5585da8.exe
1.准备
获取信息
- 32位文件
- 北斗压缩壳(nsPack)
1.脱壳
1.1 OD打开(esp定律法)
Word或者DWord都可以
点击确认就行。
这样我们的断点就下好了,直接F9运行到断点即可。
选择OllyDump插件进行脱壳。
将文件重命名就可以了。
1.2 软件脱壳法
这个没什么讲究,拖进去脱壳就行
不过这个方法有个缺点是文件有损坏
可以使用ImportREC进行修复
2.IDA打开
1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 int result; // eax 4 int v4; // eax 5 char Buf; // [esp+4h] [ebp-38h] 6 char Dst; // [esp+5h] [ebp-37h] 7 8 Buf = 0; 9 memset(&Dst, 0, 0x31u); 10 printf("Please Input Flag:"); 11 gets_s(&Buf, 0x2Cu); 12 if ( strlen(&Buf) == 42 ) 13 { 14 v4 = 0; 15 while ( (*(&Buf + v4) ^ byte_402130[v4 % 16]) == dword_402150[v4] ) 16 { 17 if ( ++v4 >= 42 ) 18 { 19 printf("right!\n"); 20 goto LABEL_8; 21 } 22 } 23 printf("error!\n"); 24 LABEL_8: 25 result = 0; 26 } 27 else 28 { 29 printf("error!\n"); 30 result = -1; 31 } 32 return result; 33 }
3.代码分析
通过第42行代码,可以了解到flag长度为42
通过第15行代码,我们知道输入的正确flag与byte_402130[v4 % 16]进行异或等于dword_402150[v4],这个v4就是一个数组下标,最大为41
.nsp0:00402130 byte_402130 db 't' ; DATA XREF: _main:loc_40107F↑r .nsp0:00402131 aHisIsNotFlag db 'his_is_not_flag',0
实际上就是"this_is_not_flag"
.nsp0:00402150 dword_402150 dd 12h ; DATA XREF: _main+8D↑r .nsp0:00402154 dd 4, 8, 14h, 24h, 5Ch, 4Ah, 3Dh, 56h, 0Ah, 10h, 67h, 0 .nsp0:00402184 dd 41h, 0 .nsp0:0040218C dd 1, 46h, 5Ah, 44h, 42h, 6Eh, 0Ch, 44h, 72h, 0Ch, 0Dh .nsp0:0040218C dd 40h, 3Eh, 4Bh, 5Fh, 2, 1, 4Ch, 5Eh, 5Bh, 17h, 6Eh, 0Ch .nsp0:0040218C dd 16h, 68h, 5Bh, 12h, 2 dup(0) .nsp0:00402200 dd 48h, 0Eh dup(0) .nsp0:0040223C dd offset dword_403000 .nsp0:00402240 dd offset dword_4022B0 .nsp0:00402244 dd 1, 53445352h, 41D713B4h, 4CDD5318h, 12DCFFBAh, 0D5AF8709h .nsp0:00402244 dd 1
这段数字实际上就需要42个。
3.脚本获取
byte_402130 = "this_is_not_flag" dword_402150 = [ 0x12, 4, 8, 0x14, 0x24, 0x5C, 0x4A, 0x3D, 0x56, 0x0A, 0x10, 0x67, 0, 0x41, 0, 1, 0x46, 0x5A, 0x44, 0x42, 0x6E, 0x0C, 0x44, 0x72, 0x0C, 0x0D, 0x40, 0x3E, 0x4B, 0x5F, 2, 1, 0x4C, 0x5E, 0x5B, 0x17, 0x6E, 0x0C, 0x16, 0x68, 0x5B, 0x12, 0, 0, 0x48 ] x = '' for i in range(0,42): x += chr(dword_402150[i]^ord(byte_402130[i%16])) print(x)
4.get flag!
flag{59b8ed8f-af22-11e7-bb4a-3cf862d1ee75}