Post

(43) pwnable.kr fd 문제 풀이

3월이 시작된 기념으로 앞으로는 포너블도 같이 풀이하도록 하겠습니다. 일주일에 포너블 하나, 드림핵 웹해킹 하나는 최소한 올릴 수 있도록 하겠습니다.

문제 설명

Mommy! what is a file descriptor in Linux?

문제 풀이

들어와서 ls를 쳐보니

위와 같은 3개의 파일이 존재 했습니다.
fd는 실행 파일로, 실행해보면

위와 같이 pass argv[1] a number라는 메세지가 출력됩니다.
당연히 flag는 권한이 맞지 않아서 읽을 수 없습니다.

fd.c 파일은 fd의 소스코드 입니다. 이 파일을 읽어보면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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)){
                printf("good job :)\n");
                system("/bin/cat flag");
                exit(0);
        }
        printf("learn about Linux file IO\n");
        return 0;

}

위와 같은 코드를 볼 수 있습니다.

일단 인자가 2개 이상인지 검사하여 2개 미만이면, 즉 아무 인자도 없이 실행했다면, pass argv[1] a number를 출력하도록 되어 있습니다. 아까 출력에서는 인자를 넘겨주지 않아서 위 메세지가 출력되었던 모양입니다.
그 다음 줄에서는 atoi( argv[1] ) - 0x1234를 계산하여 fd라는 변수를 설정하고 있네요. 그리고 앞서 계산한 fd의 값을 이용해 read(fd, buf, 32);buf에 읽어들이고 있네요. 마지막으로 buf의 값이 LETMEWIN\n인지를 검사한 뒤에 flag를 보여줍니다.

File Descriptor(fd)

File Descriptor는 유닉스 계열 시스템에서 프로세스가 파일을 다룰 때 사용하는 개념으로 파일에 접근할 때 사용되는 추상적인 값 입니다.
프로세스가 파일은 열면(open) File Descriptor값이 부여되고, 이 값을 이용해 파일에 접근할 수 있습니다.
시스템에는 기본적으로 할당되는 표준입력(Standard Input), 표준 출력(Standard Output), 표준에러(Standard Error)라는 File Descriptor가 있고, 각각 0, 1, 2라는 값이 할당 됩니다. 이후에 사용되는 프로세스는 3부터 시작하여 중복되지 않는 가장 작은 값을 부여 받습니다.

위에서 알아본 바에 따르면, 우리는 File Descriptor를 임의로 지정할 수 있고, 해당 File Descriptor 을 이용해 읽은 값이 LETMEWIN\n라면 flag를 얻을 수 있습니다.
파일을 열고 하는것은 번거로우니, fd를 0이 되도록 하여 표준 입력을 통해 buf에 값을 받을 수 있도록 하는게 좋겠습니다.

인자로 받은 값에서 0x1234 즉, 4660을 빼고 있으니 인자로 넘긴 값이 4660이라면 Standard Input로 작동할 겁니다. 그럼 우리는 LETMEWIN을 입력해 주면 됩니다.

그러면 이렇게 flag가 출력되는 것을 확인할 수 있습니다.

This post is licensed under CC BY 4.0 by the author.