---
# System prepended metadata

title: Simple Reverse - 0x01(Lab - Sacred Arts)
tags: [Reverse, eductf, CTF]

---

# Simple Reverse - 0x01(Lab - Sacred Arts)

## Background
* [X86組合語言/基本指令集](https://zh.wikibooks.org/wiki/X86%E7%B5%84%E5%90%88%E8%AA%9E%E8%A8%80/%E5%9F%BA%E6%9C%AC%E6%8C%87%E4%BB%A4%E9%9B%86)
* [neg (Negate) instruction](https://www.ibm.com/docs/en/aix/7.1?topic=set-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](https://zh.wikibooks.org/zh/X86%E7%B5%84%E5%90%88%E8%AA%9E%E8%A8%80/%E5%9F%BA%E6%9C%AC%E6%8C%87%E4%BB%A4%E9%9B%86/IA32%E6%8C%87%E4%BB%A4: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_大全][^note1]，如果有找到該檔案就會通過cmp然後跳到loc_40106F，並且讀取裡面的內容，然後loc_4010C3就看不懂了，==這時候就直接用gdb跟一下流程==，就會發現其實IDA的翻譯是有問題的，因為後面有一個`cmp rax, QWORD PTR [rbx+rdx*1]`，所以就稍微看一下內容是甚麼，
```
$rax   : 0x0
$rbx   : 0x000000000040108b  →   mov bl, 0xba
$rcx   : 0x7
$rdx   : 0x30
```
這不就是byte_40108B的所在位置嗎，而實際的`rbx+rdx*1`存的內容如下
```
gef➤  x/g $rbx+$rdx*1
0x4010bb:       0xffffffffffffcf82
```
我們必須修正IDA的錯誤翻譯，可以善用d快捷鍵然後把每一個data長度變成dq，正確翻譯如下
```
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出一些東西，所以很明顯的是那些<b>==操作==</b>到底做了甚麼事情，如果跟一下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
[^system_call_大全]:[Linux System Call Table for x86 64](https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/)
[^note1]:如果要打開的檔案存在則$rax的數值就會是一個大於零的數值，反之就會是小於零
