Bearking's Stronghold will hack for food

Debug MBR/DOS bằng Bochs và IDA

2022-09-05
th3_5had0w

Lần đầu reverse mbr/dos image, setup debug với bochs và IDA

Challenge Grandad’s Magic

Vừa bắt đầu thì mình disassemble file với IDA như thường lệ, nhưng vì đây là lần đầu reverse bootloader, nên mình không nhận ra hàm sub_151 và sub_177 là các hàm check điều kiện của flag (khá n0n…)

P/s: file challenge mình sẽ gọi là “image”.

P/s 2: bài này focus vào vụ setup môi trường debug, còn những dạng bài này bạn nào muốn nhanh thì dùng các module như Pintool, Angr, Qiling,… hay những cái tương tự.

Dùng qemu để debug thì ta có được một màn hình chờ như thế này:

Sau khi dùng qemu để emulate image mà đề bài đưa ra thì mình đã thử debug bằng gdb, nhưng thất bại thảm hại :D

Không biết vì lý do gì nhưng debugger pass tất cả các breakpoint mà mình đã set, cho dù là sau khi BIOS đã load MBR vào địa chỉ 0x7c00, nói chung nhìn địa chỉ khá là loạn và cái lệnh jmp nhảy khắp nơi, khiến cho mình cũng không hiểu các instruction đang làm gì luôn 😢

Sau khi thực hiện một loạt instruction như trên, image nhảy thẳng vào prompt để chờ user nhập input, mình không thể debug được, đã thử vô số các cách khác nhau nhưng đều thất bại thảm hại.

Vì vậy mình mò đi tìm cách khác để debug (trong vô vọng)…

Sau gần 2 tiếng đồng hồ mở vô số tab trên chrome, lúc này mình vô tình thấy được một vài article và video cổ đại có liên quan đến debug emulated image và ida bochs file, thì mình đã quyết định thử kết hợp kiến thức từ những article này lại.

IDA có Bochs plugin có lợi thế là emulate được khá nhiều các dạng executable, image, disk và binary khác nhau.

Thay vì load trực tiếp image vào IDA, mình đã load image vào Bochs và chỉnh sửa lại config menu của Bochs.

Tab Floppy Options -> Type of floppy drive -> None

Tab Boot options -> Boot drive #1 -> disk

Tab ATA channel 0 -> First HD/CD on channel 0

Ở phần Path or physical device name bạn chọn Browse và sau đó chọn image cần debug.

Sau cùng là chỉnh các option Cylinders, Heads, Sectors per track như hình dưới

Sau đó export file config này ra ngoài, file config được export sẽ có extension là .bxrc

Sau cùng là load file config này vào IDA, IDA sẽ tự nhận diện được đây là file Bochs config, và chạy thử thì:

Đặt breakpoint ở đầu chương trình và step thì ta sẽ đến được phần hàm chính của chương trình:

