pwnable.kr의 'fd' 문제 풀이

jammy0903·2024년 8월 11일

write-up

목록 보기
1/4

1. 문제 접근

먼저 주어진 명령어로 서버에 접속합니다:

ssh fd@pwnable.kr -p2222

이 명령어는 SSH(Secure Shell)를 사용해 pwnable.kr 서버의'fd' 사용자 계정으로 2222번 포트를 통해 접속하는 것입니다.

2. 파일 탐색

서버에 접속한 후, 현재 디렉토리의 파일들을 확인합니다:

ls -al

디렉토리 내용

주목할 만한 파일로 'fd.c'가 보입니다. 이 파일의 내용을 살펴보겠습니다:

nano fd.c

fd.c 파일 내용

3. 코드 분석

atoi 함수

코드에서 atoi 함수가 사용되고 있습니다. 이 함수는 "ASCII to Integer"의 약자로, 문자열을 정수로 변환하는 역할을 합니다.

atoi 함수의 특징:

  1. 공백 무시: 문자열 시작 부분의 모든 공백(스페이스, 탭, 줄바꿈)을 무시합니다.
  2. 부호 확인: 공백 다음 '+' 또는 '-' 부호가 있으면 인식합니다.
  3. 숫자 변환: 연속된 숫자들을 정수로 변환합니다.
  4. 결과 반환: 변환된 정수를 반환하며, 실패 시 0을 반환합니다.

atoi 예시:

  • " 123abc" → 123 반환

  • "-456 " → -456 반환

  • "789원" → 789 반환

  • "abc123" → 0 반환 (변환 실패)

  • " +42" → 42 반환

유사 함수들

  • atof(): 문자열을 부동 소수점으로 변환
  • atol(), atoll(): 문자열을 long 또는 long long 정수로 변환
  • strtod(), strtof(), strtold(): 문자열을 double, float, long double로 변환
  • strtod32(), strtod64(), strtod128(): 문자열을 10진수 부동 소수점으로 변환
  • strtol(), strtoll(): 문자열을 long 및 long long 정수로 변환

이후 분석은 이 atoi 함수의 동작을 고려하며 진행해야 할 것 같습니다.

tip) man 명령어를 이용하면  사용법과 다양한 옵션에 대한 설명이 표시됩니다.  

핵심 로직

int fd = atoi( argv[1] ) - 0x1234;
int len = 0;
len = read(fd, buf, 32);
if(!strcmp("LETMEWIN\n", buf)){
    printf("good job :)\n");
    system("/bin/cat flag");
    exit(0);
}
  1. fd는 file descriptor함수입니다. 중요해요
    1-2. 0x1234는 16진수입니다. 정수로는 4660이에요
  2. read 함수는 fd로부터 32바이트를 읽어 buf에 저장합니다.
    2-2. read의 매개변수 중 fd=0/1/2 일때 모두를 알아야 합니다.
  3. buf의 내용이 "LETMEWIN\n"과 일치하면 플래그를 출력합니다.

5. 취약점 파악

핵심 취약점은 fd 변수의 값을 조작할 수 있다는 점입니다.
fd가 0이 되면 read 함수는 표준 입력(키보드)에서 데이터를 읽게 됩니다.

6. 익스플로잇 전략

  1. fd가 0이 되도록 인자를 설정합니다: 0x1234 = 4660
    이거 정수로 쓰는이유는 atoi때문이져
  2. 프로그램 실행 후 "LETMEWIN"을 입력합니다.

7. 익스플로잇 실행

./fd 4660
LETMEWIN

실행 결과:
성공짤

flag: mommy! I think I know what a file descriptor is!!


요약

  1. 파일 디스크립터
  2. atoi 함수
  3. read 함수의 사용법과 입력 소스 제어
  4. 간단한 버퍼 비교를 통한 조건부 실행

0개의 댓글