쉬는시간/pwnable.kr

[pwnable.kr]Toddler - fd 풀이

happy-nut 2017. 5. 25. 21:35

pwnable.kr에서 만나볼 수 있는 가장 쉬운 문제이자 가장 처음 만나게 되는 문제입니다. 

엄마! Linux에서 파일 디스크립터가 무엇인가요? 라는 문제네요. 만약 정말 초보자라면 저 링크를 따라가서 동영상을 보라고 하는데 문제 풀 때는 몰랐다가 이제서야 봤습니다. 보고 싶으신 분들은 한 번 보시고 어떤지 댓글로 남겨주세요.ㅎ

fd@pwnable.kr에 포트 2222번으로 접속해 보라고 합니다. 접속 툴로는 putty를 사용했습니다.

접속을 해서 문제에서 알려준 패스워드를 입력하고 난 후, ls -l 명령어를 이용해 한 번 둘러봅니다.

flag파일이 하나 있고, fd라는 프로그램과 fd.c라는 프로그램 소스파일이 보입니다. fd가 setuid가 걸려있다는 점을 모두 눈치채셨기 바랍니다.

setuid가 걸려있는 파일은 실행될 때 파일소유자의 권한을 얻게 됩니다. flag가 현재는 fd_pwn계정과 root계정만 열람할 수 있게 되어 있지만, fd가 실행되면서 권한이 승격되어 있는 틈을 타 flag파일을 열어 볼 수 있게 되는 것이죠.

fd.c의 모습입니다. 익스플로잇을 할 필요도 없이 그냥 문제의 조건에 맞춰주면 cat flag를 해주네요. 따라서 앞에 설명은 이해하지 못하셨더라도 문제를 푸는 데는 전혀 지장이 없습니다. 

코드를 이해하려면 read함수가 어떤 함수인지 알아야 합니다. Linux시스템에서 man read 를 통해 read라는 함수가 어떤 친구인지 알 수 있습니다.

fd로부터 count만큼의 바이트를 읽어서 buf에다가 써주는 친구였네요.

file descriptor는 파일을 관리하기 위해 운영체제에서 필요로 하는 정보를 가지고 있는 정수입니다. 쉽게 말해 운영체제가 만드는 소켓이나 파일들에게 부여된 정수 번호입니다. 한 가지 기억해야 할 것은 Linux에서 file descriptor는 0인 경우 표준 입력(STDIN), 1인 경우 표준 출력(STDOUT), 2인 경우 표준 에러(STDERR)로 정해져 있다는 점입니다. 물론 소켓이나 파일을 오픈하면 0, 1, 2이외의 정수를 할당받게 되겠죠?

아래 사진에 잘 나와 있습니다.

다시 문제로 돌아가서, fd값을 0으로 만들어 준다면 read함수는 사용자의 표준 입력을 기다리는 함수로 탈바꿈 하게 되는 것이죠!

즉 문제에서 요구하는 바는, 첫번째 인자로 넣어준 값 - 0x1234가 0이라면 buf[32]에 입력을 받아줄 건데 그 때 LETMEWIN 이라는 문자열을 입력해 달라 정도겠습니다.

계산기를 켜서 0x1234를 계산해도 되겠지만, pwnable.kr에 접속한 김에 해당 서버에 올려져 있는 파이썬을 이용해 봅시다.

4660이 나왔으니 프로그램의 첫번째 인자로 4660을 넣어 실행시킨 뒤, read가 표준 입력 스트림을 열어주면 LETMEWIN 을 입력해 줍니다.

flag파일이 출력된 것으로 보아 문제가 잘 풀린 모양입니다.