ctfs
  • 👋Hello!
  • 🏴Practice
    • 🌐Cryptohack
      • Introduction
      • General
        • Encoding
        • XOR
        • Mathematics
        • Data Formats
      • Symmetric Ciphers
        • How AES Works
        • Symmetric Starter
        • Block Ciphers 1
        • Stream Ciphers
      • Mathematics
        • Modular Math
        • Lattices
      • RSA
        • Starter
        • Primes Part 1
        • Public Exponent
    • 🌐PortSwigger
      • Path Traversal
      • File Upload
      • SSRF Attacks
    • 🌐TryHackMe
      • Basic Skills
      • Linux
      • Penetration Testing
      • Networking
      • OSINT
  • 🚩Competitions
    • 2025
      • 🇮🇩GKSK#9 Osintathon
        • Mudik Lebaran (100 pts)
        • Foto Patung (100 pts)
        • Kolektor Komik (100 pts)
        • Tolong Aku (100 pts)
        • Kencan Pertama (100 pts)
        • Nama Si Pelaku (100 pts)
        • Cekidot (100 pts)
        • Ledakan! (100 pts)
        • 🎹🎶 (100 pts)
        • Batu Besar (100 pts)
        • Komentar (100 pts)
        • Ini dimana? (100 pts)
        • Koordinat Foto Misterius (100 pts)
        • Bianglalaaa (100 pts)
        • Aku Hacker (100 pts)
        • Anjazzz (100 pts)
        • Dikirim Kakakku (129 pts)
        • Ingfo Loker (154 pts)
        • MISSING 00 (100 pts)
        • MISSING 01 (154 pts)
        • Siapa Aku? (154 pts)
      • 🇮🇩IFEST 13
        • Ququerer (250 pts)
        • Silent Trace (370 pts)
        • Nugas (Solved After Event)
        • Free Flag (280 pts)
        • Brute (Solved After Event)
        • Web V1 (Solved After Event)
        • Bypass (Solved After Event)
        • Orbiter (Solved After Event)
      • 🌐OSINT Combine (Wildlife)
        • Getting Started (100 pts)
        • Proper Poppy (100 pts)
        • Legendary Beasts (200 pts)
        • Shadow Fleet (200 pts)
        • Proper Poppy II (200 pts)
        • Not So Smug Smuggler (200 pts)
        • Icy (200 pts)
        • Forest Pals (200 pts)
        • Safari Time II (200 pts)
        • Sneaky! (200 pts)
        • Hello Friend (300 pts)
        • Busy As A (300 pts)
        • Get Rotated! (300 pts)
        • High Seas (300 pts)
        • Nocturnal (300 pts)
        • Safari Time (400 pts)
        • Peak Weather (400 pts)
        • Singsong (400 pts)
        • Falling Fell (500 pts)
        • Kitty Cats (500 pts)
      • 🇮🇩RECURSION
        • let him cook
        • Basic Math
        • Favourite Number
        • Zarrar Cipher (100 pts)
        • paBlue Team (100 pts)
        • [🩸] I wish I was there on December 21, 2024 (100 pts)
        • Small House (200 pts)
        • [🩸] Mission Difference (456 pts)
    • 2024
      • 🌐Santa Claus CTF
        • Complete Picture
        • Day 1 - Big Bang
        • Day 2 - The Summer Job
        • Day 3 - The Visitors
        • Day 4 - Happy Birthday
        • Day 5 - Say My Name
        • Day 6 - Say "Cheese"
        • Day 7 - Revealing Pixels
        • Day 8 - Connecting The Dots
        • Day 9 - 404 Not Found
        • Day 10 - Breaking News
        • Day 11 - Ayrton Santa
        • Day 12 - Lost and Found
        • Day 13 - Planespotting
        • Day 14 - Santa Surveillance
        • Day 15 - Shaken, Not Stirred
        • Day 16 - Status Update
        • Day 17 - Waste ...of Time
        • Day 18 - Lost in Translation
        • Day 19 - Santa's Clones
        • Day 20 - Losing Tracks
        • Day 21 - Sing my Song
        • Day 22 - Eagle Eye
        • Day 23 - Distances Matters
        • Day 24 - Mastermind
      • 🌐Cyber Jawara International
        • Stone Game (100 pts)
        • prepare the tools (176 pts)
        • Persona (484 pts)
      • 🌐OSMOSIS Precon CTF
        • 1 The art of espionage
        • # 2 The Hack
        • # 3 The rabbit hole
        • # 4 The Association
        • # 6 Where is number 5
        • # 5 Who is it
        • Too many Layers
        • The prize
      • 🇮🇩Intechfest
        • Sanity Check (100 pts)
        • Alin (113 pts)
        • GerakSendiri (106 pts)
        • Details (100 pts)
      • 🇮🇩COMPFEST 16
        • Let's Help John! (100 pts)
        • money gone, wallet also gone (100 pts)
        • head’s up! (493 pts)
        • CaRd (304 pts)
        • Sanity Check (100 pts)
      • 🇮🇩Gemastik
        • Baby AES (451 pts)
        • Baby Structured (100 pts)
      • 🇮🇩Technofair 11
        • Kenangan
        • Xorban
        • Marsha
        • Siap Tempur!!
        • eftipi
        • kurang berarti
        • DUMPling
        • Malicious
      • 🌐DIVER OSINT
        • chiban
      • 🇮🇩GKSK#8 Osintathon
        • Sport Location
        • Meklaren lu warna apa boss ?
        • Postcode
        • Rumah Minang
        • Latihan
        • Anak Misterius
        • Travelling Anywhere
        • The Thief
        • Danger Watch
        • Misteri Ruang Angkasa
        • Fun Walk
        • I am Late
        • My Oshi
        • Wellcome to my Youtube Channel
        • Pesan Tersembunyi Wingdings
        • Salah Fokus
        • Apa itu GKSK?
        • Foto Bersejarah
        • Picture
        • Nostalgia Child
        • oldschool
        • Summer Olympic
      • 🇮🇩Techcomfest
        • pemanasan
        • crackable
        • Kuli-ah forensik
    • 2023
      • 🇮🇩Cyber Jawara
        • daruma
      • 🇮🇩NCW
        • Simple (220 pts)
        • wangsaf (320 pts)
        • Sillyville Saga (220 pts)
        • Freminhelp (Solved after event)
      • 🇮🇩Hology 6
      • 🇮🇩SlashRoot 7
        • Summary (441 pts)
        • eeee (480 pts)
        • Zebra Cross (409 pts)
        • Waka Waka eh eh (185 pts)
        • ANABUL (250 pts)
      • 🇮🇩COMPFEST 15
        • not simply corrupted (316 pts)
        • Artificial secret (356 pts)
      • 🇮🇩Gemastik
        • easy AES
        • k-1
        • Gen Z
      • 🇮🇩TechnoFair 10
        • RSA Bwang
        • Marsah
        • rapsodi
        • Pengen Merch JKT 😢
        • space mono
        • file pemberian fans
        • bantu aku mencari sebuah rahasia
    • 2022
      • 🇮🇩NCW
        • sabeb64 (331 pts)
        • cakemath (451 pts)
        • Downloader (244 pts)
        • 199 passcode (Solved after event)
      • 🇮🇩TEDCTF
      • 🇮🇩Gemastik
      • 🇮🇩OSCCTF
      • 🇮🇩ARA
  • 🪦Old Hello
