🇻🇳
th13
  • info
  • JAVA
    • Notes: RMI linh tinh
    • [CVE-2013-2165] Phân tích RichFaces vulnerability thông qua CTF challenge
  • CTF WRITE UP
    • [Web]ImaginaryCTF 2021
    • [Web]CSAW CTF 2021
    • [Web]RaRCTF 2021
    • [Web]LIT CTF 07/2021
    • [Web]redpwn 2021
    • [Web]WeCTF 2021
    • [Web]WannaGame 21/05/2021
    • [Web]San Diego CTF 2021
    • [Web]picoMini by redpwn
    • [Web]WannaGame 17/04/2021
    • [Web]picoCTF 2021
    • [Web]BambooCTF/Calc.exe
  • saved
    • Tài liệu JAV Sờ cu 101
    • [NT230]PE file Injection
    • [WU][web]root-me
    • [WU]Lord of SQLinjection
    • [WU][Web]CyberTalents
    • [exploit][sqli]Challenge ngày Tết
Powered by GitBook
On this page
  • login
  • caas
  • notepad

Was this helpful?

Edit on GitHub
  1. CTF WRITE UP

[Web]picoMini by redpwn

Previous[Web]San Diego CTF 2021Next[Web]WannaGame 17/04/2021

Last updated 3 years ago

Was this helpful?

login

Link chall:

View source -> vào file index.js -> beauty code:

Username và password có trong đây nhưng đang ở dưới dạng base64 encoded. Decode themm!!!

Flag: picoCTF{53rv3r_53rv3r_53rv3r_53rv3r_53rv3r}

caas

Bài này ta có nhận 1 file source:

Bài này truy cập endpoint /cowsay/:message, message request sẽ được truyền hàm vào exec và đồng thời là input thực thi bởi command cowsay của linux. Kết quả trả về sẽ là lỗi (nếu :message rỗng) hoặc text được in ra màn hình.

Dzô dziệc, command injection: /cowsay/hi;ls -a.

Đọc file falg.txt:

FLAG: picoCTF{moooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0o}

notepad

Ta nhận được 1 source code với 1 route nhận request như sau:

content gửi lên không được chứa _ và /. Độ dài không quá 512 ký tự. Ngược lại sẽ render render lên index.html với param error như sau:

Mình thử gửi content lỗi và phát hiện ra cái thú dzị:

Mình truyền cho param error gì thì index cũng sẽ render ra màn hình. Nhưng tên file error mình truyền vào không tồn tại nên không include nội dung được.

Đọc trong source kỹ 1 tí thì thấy content của mình truyền vào sẽ được lấy 128 ký tự đầu + token để làm tên file (sau khi url encode). Sau đó content được ghi vào file này và lưu vào static/file_name.html.

Ý tưởng: kết hợp 2 phát hiện trên, content nhập vào sẽ dẫn ra folder error để tạo file ở đây và tại index mình truyền tên file vừa tạo vào để index render nội dung file error khai thác server side template injection.

Thử nghiệm:

Payload: ..\templates\errors\{{7*7}} (ký tự \ khi qua hàm url_fix sẽ thành / bypass filter)

404 vì folder này không có quyền access. Nhưng ta có thể access tại index như đã nói trên.

"Khoan, dừng khoảng chừng 2s". Tên file của mình (khoảng trước token) vừa tạo cần phải đem đi url encode 1 lần trước khi truyền vào param error bởi vì tên file sẽ bị decode trước khi include gây ra chuyện sai tên file.

%7B%7B7*7%7D%7D --> %257B%257B7%2A7%257D%257D

Như vậy là đã thành công template injection!

Nhưng để tránh khá cực cho việc phải đi encode trước khi gọi thì mình có thể truyền vào đó 1 chuỗi ký tự độ dài khá dài (cho là 128 đi) để không vướng các ký tự đặc biệt bị encode.

Thực hiện exploit:

Tạo content <path error> + 128 ký tự + "payload SSTI"

content = "..\\templates\\errors\\" + "s" * 128 + "{{ config.items() }}"
print(content)

Dán tên file (without .html) vào param error.

Không lưu flag ở biến môi trường, vậy phải rce. Khó khăn ở đây là phải bypass ký tự _, trong lúc exploit SSTI không thể tránh call attribute có chứa các ký tự _.

Nhưng có cách khác để call attribute (ví dụ __class__) là gọi attribute theo kiểu mảng và truyền vào key theo phương thức truyền get request, ví dụ:

{{''.__class__.__mro__}} --> {{''[request.args.get('class')].mro()}}

Như vậy thành công, mro trỏ index 1 và call subclasses để list classes có thể access và dùng.

Class mà mình cần để có thể rce server là subprocess.Popen có tồn tại (ước gì nếu là subprocess.check_output tuyệt vời biết mấy). Tiếp theo, call class này (call bằng index) và truyền arg command.

Việc khó khăn là tìm index của class này =)) nhưng Ctr+F tí xíu là ra: 273

Vì muốn in ra màn hình nhưng popen chỉ chỉ thực hiện chứ không in ra, mình tìm solution có vấn đề này khá lâu. Nhưng trong document có đề cập đại loại là flag stdout là số âm thì sẽ trả về buffer mặc định chuẩn io có thể đọc được (0: không trả về, 1: trả về byte,...)

Sau một tỉ tỉ lần tìm và đọc thì payload chốt cuối cùng:

{{ ''[request.args.get('class')].mro()[1][request.args.get('subclasses')]()[273](['ls'], stdout=-1).communicate() }}

Cat flag:

{{ ''[request.args.get('class')].mro()[1][request.args.get('subclasses')]()[273](['cat', 'flag-c8f5526c-4122-4578-96de-d7dd27193798.txt'], stdout=-1).communicate() }}

FLAG: picoCTF{styl1ng_susp1c10usly_s1m1l4r_t0_p4steb1n}

Link chall:

Link chall:

https://caas.mars.picoctf.net/
https://notepad.mars.picoctf.net/
https://login.mars.picoctf.net/