gunnew의 잡설

pwnable.kr 14. cmd1 (Wildcard) 본문

System Security

pwnable.kr 14. cmd1 (Wildcard)

higunnew 2020. 2. 17. 17:40
반응형

 이 문제는 환경 변수에 대해 제대로 이해하고 있는지를 묻는 문제이다. 먼저 코드를 살펴보자.

 

비교적 간단하다. putenv() 함수는 무엇인가? 이전에 우리는 환경 변수에 대해서 살펴본 바 있다. 환경 변수란 내가 어떤 경로에 있든지 상관 없이 스크립트를 짤 수 있게 도와준다. 예를 들어 우리가 자주 쓰는 cat이라는 flag는 /bin에 저장되어 있다. 그런데 만약 환경 변수가 없다면 우리가 cat을 실행할 때마다 항상 

 

/bin/cat ~~

 

이런 식으로 입력해야만 한다. 얼마나 불편한가!

 

그래서 이를 편리하게 하기 위해 사용되는 것이 환경 변수이다. 이 정도는 모두가 알고 있을 것이라 생각하고 바로 환경 변수를 env 명령어를 통해 살펴보자.

 

현재 나타나는 환경변수

PATH만 따로 놓고보니 다음과 같이 등록되어 있다.

cmd1@pwnable:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

 putenv()는 해당 환경 변수가 없다면 새로이 세팅하거나, 있다면 기존의 것을 바꾼다. 이 개념을 가지고 코드를 살펴보자. 

 


man putenv

PUTENV(3)                  Linux Programmer's Manual                 PUTENV(3)

NAME
       putenv - change or add an environment variable

SYNOPSIS
       #include <stdlib.h>

       int putenv(char *string);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       putenv(): _SVID_SOURCE || _XOPEN_SOURCE

DESCRIPTION
       The  putenv()  function  adds or changes the value of environment vari‐
       ables.  The argument string is of the form name=value.   If  name  does
       not already exist in the environment, then string is added to the envi‐
       ronment.  If name does exist, then the value of name in the environment
       is  changed  to value.  The string pointed to by string becomes part of
       the environment, so altering the string changes the environment.

RETURN VALUE
       The putenv() function returns zero on success, or nonzero if  an  error
       occurs.  In the event of an error, errno is set to indicate the cause.

ERRORS
       ENOMEM Insufficient space to allocate new environment.

소스 코드 분석

#include <stdio.h>
#include <string.h>

int filter(char* cmd){
        int r=0;
        r += strstr(cmd, "flag")!=0;
        r += strstr(cmd, "sh")!=0;
        r += strstr(cmd, "tmp")!=0;
        return r;
}
int main(int argc, char* argv[], char** envp){
        putenv("PATH=/thankyouverymuch");
        if(filter(argv[1])) return 0;
        system( argv[1] );
        return 0;
}

 소스 코드에서 putenv를 통해 PATH를 /thankyouverymuch로 재지정한다. 따라서 우리가 앞서 살펴본 PATH는 사라진다. 그리고 filter 함수에서 두 번째 인자를 확인한다.

 

filter는 "flag"가 포함되어 있거나, "sh"가 포함되어 있거나, "tmp"가 포함되어 있으면 1이상의 값을 반환하여 system() 인 시스템 콜을 하지 못한다. 우리는 여기에 flag를 출력하도록 해야 한다. 이를 위해 정규식에서 배웠던 와일드카드 *를 사용해야 한다. *는 모든 문자가 나올 수 있다는 것을 의미하며 *.txt라 하면 확장자가 .txt인 모든 파일을 가리킨다. 

 

또한 주의해야 할 점은 PATH가 이상한(?) 경로로 초기화 됐으므로 cat을 사용하고 싶다면 cat 프로그램의 절대경로인 /bin/cat을 통해야 한다는 것을 잊지 말자.

 

그러면 두 번째 인자로 /bin/cat flag를 넘기면 되겠지만 flag는 사용하면 안되니까 fla*를 하자.

 

mommy now I get what PATH environment is for :)

반응형

'System Security' 카테고리의 다른 글

pwnable.kr 16. uaf (Using After Free)  (0) 2020.02.19
pwnable.kr 15. cmd2  (0) 2020.02.19
pwnable.kr 13. lotto  (0) 2020.02.17
pwnable.kr 12. blackjack  (0) 2020.02.17
pwnable.kr 11. coin1  (0) 2020.02.16
Comments