Powered by GitBook
On this page
  1. Competitions
  2. 2022
  3. NCW

199 passcode (Solved after event)

PreviousDownloader (244 pts)NextTEDCTF

Last updated 12 months ago

Diberikan file 199passcodehahahoho.pyc. Pertama-tama, kita decompile dulu file ini menggunakan tool . Setelah itu, kita dapatkan source code sebagai berikut.

# uncompyle6 version 3.7.4
# Python bytecode 3.8 (3413)
# Decompiled from: Python 2.7.17 (default, Sep 30 2020, 13:38:04)
# [GCC 7.5.0]
# Warning: this version of Python has problems handling the Python 3 "byte" type in constants properly.

# Embedded file name: soal.py
# Compiled at: 2022-11-07 09:36:17
# Size of source mod 2**32: 4776 bytes
import tkinter as tk
from tkinter import *
from Crypto.Util.number import *
from tkinter.messagebox import *
import random
turn = 0
random.seed(0)

def main():
    global turn

    class Node:

        def __init__(self, data):
            self.data = data
            self.l = None
            self.r = None
            self.height = 1

    class AdelsonVelskiiLandis:

        def insert(self, root, key):
            if not root:
                return Node(key)
                if key < root.data:
                    root.l = self.insert(root.l, key)
                else:
                    root.r = self.insert(root.r, key)
                root.height = 1 + max(self.getHeight(root.l), self.getHeight(root.r))
                b = self.getBal(root)
                if b > 1:
                    if key < root.l.data:
                        return self.rRotate(root)
                if b < -1:
                    if key > root.r.data:
                        return self.lRotate(root)
            else:
                if b > 1:
                    if key > root.l.data:
                        root.l = self.lRotate(root.l)
                        return self.rRotate(root)
                if b < -1 and key < root.r.data:
                    root.r = self.rRotate(root.r)
                    return self.lRotate(root)
            return root

        def lRotate(self, z):
            y = z.r
            T2 = y.l
            y.l = z
            z.r = T2
            z.height = 1 + max(self.getHeight(z.l), self.getHeight(z.r))
            y.height = 1 + max(self.getHeight(y.l), self.getHeight(y.r))
            return y

        def rRotate(self, z):
            y = z.l
            T3 = y.r
            y.r = z
            z.l = T3
            z.height = 1 + max(self.getHeight(z.l), self.getHeight(z.r))
            y.height = 1 + max(self.getHeight(y.l), self.getHeight(y.r))
            return y

        def getHeight(self, root):
            if not root:
                return 0
            return root.height

        def getBal(self, root):
            if not root:
                return 0
            return self.getHeight(root.l) - self.getHeight(root.r)

        def check(self, state, root, n, x):
            state = root
            for i in n:
                if i == '0':
                    state = state.l
                else:
                    if i == '1':
                        state = state.r
                if state == None:
                    showwarning(title='error lur', message='Error invalid node!\nResetting level...')
                    return False
                if state.data == x:
                    return True
                showwarning(title='yah', message='Wrong answer! \nResetting level...')
                return False

    def decrypt(key, plain):
        dec = ''
        key = long_to_bytes(int(''.join(key), 2))
        for i in range(len(key)):
            dec += chr(key[i] ^ plain[i])
        else:
            return dec

    def initialization():
        tr = AdelsonVelskiiLandis()
        root = None
        for i in init:
            root = tr.insert(root, i)
        else:
            return (
            tr, root)

    def submit(root):
        global turn
        try:
            u = inp.get()
            if not tr.check(0, root, u, target[turn]):
                turn = 0
                validatedkey.clear()
            else:
                showinfo(title='anjay', message='Correct!')
                validatedkey.append(u)
                inp.delete(0, 'end')
                turn += 1
            if turn == len(target):
                showinfo(title='kelazzz', message=(decrypt(validatedkey, FLAG)))
        except SyntaxError:
            showerror(title='Error', message='Invalid input!')
        else:
            text.set(199 - turn)

    num = [i for i in range(1, 201)]
    init = num.copy()
    random.shuffle(init)
    FLAG = [70, 106, 196, 124, 8, 66, 39, 192, 6, 86, 222, 245, 244, 101, 138, 58, 30, 27, 51, 31, 63, 175, 0, 3, 25, 58, 24, 225, 209, 18, 7, 253, 185, 174, 197, 236, 7, 171, 127, 126, 232, 243, 65, 171, 144, 237, 160, 22, 105, 213, 23, 12, 35, 20, 105, 144, 235, 96, 74, 96, 37, 207, 95, 111, 24, 156, 0, 165, 123, 211, 243, 141, 213, 104, 71, 106, 157, 252, 198, 22, 19, 73, 6, 154, 31, 47, 157, 200, 255, 246, 161, 214, 226, 97, 196, 87, 61, 201, 204, 192, 130, 73, 143, 58, 243, 190, 72, 9, 131, 29, 20, 89, 235, 149, 143, 178, 154, 47, 102, 141, 11, 158, 96, 28, 34, 168, 62, 204, 204, 74, 9, 205, 209, 133, 2, 58, 20, 108, 206, 224, 125, 223, 66, 21, 143, 157, 21, 203]
    validatedkey = []
    tr, troot = initialization()
    target = init.copy()
    target.remove(troot.data)
    random.shuffle(target)

    def on_focus_in(entry):
        if entry.cget('state') == 'disabled':
            entry.configure(state='normal')
            entry.delete(0, 'end')

    def on_focus_out(entry, placeholder):
        if entry.get() == '':
            entry.insert(0, placeholder)
            entry.configure(state='disabled')

    root = tk.Tk()
    root.geometry('300x150')
    root.title('Kunci Pintu')
    root.maxsize(300, 150)
    root.minsize(300, 150)
    inp = Entry(root, width=33, borderwidth=3, relief=RIDGE)
    inp.grid(pady=5, row=0, sticky='w', padx=15)
    inp.insert(0, 'Input Secret Key')
    inp.configure(state='disabled')
    x_focus_in = inp.bind('<Button-1>', lambda x: on_focus_in(inp))
    submitbutton = Button(root, text='submit', width=30, command=(lambda : submit(troot)), bg='red', fg='white', borderwidth=3, relief=RIDGE)
    submitbutton.grid(row=1, sticky='w', padx=15, pady=5)
    text = StringVar()
    text.set(199 - turn)
    textbox = Label(root, textvariable=text, justify='center', width=13)
    textbox.config(font=('Courier', 30))
    textbox.grid(pady=5, row=2, sticky='w')
    root.mainloop()


