over 4 years ago

用bochs把OS image跑起來,看到需要輸入Access Code

從MBR code可以看到它將img第二個sector載入5120 bytes到0x8000,並將前2048 bytes跟四位Access Code循環xor解碼
最後跳到0x8000執行

seg000:0000                 jmp     short loc_A
seg000:0000 ; ---------------------------------------------------------------------------
seg000:0002                 db  42h ; B
seg000:0003                 db  43h ; C
seg000:0004                 db  54h ; T
seg000:0005                 db  46h ; F
seg000:0006                 db  4Fh ; O
seg000:0007                 db  53h ; S
seg000:0008                 db  4Ch ; L
seg000:0009                 db  44h ; D
seg000:000A ; ---------------------------------------------------------------------------
seg000:000A
seg000:000A loc_A:                                  ; CODE XREF: seg000:0000j
seg000:000A                 cli
seg000:000B                 mov     ax, cs
seg000:000D                 mov     ds, ax
seg000:000F                 mov     es, ax
seg000:0011                 mov     ss, ax
seg000:0013                 mov     sp, 0FFFFh
seg000:0016                 sti
seg000:0017                 mov     ax, 0Ch
seg000:001A                 push    ax
seg000:001B                 lea     ax, unk_7D34
seg000:001F                 push    ax
seg000:0020                 call    sub_62
seg000:0023                 mov     ax, 800h
seg000:0026                 mov     es, ax
seg000:0028                 assume es:nothing
seg000:0028                 xor     bx, bx
seg000:002A                 xor     cx, cx
seg000:002C                 mov     cl, 2
seg000:002E                 xor     dx, dx
seg000:0030                 mov     dl, 80h ; 'Ç'
seg000:0032                 mov     ax, 20Ah
seg000:0035                 int     13h             ; DISK - READ SECTORS INTO MEMORY
seg000:0035                                         ; AL = number of sectors to read, CH = track, CL = sector
seg000:0035                                         ; DH = head, DL = drive, ES:BX -> buffer to fill
seg000:0035                                         ; Return: CF set on error, AH = status, AL = number of sectors read
seg000:0037                 call    sub_A0          ; 讀取Access Code,xor解碼
seg000:003A                 mov     ax, 800h
seg000:003D                 push    ax
seg000:003E                 xor     ax, ax
seg000:0040
seg000:0040 loc_40:                                 ; DATA XREF: sub_62+19r
seg000:0040                                         ; sub_62+29r
seg000:0040                 push    ax
seg000:0041                 retf                    ; 跳轉到0x8000
seg000:0042

取出第二個sector data後,先猜測裡面有不少連續為0的區段,試著找出最常出現的重複4bytes區段。結果最常出現的區段,重複次數只有5次,用此段xor下去後還是亂碼。但是發現亂碼第一條指令向下跳轉0xA,然後這10bytes區間內有TF字樣,因此猜測這段開頭跟MBR開頭相同,有"BCTFOS"。測試後發現是正確的,Access Code剛好為"1337"

進入系統後,發現裡面實作了簡單的檔案系統,從code可以看到檔案被每26bytes切開儲存,儲存位置根據一連串的計算會亂跳。
檔案的metadata包含檔案儲存時的加密key和第一個檔案片段偏移位置,最後接上xor 0xcc後的檔名

<bochs:10> x/32bx 0xA000
[bochs]:
0x000000000000a000 <bogus+       0>:    0x01    0x00    0x06    0x00   [0x48    0xfe]   0x01    0x0f
                                                                        加密key   
0x000000000000a008 <bogus+       8>:   [0x0b]   0x0f    0xad   [0xad    0xad    0xad    0xad    0xad]
                                        第一段位置               檔名"aaaaaa"
0x000000000000a010 <bogus+      16>:    0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x000000000000a018 <bogus+      24>:    0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
<bochs:11>

第一個檔案片段

<bochs:11> x/32bx 0xB160
[bochs]:
0x000000000000b160 <bogus+       0>:    0x01    0x00    0xff    0xff    0xff    0xff   [0x29    0x9e
                                                                                        檔案內容
0x000000000000b168 <bogus+       8>:    0x2b    0x9c    0x2d    0x9a]   0x00    0x00    0x00    0x00
0x000000000000b170 <bogus+      16>:    0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x000000000000b178 <bogus+      24>:    0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00

檔案加密方式是: 檔案byte xor 檔案offset xor (照offset奇偶輪流取key[0], key[1])
最後發現OS image中後面眾多0裡面有6個檔案片段與一個檔名為"key"的metadata,解密後得到

Dear CTFer, if you see this message, you have completely understood my OS. Congratulations!Here is what you want: BCTF{6e4636cd8bcfa93213c83f4b8314ef00}

解密code

b1 = [0x16, 0x36, 0x31, 0x23, 0x76, 0x14, 0x00, 0x13, 0x3F, 0x29, 0x74, 0x79, 0x37, 0x39, 0x7C, 0x24,
            0x2D, 0x36, 0x60, 0x32, 0x23, 0x22, 0x64, 0x31, 0x22, 0x22]
b2 = [0x4E, 0x1B, 0x41, 0x56, 0x4B, 0x1F, 0x4B, 0x5C, 0x4C, 0x57, 0x1A, 0x01, 0x64, 0x64, 0x70, 0x63,
            0x51, 0x1D, 0x4D, 0x1D, 0x18, 0x1C, 0x1A, 0x4E, 0xB6, 0xEB]
b3 = [0x3B, 0x69, 0x23, 0x2A, 0x3F, 0x3E, 0x13, 0x14, 0x15, 0x5D, 0x56, 0x0E, 0x1B, 0x00, 0x5A, 0x13,
            0x19, 0x0F, 0x1B, 0x5F, 0x1F, 0x12, 0x0F, 0x13, 0x0C, 0x04]
b4 = [0x12, 0x02, 0x08, 0x1C, 0x4A, 0x1E, 0x06, 0x0D, 0x0B, 0x1D, 0x1F, 0x19, 0x7D, 0x7C, 0x74, 0x31,
            0x7B, 0x6E, 0x34, 0x5A, 0x49, 0x35, 0x38, 0x5A, 0x71, 0x71]
b5 = [0x7B, 0x6F, 0x63, 0x77, 0x75, 0x6D, 0x67, 0x73, 0x6D, 0x6A, 0x64, 0x78, 0x29, 0x0A, 0x0D, 0x47,
            0x69, 0x7F, 0x57, 0x13, 0x59, 0x42, 0x16, 0x40, 0x5C, 0x54]
bx = [0xB2, 0xB2, 0xB0, 0xB6, 0xED, 0xE6, 0xE8, 0xEA, 0xEB, 0xBA, 0xE6, 0xEC, 0xBA, 0xE9, 0xA0, 0xFB,
            0xF3, 0xF0, 0xF2, 0xA2, 0xA2, 0xF5, 0xFA, 0xB6, 0x00, 0x00]

i = 0x52
j = 0x52

s = ''

l = b1 + b3 + b4 + b5 + b2 + bx

for k in range(len(l)):
    if k % 2:
        s += chr(l[k] ^ j ^ k)

    else:
        s += chr(l[k] ^ i ^ k)

print(s)
← BCTF 真假難辨 Writeup BCTF 混沌密码锁 Writeup →