<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    ar_u_ok

    主要考察對ptrace的認識和rc6,rc4的識別

    加密解密

    真正的加密和解密過程很簡單,就是一個標準的rc6,只要把函數中的那個int常量放到google里搜索一下就知道是rc6加密(這個函數的代碼被rc4加密了,不不解密是看不到的)。

    rc6加密和解密的代碼見源碼

    程序流程

    程序首先判斷啟動參數,如果argc為1,則以debugger身份啟動,利用fork分出parent和child。parent作為真正的debugger,child利用execve來啟動自身并以父進程的pid作為啟動參數。

    如果argc為2,說明是debuggee。程序利用puts打印plz_input_flag,但是write的syscall被ptrace hook了。puts的原始內容是亂碼,需要debugger對其進行解密。

    然后是利用scanf來接收flag。默認是允許輸入%48s但是這里ptrace hook了read syscall,檢測read syscall觸發的次數(在程序開頭利用setbuf將stdin和stdout的緩沖調整為0),從而使flag的真實最大長度為32。

    接著是一段判斷是否調試者為父進程的代碼,沒問題的話會調用fclose來關閉之前打開的文件。此處用ptrace hook了close syscall。但是在程序運行前也會調用close syscall。這里利用設置變量的方式,使得在第二次close的時候觸發。

    觸發時執行的代碼是利用rc4將兩個函數解密,然后patch代碼為0xcc使程序停在檢測trace代碼的下一行,在將其patch成jmp到data段的那段唯一可視的雷軍ascii字符處,并將flag傳遞給rdx,接著繼續執行。雷軍那段ascii其實是代碼。前面的52Mi!xor eax, 0x21694d32,從而使后面的jne全部成立,R_push rdx;pop rdi,從而將之前在rdx中的flag傳遞到rdi中。利用u_這個jne跳轉跳過中間的非代碼區,最后jmp到encrypt函數中。

    encrypt函數就是調用rc6加密,將32位的flag分16位兩次加密,最后和enc結果比較。

    由于調用了很多的ptrace來實現smc和hook,純動態分析應該不太可能實現,需要靜態分析后patch程序才能使用動態分析。

    完整程序見github,由于有smc部分,可能在不同機子上編譯結果不正確,所以提供了一個測試用的binary。

    本文章首發在 網安wangan.com 網站上。

    上一篇 下一篇
    討論數量: 0
    只看當前版本


    暫無話題~
    亚洲 欧美 自拍 唯美 另类