iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 5
1
Security

CTF 的三十道陰影系列 第 5

Day5: [Reverse] 淺談 reverse engineering

淺談 reverse engineering

其實 wiki 上對 reverse engineering (逆向工程,文章後面簡稱 reverse) 已經有很明確的定義:

逆向工程,又稱反向工程,是一種技術過程,即對一專案標產品進行逆向分析及研究,從而演繹並得出該產品的處理流程、組織結構、功能效能規格等設計要素,以製作出功能相近,但又不完全一樣的產品。逆向工程源於商業及軍事領域中的硬體分析。其主要目的是,在無法輕易獲得必要的生產資訊下,直接從成品的分析,推導產品的設計原理。

在這邊我想談的是自己對 reverse 的一些感想,逆向工程其實又可以分為 軟體硬體 兩個層面:

  • 硬體的 reverse 門檻非常高,沒有相關經驗非常難以入門,而且通常需要有相關設備才有辦法分析硬體行為,就算退一步分析韌體,也需要先能 dump 出 firmware 才有辦法開始分析
  • 軟體難度相對簡單,無論是用哪種程式語言寫的軟體,由於最後一定是翻譯成 assembly 交給 CPU 執行,如果能逐行追蹤 assembly 就一定能了解程式行為
    • 但實際上,CPU 執行 assembly 的量級已經超出人類大腦能處理的範疇了

但無論是硬體或軟體的逆向工程,本質其實都是 Code Review,透過閱讀被轉化過的 byte code 或 assembly,再加上一點腦補和猜想 (所以是 具現化系 :p),嘗試分析出原本 source code 是如何撰寫,也因為這樣,要進行逆向工程其實必須要有一定的 coding 能力,不然就算把 source code 直接攤在眼前,也沒辦法讀懂程式行為,反過來 reverse 看得多了 (尤其是逆過許多在 high quaulity 的程式之後),也可以提升自己的 coding 能力

由於 CTF 比賽性質的限制,reverse 題目其實相對 real world 的情境來說簡單很多,原因有兩點:

  1. 時間長度
    • 現在常見的 CTF 一般來說都是進行 24~48 hr,一個優秀的出題者通常會確保自己的題目在比賽內是 solvable,因此題目的規模不太可能會像現實的產品一樣到動輒上萬行,因此 reverse 的難度也輕鬆不少
    • 現在的 reverse 題目,偶爾會搭配 crypto 或 forensic 的元素,讓參賽者可以練習到逆向的技巧,又不至於讓題目太過簡單
  2. 目的明確
    • 解 CTF 的題目最重要的就只有一件事情:想辦法拿到 flag,只要看懂如何生成 flag 的段落就好,中間看不懂就跳過反正不重要 XD
    • 但 real world 的情境不能不求甚解,以分析 malware 為例,沒有把整個 malware 的行為給看懂,怎麼能確保電腦的後門已經被清除乾淨 ? 兩者的目的性不同導致要投入的時間和難度有著決定性的差異

雖然上面說了一些 CTF 的 reverse 題的缺點,但解 CTF 還是一個非常好的練習,尤其可以避免在還不熟悉的情況下直接逆向 real world 的 malware,讓電腦成為 botnet 之一,或是重要資料受到損壞,另外透過解 CTF 的題目也可以在賽後了解出題者或其他參賽者做 reverse 的思維,從中偷師學習

另外無論是不是從事 security 行業,懂一些軟體的 reverse 對一般 RD 來說也很有幫助,尤其是遇到有些 compile level 形成的 bug 時,source code 看再多也找不出問題,但看 assembly 就一目了然了

0x04: CSAW CTF 2015 Rerversing 500 wyvern

今天要介紹的是 2015 年 CSAW CTF 出的一題 500 分 Reverse,是那場最難的 reverse 題,是 CTF reverse 題中很常見的註冊機題型,要求輸入 secret,會根據輸入結果印出 failed 或 success 的相關訊息,但這題公開解法之後,大家就都知道透過 side channel 的方式爆破 flag,之後的 reverse 題目就會特別注意是否能被直接爆破出 flag 了

