문제 분석
#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가 가리키는 파일을 32 bytes 읽어 들여 buf에 저장한다. 이때 buf안에 값이 LETMEWIN이면 flag를 얻을 수 있다.
문제 풀이
문제를 풀기 위해서는 먼저 read함수에 대해 알아야 한다. read() 함수의 원형은 아래와 같다.
**ssize_t read(int fd, void *buf, size_t bytes)**
- int fd: Data를 전송할 대상을 가리키는 File Descriptor.
- void *buf: 파일을 읽어 들여 저장할 buffer이다.
- 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를 얻을 수 있다.