Tuesday, May 6, 2014

0x3004 RE150 write up

Đầu tiên chúng ta đổi tên file btc cho 150-ulock.ex_ thành 150-ulock.exe và load vào Olly. Run thử thấy xuất hiện 1 form Keygen có 3 editbox, editbox1 : là unlock code và 2 editbox sau là Name và Serial đang bị disable. Nhưng tạm thời ta chưa điền được gì vào đó cả. Gõ thử unlock code = 1 và bấm unlock. Hiện lên thông báo sai Unlock code: 'You have entered an invalid Unlock,...'. Tìm thấy 2 đoạn có dòng text này trong olly ở địa chỉ 004010C5, 00401317. Follow dòng 1 tới địa đoạn :
004010BE   > \6A 30         push    30                               ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
004010C0   .  68 A5324000   push    150-uloc.004032A5                ; |Title = "-=[ Unlock Code Error"
004010C5   .  68 BB324000   push    150-uloc.004032BB                ; |Text = "You have entered an invalid Unlock Code.
Please try again."
Đoạn nhảy tới đoạn này nằm ở địa chỉ
0040109D   . /76 1F         jbe     short 150-uloc.004010BE
Ngay trước đó có một lệnh so sánh :
00401086   .  6A 11         push    11                               ; /Count = 11 (17.)
00401088   .  68 08334000   push    150-uloc.00403308                ; |Buffer = 150-uloc.00403308
0040108D   .  68 F1030000   push    3F1                              ; |ControlID = 3F1 (1009.)
00401092   .  FF75 08       push    dword ptr ss:[ebp+8]             ; |hWnd
00401095   .  E8 38030000   call        ; \GetDlgItemTextA
0040109A   .  83F8 07       cmp     eax, 7
Đoạn này có nghĩa là sẽ so sánh chiều dài của unlock code với 7, nếu nhỏ hơn thì nhảy tới đoạn thông báo sai unlock, nếu lớn hơn thì sẽ tiếp tục tính toán. Ok đặt 1 breakpoint ở địa chỉ 0040109D( chỗ lệnh nhảy) , nhập 1 đoạn unlock code = '11111111' ( 8 ký tự 1) vào bấm unlock. Trace tiếp:
0040109F   .  E8 29020000   call    150-uloc.004012CD
Mình không tính toán kỹ đoạn này nhưng mục đích cuối cùng của nó là từ chuỗi nhập vào sau một hồi thì sẽ lưu 1 byte vào địa chỉ ds:[403318]
004012EC  |.  0005 18334000 add     byte ptr ds:[403318], al
Với chuỗi 8 ký tự 1 như trên thì byte 41 sẽ được lưu vào ds:[403318] Trace tới hàm tiếp theo :
004010A7   .  E8 4B020000   call    150-uloc.004012F7                ; \150-uloc.004012F7
Hàm này kiểm tra xem đoạn unlock code có chiều dài > 1 không. Nếu nhỏ hơn thì lại in ra đoạn sai unlock code, nếu đúng :
00401334  |> /8A1418        /mov     dl, byte ptr ds:[eax+ebx]
00401337     |3215 18334000 xor     dl, byte ptr ds:[403318]
0040133D  |. |881418        |mov     byte ptr ds:[eax+ebx], dl
00401340  |. |43            |inc     ebx
00401341  |. |49            |dec     ecx
00401342  |.^\75 F0         \jnz     short 150-uloc.00401334
Nó sẽ xor 7B byte bắt đầu từ :ds:[004011C1], với byte lúc nãy tính được( đang lưu tại ds:[403318]) và lưu lại vào chính nó dẫn tới opcode của chương trình bắt đầu từ ds:[004011C1] bị thay đổi. Tiếp theo nó sẽ enable 2 editbox name và serial:
004010AF   .  E8 94020000   call    150-uloc.00401348                ; \150-uloc.00401348
Btc đã hint ta cần phải tìm serial cho user : 0x3004 Nội dung ở bên dưới cũng không có gì quá đặc biệt, chỉ duy nhất tại địa chỉ :
00401135   .  E8 AE000000   call    150-uloc.004011E8
Gọi tới đoạn đã bị thay đổi Và 2 đoạn :
00401291   > /8A98 29334000 mov     bl, byte ptr ds:[eax+403329]
00401297   . |3898 3A334000 cmp     byte ptr ds:[eax+40333A], bl
ds:[eax+403329] : -> đại chỉ chuỗi serial ds:[eax+40333A] : -> một địa chỉ lạ. Ta có thể đoán ra địa chỉ 004011E8: sẽ làm gì đó sau đó lưu lại các byte vào địa chỉ ds:[eax+40333A] Đến đây chúng ta bắt buộc phải tính toán lại đoạn bắt đầu từ : 004011E8 Ban đầu phương pháp của mình là brute force từ 1 -> 255 điền vào ds:[403318] vì nghĩ có thể tại địa chỉ 004011E8 có thể không phải là 1 function, cách này cũng ra tuy hơi trâu bò tí :D. Nếu biết đoạn bắt đầu từ 004011E8 là 1 func ta có thể đoán ra đoạn opcode đầu tiên sẽ là :
55            push    ebp
-> byte đã được điền vào ds:[403318] = 55 xor ds:[004011C1] ( =70) -> ds:[403318] = 0x25 Điền lại unlock code > 8 ký tự, Xóa hết breakpoint và đặt lại 2 breakpoint tại
004010A7   .  E8 4B020000   call    150-uloc.004012F7                ; \150-uloc.004012F7
00401297   . |3898 3A334000 cmp     byte ptr ds:[eax+40333A], bl
Trace đến 004010A7 sau đó set lại giá trị tại ô nhớ ds:[403318] = 0x25, điền username=0x3004 Trace đến: 00401297 và dump giá trị từ 40333A -> 40333F, đây chính là flag cần tìm :
21137D5FCAAC07F9