해킹/pwnable.kr

생초보 pwnable.kr - fd write-up

hellowhales 2023. 3. 25. 13:48
728x90

사전 지식


 1. fd(file descriptor)

 

     리눅스/유닉스 시스템에서는 모든 것이 파일로 관리됩니다. 예를 들면 화면에 입력과 출력을 받는 것도 어떤 가상의 파일을 만들어서 그 파일에 입력하고 그 파일을 읽어들이는 식이죠. fd는 포인터로 fd에 지정해준 파일을 가르킵니다. 

int fd, count;
char buf[10];
fd = open("Hellowhales.txt" , O_RDONLY);
count = read(fd, buf, 10);

위와 같이 사용하면 fd는 Hellowhales.txt 파일을 가르키게 되고 이 fd를 통해 해당 파일에 여러 작업을 할 수 있습니다.

fd에는 보통 음이 아닌 정수가 사용되는데 이 때 0,1,2 각각 표준 입력(STDIN_FILENO), 표준 출력(STDOUT_FILENO), 표준 에러(STDERR_FILENO)은 프로세스가 생성되면 디폴트로 열리고 지정됩니다. 따라서 사용자 정의 fd는 3부터 지정됩니다. 

 

 

Write-UP


우선 문제 제목이 fd 인것을 보아 파일에 관련된 문제라고 추측하였습니다. 

 

 

문제를 클릭해서 보니 대놓고 file descirptor가 뭐냐고 물어보네요. 원격 접속 프로토콜인 ssh를 이용해 사이트에 접속해서 푸는 방식입니다. linux에 위의 명령어와 패스워드 입력해서 들어가면 됩니다. 

들어가서 ls명령어를 통해 무슨 파일이 있는지 확인해보니 3개의 파일이 있네요. fd를 통해 flag를 알아내야 겠네요. 바로 fd.c 파일을 vi를 통해 들어갔습니다. 

 

코드를 보니 커맨드라인 인자 입력을 받고 그 인자를 정수로 바꿔 16진수 0x1234를 빼서 fd에 넣어줍니다. 그 다음 fd에서 32byte 읽어와 buf에 넣어주고 그 버프가 LETMEWIN이면 system 함수를 통해 flag에 도달할 것으로 보입니다.

 

흠... 커맨드라인 인자를 잘 주어야겠군요. 

 

위의 사전지식을 활용해서  fd가 0이면 표준 입력인 것을 이용합니다. read(0, buf, 32)가 되면 buf에 표준 입력을 통해서 값을 넣어줄 수 있겠죠. 따라서 커맨드라인 인자로 0x1234에 해당하는 값을 주면 됩니다. atoi가 스트링 숫자를 int 숫자로 바꾸어주므로 16진수 0x1234가 10진수 4660이므로 인자로 4660을 주면 됩니다. 그러면 fd가 0이되  read가 실행될 때 표준입력을 받으므로 한번더 쉘에서 입력을 받습니다. 이 때 LETMEWIN을 넣어주면 buf에 들어가고 if문의 조건이 성립되고 system이 실행됩니다.

 

재밋는 문구가 나오면서 flag에 해당하는 값을 주네요!

 

 

AFTER Review


기본적인 C지식와 fd에 대한 지식이 있으면 풀기 어려운 문제는 아니었습니다. 물론 처음 문제를 풀다보니 조금 헤맨 부분이 있지만 무난하게 풀 수 있었습니다. 

 

추가로 fd 값으로 표준 입력 0이 아닌 1,2인 표준 출력이나 표준 에러를 주어도 입력을 받으면서 작동하더라구요. 아마도 표준 입출력 stream이 하나의 파일 취급되어있어서 이를 read 함수로 보내면 그냥 입력을 받는다 정도로 생각되네요.(정확하진 않습니다...)

 

어쨋든 그래도 첫번째 문제를 무사히 풀 수 있어서 힘이 나네요. 처음부터 막히면 힘빠지니까요. 앞으로도 더욱 정진하겠습니다. 

728x90