시스템해킹

pwnable.kr cmd1 write up

세종대학교 S.S.G / WHS 2기 2023. 12. 7. 20:18

소스코드

 

기능분석

먼저 main 함수에서 putenv함수로 환경변수를 설정한다. 이때 PATH가 /thankyouverymuch로 바뀌게 된다.

 

이후 filter 함수에 cmd1 파일을 실행할 때 넘겨준 인자가 넘어가게 되고, strstr에 의해 필터링을 하게된다.

 

인자에 flag, sh, tmp가 없었다면 system(넘겨준인자)를 실행한다.

 

 

 

익스플로잇

먼저 putenv로 path를 없앤다. 

printenv로 환경변수를 확인해보면 PATH가 이렇게 설정되어있다. /usr/bin이 기본 path이기에 cat과 같은 명령어를 cat만 쳐도 실행이 되는 것이다. 하지만 path가 사라졌으니 절대 경로를 사용해야한다. 즉 인자로 /bin/원하는 명령 을 넘겨주어야 하는 것이다.

 

우리가 하고싶은건 flag를 읽는 방법이다.

 

문제를 풀때는 쉘을 획득하기 위해 노력했다.

 

리눅스에는 wildcard라고 문자열의 패턴을 적어서 사용하는 방법이 있다.

예를 들어 flag는 fl* 라고 하면 fl로 시작하는 모든 문자열을 의미한다.

*ag는 ag로 끝나는 문자열을 의미한다.

 

또한 ? 는 해당 부분에 어떤 문자열이 들어가도 된다는 의미이다.

가령 f?ag 는 flag뿐만 아니라 다양한 문자열들을 모두 의미한다.

 

 

 

현재 etc 디렉토리에는 다양한 명령어들이 있다. 그중 내가 원하는건

sh 함수이다.

 

먼저 /bin/s* 로 s로 시작하는것을 실행시키니

맨 위에 있는 sed만 실행됐다.

 

그렇다면 /bin/*h 로 h로 끝나는 것을 실행하니

etc 디렉토리의 알파벳 순서상 앞에 있는 dash가 실행된다.

 

 

이번엔 ? 를 이용해서 /bin/?h를 이용했다

쉘을 획득한것을 볼 수 있다. 현재 디렉토리가 어딘지 궁금해 pwd를 해보니 cmd1 디렉토리였다. 하지만 cat flag를 하니 실행되지 않았다. 그 이유는 현재 쉘이 떠있는 환경이 cmd1의 환경이니 path가 없어서 그렇다. 따라서 /bin/cat 을 이용해 flag를 출력하니 flag가 나왔다.

 

 

 

 

더 쉬운 방법

이것으로 미루어보아 쉘을 따지 않고 단지 ./cmd1 "/bin/cat fl*" 와 같이 실행하면 자동으로 플래그가 출력된다.