---
# System prepended metadata

title: TJCTF-2023

---

# TJCTF-2023
## WEB
### hi
Ở bài này khi bắt đầu thì chall thì chúng ta sẽ không nhận ra gì cả
![Imgur](https://i.imgur.com/xgAY3Ac.png)

Checksource để biết thêm thông tin
![Imgur](https://i.imgur.com/SqavfZ0.png)

Flag: `tjctf{pretty_canvas_577f7045}`


### swill-squill
Bài cho chúng ta nhập đầu vào với `name` và `grade`
![Imgur](https://i.imgur.com/pb6MyBS.png)

Khi register xong thì trang sẽ redirect đến endpoint `/api` và hiện thông tin người dùng
![Imgur](https://i.imgur.com/GRb0QZj.png)

Check source:
![Imgur](https://i.imgur.com/I3Omvn0.png)
![Imgur](https://i.imgur.com/hBomeGx.png)

Nội dung của `admin` sẽ có chứa flag vì vậy chúng ta cần phải đăng nhập dưới tên `admin`, redirect đến `api` và lấy flag
Tuy nhiên, chúng ta sẽ không thể register dưới tên admin và ở bài này chúng ta sẽ dựa vào lỗ hổng SQLi
![Imgur](https://i.imgur.com/JoHTb2n.png)

Payload: name = `' OR 1=1 --`
![Imgur](https://i.imgur.com/JAOgVqd.png)

Flag: `tjctf{swill_sql_1y1029345029374}`


### outdated 
![Imgur](https://i.imgur.com/t4aienl.png)

Chall này sẽ cho chúng ta upload một file python và sau đó sẽ hiện ra output
![Imgur](https://i.imgur.com/va5tLlu.png)

OK. Vậy ý tưởng là ở đây chúng ta sẽ chạy OS command, tuy nhiên khi check source code chúng ta sẽ thấy có một blacklist:
![Imgur](https://i.imgur.com/ooDgsB9.png)

Chặn `import`, vậy là cách làm ở đây cũng sẽ gần giống các payload khi chúng ta làm SSTI. Tuy nhiên kể cả `globals`,`sys`,`open` cũng bị chặn và từ đó những payload thông thường cũng không thể dùng được.
Sau khi đi dò từng chút một thì ta có payload:
Payload 1:`print(().__class__.__mro__[1].__subclasses__()[84]().load_module('os').__dict__['sy'+'stem']('cat f*'))`

Payload 2:`print([x for x in ()._class__.__base__.__subclasses__() if x.__name_ == "_wrap_close"][0].__init__.__globals__['system']('ls'))`
![Imgur](https://i.imgur.com/XJlLZOB.png)

Flag: `tjctf{oops_bad_filter_3b582f74}`


### pay-to-win
Một bài liên quan đến brute-force để crack. Vào bài sẽ cho chúng ta nhập username và redirect đến trang chính:
![Imgur](https://i.imgur.com/ovFe5Yz.png)

Sẽ có chứa 2 `Cookie` là `data` và `hash`. Check source:
![Imgur](https://i.imgur.com/4ruOZvQ.png)

Ở dòng 55,56 ta có thể coi như nó đang tạo ra 1 `key` với độ dài 24 bit:
```python
if username not in users:
    users[username] = hex(random.getrandbits(24))[2:]
```
Sau đó từ dòng 65 đến 72 thì tạo ra 2 dữ liệu với rồi setup cookie:
+ `b64data` chứa dữ liệu người dùng bao gồm `username` và `user_type` đã được encode base64
+ `data_hash` là dữ liệu của `b64data` và `key`

Khi vào trang chính, trang sẽ check các giá trị và so khớp với nhau để bảo đảm tính toàn vẹn:
![Imgur](https://i.imgur.com/Nh7TgHh.png)

Nếu `user_type` phù hợp thì sẽ để cho chúng ta set theme.
Để lấy flag bài này chúng ta sẽ có đường đi như sau:
+ Xác định nơi có flag
 ![Imgur](https://i.imgur.com/j1Jkgoz.png)

+ Truy cập dưới `user_type` là **prenium** để set theme dẫn tới đọc file có flag
+ Tìm ra key để có thể thay đổi `b64data` và `data_hash`

Solve code: https://github.com/NamMTA892/TJCTF_2023/blob/main/pay-to-win-solve.py
Flag: `tjctf{not_random_enough_64831eff}`


### ez-sql
Lại một bài SQLi nữa nhưng ở đây chúng ta sẽ có chút lưu ý:
![Imgur](https://i.imgur.com/xbKDFUE.png)

Tên `flag table` sẽ chứa uuid có độ dài 128bit nhưng ở phần truy vấn:
![Imgur](https://i.imgur.com/xmJQpIm.png)

Độ dài `name` không quá 6 ký tự. Vậy làm sao để giải quyết được bài này ???
Ở đy chúng ta sẽ có 1 trick:
![Imgur](https://i.imgur.com/AyfXH7w.png) 

![Imgur](https://i.imgur.com/NflP8yk.png)

Sử dụng SQLmap:
Flag: `tjctf{ezpz_l3mon_squ33zy_603f8308}`

### back-to-the-past
Bài này là một dạng bypass qua JWT để có thể lấy được flag. Cùng check source nào:
![Imgur](https://i.imgur.com/zPdVnu9.png)

![Imgur](https://i.imgur.com/eXUCqGJ.png)

OK, vậy là chúng ta không thể tạo năm nhỏ hơn 1970 rồi. Cùng xem qua cách tạo token nào:
![Imgur](https://i.imgur.com/AKc8g36.png)

Và phương pháp decode để lấy dữ liệu:
![Imgur](https://i.imgur.com/EsxN1tV.png)

![Imgur](https://i.imgur.com/bCF4832.png)

Vậy theo flow của bài này thì đầu tiên sẽ tạo ra Token với `algorithm` mặc định là RS256. Sau đó được nhận `alg` từ `json_header` và decode theo phương pháp đó. Từ đây chúng ta có thể làm mất đi phần xác thực `Signature` bằng cách để `alg` là **NONE**
Solve code: https://github.com/NamMTA892/TJCTF_2023/blob/main/back-to-the-past-solve.py
Setup cookie và vào endpoint `retro` để lấy flag.
Flag: `tjctf{very_very_retro_3bbff613}`


### 