[pwnable.kr]fd
pwnable.kr은 포너블 워게임 사이트이다.
포너블은 쉽게 말하면 시스템 해킹이다.
사이트에 들어가서 좌측 상단 play를 클릭하면 문제들이 나오고 회원가입 후 문제를 풀면된다.
첫 문제를 보면 "엄마! 리눅스에서 파일 디스크립터가 뭐야?"라고 나온고, 하단에 너 완전 쌩초보면 영상참고하라고 나온다. 그리고 ssh로 접속할 수 있게 호스트이름이랑 포트 알려준다. 들어가서 문제를 풀면 flag를 알려줄 것이다. 그리고 여기 폼에다 플래그 입력해서 풀면된다.
나는 putty를 사용해 접속했다.
putty로 접속하면 로그인창이 나오고 fd/guest로 로그인 했다.
폴더 안에 뭐가있는지 보면 fd, fd.c, flag가 있다. fd는 fd.c를 컴파일 한 프로그램일 거고, flag는 플래그 관련된 것 같다.
fd.c의 내용이다. 자세히 보면
#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;
}
메인함수 하나이고 argc, argv envp가 나와있다.
argc의 경우 argument counter라고 하여 인자의 수가 저장되는 int형 변수
argv의 경우 argument vector라고 하여 인자의 내용이 저장되는 포인터형 배열
envp의 경우 program environment라고 하여 인자 값 중 환경변수값이 들어가는 포인터형 배열
6번째 줄 if문부터 보면 인자 개수가 2개 밑이면 조건 성립되서 "pass [첫번째 인자] a number"프린트 하고 종료한다.
인자는 2개이상 입력하면 될 것같다.
10번 째 줄을 보면 int형 fd변수에 두번째 인자를 atoi(스트링->정수)함수로 묶고 16진수 1234만큼 뺀 값을 넣는다.
11번 째 줄 len에 0넣는다.
12번째 줄에 read함수가 나오는데 이 부분이 중요하다. read함수에 대해 알아보면
ssize_t read(int fd, void *buf, size_t nbytes);
리턴 값은 수신한 바이트 수, 실패 시 -1
fd는 데이터를 전송해 주는 대상을 가리키는 파일 디스크립터
buf는 수신한 데이터를 저장할 버퍼를 가리키는 포인터
nbytes는 수신할 최대 바이트 수
여기서 아까 문제의 키워드인 파일 디스크립터가 나온다. 이 부분이 키워드 인 것 같다.
따라서 13번째 줄은 fd의 파일 데이터를 buf에 저장하는데 buf의 크기인 32바이트를 최대로 지정하고 리턴 값은 len에 저장한다는 뜻이다.
13번째 줄을 보면 if 조건문 안에 strcmp(문자열 비교)함수가 나오고 "LETMEWIN\n"과 buf를 비교한다. 이 때 strcmp 앞에는 !가 있으므로 strcmp의 리턴값은 0이 나와야한다. 0은 두개의 문자열이 같을 때 리턴된다.
조건문 안으로 들어가면 "good job :)"이라는 문구와 시스템 함수로 아까 디렉토리에 있던 flag를 출력하고 시스템을 종료한다.
조건문 안으로만 들어가면 문제를 풀 수 있을 것 같다.
여기서부터 많이 해맸는데 2번째 인자에 무엇을 넣어야 할 지 도대체 몰랐었다.
한참을 보다 이 때 처음에 나왔던 파일 디스크립터를 다시 봤다.
0은 입력
1은 출력
2는 에러
fd가 파일 디스크립터이므로 0으로만 만들어주면 "LETMEWIN\n"을 내가 입력할 수 있으므로 buf에 "LETMEWIN\n"이 저장 될 것이다.
fd를 0으로 만들려면 10번 째 줄 16진수 1234를 뺄 때 0으로 만들 수 있을 것 같았다. 16진수를 쓸수는 없으니까 10진수로 변환해서 넣으면 될 것같다.
16진수 1234의 10진수는 4660
./fd 4660입력해 fd(파일 디스크립터)를 0으로 만들어 내가 "LETMEWIN\n"을 입력했더니 문제가 풀렸다.
flag는 "mommy! I think I know what a file descriptor is!!"다.
확실히 포너블은 처음접해봐서 속도&시간이 뎌디다.
끝.
'정보보안 > Wargames' 카테고리의 다른 글
[해커스쿨ftz]Level 4 (0) | 2018.01.02 |
---|---|
[해커스쿨ftz]Level 3 (0) | 2017.12.30 |
[해커스쿨ftz]Level 2 (0) | 2017.12.30 |
[해커스쿨ftz]Level 1 (0) | 2017.12.29 |
댓글
이 글 공유하기
다른 글
-
[해커스쿨ftz]Level 4
[해커스쿨ftz]Level 4
2018.01.02 -
[해커스쿨ftz]Level 3
[해커스쿨ftz]Level 3
2017.12.30 -
[해커스쿨ftz]Level 2
[해커스쿨ftz]Level 2
2017.12.30 -
[해커스쿨ftz]Level 1
[해커스쿨ftz]Level 1
2017.12.29