debug002:E000 lea     si, aWelcomeToTheOf_0           ; "\t\t\tWelcome to the OFFZONE reverse ta"...
debug002:E004 call    near ptr unk_E126
debug002:E007 lea     si, aEnterPassword_0            ; "\t\t\tEnter password: "
debug002:E00B call    near ptr unk_E126
debug002:E00E mov     di, 1000h
debug002:E011 call    sub_E114
debug002:E014 mov     di, 1000h
debug002:E017 call    near ptr unk_E13A
debug002:E01A pop     cx
debug002:E01B cmp     cx, 9DE0h
debug002:E01F jnz     loc_E107
debug002:E023 pop     cx
debug002:E024 cmp     cx, 0B3D3h
debug002:E028 jnz     loc_E107
debug002:E02C pop     cx
debug002:E02D cmp     cx, 0CEA7h
debug002:E031 jnz     loc_E107
debug002:E035 pop     cx
debug002:E036 cmp     cx, 8FE2h
debug002:E03A jnz     loc_E107
debug002:E03E mov     di, 1000h
debug002:E041 call    near ptr unk_E160
debug002:E044 pop     cx
debug002:E045 cmp     cx, 30F0h
debug002:E049 jnz     loc_E107
debug002:E04D pop     cx
debug002:E04E cmp     cx, 2B74h
debug002:E052 jnz     loc_E107
debug002:E056 pop     cx
debug002:E057 cmp     cx, 171Ch
debug002:E05B jnz     loc_E107
debug002:E05F pop     cx
debug002:E060 cmp     cx, 31D8h
debug002:E064 jnz     loc_E107
debug002:E068 mov     al, byte_100F
debug002:E06B mov     bl, byte_100E
debug002:E06F cmp     al, bl
debug002:E071 jnz     loc_E107
debug002:E075 mov     al, byte_1001
debug002:E078 cmp     al, 30h ; '0'
debug002:E07A jnz     loc_E107
debug002:E07E mov     bl, byte_1006
debug002:E082 add     al, 3
debug002:E084 cmp     al, bl
debug002:E086 jnz     short loc_E107
debug002:E088 mov     al, byte_1004
debug002:E08B mov     bl, byte_1002
debug002:E08F cmp     al, bl
debug002:E091 jnz     short loc_E107
debug002:E093 mov     al, byte_1005
debug002:E096 dec     al
debug002:E098 mov     bl, byte_100A
debug002:E09C cmp     al, bl
debug002:E09E jnz     short loc_E107
debug002:E0A0 mov     al, byte_1009
debug002:E0A3 cmp     al, bl
debug002:E0A5 jz      short loc_E107
debug002:E0A7 mov     al, byte_100B
debug002:E0AA inc     al
debug002:E0AC mov     bl, byte_100C
debug002:E0B0 cmp     al, bl
debug002:E0B2 jnz     short loc_E107
debug002:E0B4 lea     si, unk_E1DA
debug002:E0B8 call    near ptr unk_E126
debug002:E0BB mov     ah, 2
debug002:E0BD mov     al, 1
debug002:E0BF mov     dl, 80h
debug002:E0C1 mov     dh, 5
debug002:E0C3 mov     ch, 9
debug002:E0C5 mov     cl, 1Eh
debug002:E0C7 lea     bx, unk_F000
debug002:E0CB int     13h                             ; DISK - READ SECTORS INTO MEMORY
debug002:E0CB                                         ; AL = number of sectors to read, CH = track, CL = sector
debug002:E0CB                                         ; DH = head, DL = drive, ES:BX -> buffer to fill
debug002:E0CB                                         ; Return: CF set on error, AH = status, AL = number of sectors read
debug002:E0CD xor     si, si
debug002:E0CF
debug002:E0CF loc_E0CF:                               ; CODE XREF: debug002:E0DB↓j
debug002:E0CF mov     al, [si+1000h]
debug002:E0D3 xor     [si-1000h], al
debug002:E0D7 inc     si
debug002:E0D8 cmp     si, 10h
debug002:E0DB jnz     short loc_E0CF
debug002:E0DD mov     ah, 3
debug002:E0DF mov     al, 1
debug002:E0E1 mov     dl, 80h
debug002:E0E3 mov     dh, 5
debug002:E0E5 mov     ch, 9
debug002:E0E7 mov     cl, 1Eh
debug002:E0E9 lea     bx, unk_F000
debug002:E0ED int     13h

Ở đây thì chương trình sau khi đọc password do ta nhập vào sẽ chạy một loạt các biểu thức toán học để kiểm tra, nếu input nhập vào thỏa mãn tất cả các điều kiện ta sẽ login được vào OS. Mình dùng z3 để giải các biểu thức này.

Sau khi nhập password thì ta vào được OS chính và…


Similar Posts

Previous post Writeup GoogleCTF 2022

Next post Compiler101 - 0x00

Comments