[ pwnable.kr ] fd
포스트
취소

[ pwnable.kr ] fd

img


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;

}

소스코드를 먼저 확인해보자


입력받은 인자를 정수로 바꾸고 0x1234를 빼준다. 이후 fd가 가리키는 파일을 32bytes 읽어들여 buf에 저장한다.

buf안에 값이 LETMEWIN이면 flag를 얻을 수 있다.


문제를 풀기 위해서는 먼저 read함수에 대해 알아야 한다.

read() 함수의 원형은 아래와 같다.

**ssize_t read(int fd, void *buf, size_t bytes)**


  1. int fd: Data를 전송할 대상을 가리키는 File Descriptor.
  2. void *buf: 파일을 읽어들여 저장 할 buffer이다.
  3. size_n bytes: 읽어 들일 byte의 수.


여기서 file descriptor란 다음과 같다.

File Descriptor목적Stream
0표준 입력stdin
1표준 출력stdout
2표준 에러stderr


문제로 돌아와서 read함수의 첫 번째 인자 fd가 0일 경우 표준 입력으로 인식되어, 키보드로 입력하는 값을 buf안에 값을 저장하게 된다.

따라서 0x1234를 뺐을 때 0이 되는 값을 인자로 넣어주면 키보드로 값을 입력할 수 있고, 그 값은 buf에 들어가 LETMEWIN이랑 비교하게 된다.


0x1234는 10진수로 4660이므로 인자로 4660을 넘겨 준 후 LETMEWIN입력하여 buf에 넣어주면 flag를 얻을 수 있다.

image-20230709211724514