if __name__ == '__main__':
    main()

Ketika kodenya dicoba di-run, muncul sebuah error yang mengarah pada fungsi insert di dalam kelas AdelsonVelskiiLandis. Rupanya pada bagian ini sepertinya ada error pada saat proses decompiling.

Di sini yang terlihat aneh adalah adanya serangkaian if-else setelah return, padahal kalau seperti itu maka tidak akan terbaca. Oleh karena itu, kami mencoba untuk menggesernya 1 tab ke kiri. Selain itu, di bagian paling bawah tertulis if b < -1 and key < root.r.data: tapi untuk conditional if’s di atasnya tidak. Oleh karena itu kami coba samakan cara penulisannya.

Setelah mencoba memahami kode dari source code-nya, kami menyadari bahwa ini adalah semacam program permainan guess the passcode di mana passcode yang diminta adalah sebuah string yang merepresentasikan path/langkah yang diambil untuk mencari sebuah node dalam AVL Balanced Binary Search Tree (BBST). Jadi misalnya node paling atas itu root, lalu child nodenya ada dua, node yang di kiri nilainya lebih kecil dan node yang di kanan nilainya lebih besar, lalu masing-masing node tersebut memiliki dua child node juga, yang kiri lebih kecil dan yang kanan lebih besar, dan seterusnya. Nah untuk mencari node-node tersebut, kita bisa menuliskan sebuah baris string di mana ‘0’ berarti ‘ke kiri’ dan ‘1’ berarti ‘ke kanan’ sebagaimana yang dijelaskan dalam fungsi check di dalam kelas AdelsonVelskiiLandis.

Sementara itu, di source code juga ada list target yang berisi nilai-nilai yang ingin dicari dari BBST tersebut. Jumlah angka dalam target ada 199 angka, dan jumlah turn yang kita miliki dalam permainan ini adalah 199, jadi kita harus menebak semua path dengan benar supaya variabel validatedkey terisi penuh dan fungsi decrypt terpanggil lalu kita mendapatkan flag.

Untuk mendapatkan path untuk semua elemen di target, kita bisa menambahkan fungsi search berikut ke dalam kelas AdelsonVelskiiLandis. Lalu kita loop untuk semua elemen di target dan kita masukkan ke dalam list key_list. Kalau sudah selesai tinggal kita panggil fungsi decrypt lalu kita masukkan key_list dan FLAG sebagai argumennya.

Flag-pun kita dapatkan.

Flag: NCW22{congratz_you_have_successfully_decompiled_the_pyc_then_solving_the_tree_traversal_problem_and_find_this_flag_damn_you_really_deserve_it_champ}

🚩
🇮🇩
https://www.decompiler.com/