BuringStraw

BuringStraw

Junk_Instruction(2019_西湖論劍_預選賽)

題目:xctf

MFC 程式,使用 xspy 查看視窗資訊。

check 按鈕的 id 為 03e9,同時視窗存在OnCommand: notifycode=0000 id=03e9,func= 0x00C72420(Junk_Instruction.exe+ 0x002420 )函數。

進入該函數(sub_402420),可以看到有一個條件判斷:if ( (unsigned __int8)sub_402600(v2 + 16) )。兩個分支分別是彈出正確和錯誤的對話框,說明sub_402600是檢驗函數。

這個函數中就出現了很多垃圾指令了。就是先用一個 call 壓好返回地址,再把堆疊裡的返回地址彈出來,改一下,壓回去。啪,返回地址變了。

.text:0040293F E8 00 00 00 00                call    $+5
.text:0040293F
.text:00402944
.text:00402944                               loc_402944:                             ; DATA XREF: sub_402600+398↓r
.text:00402944 58                            pop     eax
.text:00402945 89 85 C4 FD FF FF             mov     [ebp+var_23C], eax
.text:0040294B E8 03 00 00 00                call    loc_402953
.text:0040294B
.text:0040294B                               ; ---------------------------------------------------------------------------
.text:00402950 EA                            db 0EAh
.text:00402951                               ; ---------------------------------------------------------------------------
.text:00402951 EB 09                         jmp     short loc_40295C
.text:00402951
.text:00402953                               ; ---------------------------------------------------------------------------
.text:00402953
.text:00402953                               loc_402953:                             ; CODE XREF: sub_402600+34B↑j
.text:00402953 5B                            pop     ebx
.text:00402954 43                            inc     ebx
.text:00402955 53                            push    ebx
.text:00402956 B8 11 11 11 11                mov     eax, 11111111h
.text:0040295B C3                            retn
.text:0040295C                               ; ---------------------------------------------------------------------------
.text:0040295C
.text:0040295C                               loc_40295C:                             ; CODE XREF: sub_402600+351↑j
.text:0040295C E8 07 00 00 00                call    loc_402968
.text:0040295C
.text:00402961 BB 33 33 33 33                mov     ebx, 33333333h
.text:00402966 EB 0D                         jmp     short loc_402975
.text:00402966
.text:00402968                               ; ---------------------------------------------------------------------------
.text:00402968
.text:00402968                               loc_402968:                             ; CODE XREF: sub_402600:loc_40295C↑p
.text:00402968 BB 11 11 11 11                mov     ebx, 11111111h
.text:0040296D 5B                            pop     ebx
.text:0040296E BB 75 29 40 00                mov     ebx, offset loc_402975
.text:00402973 53                            push    ebx
.text:00402974 C3                            retn

結果這些垃圾指令沒有搞出很複雜的分支結構,都是順著跳到下一段,只需要全部nop掉就行了。

2AF0, 2CA0, 2e80 這幾個函數同理。去花之後發現他們的作用分別是去掉 flag 和括號並反向,rc4 初始化,rc4 加密。下面有個迴圈,對比密文是否正確。

密文是 2600 開頭那一長段賦值(5bD6D026C8DD197E6E3ECB16917DFFAFDD7664B0F7E58957829F0C009ED045FA),密碼是qwertyuiop

丟到 CyberChef 就出結果了。記得反向。記得包 flag {}。


PS:

開始的時候完全不敢全部 NOP 掉,因為有對 eax 和 ebx 賦值,害怕他們很重要。結果留下了一堆 JMP。ida: 6。後來看了大佬的去花腳本,發現是直接 nop 掉了。。。那個腳本是 python2 的,為了跑起來,我給改成 python3 的了。

from ida_bytes import get_bytes, patch_bytes
import re
addr = 0x402600
end = 0x402ae3
buf = get_bytes(addr, end-addr)
def handler1(s):
    s = s.group(0)
    print("".join(["%02x"%i for i in s]))
    s = b"\x90"*len(s)
    return s
p = b"\xe8\x00\x00\x00\x00.*?\xc3.*?\xc3"
buf = re.sub(p, handler1, buf, flags=re.I)
patch_bytes(addr, buf)
print("Done")

不過這個匹配好像有點問題,rc4 加密那個函數會被多 nop 掉很多,所以上面寫的範圍是僅限 sub_402600。(如果已經猜到是 rc4 加密了的話就沒什麼影響了)。


原以為 MFC 我還是知道的,結果一頭霧水,現在才知道有 xspy 這個東西。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。