FPTU Secathon 2025
Web Exploitation
1. Simple Business Failure
Định nghĩa sơ qua
SSTI (Server-Side Template Injection) là một trong những lỗ hổng web phổ biến, xảy ra khi dữ liệu do người dùng nhập vào được đưa thẳng vào template engine (hệ thống xử lý giao diện động) mà không được kiểm soát.
Template engine thường có cú pháp đặc biệt như {{ ... }}, ${ ... }, {% ... %},… để nhúng biến, gọi hàm, hoặc thậm chí thực thi code. Thông thường thì một trong những cách phổ biến nhất thường được sử dụng để kiểm tra rằng hệ thống có SSTI là nhập vào {7*7} hoặc {{7*7}}Và ta nhận được kết quả là 49, chứng minh rằng hệ thống có lỗ hổng SSTI.
Để ngăn chặn SSTI đó chính là không bao giờ render dữ liệu đầu vào từ user trực tiếp qua template engine mà không xử lý, có thể thực hiện bằng vài cách như:
- Sanitize (lọc) dữ liệu nhập vào nghiêm ngặt.
- Sử dụng template engine có cơ chế chống SSTI (các pipelines HTML-escaping, auto-escaping).
Phân tích đề bài
Về cấu trúc hệ thống, khi ta đăng nhập bằng tài khoản admin được cung cấp, người chơi có thể generate flag thông qua /admin/flag
. Khi đó, hệ thống sẽ cho ta kết quả:
1 | Flag is stored in Session with key: pxkheosz |
Điều này cho thấy flag đã được lưu vào session phía server với key là pxkheosz. Do đó, mục tiêu là phải tìm cách đọc nội dung session từ một tài khoản user khác.
Các bước thực hiện
- Đăng nhập tài khoản admin
Truy cập vào login
:
1 | Username: admin |
Từ đó ta tạo flag tại endpoint /admin/flag
:
- Tạo user mới
Truy cập /register để tạo một tài khoản mới ở trên cùng trình duyệt (vì mã được tạo ra từ cred admin là sẽ dựa theo session):
1 | Username: huhu |
Sau đó đăng nhập bằng tài khoản này để truy cập trang người dùng – tại đây có mục cho phép nhập mô tả (Description) và cập nhật nội dung.
- Sử dụng SSTI để đọc nội dung flag
Biết rằng flag được lưu với key pxkheosz trong session, ta dùng payload sau để truy xuất:
1 | ${pageContext.session.getAttribute('pxkheosz')} |
Lỗ hổng ở đây là SSTI qua Java EL do ban đầu ta sử dụng một cú pháp là ${...}
, Và flag được lưu dưới dạng : session.setAttribute("pxkheosz", "flag{xxx}")
:
${…}: Cú pháp Expression Language (EL) trong Java, dùng để chèn biến vào trang.
pageContext: Đối tượng đại diện cho ngữ cảnh trang JSP hiện tại.
session: Truy cập session hiện tại của người dùng.
getAttribute(‘pxkheosz’): Lấy giá trị của biến
pxkheosz
đã được lưu trong session (ở đây là flag).
2. Insecurity Is Fun
Định nghĩa sơ qua
Trong challnge này, sử dụng curl
để gửi một requests như:
1 | http://insecurityisfun.secathon2025-env.net/hello?username=Hwng |
thì server sẽ render chuỗi "Hello Hwng"
. Tuy nhiên, thay vì chỉ in ra text, ứng dụng lại xử lý input bằng Java Expression Language (hoặc một cơ chế eval tương tự). Điều này có nghĩa là attacker có thể chèn biểu thức Java trực tiếp, và server sẽ evaluate (chạy) nó.
Đây là một dạng của Server-Side Template Injection (SSTI) nhưng nguy hiểm hơn vì dev đã dùng eval: hoặc cơ chế tương tự để chạy Java code. Hậu quả gây ra là input người dùng không chỉ những được hiển thị, mà thậm chí được thực thi như code Java. Ví dụ cơ bản:
1 | Runtime.getRuntime().exec("ls").getInputStream() |
→ chạy lệnh ls trực tiếp trên server.
Các bước thực hiện
Sử dụng lỗ hổng eval
, ta chạy payload sau:
1 | curl --get "http://insecurityisfun.secathon2025-env.net/hello" \ |
và nhận về với kết quả:
1 | next()!</h1> |
Sau một hồi tìm kiếm thì bọn mình tìm ra được là flag nằm trong ./webapps/ROOT/WEB-INF/flag.txt
, và sử dụng payload trên để dùng lệnh cat
và ta sẽ có flag:
1 | http://insecurityisfun.secathon2025-env.net/hello?username=eval:Runtime.getRuntime().exec(%22webapps%2FROOT%2FWEB-INF%2Fflag%2Etxt%22).getInputStream() |
Pwn
1. Contest Rating
Định nghĩa sơ qua
Challenge này sử dụng lỗ hổng Use-After-Free: Khi chương trình free một con trỏ (chunk), nhưng vẫn giữ reference tới vùng nhớ đó và tiếp tục sử dụng.
Với lỗ hổng này, Attacker có thể:
- Dùng UAF để đọc dữ liệu nhạy cảm (leak địa chỉ heap/libc).
- Ghi đè dữ liệu (overwrite) vào vùng nhớ đã free để sửa biến quan trọng (ở đây là
userLevel
).
Các bước thực hiện
Ý tưởng là ta sẽ thay đổi giá trị của userLevel
thành 0, để làm được điều đó ta cần phải thực hiện Double Free, bằng cách tận dụng việc free trong hàm comment
ta có thể fill được tcache và thực hiện double free ở fastbin → leak được địa chỉ heap và sau đó là overwrite userLevel
1 | #!/usr/bin/env python3 |
2. Access Code Checking
Định nghĩa sơ qua
Bài này sử dụng lỗ hổng Buffer Overflow: Khi một biến mảng (buffer) được khai báo với kích thước cố định (ví dụ char buf[32]
), nhưng chương trình cho phép nhập nhiều hơn 32 byte mà không giới hạn → dữ liệu thừa sẽ tràn sang vùng nhớ bên cạnh trên stack. Nếu ngay sau buffer có một biến khác (ví dụ int accessCode
), attacker có thể ghi đè giá trị biến này bằng payload.
Đây là dạng stack-based buffer overflow, cụ thể là overflow để ghi đè biến cục bộ chứ chưa tới mức ghi đè EIP/RIP, mục tiêu chỉ đơn giản là bypass điều kiện kiểm tra bằng cách thay đổi giá trị biến kiểm soát luồng chương trình.
Một số những cách có thể phòng tránh bao gồm:
- Không dùng hàm không an toàn như
gets()
,scanf("%s")
,strcpy()
, mà thay vào đó là những hàm nhưfgets(buf, sizeof(buf), stdin);
hayscanf("%31s", buf);
- Bật compiler protections như Stack canaries (-fstack-protector),
FORTIFY_SOURCE
vàASLR
.
Cách giải
Đơn giản chỉ là 1 bài dùng Buffer Overflow
để thay đổi giá trị của biến và sau đó pass điều kiện:
1 | #!/usr/bin/env python3 |
- Title: FPTU Secathon 2025
- Author: FPTU-Ethical-Hackers-Club
- Created at : 2025-08-25 14:34:00
- Updated at : 2025-09-14 15:49:56
- Link: https://blog.ehc-fptu.club/2025/08/25/FPTU-Secathon_2025/
- License: All Rights Reserved © n1ghtf4ll