일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- #MINT64 #Sqix
- vim
- 오버워치 세이버메트릭스
- FTZ 레벨2
- #Best of the Best #OS #MINT64 #Sqix
- #Qt Creator
- Overwatch League SaberMetrics
- Network
- #
- Find
- BEST of the BEST
- Sqix
- #IntelManual
- 인터럽트
- >
- command
- vi 외부 명령어
- 오버워치
- libtins
- KASAN
- C++11
- vi
- #IntelManual #segment Descriptor #세그먼트 디스크립터 #MINT64 #Sqix
- ftz
- linux
- libpcap
- Today
- Total
Sqix
Pwnable.kr - Toddler's Bottle : File Descriptor 본문
문제의 안내에 따라서 터미널에 "ssh fd@pwnable.kr -p2222" 를 터미널에 입력하여 접속을 한다.
<본인이 사용하는 OS는 Ubuntu 16.04 LTS 버전이고, Host로 올린 채 사용 중입니다.>
이번 문제는 Pwnable.kr의 가장 첫 번째 문제로, Linux의 File I/O에 대해서 알고 있는가? 에 대한 문제입니다. 사실 문제의 풀이는 매우 간단합니다. 하지만, 공부해야 할 주제를 던져주었다는 점에서 나쁘지 않은 문제라고 할 수 있습니다. 그렇다면, 공부해야 할 것은 어떠한 것일까요? 바로 Linux의 File Descriptor(fd)입니다.
File Descriptor는 시스템으로부터 할당받은 파일을 대표하는 정수 값을 말합니다. 또한, 프로세스에서 열린 파일의 목록을 관리하는 Table의 Index이기도 합니다. 리눅스의 모든 객체는 파일로 관리되고 있습니다. 심지어는 ls, cd, cp, mv 등과 같은 명령어도 마찬가지입니다. 프로세스가 이러한 파일들에게 접근하기 위해서는, 파일 디스크립터라는 개념을 이용하여 접근할 수 있습니다. fd는 라이브러리 차원에서 구현된 것이 아니고, 시스템 차원에서 구현되어 있습니다. 프로그램이 실행이 된 후 메모리의 프로세스 Descriptor을 보신다면 fd의 배열을 포함하고 있음을 알 수 있습니다.
Standard File Descriptor를 표현한 그림. 출처 : https://www.usna.edu/Users/cs/aviv/classes/ic221/s16/lec/21/lec.html
간단하게 말하면, 파일 디스크립터는 우리가 파일을 잘 찾을 수 있도록 라벨링을 해 놓은 것이라고 생각할 수 있습니다. 일반적으로 파일 디스크립터는 C언어를 기준으로 Open, Close를 이용하여 파일 디스크립터를 열고 닫는데, 이번 문제에서는 다른 방식으로 파일 디스크립터를 가져오도록 되어있었습니다. 일반적으로 우리가 사용하는 Linux를 포함한 POSIX에서는 3개의 표준 fd를 가집니다.
0. Stdin
1. Stdout
2. Stderr
이제 문제를 한번 살펴보겠습니다.
위의 그림 1에서, ls 명령어를 실행하였더니 실행 파일인 fd, fd의 소스 코드로 예상되는 fd.c, 그리고 flag가 있을 것으로 추정되는 flag까지 총 세 개의 파일이 보입니다. fd.c를 열어보도록 하겠습니다.
fd.c의 소스 코드
소스코드를 살펴보면, 인자를 하나 받아서 문자열 상태의 인자를 int로 변환하고, 이를 fd로 사용합니다. 그 후, read를 호출하여 인자를 받아들이도록 합니다. 이를 "LETMEWIN\n" 문자열과 비교하여 만약 문자열이 같다면 flag를 띄워 주고, 그렇지 않다면 fd에 대해서 좀 공부를 하라고 하네요. 저기서 우리가 해야 할 것은 표준 입력을 통해서 사용자에게 입력을 받아들이는 것이기 때문에, read의 인자로 들어간 fd에는 0이 필요합니다. 즉, 0x1234를 사용자 입력으로 준다면 맞게 된다는 것이죠. 0x1234 == 4660이기 때문에 4660을 입력해 줍니다.
./fd 4660
그러면, 사용자에게 입력을 받을 수 있는 창이 등장합니다. 여기에는 위의 소스코드와 같은 LETMEWIN 을 입력합니다. 그렇게 한다면, flag를 얻을 수 있습니다.
'Wargame > Pwnable.kr' 카테고리의 다른 글
Pwnable.kr - Toddler's Bottle : Flag (0) | 2017.09.06 |
---|---|
Pwnable.kr - Toddler's Bottle : Buffer Overflow (0) | 2017.09.06 |
Pwnable.kr - Toddler's Bottle : Hash Collision (0) | 2017.09.04 |