pwnable.kr의 첫 문제인 fd 문제를 풀어보자.
[문제]
Linux의 file descriptor가 해결의 열쇠가 될 것 같다.
접속하면 실행파일 fd, 소스 fd.c와 flag파일이 있다.
fd.c를 살펴보자.
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; } | cs |
먼저 문자열 buf를 선언한 다음, int형 변수 fd에 인자로 받은 숫자에서 0x1234를 뺀 값을 대입한다.
그리고 read함수를 호출하고, buf와 LETMEWIN\n을 비교하여 같으면 flag를 보여주는 코드이다.
buf를 어떻게 LETMEWIN\n으로 만드느냐가 이 문제의 관건이라고 할 수 있겠다.
buf는 read함수에서 참조되고 있으므로 read함수를 알아보자.
리눅스의 read함수
1 | ssize_t read (int fd, void *buf, size_t len); | cs |
read() 함수는 위와 같이 정의되어 있다.
buf는 읽어들일 버퍼 같고, len은 그 길이 같은데, fd란 과연 무엇일까?
이때 fd는 문제의 힌트에서 언급한 file descriptor의 약자로서, 먼저 그 개념을 알아볼 필요가 있다.
File Descriptor
유닉스 계열의 운영체제에서는 모든 요소가 파일로서 관리되는데, 파일 디스크립터는 파일에 접근하기 위해 사용되는 개념이다.
리눅스에서 파일을 읽고 쓰기 위해서는 반드시 파일을 Open해야 하는데 파일이 오픈되면 커널은 해당 프로세스의 파일 디스크립터 숫자 중에 사용하지 않는 가장 작은 값을 할당하고 파일 디스크립터 테이블에 등록시켜 관리한다. 그 다음 프로세스가 열려 있는 파일에 시스템 콜을 이용해서 접근할 때 파일 디스크립터 값을 이용해서 이 파일을 가리킬 수 있다.
또한, 프로세스마다 관례적으로 0,1,2 번은 예약되어 있는데 각각 번호별 의미는 다음과 같다.
0 : 표준 입력 (stdin) / 1 : 표준 출력 (stdout) / 2 : 표준 오류 (stderr)
따라서 실제 하나의 파일을 생성하게 되면 “3번” 부터 File Descriptor가 부여된다.
문제로 돌아와서, read함수는 결국 fd가 가리키고 있는 파일에서 len만큼 buf에 불러들인다고 해석할 수 있다.
우리는 read함수를 통해 buf에 LETMEWIN\n이라는 문자열을 읽어들여야 한다.
read함수의 fd 인자에 stdin을 가리키는 0을 전달한다면 우리가 LETMEWIN을 입력하여 buf에 저장할 수 있을 것이다.
따라서 fd값이 0이 되도록 하여야 하므로 프로그램을 실행시키고 0x1234의 십진수 값인 4660을 인자로 전달하면 된다.
pwnable 첫 문제를 풀었다!
[참고문헌]
http://noplanlife.com/?p=1211
http://dev.plusblog.co.kr/22
http://unabated.tistory.com/entry/%ED%8C%8C%EC%9D%BC-%EB%94%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%84%B0
'WriteUp > pwnable.kr' 카테고리의 다른 글
pwnable passcode writeup (0) | 2019.01.01 |
---|---|
pwnable coin1 writeup (2) | 2018.12.30 |
pwnable input writeup (0) | 2018.12.30 |