이번에 풀이할 문제는 pwnable.kr의 fd 문제다. 다른 사이트의 문제들과 달리 문제 파일 없이 ssh 서버 주소만 주어져 있다.
주어진 주소로 putty를 통해 접속했다. 접속하고 ls 명령어를 쳐보니 fd(문제 파일), fd.c(c언어 소스 코드), flag가 주어져 있다.
일단 문제 파일을 실행해 봤다. 인자 없이 실행하니 인자를 달라는 문구가 나와서 더미 값으로 1234를 주고 실행해 봤다.
1234를 주고 실행하니 learn about Linux file IO(리눅스 파일 io에 대해 공부해라)라는 문구가 나온다.
일단 혹시 모르니 flag를 cat 명령어로 한 번 확인해봤다.
당연하게도 flag를 볼 수 없었기 때문에 문제를 풀기 위해 fd.c를 cat 명령어로 확인해봤다.
#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; // 입력 값을 정수형으로 변환한 후 - 0x1234한 값을 정수형 변수 fd에 저장
int len = 0;
len = read(fd, buf, 32); // fd 옵션으로 읽은 값을 32byte만큼 buf에 저장
if(!strcmp("LETMEWIN\n", buf)){ // buf의 값이 LETMEWIN\n이면 쉘 획득
printf("good job :)\n");
system("/bin/cat flag");
exit(0);
}
printf("learn about Linux file IO\n");
return 0;
}
위는 fd의 c언어 코드에 주석을 달아본 것이다. 처음에는 취약점이 보이지 않아 해맸지만 read 함수의 형태와 fd에 대해 알아보니 풀 수 있었다.
read 함수는 fd, buffer, buffersize를 인자로 받는데(참고 : msdn) 여기서 fd는 파일 디스크립터다.
이 fd에 0이 들어간다면 사용자의 입력을 받을 수 있게된다고 한다.(참고 : 파일 디스크립터)
위 코드를 보면 인자를 atoi 함수를 통해 정수형으로 바꿔주는데, 이 바뀐 정수형에 - 0x1234한 값이 read의 fd 인자로 들어가게 된다. 즉 - 0x1234를 했을 때 0이 되는 값을 인자로 준다면 fd가 0이돼 입력을 받을 수 있게 되는 것이다.
0x1234는 10진수로 4660이므로 이 4660을 인자로 준 후 입력란에 LETMEWIN을 입력해주면 될 것 같다.
'Wargame > Pwnable.kr' 카테고리의 다른 글
pwnable.kr [random] (0) | 2021.04.08 |
---|---|
pwnable.kr [leg] (0) | 2021.04.08 |
pwnable.kr [flag] (0) | 2021.04.08 |
pwnable.kr [bof] (0) | 2021.04.04 |
pwnable.kr [collision] (0) | 2021.04.02 |