1 분 소요

1. 문제

WSL 환경에서 ssh cmd1@pwnable.kr -p2222 로 접속하고 ls 명령어를 통해 확인해 보면 cmd1, cmd1.c, flag 총 3가지의 파일이 있는 것을 확인할 수 있다. cmd1.c 파일의 소스코드를 확인해 보자. cmd1.c

2. cmd1.c

thankyouverymuch 라는 패스로 경로가 설정되고 argv[1]에 입력된 인자를 filter 함수의 파라미터로 해 실행한다. filter 함수의 반환값에 따라 return 0;로 그대로 종료하거나 system 함수의 인자로 argv[1]에 입력된 인자를 실행시키도록 되어 있다.

그렇다면 filter 함수는 어떤 값을 반환하는지 살펴보자.

strstr이라는 함수에 filter 함수의 파라미터인 cmd가 들어가 있다. strstr함수는 두 가지 인자를 가지는데, 첫 번째 인자로 받은 문자열에서 두 번째 인자로 받은 문자열을 찾아 시작 위치를 반환하는 함수이다. 만약 두 번째 문자열이 첫 번째 문자열에 나타나지 않으면 NULL을 리턴한다.

filter 함수는 strstr 함수의 값에 따라 달라지는 r이라는 변수를 반환하도록 되어 있다. 즉 strstr 함수 내에 있는 단어 flag, sh, tmp가 argv[1]의 입력으로 들어온 경우 r값이 증가되어 filter의 반환값은 true가 되어 return 0;로 프로그램이 종료된다.

따라서 filter 함수가 false값을 반환하게 하려면 r값을 증가시키지 않아야 하므로 3가지 단어를 입력으로 주어서는 안된다.

3. 입력

이제 argv[1]에 어떤 것을 입력으로 주어야 하는지 알아볼 차례다. argv[1]이라고 하면 이게 무엇을 뜻하는 지 모를 수 있는데, 간단하게 말하면 파일에 입력으로 주는 첫 번째 인자이다. argv[0]는 파일명, 이후 입력되는 것이 argv[1]이다. argv가 무엇인지는 다른 포스트에서 설명하도록 하고 입력할 것을 보자.

우선 flag 파일을 읽기 위한 명령어는 cat flag이다. 하지만 flag라는 단어는 위에서처럼 filter 함수에 의해 사용할 수 없다. 그렇다면 어떻게 flag 파일을 실행할 수 있을까? 이것을 보고 떠올린 것은 바로 와일드카드 였다. 와일드카드는 문자열을 대체해서 사용할 수 있는 문자로 f*이라면 f로 시작하는 모든 이름들을 의미할 수 있다. 그렇다면 와일드카드를 사용해서 입력을 넣어 보자.

cmd1 파일 실행을 위한 ./cmd1이 argv[0]가 될 것이고 cat flag가 argv[1]이 되어야 한다. 하지만 띄어쓰기가 되어 있다면 cat이 argv[1], flag가 argv[2]가 되기 때문에 큰 따옴표 안에 해당 명령어를 묶어 준다. 즉 ./cmd1 “cat flag”가 되어야 한다. 그러나 여기서 와일드카드를 사용할 것이고 이 때 주의할 점은 와일드카드 문자는 따옴표 밖에 위치해야 한다는 것이다. 따옴표 안에 있으면 일반 문자로 인식된다. 따라서 ./cmd1 “cat fla”* 와 같이 입력을 줄 것이다. input1

하지만 cat 이라는 명령어를 찾을 수 없다고 하며 flag를 읽지 못한다.

4. flag

위에서 flag를 읽지 못했던 이유는 cat 명령어를 찾지 못해서이다. 일반적으로 위치란 쉘의 경우 cat 명령어가 동작해야 정상이지만, cmd1의 코드를 보면 putenv 함수를 통해 thankyouverymuch라는 경로에서 실행하도록 설정되어 있다. 따라서 해당 경로에는 cat 명령어가 없기 때문에 동작하지 않은 것이다. 최종적으로 flag를 읽기 위해서는 현재 쉘에서 실행해 주어야 하기 때문에 ./cmd1 “/bin/cat fla”* 의 형태로 입력을 주어야 한다.

flag

flag가 정상적으로 출력된 것을 확인할 수 있다.

카테고리:

업데이트: