첫번째 문제라서 튜토리얼 영상이 존재한다.
(사실 영어라 아무도움도 안됐다)
(pw:guest)
여기서부터 몰라 찾아보니
SSH 프로토콜은 웹호스팅을 이용하거나, 리눅스서버에 접속하기 위하여 사용하는 원격접속 툴 이라고 한다.
SSH 프로토콜을 이용하기 위해 PuTTY를 사용했다.
이런식으로 접속해준다.
이런 화면이 나온다.
디렉토리 목록 확인 명령어 ls 를 사용해보니 세개의 파일이 존재한다.
fd는 마치 암호화 되어있는것 같았고 flag는 권한 허가가 되지 않아 읽을 수 없었다.
fd.c파일을 읽어보니 아래와 같은 익숙한 C언어가 있어 먼저 코드 해석을 했다.
파일의 내용을 출력하는 리눅스 명령어 cat 사용
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 char buf[32];
5 int main(int argc, char* argv[], char* envp[]){
6 if(argc<2){
7 printf("pass argv[1] a number\n");
8 return 0;
9 }
10 int fd = atoi( argv[1] ) - 0x1234;
11 int len = 0;
12 len = read(fd, buf, 32);
13 if(!strcmp("LETMEWIN\n", buf)){
14 printf("good job :)\n");
15 system("/bin/cat flag");
16 exit(0);
17 }
18 printf("learn about Linux file IO\n");
19 return 0;
20 }
워낙 처음보는 함수들이 많았다.
천천히 살펴보니 15번 줄의 system (“/bin/cat flag”);
이 코드가 단서인 것 같아 찾아보니
system 함수는 명령어를 수행하는 함수라고 한다.
위 strcmp함수를 만족시키기 위해
(두 문자열을 비교하는 함수, 일치하면 0을 리턴)
buf가 “LETMEWIN\n”이 되게 해야할 것 같다.
(막막함)
그렇기에 필요한 buf가 포함된 read함수에 대해 알아보니
read(a, b, c); 일때,
리턴 값은 수신한 바이트 수, 실패하면 -1
a는 데이터를 전송해 주는 대상을 가리키는 파일 디스크립터
b는 수신한 데이터를 저장할 버퍼를 가리키는 포인터
c는 수신할 최대 바이트 수라고 한다.
여기서 중요한 것은 파일 디스크립터이다.
18번 줄의 “learn about Linux file IO” 에 대해 구글링 해 보니
파일 디스크립터가
0 일때 입력
1 일때 출력
2 일때 에러
라는 것을 알 수 있었다.
즉, fd를 0으로 만들어 줘야 buf에 LETMEWIN을 입력할 수 있다는 뜻이다.
그렇기 위해선 10번째 줄에서 fd를 0으로 만들어줘야 한다.
16진수인 0x1234는 10진수 4660과 같기에
10번째 줄에 4660을 입력해 fd를 0으로 만든다.
./fd 4660 를 입력해 fd를 0으로 만들어준다.
![[pwnable.kr] fd 이미지 5](/images/naver/naver-222123348059-5.webp)
이렇게 플래그를 얻었다.
허나, 남은 궁금증이 많다.
1. 6~9줄의 함수는 무슨 역할을 하고 argc, argv, envp는 무슨 역할을 하는가?
2. ./fd 4660이라는 명령어는 어디에 4660이라는 값을 주는 것이고 그냥 실행했을대는 왜 아무값도 입력받지 않는가?
3. atoi는 문자열을 숫자로 바꾸는 함수인데 근본적으로 fd가 아니라 argv[1]이라는 값을 바꿔야 하는 것이 아닌가?
4. 디렉토리에 있던 fd파일은 무엇인가?
함수들과 디스크립터에 대한 이해가 필요했던 문제인 것 같다.
다른 라이트업들을 많이 참고했고, 그렇기에 부족했지만 많은 것을 얻을 수 있었다.
의문에 대한 답변은 잊지 말고 후에 답하자.