--- tags: CS 2022 Fall, 程式安全 --- # [0x06] Reverse III slide: https://drive.google.com/drive/folders/1ZC6mdxIzcLsnGJ7j8S4emGsiY_LRNlKt?usp=sharing lecture: https://youtu.be/4-hgyiCV3ZA ### Exception #### `main`  跳到 `main` `xrefs` #### `.pdata`   ```cpp typedef struct _RUNTIME_FUNCTION { ULONG BeginAddress; ULONG EndAddress; ULONG UnwindData; } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; ``` 來到 `main` 的 `UnwindData` 指的地方 #### `_UNWIND_INFO` 先做好 `SCOPE_RECORD` <!-- ^r use image base as offset base -->  然後放到 `main` 的 `UnwindData` 的下面  回到 `main_0` #### `main_0`   看到 2 個處以 0 的地方 那邊會有 `exception` 分別標上 `exception1` `exception2` 可以發現對應到上面 `_UNWIND_INFO` 的`SCOPE_RECORD` <!-- https://learn.microsoft.com/en-us/cpp/cpp/try-except-statement?view=msvc-170 --> ```c // win32.h #define EXCEPTION_EXECUTE_HANDLER 1 #define EXCEPTION_CONTINUE_SEARCH 0 #define EXCEPTION_CONTINUE_EXECUTION -1 ```  由以上資料 我們知道 `exception` 發生後會跳到那邊了 來看看 `exception1` 發生後會跳到的位置 #### `exception1` `jumpTarget`  大概就是進行下面這樣的操作 ```c for (int i = 0; i < 38; i++) { flag_inp[i] ^= key + i; } ``` 至於 `key` 的值我們可以往上看 於 `main` `unwine_info` 的 `_C_specific_handler`  我們了解到了 `key` 會是 `rax`  `rax` 的值則會是 `0xBE` 實際跑起來也確實如此  接著來看 `exception2` 的 `jumpTarget` #### `exception2` `continue_exec`   做的事情大概像這樣 ```c for (int i = 0; i < 38; i++) { flag_inp[i] += key + i; } ``` 其中 `key` 會是 `0xEF`  之後就是正常的執行後面 `IDA` 有成功反編譯出來的的迴圈  所以之後把 `flag_enc` 拉出來解密即可 #### `Exception/sol.cpp` ```cpp for (int i = 0; i < 38; i++) { unsigned char key = 0xEF; flag_enc[i] -= key + i; } for (int i = 0; i < 38; i++) { unsigned char key = 0xBE; flag_enc[i] ^= key + i; } // output flag for (int i = 0; i < 38; i++) { cout << flag_enc[i]; } // output: FLAG{__C_specific_handler_is_hooked:O} ``` <!-- https://learn.microsoft.com/en-us/cpp/cpp/writing-an-exception-filter?view=msvc-170 --> <!-- https://learn.microsoft.com/en-us/windows/win32/debug/exception-handler-syntax --> ### [LAB] TLS Callback 從 `IDA` 可以看到城市一開始會有三次的 `TLS Callback`  #### `TlsCalllback1` 這個做的是把 `key` 進行 `funcs` 的操作  #### `TlsCalllback2` 這個做的事把 `funcs[3]` 的東西往左 `rotate`   #### `main`  由於上面的 `TlsCallback` 所以 `main` 裏面用到的 `funcs` `key` 都會跟一開始的不同 只要把 `TlsCallback` 操作後的 `funcs` `key` 拉出來然後就可以解密了  #### `TLS Callback/sol.cpp` ```cpp for (int i = 0; i < 58; i++) { flag_enc[i] -= key[i & 3]; (funcs[i % 3u])(flag_enc[i]); } // output for (int i = 0; i < 58; i++) { cout << (unsigned char)flag_enc[i]; } // output: FLAG{The_first_TLS_callback_function_is_called_two_times!} ``` ### [LAB] Meow #### `main`  由 `:9,10` 可以知道 `flag` 長度可能為 39 進入 `sub_401604` #### `sub_401604`  看到了一些 `GetProcAddress` 整理一下 之後把 `sub_401604` 命名為 `getProcAddresses` 回到 `main`  進入 `sub_401884` #### `sub_401884`  進入 `sub_401550` #### `sub_401550`  已經知道這是把一個 `exe` 解密了 把這個 `exe` 透過動態分析直接取出解密後的樣子 把函式取名為 `decrypt_exe` 回到上一層 #### `sub_401884` 修一修可以看出   `:21` 取得了`自己這個執行檔`的位置 `:22` 把`自己這個執行檔`跑起來 第6個參數 `4` 表示 `CREATE_SUSPENDED` 之後用 `exe` 把 `自己這個執行檔` 記憶體中的東西換掉 所以到了 `:53` 會恢復執行的東西變成 `exe` 回到 `main`  進入 `sub_401723` #### `sub_401723` `exe` ##### `sub_401723`   ##### `exe`  可以看到 `sub_401723:28` 會先把 `flag_inp` 傳給 `exe:19` 然後 `exe:21` 會對 `flag_inp` 做一些事 (`sub_401550`) 然後 `exe:24` 會把 `flag_inp` 回傳給 `sub_401723:32` 來看看 `sub_401550` 對 `flag_inp` 做了什麼事 #### `sub_401550`  很明顯的 這裡做的事加密 `flag_inp` 回到 `main`  進入 `sub_401C37` #### `sub_401C37`  是很一般的 `check_flag` 所以這裡只要把 `flag_enc` 拉出來 把上面的加密倒過來做就會得到 `flag` ##### `Meow/sol.cpp` 這邊的部分我先把 `encrypt` 的部分複製貼上 然後 `copilot` 會幫忙寫好 `decrypt` 然後把 `check_flag` 的部分複製貼上 然後 `copilot` 會幫忙寫好 `output_flag` 這邊只要呼叫 `output_flag` 出來的就會是答案 ```cpp int main () { output_flag(); // output: FLAG{pr0c355_h0ll0w1ng_4nd_n4m3d_p1p35} } ``` 順帶議題 這題的 `key` 是 `meow` 的 `base64` ### [HW] dropper #### DIE  看到有被包殼 先解殼 ```sh Ultimate Packer for eXecutables Copyright (C) 1996 - 2022 UPX 4.0.0 Markus Oberhumer, Laszlo Molnar & John Reiser Oct 28th 2022 File size Ratio Format Name -------------------- ------ ----------- ----------- 39424 <- 16896 42.86% win64/pe dropper_43741eb13c4a767e.exe Unpacked 1 file. ``` #### `main`   動態分析發現跑道這會跳到其他的地方 來看看是什麼地方  原來跑去 `kernel32.sleep(0x9AEC800)` 了 所以這裡才會跑這麼久 把他 patch 成 `sleep(1)` 往下走到 `00007FF60FE92DC5` 然後觀察一下參數 結果 `flag` 就在裡面 `5: [rsp+20]` 那就直接把 `flag` 拿走咯 ~~  ``` 5: [rsp+20] 000001D60364D2C0 000001D60364D2C0 "FLAG{H3r3_U_G0_iT_Is_UR_flAg}" ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up