Try   HackMD

[0x06] Reverse III

slide: https://drive.google.com/drive/folders/1ZC6mdxIzcLsnGJ7j8S4emGsiY_LRNlKt?usp=sharing
lecture: https://youtu.be/4-hgyiCV3ZA

Exception

main

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

跳到 main xrefs

.pdata

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

typedef struct _RUNTIME_FUNCTION {
 ULONG BeginAddress;
 ULONG EndAddress;
 ULONG UnwindData;
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;

來到 mainUnwindData 指的地方

_UNWIND_INFO

先做好 SCOPE_RECORD

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

然後放到 mainUnwindData 的下面

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

回到 main_0

main_0

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

看到 2 個處以 0 的地方
那邊會有 exception
分別標上 exception1 exception2

可以發現對應到上面 _UNWIND_INFOSCOPE_RECORD

// win32.h
#define EXCEPTION_EXECUTE_HANDLER           1
#define EXCEPTION_CONTINUE_SEARCH           0
#define EXCEPTION_CONTINUE_EXECUTION        -1

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

由以上資料
我們知道 exception 發生後會跳到那邊了

來看看 exception1 發生後會跳到的位置

exception1 jumpTarget

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

大概就是進行下面這樣的操作

for (int i = 0; i < 38; i++)
{
    flag_inp[i] ^= key + i;
}

至於 key 的值我們可以往上看
main unwine_info_C_specific_handler

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

我們了解到了 key 會是 rax

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

rax 的值則會是 0xBE

實際跑起來也確實如此

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

接著來看 exception2jumpTarget

exception2 continue_exec

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

做的事情大概像這樣

for (int i = 0; i < 38; i++)
{
    flag_inp[i] += key + i;
}

其中 key 會是 0xEF

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

之後就是正常的執行後面 IDA 有成功反編譯出來的的迴圈

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

所以之後把 flag_enc 拉出來解密即可

Exception/sol.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}

[LAB] TLS Callback

IDA 可以看到城市一開始會有三次的 TLS Callback

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

TlsCalllback1

這個做的是把 key 進行 funcs 的操作

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

TlsCalllback2

這個做的事把 funcs[3] 的東西往左 rotate

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

main

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

由於上面的 TlsCallback
所以 main 裏面用到的 funcs key 都會跟一開始的不同
只要把 TlsCallback 操作後的 funcs key 拉出來然後就可以解密了

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

TLS Callback/sol.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

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

:9,10 可以知道 flag 長度可能為 39

進入 sub_401604

sub_401604

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

看到了一些 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_401550flag_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
出來的就會是答案

int main ()
{
    output_flag();
    // output: FLAG{pr0c355_h0ll0w1ng_4nd_n4m3d_p1p35}
}

順帶議題
這題的 keymeowbase64

[HW] dropper

DIE

看到有被包殼
先解殼


                       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}"