# Tenable CTF 2023
## Braggart

Đây là một challenge pwn x web khá thú vị. Chúng ta được cung cấp một link và khi bấm vào link đó sẽ hiện như sau:

Click vào `backup` sẽ cho ta một binary. Decompile file binary đó thì ta biết được nó là thành phần back-end xử lý gói tin request tới khi ta xem hàm `printMain`:

Chương trình thực thi khá nhiều hàm `getenv` nhưng ta thấy có một vài hàm lấy chuỗi bắt đầu với `HTTP_`, đây có thể được xem là header của gói tin request. Do đó ta sẽ dùng burpsuite để có thể thêm bớt một cách dễ dàng. Sau một hồi tìm kiếm bug, ta thấy trong hàm `printDebugInfo` có lỗi **Buffer Overflow** khi thực hiện `strcpy` với dữ liệu là `User-Agent`:

Biến `dest` nằm ngay trên biến `format`, do đó nếu nó overflow, ta hoàn toàn có thể thay đổi format của biến `format` để thực thi format tùy ý --> **Format String**. Để tìm offset phù hợp, ta sẽ cùng debug chương trình này và thiết lập các biến môi trường phù hợp để có thể đi vào hàm `printDebugInfo` của `printMain`:

Vì biến môi trường `HTTP_USER_AGENT` sẽ gây ra overflow nên ta sẽ set nó với 0x400 byte dữ liệu. Debug dừng ngay đoạn printf sau khi `strcpy` để tìm offset:


Vậy ta sẽ thử thêm format `%p%p%p` sau 1008 byte xem coi ta có leak được địa chỉ trên server hay không:


Vậy là ta overflow thành công. Bây giờ ta sẽ lợi dụng format string để leak dữ liệu của biến `AdminPass` nằm ngoài hàm main. Ta có thể debug và tìm offset:

Thay thế format string mới là `%275$s` để leak password:

Vậy password là `xbYP3h7Ua94c`. Bây giờ ta sẽ bổ sung thêm header `X-PASSWORD` với password ta lấy được để đi vào hàm `printSecrets`:

Ta đã thực thi được hàm đó nhưng file được đọc là `/home/ctf/brag`. Do đó ý tưởng sẽ là dùng format string để thay đổi chữ `brag` thành `flag` để lấy flag. Vẫn là tìm offset từ printf cho tới chuỗi `brag` trên stack là `267` (dùng gdb để tìm, set các env để nhảy vào `printSecrets`):

Vậy ta chỉ việc thêm `%c` để in ra một lượng byte phù hợp và ta dùng `%hn` để thay đổi 2 byte `br` thành `fl` của chuỗi `brag` để thành `flag`:

Vậy ta sẽ in ra `27750` byte tương ứng với 2 byte `fl`. Ta kết hợp với `%hn` được payload `%27750c%267$hn` lấy được flag:

Flag là `flag{f0rmat_th3m_str1ngz}`
## Brick Breaker

Đây là một challenge reverse. Chúng ta được cung cấp một file duy nhất và định dạng là một con game Nintendo Dual Screens:

Do đó ta sẽ tải trình giả lập [DeSmuME](https://www.emulatorgames.net/emulators/nintendo-ds/desmume-0911-32-bit/) để tiến hành chạy file. Sau khi giải nén, ta chạy trình giả lập lên. Để load file game `ctf.nds` ta chọn `File -> Open ROM...`

Tiếp theo đó ta chọn con game và bấm `Open`:

Và ta được giao diện như sau:

Khi bấm start thì ta được trò chơi phá gạch:

Để điều khiển trái phải thì ta dùng mũi tên trái và mũi tên phải, để bắn bi thì dùng phím `x`. Tổng cộng có 5 lượt chơi, nếu hết thì sẽ phải chơi lại từ đầu.
Ý tưởng đầu tiên sẽ là chỉnh lại số lượt chơi đó cho thật lớn và việc chỉnh sẽ tác động trực tiếp tới memory. Do đó ta chọn `Tools -> RAM Search...` để tiến hành tìm biến count đó:

Sẽ có 2 hướng biến count thay đổi, 1 là count từ 5 về 0, 2 là count từ 0 lên 5. Do đó ta sẽ thử trước với trường hợp 1, thiết lập Specific Value thành 5 và bấm `Search`:

Sau đó ta tiến hành chơi game và để mất một mạng. Bây giờ ta thay số 5 thành số 4 và bấm `Search` tiếp tục để tìm tiếp từ các giá trị đã search cũ. Sau khi search thì ta thu gọn lại được chỉ còn 2 kết quả:

Vì 2 giá trị đó thay đổi giống nhau nên ta sẽ thay đổi thử giá trị ở địa chỉ đầu tiên `02060DB8`. Ta chọn vào `Tools -> View Memory` để xem bộ nhớ:

Ta thay phần `Address` thành địa chỉ của biến count đó và bấm `Go` để nhảy tới vị trí của biến đó:

Ta sẽ chơi thử thêm một lượt để thấy giá trị đó giảm dần:

Vậy ta thay đổi thành 0xff để có thể chơi được nhiều lần và qua màn. Sau khi qua màn, ta thấy giá trị `02` tăng lên thành giá trị `03` (số nằm sau biến count tại cột A):

Do đó ta sẽ chơi thử các màn nhưng tới khi giá trị màn là 5 thì nhảy lại màn có giá trị 2. Ý tưởng sẽ là set thành màn số 6 để khi chơi xong sẽ nhảy sang màn 7:

Mỗi màn sẽ là một ký tự của flag nên ta cứ chơi tiếp theo để lấy flag.