Pwnable Là Gì
Bạn đang xem: Pwnable là gì
Target : Tokyo Western CTF 2019 Chall : nothing more to say
File here
Description: Japan is fucking hot.
nc nothing.chal.ctf.westerns.tokyo 10001
Bạn đang xem: Pwnable là gì

ta dùng lệnh $ file để kiểm tra
File này cho ta biết nó là file executable chạy 64bit, với liên kết động (libc) và không stripped (nghĩa là tên hàm tên biến không bị giản lược)
ta sẽ run file để xem file làm gì
Xem thêm: Số Model Điện Thoại Là Gì, Ý Nghĩa Tác Dụng Của Số Imei, Số Model Iphone Là Gì

Ở đây nó in ra description và hint rồi cho chúng ta nhập, giả sử ở đây mình nhập là “input” thì nó trả về kết quả là “input” rồi out chương trình. Giờ mình sẽ debug xem thử nó làm gì.Mình sẽ sử dụng IDA để xem

Xem thêm: 3Q Ta Là Vua Tam Quốc Ta Là Vua, Ta Là Vua Tam Quốc Hd Cho Android

Ở phần description họ bảo không có SSP, không NX, không PIESSP là cơ chế chống stack overflow, NX (Non-eXecutable) sẽ không có quyền execute trong stack, PIE sẽ random địa chỉ vùng code để ta khó exploit hơn.Rất may là nó tắt hết cảbài này cho ta nhập vào từ bàn phím với hàm gets(&format). Theo như tìm hiểu về hàm ta thấy hàm này có lỗ hổng có thể dẫn đến tràn bộ đệmCụ thể là hàm không check maximum size nên ta có thể thoải mái với số kí tự nhập vàoMục tiêu là ta sẽ get shell đúng ý với description mà BTC đưa ra. Thông thường đa số các chall đều cần phải get shell để lấy được flag.Trước tiên ta cần test trên local trước, ta sẽ cần dùng đến gdb.Chương trình sẽ dừng tại hàm gets. Lúc này ta có thể kiểm tra được các tham số của hàm trước khi gọi hàm.Ở đây ta thấy chương trình chạy 64bit nên các tham số sẽ nằm ở trên các thanh ghi theo thứ tự: RDI, RSI, RDX, RCX, R8, R9, stackTa biết hàm gets(&format) nhận 1 tham số cho nên tham số sẽ nằm trên thanh ghi RDI tại địa chỉ 0x7ffffffffe320Ta có thể dùng lệnh “telescope ” để check layout của stack và vì buffer ta nhập nằm trên stack nên ta sẽ lợi dụng điều này để khai thác lỗ hổng trên stackTa thấy địa chỉ trả về của hàm main sẽ nằm sau địa chỉ của thanh ghi RBP. Suy ra tại vị trí RBP+8 = return addressSau khi hàm main thực thi xong sẽ quay về hàm đã gọi nó (__libc_start_main) thế nên nếu ta ghi đè lên địa chỉ trả về thì ta có thể redirect luồng thực thi sang hướng khác mà ta muốn mà cụ thể ở đây là get shellVì NX disable cho nên ta có thể thực thi shellcode ngay trong stack. Shellcode là một đoạn code asm dùng để get shell hoặc làm những việc khác tùy mình muốn.Okay hướng giải quyết sẽ như sau: ta sẽ nhập input sao cho kí tự ta nhập vào tràn qua khỏi bộ đệm và tràn đến return address, thay địa chỉ ret thành địa chỉ shellcode trong stack. Để làm được điều này ta cần phải tìm gadget để ghi địa chỉ shellcode vào retVì shellcode nằm tron stack mà stack thì luôn random (ASLR) nên ta cần phải dùng gadget.Theo như ta thấy thì không có gadget nào để đưa địa chỉ shellcode vào stack cả nên ta sẽ tìm cách khác. Nếu ta để ý một chút ta sẽ thấy một vùng nhớ được load cùng binary và cố định, và có cả execute đó là vùng .bssVậy ta sẽ giải theo hướng khác đó là ghi đè ret thành gets để nhập thêm lần nữa, ta sẽ nhập shellcode vào vùng đó rồi ret về nơi ta nhập shellcode thì sẽ thực thi được shellcode.Ta thấy ở đoạn “lea rax, ; mov rdi, rax” nghĩa là đưa địa chỉ stack cách rbp khoảng là 0x100 vào rax và đưa vào rdi. Suy ra offset giữa rbp và buffer là 0x100 hay nói cách khác rbp-0x100 = buff -> buff + 0x100 = rbpmà ret nằm dưới rbp với rbp + 0x8 = ret nên buff + 0x108 = retSuy ra offset là 0x108Để đưa địa chỉ vùng .bss nơi mà ta nhập shellcode vào thanh ghi rdi thì ta cần gadget “pop rdi; ret”Lấp đầy buffer tràn đến ret rồi sau đó đưa shellcode address lên rdi làm tham số và ret về gets lần nữa để nhập shellcode vào (shellcode có thể lấy ở trên web shell-storm.org)sau đó ret về shellcode để thực thi.Ta có thể attach file để test như sau:
Đầu tiên mở thêm 1 tab để run file .py, ta sửa lại một chút như sau:
Thêm 2 dòng context.log_level=’debug’ để giúp ta debug đẹp hơn
và pause() sẽ làm chương trình dừng lại đợi ta attach vào
Sau đó đặt breakpoint trong gdb, ví dụ đặt breakpoint tại ret, Tiếp theo run file .py lên
attach xong ta gõ lệnh “continue” để chương trình tiếp tục, sau đó sang file .py ta nhấn phím bất kì để chương trình chạy tiếp