Pwnablekr_Toddlers Bottle_cmd2

cmd1의 flag를 비밀번호로 이용해 접속한다. 문제는 다음과 같다.
#include <stdio.h>
#include <string.h>
int filter(char* cmd){
int r=0;
r += strstr(cmd, "=")!=0;
r += strstr(cmd, "PATH")!=0;
r += strstr(cmd, "export")!=0;
r += strstr(cmd, "/")!=0;
r += strstr(cmd, "`")!=0;
r += strstr(cmd, "flag")!=0;
return r;
}
extern char** environ;
void delete_env(){
char** p;
for(p=environ; *p; p++) memset(*p, 0, strlen(*p));
}
int main(int argc, char* argv[], char** envp){
delete_env();
putenv("PATH=/no_command_execution_until_you_become_a_hacker");
if(filter(argv[1])) return 0;
printf("%s\n", argv[1]);
system( argv[1] );
return 0;
}문제에서는 환경변수를 삭제한다. 실행 인자가 필터를 통과하면 system 함수의 인자로 준다.
생각한 방법
PWD 활용하기
환경변수를 지워도 실행 가능한 명령어가 있다. echo나 pwd였다. echo $PWD 했을 때 현재 디렉토리를 출력한다. 환경변수 $PWD를 /bin으로 조작한다면 cat 등의 명령어를 찾을 수 있지 않을까?
→ 실패. 환경변수 $PWD를 수정하여도 echo $PWD시 실제 현재 디렉토리를 출력한다. 디버거로 환경변수를 조사해보면 $PWD 환경변수도 지워지는데, 어떻게 현재 디렉토리를 얻는지는 모르겠다. echo $PWD 실행까지 디버거로 따라가면 보이겠는데.. 일단은 셸의 built-in 커맨드라서 가능한 것으로? 추정된다.
심볼릭 링크를 이용
tmp 폴더에 no_command_execution_until_you_become_a_hacker 폴더를 생성하고 이 안에 flag 파일의 심볼릭 링크를 생성한다.
→ 실패. 이 방법은 새로 설정되는 PATH가 ./no_command_execution_until_you_become_a_hacker가 아닌 /no_command_execution_until_you_become_a_hacker이기에 불가능하다. 루트 디렉토리에 디렉토리를 생성할 권한이 없다.
심볼릭 링크로 cat과 flag를 생성
tmp에 심볼릭 링크로 cat과 flag를 생성하고 tmp에서 /home/cmd2/cmd2 'cat myfile' 를 실행하는 방법은 어떨까?
→ 실패. PWD가 PATH 용도로는 이용이 안 되나 보다. 같은 디렉토리에 있으면 찾을 수 있을 줄 알았는데 안 됨.
실행되는 다른 명령어 찾아보기
echo와 pwd가 실행되는 것으로 보아 어떤 명령어는 실행 가능할지도 모른다. 문자열 파싱 명령어 등을 이용하면 명령어를 생성할 수 있지 않을까?
→ 실패. 파싱 명령어가 실행되지 않았다. built-in이 아니라서 그런 것 같다.
/bin/ 폴더에서 실행
/bin/ 폴더에 이동해서 실행하면 어떨까?
→ 실패. 적어도 cat 명령어 등은 찾을 줄 알았는데, 3번과 같이 역시 PWD는 찾아도 PATH로 쓰지는 않는 것 같다.
풀이
인터넷을 참고하였다. read 명령어를 이용하여 변수에 명령어를 읽은 뒤 실행하는 방법이다. read는 셸의 built-in 커맨드라서 호출 가능하다.
./cmd2 "read a;\$a" 입력 후 원하는 명령어를 입력하면 된다.
또다른 방법으로는 set 커맨드를 이용하여 환경변수를 설정할 수도 있다. ./cmd2 'set -s' 를 통해 환경변수를 다시 잡아주고, /bin/cat ./flag 를 입력하면 된다. 이는 sh에서만 가능하다. (bash 불가)
또한 echo와 헥사값을 이용하여 필터링을 우회할 수도 있다. ./cmd2 '$(echo "\57")bin$(echo "\57")cat f*' 와 같이 필터링을 우회하여 실행할 수 있다.
command 라는 built-in 커맨드는 -p옵션을 주면 환경변수를 초기화해준다고 한다. ./cmd 'command -p cat f*' 를 통해 초기화할 수 있다.

flag는 FuN_w1th_5h3ll_v4riabl3s_haha 이다.
리눅스 커맨드를 여러가지 알아두면 상황에 따라 유연하게 대처할 수 있겠다.
tags: writeup, pwnable, elf file, linux, c lang, environment variables