Simple Reverse 0x12(Lab - TLSCallback)
Background
課程相關影片 [C語言] function pointer的應用[四]: function pointer array
Source Code
:::spoiler IDA main function
1 |
|
:::
Recon
這一題也蠻簡單的,只要有耐心分析一下就可以了
- 首先執行一下這隻程式,發現沒啥特別的,就和之前的題目一樣
- 用IDA看一下,可以發現也蠻單純的,就用function pointer array然後傳入我們輸入的flag進行一些事情再加上一個數值(來自某一個array)
- 仔細看一下有哪些function然後分別做了甚麼事
- xor 0x87
:::spoiler source
1
2
3
4void __fastcall do_xor(_BYTE *a1) { *a1 ^= 0x87u; }
:::
- xor 0xff
:::spoiler source
1
2
3
4void __fastcall do_inverse(_BYTE *a1) { *a1 = ~*a1; }
:::
- xor 0x63
:::spoiler source
1
2
3
4void __fastcall do_xor_2(_BYTE *a1) { *a1 ^= 0x63u; }
:::
- xor 0x87
:::spoiler source
-
陷阱
如果直接分析這樣的code會做白工,因為這一題有tls callback function在搞事,這件事情IDA和x64dbg都有分析出來,或者是也可以用PE-Bear看一下,所以我們就朝這個方向分析一下,看起來兩者都沒有很複雜,tlscallback function 2就只是把剛剛前面的function pointer array的順序置換一下,而tlscallback function 1也只是用置換過後的function pointer array把key的數值做一些操作而已,如果看psuedo code看不太懂得話可以直接用x64dbg用肉眼跟一下(我就這樣XDD),應該也是可以很直觀的猜出這些事情 :::spoiler TLS Callback function 1 & 2
:::
- 用x64dbg直接動態跟code,以下的screenshot我都有加上一些comment幫助理解
- TLSCallback相關的code
- 三個Function pointer
- main function
- TLSCallback相關的code
- 結論
在function pointer的順序是xor 0x63 $\to$ xor 0x87 $\to$ xor 0xff
在key的部分是0x21 $\to$ 0xce $\to$ 0x39 $\to$ 0x40
xor 0x63 + 0x21 xor 0x87 + 0xce xor 0xff + 0x39 xor 0x63 + 0x40 xor 0x87 + 0x21 xor 0xff + 0xce xor 0x63 + 0x39 ...
:::info Note: 相加的部分最後只會取==低位byte==喔,所以如果減回去發現是負的,就要在加0x100導正回來 :::
- 開寫script
Exploit
key = [0x21, 0xCE, 0x39, 0x40]
enc_flag = [0x46, 0x99, 0xF7, 0x64, 0x1D, 0x79, 0x44, 0x22, 0xC1, 0xD3, 0x27, 0xCD, 0x31, 0xC1, 0xD9, 0x77, 0xEC, 0x7A, 0x75, 0x24, 0xBF, 0xDD, 0x24, 0xDD, 0x23, 0xB2, 0xCD, 0x7C, 0x02, 0x58, 0x46, 0x24, 0xAC, 0xD8, 0x21, 0xD1, 0x5D, 0xBC, 0xC5, 0x7C, 0x05, 0x6C, 0x48, 0x2B, 0xBB, 0xD5, 0x11, 0xCB, 0x35, 0xB6, 0xD9, 0x57, 0x0F, 0x60, 0x3F, 0x34, 0xFF, 0xEC]
def xor(index, val):
if index % 3 == 0:
return val ^ 0x63
elif index % 3 == 1:
return val ^ 0x87
else:
return val ^ 0xff
FLAG = []
for i in range(len(enc_flag)):
tmp = enc_flag[i] - key[i % 4]
if tmp < 0:
tmp += 0x100
tmp = xor(i, tmp)
FLAG.append(bytes.fromhex(hex(tmp)[2:]).decode('utf-8'))
print("".join(FLAG))
Flag: FLAG{The_first_TLS_callback_function_is_called_two_times!}