題目執行起來長以下這樣:

+-----------------------+
| Welcome Hero |
+-----------------------+
[!] Quest: there is a dragon prowling the domain.
brute strength and magic is our only hope. Test your skill.
Enter the dragon's secret: ggwp
[-] You have failed. The dragon's power, speed and intelligence was greater.

程式是用 C++ 撰寫,在比對 flag 的地方有進行一些 bitwise 運算和混淆,即使透過 ida pro 將 assembly 轉回 pseudo code 也很難看懂程式邏輯,更別說反推 secret

if ( v7 )
  {
    if ( y26 >= 10 && (((_BYTE)x25 - 1) * (_BYTE)x25 & 1) != 0 )
      goto LABEL_14;
    while ( 1 )
    {
      *v9 = legend >> 2;
      if ( y26 < 10 || (((_BYTE)x25 - 1) * (_BYTE)x25 & 1) == 0 )
        break;
LABEL_14:
      *v9 = legend >> 2;
    }
  }
  else
  {
    if ( y26 >= 10 && (((_BYTE)x25 - 1) * (_BYTE)x25 & 1) != 0 )
      goto LABEL_15;
    while ( 1 )
    {
      v1 = v12;
      std::string::string(v8, v12);
      if ( y26 < 10 || (((_BYTE)x25 - 1) * (_BYTE)x25 & 1) == 0 )
        break;
LABEL_15:
      std::string::string(v8, v12);
    }
    v6 = sanitize_input(v8, v1);
    if ( y26 >= 10 && (((_BYTE)x25 - 1) * (_BYTE)x25 & 1) != 0 )
      goto LABEL_16;
    while ( 1 )
    {
      *v9 = v6;
      std::string::~string(v8);
      if ( y26 < 10 || (((_BYTE)x25 - 1) * (_BYTE)x25 & 1) == 0 )
        break;
LABEL_16:
      *v9 = v6;
      std::string::~string(v8);
    }
  }
  do
    v5 = *v9;
  while ( y26 >= 10 && (((_BYTE)x25 - 1) * (_BYTE)x25 & 1) != 0 );

但我們只需要想辦法知道 secert 是什麼就好,所以不用看懂整段邏輯也沒關係,我們只需要看懂兩件事:

  1. 這段檢查邏輯每次只會拿 input 的一個 byte 做檢查
  2. 檢查成功執行的 instruction 數量會比檢查失敗多

滿足以上兩個條件,我們就可以直接對程式進行 brute force 來猜 secert 是多少,每次 input 給不同的 char,再透過工具觀察這次程式執行了多少的 instruction,就可以知道這次給的 char 是不是和 secret 相同

  • 工具可以直接選用 Pintools,已經有現成的 inscount0.so 模組

具體步驟如下:

  1. 先知道失敗情況會執行多少個 instruction

    • base_cnt = run("echo '' | pin -t ./inscount0.so -- ./wyvern; cat ./inscount.out")
  2. 開始嘗試可能的字元,如果發現某次執行的的 instruction 比較多,就代表猜中 secert 的某個 char 了

     flag = ''
     for c in chars:
       _ = flag + c
     	cnt = run("echo '%s' | pin -t ./inscount0.so -- ./wyvern; cat ./inscount.out" % _)
       if cnt > base_cnt:
         flag += c
         base_cnt = cnt
    
  3. 重複以上行為,直到印出 success message,就代表猜中 secret 了

  4. 最後執行結果是:

+-----------------------+
| Welcome Hero |
+-----------------------+
[!] Quest: there is a dragon prowling the domain.
brute strength and magic is our only hope. Test your skill.
Enter the dragon's secret: dr4g0n_or_p4tric1an_it5_LLVM
success
[+] A great success! Here is a flag{dr4g0n_or_p4tric1an_it5_LLVM}


上一篇
Day4: [Pwn] Buffer Overflow (CWE-120)
下一篇
Day6: [Web] Path Traversal
系列文
CTF 的三十道陰影31

尚未有邦友留言

立即登入留言