Pwnable.kr fd Writeup

  • 오늘은 Pwnable.kr의 fd라는 문제를 한번 풀어보겠습니다.

  • 먼저 사이트를 접속해서 fd문제를 봐줍니다.

  • ssh 주소를 복사해서 터미널에 붙여넣기 해줍니다.

  • 그 후 비밀번호를 입력하면?

  • 정상적으로 문제 서버에 접속이 되는 것을 확인할 수 있습니다.

  • 제일 먼저 ls -al 명령어로 .(점)을 포함한 경로안의 모든 파일과 디렉터리의 내용을 자세히 봐줍니다.

  • flag 파일이 존재하네요.... 실행이 안될 것 같지만 ./ 명령어로 한번 실행해보겠습니다.

  • 예상대로 안됩니다....

  • 그럼 다음으로 fd파일을 실행해보겠습니다.

  • 이 파일도 어떠한 정보가 없으면 별로 많은 정보를 얻을 수는 없는 것 같습니다.

  • 그럼 마지막으로 cat 명령어를 사용해서 fd.c의 소스코드를 한번 확인해보겠습니다.

  • 그러면 아래와 같은 소스코드를 확인할 수 있습니다.

  • fd.c 소스코드를 분석하면 다음과 같습니다.
  • 즉, ./fd 뒤에 0x1234를 10진수로 변환한 값이 인자로 오면 문자열 입력이 가능해지고 거기에 LETMEWIN을 입력하면 if문이 수행되면서 flag를 얻을 수 있습니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32]; // 전역 변수 buf 선언[배열값 32]

int main(int argc, char* argv[], char* envp[]){

	if(argc<2){ // argc 즉, 인자가 2미만이면 if문 실행

		printf("pass argv[1] a number\n");
		return 0; // 반환한다.

	}

    // atoi()함수 : 문자 스트링을 10진수 정수형으로 변환하는 함수이다.
	int fd = atoi( argv[1] ) - 0x1234; // fd = file descriptor(파일 디스크립터는 시스템으로부터 할당 받은 파일이나 소켓을 대표하는 정수), argv[1]을 atoi() 함수로 정수형으로 변환하고 0x1234만큼 뺀다.
	int len = 0;

    // read()함수 : 파일의 내용을 읽는 함수이다. (형태 : ssize_t read (int fd , void *buf , size_t nbytes)
	len = read(fd, buf, 32); // fd, 저장할 버퍼의 포인터, byte길이 (32)

    // strcmp() 함수 : 매개변수로 들어온 두개의 문자열을 비교하여 같으면 0 다르면 1을 반환한다.
	if(!strcmp("LETMEWIN\n", buf)){ 

		printf("good job :)\n");
		system("/bin/cat flag");
		exit(0);

	}

	printf("learn about Linux file IO\n");

	return 0;

}

// 즉, ./fd 뒤에 0x1234를 10진수로 변환한 값이 인자로 오면 문자열 입력이 가능해지고 거기에 LETMEWIN을 입력하면 if문이 수행된다.
  • 먼저 16진수인 0x1234의 10진수 값을 알기 위해서 계산기를 열어줍니다.

  • 그런 다음 계산기를 프로그래머 모드로 변경해줍니다.

  • 여기에 우리가 변환할 값인 0x1234를 입력합니다.

  • 그러면 우리가 알고 싶은 0x1234(16진수)의 10진수 값은 4660이라는 것을 알 수 있습니다.

  • 그럼 ./fd 4660으로 fd파일을 실행하면 입력 값을 입력할 수 있게 되고,

  • 해당 입력 가능한 곳에 LETMEWIN을 입력하면?

  • 문제가 풀리면서 우리가 구하는 FLAG가 나오는 것을 확인할 수 있습니다.

좋은 웹페이지 즐겨찾기