Simple Reverse - 0x01(Lab - Sacred Arts)

Simple Reverse - 0x01(Lab - Sacred Arts)

Background

  • X86組合語言/基本指令集
  • neg (Negate) instruction 實作:先在執行neg rax之前把$rax設定成2,執行指令之後剛好是2的補數
      gef➤  set $rax=2
      gef➤  info r $rax
      rax            0x2                 0x2
      gef➤  ni
      0x00000000004010e0 in ?? ()
      gef➤  info r $rax
      rax            0xfffffffffffffffe  0xfffffffffffffffe
    
  • X86組合語言/基本指令集/IA32指令:xchg 實作:執行xchg ah, al之前先看一下$rax的狀態
      gef➤  info r $rax
      rax            0xfffffffffffffffe  0xfffffffffffffffe
      gef➤  ni
      0x00000000004010e2 in ?? ()
      gef➤  info r $rax
      rax            0xfffffffffffffeff  0xfffffffffffffeff
    

Source Code

:::spoiler IDA Pro Disassembler Code

                        start:                                  ; DATA XREF: LOAD:0000000000400018↑o
                                                                ; LOAD:0000000000400088↑o
48 C7 C0 02 00 00 00                    mov     rax, 2
48 C7 C7 1C 10 40 00                    mov     rdi, offset aTmpFlag ; "/tmp/flag"
48 C7 C6 00 00 00 00                    mov     rsi, 0
0F 05                                   syscall                 ; LINUX - sys_open
49 89 C7                                mov     r15, rax
EB 0A                                   jmp     short loc_401026
                        ; ---------------------------------------------------------------------------
2F 74 6D 70 2F 66 6C 61+aTmpFlag        db '/tmp/flag',0        ; DATA XREF: .text:0000000000401007↑o
                        ; ---------------------------------------------------------------------------
                        loc_401026:                             ; CODE XREF: .text:000000000040101A↑j
48 83 F8 00                             cmp     rax, 0
7E 09                                   jle     short loc_401035
EB 41                                   jmp     short loc_40106F
                        ; ---------------------------------------------------------------------------
77 72 6F 6E 67 0A 00    aWrong          db 'wrong',0Ah,0        ; DATA XREF: .text:0000000000401043↓o
                        ; ---------------------------------------------------------------------------
                        loc_401035:                             ; CODE XREF: .text:000000000040102A↑j
                                                                ; .text:00000000004010E6↓j
48 C7 C0 01 00 00 00                    mov     rax, 1
48 C7 C7 01 00 00 00                    mov     rdi, 1
48 C7 C6 2E 10 40 00                    mov     rsi, offset aWrong ; "wrong\n"
48 BA 07 00 00 00 00 00+                mov     rdx, 7
0F 05                                   syscall                 ; LINUX - sys_write
                        loc_401056:                             ; CODE XREF: .text:000000000040111E↓j
48 C7 C0 3C 00 00 00                    mov     rax, 3Ch
48 C7 C7 00 00 00 00                    mov     rdi, 0
0F 05                                   syscall                 ; LINUX - sys_exit
                        loc_401066:                             ; DATA XREF: .text:000000000040110B↓o
63 6F 72                                movsxd  ebp, dword ptr [rdi+72h]
72 65                                   jb      short near ptr loc_4010CA+6
63 74 0A 00                             movsxd  esi, dword ptr [rdx+rcx+0]
                        loc_40106F:                             ; CODE XREF: .text:000000000040102C↑j
48 83 EC 40                             sub     rsp, 40h
48 C7 C0 00 00 00 00                    mov     rax, 0
4C 89 FF                                mov     rdi, r15
48 89 E6                                mov     rsi, rsp
48 C7 C2 32 00 00 00                    mov     rdx, 32h
0F 05                                   syscall                 ; LINUX - sys_read
EB 38                                   jmp     short loc_4010C3
                        ; ---------------------------------------------------------------------------
B3 BA BE B8 84          byte_40108B     db 0B3h, 0BAh, 0BEh, 0B8h, 84h
                                                                ; DATA XREF: .text:loc_4010CA↓o
99 90 8D 92 8B D1 98 9E+                dq 9E98D18B928D9099h, 0D19290D29C8D9A92h, 8F978FBDD1D0888Bh
92 9A 8D 9C D2 90 92 D1+                dq 0CCCDCB92C28C9DC0h, 0CEC2BE8D91D9C7C7h, 0FFFFFFCF82C8CFC7h
FF FF FF                                db 3 dup(0FFh)
                        ; ---------------------------------------------------------------------------
                        loc_4010C3:                             ; CODE XREF: .text:0000000000401089↑j
