zenCipher

Back

TSC CTF Individual 2025 - WriteupBlur image

CTFTime : https://ctftime.org/event/2598/ β†—

Date : Mon, 13 Jan. 2025, 09:00 UTC+7 β€” Thu, 16 Jan. 2025, 09:00 UTC+7

[!NOTE] Capturing the flag solo as zenCipher

Table of contents
  1. Welcome
  2. Crypto
  3. Pwn

πŸ‘‹ Welcome#

Free flag#

Just select all of the text, gambar desc Flag :

TSC{W3llc0me_t0_TSC2O2SIlIllI}
sh

Discord#

gambar desc Just enter to TSC’s discord and explore it

TSC{w31c0m3_t0_t5cc7f2025_d15c0rd!!!}
sh

πŸ” Crypto#

classic#

gambar desc

Attachment file : share.tgz

So, basically, it’s just a Affine Cipher β†— chall. It will do transformation and do this aritmetic operation to get the cipher text. C = (A Γ— P + B) mod N. We can use the formula to get the plain text. The formula is P=(Cβˆ’B)Γ—A βˆ’1 mod N. So, use this script to solve it.

classic-solver.py
import string

# Charset used in encryption
charset = string.digits + string.ascii_letters + string.punctuation

# Encrypted string (ciphertext)
encrypted_string = "o`15~UN;;U~;F~U0OkW;FNW;F]WNlUGV"

# Length of the charset
charset_length = len(charset)

# Function to decrypt using guessed A and B
def decrypt(encrypted_string, A, B, charset):
    mod_inverse_A = pow(A, -1, len(charset))
    decrypted = ""
    for c in encrypted_string:
        original_index = (charset.find(c) - B) * mod_inverse_A % len(charset)
        decrypted += charset[original_index]
    return decrypted

# Brute-force A and B
for A in range(2**16):  # Limiting the range for practicality; adjust as needed
    for B in range(2**16):
        try:
            decrypted_flag = decrypt(encrypted_string, A, B, charset)
            if decrypted_flag.startswith("TSC{"):  # Check for the correct flag format
                print(f"Found A: {A}, B: {B}")
                print("Decrypted flag:", decrypted_flag)
                break
        except ValueError:
            continue
python

Flag :

TSC{c14551c5_c1ph3r5_4r5_fr4g17e}
sh

πŸ’» Pwn#

gamble_bad_bad#

Attachment file : main.cpp

Because the game.jackpot_value gets input user only takes 20 bytes of buffer. So, we can overflow it to get into jackpot() function using this payload

AAAAAAAAAAAAAAAAAAAA777 | nc 172.31.0.2 1337
sh

Flag :

TSC{Gamb1e_Very_bad_bad_but_}
sh

Thanks for read this writeup. If u wanna support me, buy me a coffee here β†— or click button below

TSC CTF Individual 2025 - Writeup
https://zenc.my.id/blog/tsc-ctf-2025
Author Abi Abdillah
Published at January 17, 2025