cmd1을 풀이하였습니다.
Mommy! what is PATH environment in Linux?
리눅스에서 환경변수에 관한 문제인듯 합니다.
ssh 접속후 ls 로 파일명을 보면 cmd.c 파일이 있는데 아래와 같습니다.
cmd1@ubuntu:~$ cat cmd1.c
#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로 초기화하고 있고, filter() 에서 0이상이 반환되어 온다면 if문 안으로 들어와서 return 0; 즉 정상종료 됩니다.
하지만 0으로 반환된다면 system() 에 우리가 입력한 argv[1]가 인자로 들어가서 해당 명령을 실행하고 종료합니다.
우리는 여기서 flag를 보는 것이 목적이기 때문에 그 경우를 생각하면 됩니다.
우리가 인자 값을 주면 system()에 들어가기 전에 filter() 에서 우리가 줬던 인자 중 flag, sh, tmp라는 문자열이 있는지 검사하고 만약 있다면 r이라는 지역 변수에 +1씩하여 return 값이 0을 초과하게끔 만듭니다.
이를 우회하기 위해서는 flag, sh, tmp라는 인자값을 주면 안되는데
flag 파일을 봐야하므로 *(와일드카드) 를 이용하면 쉽게 우회가 가능합니다.
예를 들어 cat fl* 라는 인자값을 줬다면 fl로 시작하는 모든 파일을 cat 해줄 것입니다.
cmd1@ubuntu:~$ ./cmd1 'cat fl*'
sh: 1: cat: not found
하지만 소스코드에도 나와있듯이 putenv() 를 통해서 PATH를 초기화 해주는데요.
리눅스에서 cd, ls 등의 명령어는 어딘가의 경로에 디렉토리 안에서 프로그램이 존재하는데 그렇기 때문에 원래는 /bin/cat
/bin/ls 이렇게 명령어를 입력해줘야합니다. 절대경로로 말이죠.
하지만 편의성을 위해서 PATH라는 환경변수에 경로를 추가하면 추가된 경로의 명령어를 쓸 수 있게 됩니다.
이 문제에서는 putenv() 를 통해서 PATH의 값을 초기화 하기 때문에 cat 이 실행되지 않으니
절대경로로 /bin/cat fl*를 전달해보면
cmd1@ubuntu:~$ ./cmd1 '/bin/cat fl*'
~~~~~~~~~~~~~~~~~~~~~flag~~~~~~~~~~~~~~~~~~~~~~~
이렇게 flag가 나오는것을 확인 할 수 있습니다.
이상 cmd1의 풀이를 마칩니다.