本帖最后由 yechen123 于 2018-9-24 17:13 编辑
这道题解了好久 发现大佬48分钟拿下了一血 果然还是自己太菜了
果然还是得多练 以后练多一点发多一点帖子
先上传附件
NewDrive.rar
(3.93 KB, 下载次数: 78)
链接: https://pan.baidu.com/s/1aO55f6nJ2UOpfukyJanovA 提取码: adjt 没有CB看这里
PS:如果想找到快速解题的方法 可以看看评论区各位大佬的方法 如果想一步一步调出来 也可以看看这个帖子
无壳 直接用IDA打开分析
有个flag 但是明显不是正确的flag 猜测后面会用的上 先记着
f5显示分析失败 应该出题人动了手脚 对这个分析不深
用od分析试试
查找字符 发现有input flag:
直接定位关键点代码
[Asm] 纯文本查看 复制代码 00D41280 $ 55 push ebp
00D41281 . 8BEC mov ebp,esp
00D41283 . 81EC 38020000 sub esp,238
00D41289 . A1 0030D400 mov eax,dword ptr ds:[D43000]
00D4128E . 33C5 xor eax,ebp
00D41290 . 8945 FC mov dword ptr ss:[ebp-4],eax
00D41293 . 53 push ebx
00D41294 . 56 push esi
00D41295 . 57 push edi
00D41296 . 68 FF000000 push 0FF ; /n = FF (255.)
00D4129B . 8D85 C9FDFFFF lea eax,dword ptr ss:[ebp-237] ; |
00D412A1 . 6A 00 push 0 ; |c = 00
00D412A3 . 50 push eax ; |s
00D412A4 . C685 C8FDFFFF>mov byte ptr ss:[ebp-238],0 ; |
00D412AB . E8 E4080000 call <jmp.&MSVCR100.memset> ; \memset
00D412B0 . B9 08000000 mov ecx,8
00D412B5 . BE 9421D400 mov esi,5ba358a4.00D42194 ; flag{this_is_not_the_flag_hahaha}
00D412BA . 8DBD C8FEFFFF lea edi,dword ptr ss:[ebp-138]
00D412C0 . F3:A5 rep movs dword ptr es:[edi],dword ptr ds>
00D412C2 . 68 DE000000 push 0DE ; /n = DE (222.)
00D412C7 . 8D8D EAFEFFFF lea ecx,dword ptr ss:[ebp-116] ; |
00D412CD . 6A 00 push 0 ; |c = 00
00D412CF . 51 push ecx ; |s
00D412D0 . 66:A5 movs word ptr es:[edi],word ptr ds:[esi] ; |
00D412D2 . E8 BD080000 call <jmp.&MSVCR100.memset> ; \memset
00D412D7 . 8B1D 9C20D400 mov ebx,dword ptr ds:[<&MSVCR100.printf>>; MSVCR100.printf
00D412DD . 68 B821D400 push 5ba358a4.00D421B8 ; /input flag:\n
00D412E2 . FFD3 call ebx ; \printf
00D412E4 . 8D55 C8 lea edx,dword ptr ss:[ebp-38]
00D412E7 . 52 push edx
00D412E8 . 68 C821D400 push 5ba358a4.00D421C8 ; /%50s
00D412ED . FF15 A420D400 call dword ptr ds:[<&MSVCR100.scanf>] ; \scanf
00D412F3 . 83C4 24 add esp,24
00D412F6 . 50 push eax
00D412F7 . 33C0 xor eax,eax
00D412F9 . 74 03 je short 5ba358a4.00D412FE
00D412FB . 83C4 1E add esp,1E
00D412FE > 58 pop eax
00D412FF . 8D45 C8 lea eax,dword ptr ss:[ebp-38] ; ascii
00D41302 . 8D50 01 lea edx,dword ptr ds:[eax+1] ; ascii
00D41305 > 8A08 mov cl,byte ptr ds:[eax]
00D41307 . 40 inc eax
00D41308 . 84C9 test cl,cl
00D4130A .^ 75 F9 jnz short 5ba358a4.00D41305
00D4130C . 2BC2 sub eax,edx ; 上面就是计算长度
00D4130E . 83F8 21 cmp eax,21 ; 21
00D41311 . 75 7D jnz short 5ba358a4.00D41390
00D41313 . 8D45 C8 lea eax,dword ptr ss:[ebp-38]
00D41316 . E8 45FEFFFF call 5ba358a4.00D41160 ; 第一个加密
00D4131B . 8BF0 mov esi,eax
00D4131D . 8D85 C8FEFFFF lea eax,dword ptr ss:[ebp-138]
00D41323 . 8D50 01 lea edx,dword ptr ds:[eax+1]
00D41326 > 8A08 mov cl,byte ptr ds:[eax]
00D41328 . 40 inc eax
00D41329 . 84C9 test cl,cl
00D4132B .^ 75 F9 jnz short 5ba358a4.00D41326
00D4132D . 2BC2 sub eax,edx
00D4132F . 50 push eax
00D41330 . 8D85 C8FEFFFF lea eax,dword ptr ss:[ebp-138]
00D41336 . 50 push eax
00D41337 . 8DBD C8FDFFFF lea edi,dword ptr ss:[ebp-238]
00D4133D . E8 BEFCFFFF call 5ba358a4.00D41000
00D41342 . 8BC6 mov eax,esi
00D41344 . 83C4 08 add esp,8
00D41347 . 8D50 01 lea edx,dword ptr ds:[eax+1]
00D4134A . 8D9B 00000000 lea ebx,dword ptr ds:[ebx]
00D41350 > 8A08 mov cl,byte ptr ds:[eax]
00D41352 . 40 inc eax
00D41353 . 84C9 test cl,cl
00D41355 .^ 75 F9 jnz short 5ba358a4.00D41350
00D41357 . 2BC2 sub eax,edx
00D41359 . 50 push eax ; /Arg2
00D4135A . 56 push esi ; |Arg1
00D4135B . 8D85 C8FDFFFF lea eax,dword ptr ss:[ebp-238] ; |
00D41361 . E8 7AFDFFFF call 5ba358a4.00D410E0 ; \5ba358a4.00D410E0
00D41366 . 83C4 08 add esp,8
00D41369 . 33C0 xor eax,eax
00D4136B . 81EE 0421D400 sub esi,5ba358a4.00D42104
00D41371 > 8A8C06 0421D4>mov cl,byte ptr ds:[esi+eax+D42104]
00D41378 . 3A88 0421D400 cmp cl,byte ptr ds:[eax+D42104]
00D4137E 75 23 jnz short 5ba358a4.00D413A3
00D41380 . 40 inc eax
00D41381 . 83F8 2C cmp eax,2C
00D41384 .^ 7C EB jl short 5ba358a4.00D41371
00D41386 . 68 7C21D400 push 5ba358a4.00D4217C ; Congratulation!!!!!!\n
00D4138B . FFD3 call ebx
00D4138D . 83C4 04 add esp,4
00D41390 > 8B4D FC mov ecx,dword ptr ss:[ebp-4]
00D41393 . 5F pop edi
00D41394 . 5E pop esi
00D41395 . 33CD xor ecx,ebp
00D41397 . 33C0 xor eax,eax
00D41399 . 5B pop ebx
00D4139A . E8 0D000000 call 5ba358a4.00D413AC
00D4139F . 8BE5 mov esp,ebp
00D413A1 . 5D pop ebp
[Asm] 纯文本查看 复制代码
00D4130E . 83F8 21 cmp eax,21 ; 21
判断输入字符长度
长度为0x21
分析了下
这个程序有两层加密
第一层在00D41316 . E8 45FEFFFF call 5ba358a4.00D41160 ; 第一个加密
主要是把输入字符串按照里面的字母表替换
第二层在00D41361 . E8 7AFDFFFF call 5ba358a4.00D410E0 ; \5ba358a4.00D410E0
主要是对替换过后的字符进行异或加密
最后再跟一串字符比较 如果全部相等就输出成功字符
[Asm] 纯文本查看 复制代码 00D41366 . 83C4 08 add esp,8
00D41369 . 33C0 xor eax,eax
00D4136B . 81EE 0421D400 sub esi,5ba358a4.00D42104
00D41371 > 8A8C06 0421D4>mov cl,byte ptr ds:[esi+eax+D42104]
00D41378 . 3A88 0421D400 cmp cl,byte ptr ds:[eax+D42104]
00D4137E 75 23 jnz short 5ba358a4.00D413A3
00D41380 . 40 inc eax
00D41381 . 83F8 2C cmp eax,2C
00D41384 .^ 7C EB jl short 5ba358a4.00D41371
00D41386 . 68 7C21D400 push 5ba358a4.00D4217C ; Congratulation!!!!!!\n
00D4138B . FFD3 call ebx
先把最后比较的字符提取出来 然后用逆着写脚本解密这串字符
20 C3 1A AE 97 3C 7A 41 DE F6 78 15 CB 4B 4C DC 26 55 8B 55 E5 E9 55 75 40 3D 82 13 A5 60 13 3B F5 D8 19 0E 47 CF 5F 5E DE 9D 14 BD
然后分析第二层加密
[Asm] 纯文本查看 复制代码 00D410E0 /$ 55 push ebp
00D410E1 |. 8BEC mov ebp,esp
00D410E3 |. 56 push esi
00D410E4 |. 57 push edi
00D410E5 |. 33C9 xor ecx,ecx
00D410E7 |. 33F6 xor esi,esi
00D410E9 |. 33FF xor edi,edi
00D410EB |. 394D 0C cmp [arg.2],ecx
00D410EE |. 76 5E jbe short 5ba358a4.00D4114E
00D410F0 |. 53 push ebx
00D410F1 |> 41 /inc ecx ; v5
00D410F2 |. 81E1 FF000080 |and ecx,800000FF ; v3 = (v3 + 1) % 256;
00D410F8 |. 79 08 |jns short 5ba358a4.00D41102
00D410FA |. 49 |dec ecx
00D410FB |. 81C9 00FFFFFF |or ecx,FFFFFF00
00D41101 |. 41 |inc ecx
00D41102 |> 8A1401 |mov dl,byte ptr ds:[ecx+eax] ; ff740 *(_BYTE *)(v3 + result);
00D41105 |. 0FB6DA |movzx ebx,dl
00D41108 |. 03F3 |add esi,ebx ; v6 + v4)
00D4110A |. 81E6 FF000080 |and esi,800000FF ; v4 = (v6 + v4) % 256;
00D41110 |. 79 08 |jns short 5ba358a4.00D4111A
00D41112 |. 4E |dec esi
00D41113 |. 81CE 00FFFFFF |or esi,FFFFFF00
00D41119 |. 46 |inc esi
00D4111A |> 0FB61C06 |movzx ebx,byte ptr ds:[esi+eax] ; *(_BYTE *)(v4 + result);
00D4111E |. 881C01 |mov byte ptr ds:[ecx+eax],bl ; *(_BYTE *)(v3 + result) = *(_BYTE *)(v4 + result);
00D41121 |. 881406 |mov byte ptr ds:[esi+eax],dl ; *(_BYTE *)(v4 + result) = v6;
00D41124 |. 0FB61C01 |movzx ebx,byte ptr ds:[ecx+eax] ; (v3 + result))
00D41128 |. 0FB6D2 |movzx edx,dl
00D4112B |. 03DA |add ebx,edx ; v6 + *(unsigned __int8 *)(v3 + result)
00D4112D |. 81E3 FF000080 |and ebx,800000FF ; v6 + *(unsigned __int8 *)(v3 + result)) % 256
00D41133 |. 79 08 |jns short 5ba358a4.00D4113D
00D41135 |. 4B |dec ebx
00D41136 |. 81CB 00FFFFFF |or ebx,FFFFFF00
00D4113C |. 43 |inc ebx
00D4113D |> 0FB61C03 |movzx ebx,byte ptr ds:[ebx+eax] ; *(_BYTE *)((v6 + *(unsigned __int8 *)(v3 + result)) % 256 + result);
00D41141 |. 8B55 08 |mov edx,[arg.1]
00D41144 |. 301C17 |xor byte ptr ds:[edi+edx],bl ; 7a a6 6a
00D41147 |. 47 |inc edi
00D41148 |. 3B7D 0C |cmp edi,[arg.2]
00D4114B |.^ 72 A4 \jb short 5ba358a4.00D410F1
00D4114D |. 5B pop ebx
00D4114E |> 5F pop edi
00D4114F |. 5E pop esi
00D41150 |. 5D pop ebp
00D41151 \. C3 retn
这段程序主要是经过乱七八糟的运算 然后根据运算取出内存中的值用来跟输入的字符异或
这就表示 取出内存中的值是不会变的
这段加密程序的话 有点复杂 写脚本解密花的时间也有点多
主要看关键点
[Asm] 纯文本查看 复制代码 00D4113D |> \0FB61C03 |movzx ebx,byte ptr ds:[ebx+eax] ;提取内存中的数据
00D41141 |. 8B55 08 |mov edx,[arg.1]
00D41144 |. 301C17 |xor byte ptr ds:[edi+edx],bl ;跟字符串异或加密
这个时候 只要不断摁f4 把内存中的数据提取出来就行
7a a6 6a da cd 0f 16 74 8b be 29 67 aa 79 79 b2 42 64 b2 2c bc 93 18 07 19 6f b7 64 fd 52 59 4f 96 ea 49 3c 11 89 66 39 87 d3 59 84
然后用python写脚本解密
[Asm] 纯文本查看 复制代码 key = '7a a6 6a da cd 0f 16 74 8b be 29 67 aa 79 79 b2 42 64 b2 2c bc 93 18 07 19 6f b7 64 fd 52 59 4f 96 ea 49 3c 11 89 66 39 87 d3 59 84'
en_flag = '20 C3 1A AE 97 3C 7A 41 DE F6 78 15 CB 4B 4C DC 26 55 8B 55 E5 E9 55 75 40 3D 82 13 A5 60 13 3B F5 D8 19 0E 47 CF 5F 5E DE 9D 14 BD'
key = key.split(' ')
en_flag = en_flag.split(' ')
en_flags = []
keys = []
g = ''
for i in key:
keys.append(int(i, 16))
for i in en_flag:
en_flags.append(int(i, 16))
for q in range(len(key)):
g += chr(keys[q]^en_flags[q])
print g
得到这段字符
ZeptZ3l5UHQra25nd19yYzMrYR5wX2Jtc2P2VF9gYNM9
再看第一层加密
代码篇幅有点多
我主要列出重要的
[Asm] 纯文本查看 复制代码 00D411DA |. 8D9B 00000000 lea ebx,dword ptr ds:[ebx]
00D411E0 |> 6A 03 /push 3 ; /maxlen = 3
00D411E2 |. 8D55 F8 |lea edx,[local.2] ; |
00D411E5 |. 53 |push ebx ; |src
00D411E6 |. 33FF |xor edi,edi ; |
00D411E8 |. 52 |push edx ; |dest
00D411E9 |. 897D F8 |mov [local.2],edi ; |
00D411EC |. FF15 A020D400 |call dword ptr ds:[<&MSVCR100.strncpy>] ; \strncpy
00D411F2 |. 8D4D F8 |lea ecx,[local.2] ; _is
00D411F5 |. 83C4 0C |add esp,0C
00D411F8 |. 33C0 |xor eax,eax
00D411FA |. 8D71 01 |lea esi,dword ptr ds:[ecx+1]
00D411FD |. 8D49 00 |lea ecx,dword ptr ds:[ecx]
00D41200 |> 8A11 |/mov dl,byte ptr ds:[ecx] ; _
00D41202 |. 41 ||inc ecx
00D41203 |. 84D2 ||test dl,dl
00D41205 |.^ 75 F9 |\jnz short 5ba358a4.00D41200
00D41207 |. 2BCE |sub ecx,esi
00D41209 |. 8BD1 |mov edx,ecx
00D4120B |. 74 16 |je short 5ba358a4.00D41223
00D4120D |. B9 10000000 |mov ecx,10
00D41212 |> 0FBE7405 F8 |/movsx esi,byte ptr ss:[ebp+eax-8] ; _
00D41217 |. D3E6 ||shl esi,cl ; 10 69 00
00D41219 |. 40 ||inc eax ; 740000 5F00 74
00D4121A |. 83E9 08 ||sub ecx,8
00D4121D |. 0BFE ||or edi,esi
00D4121F |. 3BC2 ||cmp eax,edx
00D41221 |.^ 72 EF |\jb short 5ba358a4.00D41212
00D41223 |> 33C0 |xor eax,eax
00D41225 |. 8D72 01 |lea esi,dword ptr ds:[edx+1] ; 04
00D41228 |. 8D48 12 |lea ecx,dword ptr ds:[eax+12] ; 12
00D4122B |. EB 03 |jmp short 5ba358a4.00D41230
00D4122D | 8D49 00 |lea ecx,dword ptr ds:[ecx]
00D41230 |> 3BF0 |/cmp esi,eax
00D41232 |. 76 15 ||jbe short 5ba358a4.00D41249
00D41234 |. 8B5D FC ||mov ebx,[local.1]
00D41237 |. 8BD7 ||mov edx,edi
00D41239 |. D3FA ||sar edx,cl ; 12 0C 06 00
00D4123B |. 83E2 3F ||and edx,3F
00D4123E |. 8A92 3821D400 ||mov dl,byte ptr ds:[edx+D42138] ; 主要是这两步
00D41244 |. 881403 ||mov byte ptr ds:[ebx+eax],dl
00D41247 |. EB 07 ||jmp short 5ba358a4.00D41250
00D41249 |> 8B55 FC ||mov edx,[local.1]
00D4124C |. C60402 3D ||mov byte ptr ds:[edx+eax],3D
00D41250 |> 83E9 06 ||sub ecx,6
00D41253 |. 40 ||inc eax
00D41254 |. 83F9 FA ||cmp ecx,-6
00D41257 |.^ 7F D7 |\jg short 5ba358a4.00D41230
00D41259 |. 8B5D F0 |mov ebx,[local.4]
00D4125C |. 8345 FC 04 |add [local.1],4
00D41260 |. 83C3 03 |add ebx,3
00D41263 |. FF4D EC |dec [local.5]
00D41266 |. 895D F0 |mov [local.4],ebx
00D41269 |.^ 0F85 71FFFFFF \jnz 5ba358a4.00D411E0
00D4126F |> 8B45 F4 mov eax,[local.3]
00D41272 |. 5F pop edi
00D41273 |. 5E pop esi
00D41274 |. 5B pop ebx
00D41275 |. 8BE5 mov esp,ebp
00D41277 |. 5D pop ebp
00D41278 \. C3 retn
主要思路是
循环strlen(input)/3次
一开始会把输入字符串复制到另一块内存区域 长度为3
[Asm] 纯文本查看 复制代码 00D411E0 |> /6A 03 /push 3 ; /maxlen = 3
00D411E2 |. |8D55 F8 |lea edx,[local.2] ; |
00D411E5 |. |53 |push ebx ; |src
00D411E6 |. |33FF |xor edi,edi ; |
00D411E8 |. |52 |push edx ; |dest
00D411E9 |. |897D F8 |mov [local.2],edi ; |
00D411EC |. |FF15 A020D400 |call dword ptr ds:[<&MSVCR100.strncpy>] ; \strncpy
然后会把输入字符 换成ascii码 左移 第一个字符左移四位(16进制下) 第二个字符左移两位最后一个字符不左移 再相加起来
比如fla 最后会变成00666C61
[Asm] 纯文本查看 复制代码 00D41212 |> /0FBE7405 F8 |/movsx esi,byte ptr ss:[ebp+eax-8] ; _
00D41217 |. |D3E6 ||shl esi,cl ;
00D41219 |. |40 ||inc eax ;
00D4121A |. |83E9 08 ||sub ecx,8
00D4121D |. |0BFE ||or edi,esi
00D4121F |. |3BC2 ||cmp eax,edx
00D41221 |.^\72 EF |\jb short 5ba358a4.00D41212
在最后 得到的数值00666C61 右移后 使用and保留最后6位(二进制下)
循环四次 第一次右移移动了18位(2进制)
第二次右移移动了12位
第三次右移移动了6位
最后一次不右移
00666C61 转成2进制是24位的
and 0x3f 只保留最低6位
所以 四次 恰好能保存 这个24位的数值(00666C61)
然后在用经过加密后的数值+D42138 后当做地址取出里面的值
看了下内容 是个字母表ABCDEFGHIJSTUVWK
LMNOPQRXYZabcdqr
stuvwxefghijklmn
opyz0123456789+
附上代码
[Asm] 纯文本查看 复制代码 00D41230 |> 3BF0 |/cmp esi,eax
00D41232 |. |76 15 ||jbe short 5ba358a4.00D41249
00D41234 |. |8B5D FC ||mov ebx,[local.1]
00D41237 |. |8BD7 ||mov edx,edi
00D41239 |. |D3FA ||sar edx,cl ; 12 0C 06 00
00D4123B |. |83E2 3F ||and edx,3F
00D4123E |. |8A92 3821D400 ||mov dl,byte ptr ds:[edx+D42138] ; 主要是这两步
00D41244 |. |881403 ||mov byte ptr ds:[ebx+eax],dl
00D41247 |. |EB 07 ||jmp short 5ba358a4.00D41250
00D41249 |> |8B55 FC ||mov edx,[local.1]
00D4124C |. |C60402 3D ||mov byte ptr ds:[edx+eax],3D
00D41250 |> |83E9 06 ||sub ecx,6
00D41253 |. |40 ||inc eax
00D41254 |. |83F9 FA ||cmp ecx,-6
00D41257 |.^\7F D7 |\jg short 5ba358a4.00D41230
00D41259 |. 8B5D F0 |mov ebx,[local.4]
00D4125C |. 8345 FC 04 |add [local.1],4
00D41260 |. 83C3 03 |add ebx,3
00D41263 |. FF4D EC |dec [local.5]
00D41266 |. 895D F0 |mov [local.4],ebx
00D41269 |.^ 0F85 71FFFFFF \jnz 5ba358a4.00D411E0
到了这里 这层加密的主要思路是 主循环循环len(input)/3 次
先复制内容到另一段内存 长度为三
然后取出字符左移储存
在循环四次 每次把数值右移 在进行and 0x3f截断数值
最后得到这个数值+D42138 取出字母当做密文
最后得到
ZeptZ3l5UHQra25nd19yYzMrYR5wX2Jtc2P2VF9gYNM9
可以根据这段密文解密
直接上脚本 用C写比较方便一些
[Asm] 纯文本查看 复制代码 #include <stdio.h>
int main()
{
char asciis[62] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'S', 'T', 'U', 'V', 'W', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
char encrypt[44] = {'Z', 'e', 'p', 't', 'Z', '3', 'l', '5', 'U', 'H', 'Q', 'r', 'a', '2', '5', 'n', 'd', '1', '9', 'y', 'Y', 'z', 'M', 'r', 'Y', 'R', '5', 'w', 'X', '2', 'J', 't', 'c', '2', 'P', '2', 'V', 'F', '9', 'g', 'Y', 'N', 'M', '9'};
int base[4];
int flag[3];
for(int i=43; i>=0; i=i-4)
{
base[3] = i;
base[2] = i-1;
base[1] = i-2;
base[0] = i-3;
//下面找出字母在字母表中对应的位置
flag[0] = 0;
flag[1] = 0;
flag[2] = 0;
flag[3] = 0;
for(int count=3; count>=0; --count)
{
for(int counts=0; counts<62; counts++)
{
if(encrypt[base[count]] == asciis[counts])
{
flag[count] = counts;
break;
}
}
}
flag[2] = flag[2] * 0x40;
flag[1] = flag[1] * 0x1000;
flag[0] = flag[0] * 0x40000;
printf("%x\n", flag[0]+flag[1]+flag[2]+flag[3]);
}
return 0;
}
好了 可以看到下面的字符 是fla 这些数字是16进制的
可以用python写脚本输出
[Asm] 纯文本查看 复制代码 i = '666c61677b7930755f6b6e6f775f7263345f616e645f6261736536345f6861247d'
jjj = ''
for j in range(0, len(i), 2):
jjj += chr(int(i[j:j+2], 16))
print jjj
写得比较匆忙 望见谅
果然还是自己太菜了 写解密脚本拖了好久
这个flag提到 base64和 rc4 是不是还有更快的解法 希望有能力的大佬给看看
|