[Toddler's Bottle] fd

#코딩노예#·2022년 7월 15일
0

pwnable.kr

목록 보기
1/3

이번 문제는 파일 디스크립터에 대한 문제인 거 같습니다. 먼저 파일 디스크립터에 대해 살펴보면


파일 디스크립터란 특정한 파일에 접근하기 위한 추상적인 키입니다.
모든 프로세스가 갖추어야 하는 표준 POSIX 파일 서술자에는 3개가 있습니다.

0표준 입력 (stdin)
1표준 출력 (stdout)
2표준 오류 (stderr)

이제 문제를 풀기위해 서버에 접속해서 ls -l 명령어를 입력해보면

fd@pwnable:~$ ls -l
total 16
-r-sr-x--- 1 fd_pwn fd   7322 Jun 11  2014 fd
-rw-r--r-- 1 root   root  418 Jun 11  2014 fd.c
-r--r----- 1 fd_pwn root   50 Jun 11  2014 flag

flag 파일과 fd 파일이 있습니다.


fd.c 파일을 출력해보면

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
        if(argc<2){
                printf("pass argv[1] a number\n");
                return 0;
        }
        int fd = atoi( argv[1] ) - 0x1234;
        int len = 0;
        len = read(fd, buf, 32);
        if(!strcmp("LETMEWIN\n", buf)){	// buf가 "LETMEWIN\n"이면
                printf("good job :)\n");	// "good job :)\n" 출력
                system("/bin/cat flag");	// "/bin/cat flag" 실행
                exit(0);	// 종료
        }
        printf("learn about Linux file IO\n");
        return 0;

}

buf가 LETMEWIN\n이면 flag 파일을 출력해주는 프로그램입니다.


buf가 LETMEWIN\n이 되려면 buf에 값을 입력할 수 있어야 하기 때문에, read 함수에 대해 살펴보면

헤더unistd.h
형태ssize_t read(int fd, void *buf, size_t len);
인수int fd : 파일 디스크립터 void *buf : 파일을 읽어 들일 버퍼 size_t len : 버퍼의 크기
반환실패 → -1 성공 → 읽어들인 바이트 수

fd를 0으로 만들면 read() 함수를 이용해서 buf에 표준 입력을 할 수 있습니다.


먼저 fd를 0으로 만들려면

int fd = atoi( argv[1] ) - 0x1234;

0x1234 = 4660
argv[1]4660이면 fd가 0이 됩니다.

4660을 argv[1]의 인자로 fd를 실행시켜보면

fd@pwnable:~$ ./fd 4660
LETMEWIN

표준 입력을 받게 되고 LETMEWIN을 입력하면


good job :)
mommy! I think I know what a file descriptor is!!

플래그가 출력되었습니다.

0개의 댓글