#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;
    
    }

    풀이

    if(argc<2){
            printf("pass argv[1] a number\n");
            return 0;
    }

    매개변수에 넘기는 값이 하나라도 없으면, pass argv[1] a number 메시지를 출력한다.

    일반적으로 매개변수 없이 바이너리만 실행했을 때 발생한다.

    int fd = atoi( argv[1] ) - 0x1234;
    int len = 0;
    len = read(fd, buf, 32);

    atoi는 10진수 정수 문자열을 정수값으로 변환한다.

    read는 말그대로 파일을 읽을때 쓰는 함수다.

    각각 매개변수에는 파일 디스크립터, 파일을 읽어들일 버퍼, 버퍼의 크기가 들어간다.

    파일 디스크립터는 프로세스에서 특정 파일에 접근할 때 사용하는 추상적인 값으로, 기본으로 할당되는 값은 다음과 같다.

    파일 디스크립터목적POSIX 이름stdio 스트림
    0표준 입력STDIN_FILENOstdin
    1표준 출력STDOUT_FILENOstdout
    2표준 에러STDERR_FILENOstderr
    if(!strcmp("LETMEWIN\n", buf)){
            printf("good job :)\n");
            system("/bin/cat flag");
            exit(0);
    }

    strcmp는 문자열을 비교하는 함수다.

    서로 문자열이 같을 때 0을 반환하고 플래그를 출력한다.

    1. buf 변수에 LETMEWIN이 들어가기 위해서는 사용자의 입력이 필요하다.
    2. 파일 디스크립터가 표준 입력인 0이 되어야 하기 때문에, 매개변수에 0x1234의 10진수인 4660 문자열과 함께 fd를 실행한다.
    3. 그리고 LETMEWIN을 입력한다.
    fd@pwnable:~$ ./fd 4660
    LETMEWIN
    good job :)
    mommy! I think I know what a file descriptor is!!

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다