48 C7 C1 07 00 00 00                    mov     rcx, 7
                        loc_4010CA:                             ; CODE XREF: .text:0000000000401069↑j
48 C7 C3 8B 10 40 00                    mov     rbx, offset byte_40108B
                        loc_4010D1:                             ; CODE XREF: .text:00000000004010EC↓j
48 8D 14 CD F8 FF FF FF                 lea     rdx, ds:0FFFFFFFFFFFFFFF8h[rcx*8]
48 8B 04 14                             mov     rax, [rsp+rdx]
48 F7 D8                                neg     rax
86 C4                                   xchg    al, ah
48 3B 04 13                             cmp     rax, [rbx+rdx]
0F 85 49 FF FF FF                       jnz     loc_401035
E2 E3                                   loop    loc_4010D1
EB 0D                                   jmp     short loc_4010FD
                        ; ---------------------------------------------------------------------------
68 65 6C 6C 6F 20 77 6F+aHelloWorld     db 'hello world',0Ah,0
                        ; ---------------------------------------------------------------------------
                        loc_4010FD:                             ; CODE XREF: .text:00000000004010EE↑j
48 C7 C0 01 00 00 00                    mov     rax, 1
48 C7 C7 01 00 00 00                    mov     rdi, 1
48 C7 C6 66 10 40 00                    mov     rsi, offset loc_401066
48 BA 09 00 00 00 00 00+                mov     rdx, 9
0F 05                                   syscall                 ; LINUX - sys_write
E9 33 FF FF FF                          jmp     loc_401056
                        _text           ends
                                        end start

:::

Recon

這一題就只是單純的用工人智慧看組語,我的想法是先看一下system call,他先把/tmp/flag打開[^system_call_大全]1,如果有找到該檔案就會通過cmp然後跳到loc_40106F,並且讀取裡面的內容,然後loc_4010C3就看不懂了,==這時候就直接用gdb跟一下流程==,就會發現其實IDA的翻譯是有問題的,因為後面有一個cmp rax, QWORD PTR [rbx+rdx*1],所以就稍微看一下內容是甚麼,

1
2
3
4
$rax   : 0x0
$rbx   : 0x000000000040108b  →   mov bl, 0xba
$rcx   : 0x7
$rdx   : 0x30

這不就是byte_40108B的所在位置嗎,而實際的rbx+rdx*1存的內容如下

1
2
gef➤  x/g $rbx+$rdx*1
0x4010bb:       0xffffffffffffcf82

我們必須修正IDA的錯誤翻譯,可以善用d快捷鍵然後把每一個data長度變成dq,正確翻譯如下

1
2
3
4
5
6
7
qword_40108B    dq 8D909984B8BEBAB3h    ; DATA XREF: .text:loc_4010CA↓o
                dq 8D9A929E98D18B92h
                dq 0D0888BD19290D29Ch
                dq 8C9DC08F978FBDD1h
                dq 0D9C7C7CCCDCB92C2h
                dq 0C8CFC7CEC2BE8D91h
                dq 0FFFFFFFFFFFFCF82h

所以整體流程應該就蠻清楚了,這支程式就是先讀取/tmp/flag的資料然後從後面讀取8個bytes後==做了一些操作==和qword_40108B的每一個dq做比較,如果比較的結果不符合就會跳到loc_401035(print出wrong後直接exit(0)),如果每一個dq都是正確的就會到下面的loc_4010FD然後print出一些東西,所以很明顯的是那些==操作==到底做了甚麼事情,如果跟一下gdb就會發現只是

  1. 把數值變成負數
  2. 交換ah和al暫存器

Exploit

  1. 先把ah和al的數值交換
  2. 取補數 ```python= fake_flag = [“8D909984B8BEBAB3”, “8D9A929E98D18B92”, “D0888BD19290D29C”, “8C9DC08F978FBDD1”, “D9C7C7CCCDCB92C2”, “C8CFC7CEC2BE8D91”, “FFFFFFFFFFFFCF82”] BIG_NUM = 1«64 FLAG = [] for i in fake_flag: tmp = i[:12] + i[14:16] + i[12:14] print(tmp) tmp = BIG_NUM - int(tmp, 16) FLAG.append(bytes.fromhex(hex(tmp)[2:]).decode(‘utf-8’)[::-1])

print(““.join(FLAG)) ```

Reference

  1. 如果要打開的檔案存在則$rax的數值就會是一個大於零的數值,反之就會是小於零