showmewhatyougot - ImaginaryCTF 2022
(Chall này mình lấy lại của 1 anh trên youtube để viết)
Last updated
(Chall này mình lấy lại của 1 anh trên youtube để viết)
Last updated
Tức là khi trỏ tới dev/null
thì flag đọc được sẽ không hiện ra màn hình... Vì vậy việc ret2win là bất khả thi. Vậy chỉ còn dựa vào các ROPgadget để đọc được nó.
Ở đây, mình sẽ RCE nó để đọc flag chứ không đọc qua script (bởi ví tôi thấy có hàm system trong binary nên tôi sẽ tận dụng nó luôn).
Ngay sau format string ta chỉ có duy nhất 1 lệnh call đó là call
0x401090
puts@plt
.
Bởi vậy tôi sẽ overwrite luôn địa chỉ của puts@plt. Và điều chú ý hơn đó là địa chỉ got của puts địa chỉ mà bạn thấy trên ảnh chỉ là địa chỉ plt của nó. Không có nghĩa lý gì khi bạn ghi đè lên đó.
Đây là địa chỉ got (got entry) của puts trước khi puts được thực thi. Khi puts được chạy thì đây là địa chỉ trong libc của nó.
Việc của mình bây giờ sẽ làm tìm cách thay đổi địa chỉ này thành địa chỉ của các ROPgadget để win.
Đó là sử dụng arbitrary write của format string. Cụ thể là tôi sẽ ghi địa chỉ của gadget pop rdi; ret vào puts@got
.
Script sẽ như sau:
Tôi viết %10$n trước bởi vì nếu viết sau %9$n nó sẽ tính số kí tự mà offset 9 sử dụng vào offset 10 vì vậy nó sẽ ghi giá trị y sì như offset 9 :v
Nhưng 1 vấn đề nữa sinh ra. Đó là nó sẽ pop cái gì lên rdi ??
Vậy trong trường hợp này, thay vì pop rdi thì phải pop hết những giá trị rác trong stack ra trước. Ở đây ta cần pop ra tổng là 3 lần.
Sau khi chạy thì stack còn 1 giá trị rác nữa lên ta sẽ lấy pop 4 lần.
Vậy stack bây giờ đã không còn những thứ mà tôi vừa nhập vào.
Giờ tôi sẽ chỉnh 1 chút để nó thành pop rdi ; ret + sh + system
.
Bạn có thể thử với đoạn payload này:
Thì thấy trên stack bây giờ chiếm 4 offset nên ta phải thay pop4_ret ---> pop5_ret. (vì ban đầu ta để là pop 4 lần thì stack của ta mới hết giá trị rác nên lần này stack tăng lên 1 thì pop thêm 1 lần nữa là được)
Nếu bạn đọc đến đây vẫn hiểu thì bạn có thể tự viết payload theo cách của mình hoặc như mình:
Bạn chỉ cần nhìn vào việc setup stack của mình là có thể làm viết được payload rồi.