---
# System prepended metadata

title: KCSC WU

---

# KCSC WU
## Santa Shop
truy cập url đăng nhập em đọc source đầu tiên , crl+F thử và  thấy luôn flag
![image](https://hackmd.io/_uploads/SJmffETf-l.png)

## Santa Shop Revenge
Sau khi truy cập url thử thách em thấy có giao diện đăng kí và đăng nhập
![image](https://hackmd.io/_uploads/BJcNFXpGbl.png)
thử tạo 1 tài khoản bình thường với username là vanan11 
![image](https://hackmd.io/_uploads/r1d_YQ6fZg.png)
quan sát giao diện sau khi đăng nhập , user có 100 coin và Gif box 99,999 coin . Thử mua thì có nhận 1 thông báo là nạp tiền hoặc cập nhật coin từ admin
![image](https://hackmd.io/_uploads/rkPMc7pfbx.png)
thử nạp tiền thì được chuyển đến /payment.php với nội dung: The file you are looking for, is not where you think it is .
Có thể có thông tin ở 1 đường dẫn ẩn . Em thử search bằng gobuster nhưng status toàn 403 . ![image](https://hackmd.io/_uploads/Hy8ej76Gbx.png)
Em thử cập nhật coin từ admin 
đầu tiên click dashboard thì nhận được thông báo : Chỉ có thể cập nhật coin từ localhost !
Em thấy trong HTTP history có đường dẫn dạng : ![image](https://hackmd.io/_uploads/By-iiQTz-x.png)
em thử sửa thành 1 file php bất kì để hi vọng có để đọc nội dung thì nhận được respone:![image](https://hackmd.io/_uploads/SkuH2mpMbg.png)
sever sử dụng file_get_contents() em thử đọc file admin.php
thì nhận được respone : ![image](https://hackmd.io/_uploads/Hyhn37afWg.png)
Ở đây có 2 cách: 
1 là bypass bằng PHP filter để encode nội dung file trước khi trả về 
2 là dựa vào thông báo ban đầu khi truy cập admin dashboard , có thể truy cập từ localhost từ đó có để đọc được nội dung trang .
![image](https://hackmd.io/_uploads/HkoYpmazbl.png)
![image](https://hackmd.io/_uploads/SkTxCQTzZl.png)
![image](https://hackmd.io/_uploads/HkK70mpzZl.png)
cả 2 cách ta đều biết được cách để cập nhật coin . tuy nhiên cách 2 ta phải đoán SECRET ở đâu . còn cách 1 cho ta biết SECRET ở secret.txt
Vì là file .txt nên ta có thể đọc trực tiếp![image](https://hackmd.io/_uploads/ryO3RQ6Gbx.png)
secret là: ChiCon1BuocNuaThoi~_~
![image](https://hackmd.io/_uploads/Hk9Ie4pG-g.png)
gửi request tuy nhiên lỗi , em thử encode url thì được:![image](https://hackmd.io/_uploads/B1Hol46z-g.png)
sau đó mua box và có được flag ![image](https://hackmd.io/_uploads/HyYgbNafZe.png)
## Simple Web
Truy cập thử thách thấy giao diện đăng kí đăng nhập: ![image](https://hackmd.io/_uploads/r1ejRu6MWe.png)
Đầu tiên thử tạo và đăng nhập 1 tài khoản bất kì
![image](https://hackmd.io/_uploads/S15j1F6Gbx.png)
Không thấy có chức năng gì có thể khai thác, đọc source không phát hiện được điều gì. quét gobuster và thử truy cập /admin thì bị redirect về /guest . truy cập /flag thì hiện thông báo Only local access allowed , thử thêm header X-Forwarded-For: 127.0.0.1 cũng không được , thay GET thành POST cũng không được
Em quay lại thử đăng kí với username là admin thì hiện thông báo: 
![image](https://hackmd.io/_uploads/BJUmVt6zZe.png)
có thể đã có tài khoản admin , em thử 1 vài paylaod SQLi nhưng đều không đăng nhập được .
em để ý hint là unicode normalize
Sau khi tìm hiểu về về vurlnerable:
https://systemweakness.com/unicode-normalization-leads-to-account-takeover-c0d883915ec5
https://medium.com/@instatunnel/unicode-normalization-attacks-when-admin-admin-32477c36db7f
em hiểu Unicode có một quy trình gọi là Normalization để đưa các ký tự về dạng chuẩn với hàm unicodedata.normalize trong (Python) hoặc hàm String.normalize() trong JS do đó trước khi vào DB thì ⓐⓓⓜⓘⓝ => admin
kiểm tra filter thì ⓐⓓⓜⓘⓝ ≠ admin => bypass kiểm tra
đăng nhập với username = admin và pass đã tạo 
![image](https://hackmd.io/_uploads/r1j71cpG-l.png)
nhập url để check nên gửi url để đọc flag , vì /flag cần truy cập từ localhost như đã biết ở trên nên có url http://localhost/flag nhưng hiện thông báo ![image](https://hackmd.io/_uploads/SJc6yqpfWg.png)
có lẽ sever đã filter kiểu ```
if path == "flag":
    return "You can not access the flag directly"```hoặc tương tự 
bypass bằng cách thêm Query String rỗng 
thử thêm ? / # ; vào sau thì truy cập được ( ? và #)
![image](https://hackmd.io/_uploads/HkgXbcafbg.png)
## Hoshino Portal
Đọc source thấy mục tiêu là truy cập tài khoản admin để lấy flag
trang web có những chức năng như ![image](https://hackmd.io/_uploads/Hkkzl3az-x.png)
Thử reg với username là admin thì ![image](https://hackmd.io/_uploads/SJA4xnTG-g.png)
do đó thử sqli với chức năng login Tuy nhiên đọc source thấy trong tất cả các câu SQL đều thay tham số thành ? - không có sqli
-> khai thác ở chức năng resetpassword
resetpassword có 2 step : đầu tiên là nhập username và email để tạo resetcode
sau đó là nhập username,email,resetcode,newpassword để resetpassword 
trong file resetpassword.js có đoạn code:
  ![image](https://hackmd.io/_uploads/rJLIP3pfZx.png)

 hệ thống kiểm tra độc lập username có trong user không và email có trong user không , không kiểm tra email có thuộc username không. UNION để gộp kết quả kiểm tra 

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

- chỉ cần cả 2 tồn tại là pass       
Tiếp theo đọc source để xem resetcode được tạo như nào:
![image](https://hackmd.io/_uploads/HkJOvhpzWl.png)
nếu email có kí tự 'admin' thì resetcode là chuỗi uuidv4 32 kí tự không thể brute force được
còn nếu không có 'admin' thì resetcode có dạng : 
[A-F][10-99][A-F] có 6*90=540 trường hợp
tạo payload :![image](https://hackmd.io/_uploads/S1M2q2TzZx.png)
đưa vào intruder và bruteforce:
![image](https://hackmd.io/_uploads/rkAJo2TGWe.png)
nhưng có 1 vấn đề
resetcode tạo ra có giới hạn thời gian , bruteforce chưa tới 200 là expired @@
em nhờ ai gen script với prompt:
![image](https://hackmd.io/_uploads/Hy1uMv0zZl.png)
sửa lại chút và chạy :![image](https://hackmd.io/_uploads/HJ6UQKAzZg.png)
 ![image](https://hackmd.io/_uploads/B1Q2fw0GZg.png)
sau đó em đăng nhập admin với pass vừa đổi và lấy flag:![image](https://hackmd.io/_uploads/H1iJ7DAMWl.png)
## Ka Cê Ét Cê
đầu tiên em đọc source thấy flag.txt được copy vào /flag.txt sau đó đổi tên thành /flag_REDACTED.txt với biến ADMIN_PASSWORD="REDACTED" => cần tìm ADMIN_PASSWORD ![image](https://hackmd.io/_uploads/Sk2xbbkQZl.png)
/note.php in ra ADMIN_PASSWORD chỉ được đăng nhập tại localhost . thử gửi request và thêm header X-Forwarded-For: 127.0.0.1 nhưng không được . không thấy dấu hiệu lỗ hổng XSS nên chưa có hướng truy cập
Thử tìm cách truy cập admin.php và update.php để tìm thêm thông tin vì hint là viết tên vào danh sách nên có liên quan đến update.php
![image](https://hackmd.io/_uploads/B1nT5JJmZe.png)
Cả 2 file đều require JWT.php và KCSC.php nên em đọc trước 
đầu tiền là file JWT.php có 1 số chức năng bảo mật tốt ví dụ như generateToken,validateToken khi sử dụng sha256 'trộn' header, payload với key secret(chỉ sever biết) với nhau tạo ra expectedSignature 
![image](https://hackmd.io/_uploads/ByTm1l1mWg.png)

Do đó nếu xác thực bằng cách so sánh Token với ValidateToken thì không thể truy cập nếu không có tk mk admin

!!! Tuy nhiên, ở file KCSC.php , kiểm tra Admin lại bằng function DecodeToken() - một chức năng decode mà không kiểm ktra Signature 
![image](https://hackmd.io/_uploads/SJOfgg17Zx.png)
xác thực isAdmin chỉ cần payload(part[1] là phần payload Json => fake role ở payload ) có ['role']='admin'
![image](https://hackmd.io/_uploads/SyW4ggy7-l.png)
đã có ideal fake cokie để qua xác thực admin .
 Dựa vào chức năng decodeToken thấy cokie sẽ 3 phần cách nhau bằng dấu "." và được encodebase64
 fake payload: {
 "username": "admin",
"role": "admin"
 }
encode base64 thành : eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIn0= 
thử gửi request tới /admin.php với fake token a.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIn0=.a
và thành công   ![image](https://hackmd.io/_uploads/SJYlDeJX-l.png)
tuy nhiên thử vào /note.php thì không được
 Trong adminPanel có thể update members.xml![image](https://hackmd.io/_uploads/Hkem2BlgQ-l.png)
chặn request khi ấn Save changes thì thấy post lên /api/members/update.php . vào đọc file /api/members/update.php 
![image](https://hackmd.io/_uploads/Sk5l1Wk7Wx.png)
input phải có xml_content . Em không biết xml là gì nên đã search và tìm xem có thể khai thác lỗ hổng gì không:
![image](https://hackmd.io/_uploads/B1Vug-JQbg.png)
kết quả nhắc đến lỗ hổng XXE:
![image](https://hackmd.io/_uploads/BJH-zWy7Zl.png)
em đã hiểu qua qua về lỗ hổng . tức là qua cơ chế 'entity' trong xml và tính năng tải thực thể bên ngoài em có thể định nghĩa 1 biến là url localhost/note.php khi chạy thông tin biến thì sẽ in ra thông tin của url localhost/note.php
Lúc đầu em đặt biến ở tên member sau đó vào /members.php để xem thông tin của biến (note.php) nhưng e không biết vì sao không xem được![image](https://hackmd.io/_uploads/rydGDgxQ-g.png)
![image](https://hackmd.io/_uploads/B11HPllQWl.png)
Một lúc loay hoay thì em để ý thông báo
![image](https://hackmd.io/_uploads/S1ziPlemZl.png)
em thử đặt biến vào tag admin thử : ![image](https://hackmd.io/_uploads/S1A-OglQ-l.png)
và nhận được thông tin của biến là ADMIN_PASSWORD echo bởi note.php :![image](https://hackmd.io/_uploads/SyjLulgXbg.png)
chặn request để đọc hết respone để lấy ADMIN_PASSWORD đầy đủ : ![image](https://hackmd.io/_uploads/S1deFge7be.png)
ADMIN_PASSWORD là "Take me back to the night we met, and then I can tell myself, what the hell I'm supposed to do.."
Nhưng như thế tên file lại chữ dấu cách , thử thay space thành %20 cũng không truy cập . Rõ đọc hết trong source thì chỉ cần tìm ADMIN_PASSWORD là cso được tên file chứa flag 
như vậy có lẽ khi chạy container có script khác mà khoogn có trong source có thể thấy được
khi container chạy,lệnh trong docker được ghi lại /proc/1/line Nếu có script hoặc logic nào đó thay đổi tên flag thì tên file flag thực tế sẽ xuất hiện trong dòng lệnh này.
![image](https://hackmd.io/_uploads/B1r-QElmbl.png)
thử tiếp tục xxe để đọc /pro/1/cmdline thì hiện thông báo trên , nội dung chứa kí tự gây lỗi
thử encode trước khi trả về
![image](https://hackmd.io/_uploads/ByQ1NNgXZg.png)
đem decode thì ra được tên file ![image](https://hackmd.io/_uploads/SJY-EEg7Zx.png)
/flag_f46ef942743225f094999b26af3080d0.txt
truy cập file và có flag ![image](https://hackmd.io/_uploads/HyYi4VeXbx.png)
## Ka Cê Ét Cê Revenge
đọc source em thấy đã fix xác thực admin bằng DecodeToken thành ValidateToken nên không thể fake payload như bài trước . 
Như thế xác thực của bài này rất chặt
Sau khi loay hoay đọc source , chợt thấy chức năng login của bài trước chưa sử dụng 
khi đăng nhập với quyền admin , ta sẽ nhận được token với role admin và được tạo bởi function generateToken - có trộn secret(chỉ sever biết)với header và payload
Bài 2 chỉ thay cơ chế xác thực admin ở kcsc.php thì có thể cùng 1 secret . 
hơn nữa chức năng login ở bài trước laij không dùng , tận dụng ở bài revenge thì khả năng cao hướng đi này là intend của author
![image](https://hackmd.io/_uploads/HJe9aExXbl.png)
chúc năng login chỉ cho post , yêu cầu nhập username và password là ADMIN_PASSWORD-chuỗi dài dài đã tìm ở trên , input là json .
![image](https://hackmd.io/_uploads/By8KAVlQZe.png)
thêm token = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzY1OTgwNzU1LCJleHAiOjE3NjU5ODQzNTV9.1qr1IL9ItLVQvELDIyB9oG8cKFgXo_Ld1oKkhrkG5BI" vào cookie rồi thử truy cập /admin.php![image](https://hackmd.io/_uploads/rJk8kHlXbl.png)
thành công qua xác thực admin , như vậy suy đoán trên là đúng . đến đây làm tương tự như bài cũ là ra flag
![image](https://hackmd.io/_uploads/HyoWfSgmbg.png)
## SECURE STORE
![image](https://hackmd.io/_uploads/BJnUkvlQZe.png)
đọc code em nghĩ flag là voucher 100% discount
![image](https://hackmd.io/_uploads/SJEskvlX-l.png)
chức năng checkvoucher dễ bị SQLi nhưng code bị limit 18 kí tự
theo intend các anh gợi ý là có thể dùng thoải mái length mà kh bị giới hạn <=18 kí tự 
Sau khi tìm hiểu code.length trong javascript thì em nhận thấy có 2 trường hợp . nếu code là string thì 1 kí tự là 1 length , nếu code là array thì length là số phần tử . ví dụ array code=[a,b,c] thì length = 3
Do đó payload SQLi kh bị giới hạn kí tự
Ý tưởng sẽ sử dụng UNION để brute từng kí tự code bắt đầu bằng KCSC{... nếu trả về Voucher Valid là đúng .![image](https://hackmd.io/_uploads/S1Ej6eW7-l.png)
thấy db Voucher có 3 cột:
![image](https://hackmd.io/_uploads/Skn62gbXWg.png)
có thể brute force từng kí tự trong intruder burpsuite hoặc nhờ ai viết script brute force theo ý tưởng như và payload :' UNION SELECT 1,code,100 FROM Voucher WHERE code LIKE 'KCSC{%'-- -
![image](https://hackmd.io/_uploads/r1-1kWZ7Ze.png)
có có được flag
nhưng submit flag thì incorrect , trong trang web em cũng kh thấy chức năng nào khác nữa nên em hết ý tưởng.





























