Thứ Bảy, 26 tháng 9, 2015

[Writeup] RE200 - CSAW CTF 2015

Hacking Time

200

180 solves
We're getting a transmission from someone in the past, find out what he wants.
HackingTime_03e852ace386388eb88c39a02f88c773.nes
Mặc dù RE không phải sở trường của mình nhưng thôi kệ. Thấy hay hay cũng bay vào chiến.

lehuyhoang@lehuyhoang-X550LD:~/ctf/2015/csaw/re/re200$ file HackingTime_03e852ace386388eb88c39a02f88c773.nes
HackingTime_03e852ace386388eb88c39a02f88c773.nes: iNES ROM dump, 2x16k PRG, 1x8k CHR, [Vert.]

Google thì nó là Nintendo Entertainment System (NES) ROM. Nhớ về tuổi thơ ngày xưa chơi Contra, Mario với chơi Tank 1999 với papa cả đêm.

Đầu tiên là dùng giả lập fcuex trên ubuntu load room vào test.
Cứ ấn F để qua thôi :D Mấy cái tào lao lừa tình bỏ qua hết.
Tới 1 chỗ nó yêu cầu nhập password

Lấy password ở đâu trong khi password nó tới 24 kí tự thì không đoán được rồi.
Chắc phải debug thôi.
Google nes debugger nó ra cho mình cái No$NES Debugger
http://www.romhacking.net/utilities/807/
Down về giải nén nó ra NO$NES.EXE.
Dùng Wine chạy EXE hoặc qua Windows chạy thôi :D

Giao diện của No$Nes debugger
Tiếp theo ta load room vào:
File -> Floppy Menu (filename) -> tìm file .nes open thôi :D
Thay vì F như fceux thì ta ấn space để next.
Nhập thử password: ABCDEFGHIJK rồi space
Sau đó qua Debugger ta thấy như sau:
Khó nhìn quá nên mình chuyển qua Windows chạy cho dễ nhìn.


Ta thấy password của ta nhập vô nó nằm ở địa chỉ 0005 trong WRAM.
OK vào code tìm chỗ nào liên quan 0005 đặt breakpoint thôi.

Tìm được vài chỗ có [0005+y] ta đặt breakpoint bằng cách F2 hết những chỗ đó.
Sau đó qua bên chương trình chính space phát nữa để thử lại password ABCDEFGHIJK.
Ta thấy chương trình dừng lại do dính breakpoint ở địa chỉ: ROMO:82F7
Ta f7 trace coi các giá trị password của ta thay đổi và được kiểm tra như nào thôi.
Sau khi qua từa lưa bước thuật toán thay đổi giá trị thì kết quả sau đó của ta được lưu tại địa chỉ [001E]
Sau khi kiểm tra toàn bộ 24 (0x18) kí tự của password thì tới đoạn kiểm tra các giá trị tại địa chỉ [001E+0] tới [001E+24], nếu khác 0 thì sẽ văng ra và báo Access denied.
Mình có làm trick thử là thay đổi instruction từ JNZ thành JZ thì nó cho mình bypass password mặc dù password sai. Nhưng đoạn sau nó báo password chính là Flag luôn nên đành phải tìm hiểu thuật toán coi password là gì.

Qua quá trình debug và coi asm thì mình thấy mỗi kí tự của password sẽ RCL 3 lần, giá trị tại địa chỉ [3B] sẽ được RCR 2 lần. Sau đó ADC giá trị của kí tự password với giá trị tại [3B]. Sau đó xor kí tự của password đó với giá trị tại địa chỉ [955E+y] (với y là thứ tự của kí tự trong password), rồi lưu kết quả tại [3B]. Sau đó giá trị đó lại tiếp tục RCL 3 lần nữa rồi xor với giá trị tại [9576+y]
Nếu kết quả = 0 thì sẽ không bị thoát và báo access denied.
Vậy ta coi giá trị tại [955E] và [9575] sau đó coi thôi :D

Code:
http://pastebin.com/VHryXF8L
Trong quá trình debug mình bị hoa mắt nên debug chạy đi chạy lại thấy lạ vì add with carry mà 0xa4 + 0xe4 ra lại ra 0x2e. Thử đi thử lại rồi thử binary nó ra cộng thủ công bit cũng không thể nào ra được như thế. Hóa ra mình nhìn lộn 0x4a thành 0xa4 nên thế :'(
Thế là code cho nhanh để làm bài khác luôn vì vậy code chưa được đẹp và chuẩn cho lắm.

Không có nhận xét nào:

Đăng nhận xét