티스토리 뷰

71번째 글.

 

 

1. 시나리오

You are contracted to perform a penetration test for a company, and through your pentest, you stumble upon an interesting file manager web application. As file managers tend to execute system commands, you are interested in testing for command injection vulnerabilities.

Use the various techniques presented in this module to detect a command injection vulnerability and then exploit it, evading any filters in place.

 

 

2. 인터페이스

guest/guest로 로그인을 하면 이렇게 파일 매니저가 나온다.

파일 내용 확인, 파일 다운로드, 파일 옮기기가 기본적으로 동작하였다.

 

 

3. Finding Attack Vector

http://188.166.173.208:30913/index.php?to=&from=877915113.txt

여러 가지 버튼을 눌러보던 중 파일을 옮기는 기능을 하는 페이지를 발견하였다.

여기서 tmp 디렉터리를 선택을 하면 url의 'to' 변수에 tmp가 반영된다 즉 아래와 같이 된다.

http://188.166.173.208:30913/index.php?to=tmp&from=877915113.txt

 

여기서 'mv명령어를 이용하지 않았을까?' 라는 유추를 하였다.

그래서 오류를 뱉어낼 수 있을것같아서 'to' 변수에 아무런 값을 넣지 않고 Move버튼을 눌러보았다.

 

이처럼 에러를 통해서 mv 명령어를 사용했음을 알 수 있었다.

 

 

4. Exploit

mv 명령어를 사용한다는 것을 알았으니 GET 파라미터를 적절히 injection해야한다.

여기서 주의할 점이 있다. 기존의 mv 명령어를 이용하여 파일을 이동시킬 때 

mv <파일명> <이동할 디렉토리>이런 식으로 명령어를 입력하기 때문에

우리는 'from'이 아니라 'to'에 우리가 원하는 명령어를 이어서 주입해야 한다.

 

그렇다면 이제 정확한 공격 벡터를 알았으니 하나씩 페이로드를 주입해보자.

나 같은 경우는 ||(%7c%7c)를 이용했다. &&을 쓰려면 앞의 명령어가 정상적으로

동작을 해야 하기 때문에 테스트를 하다 보면 파일을 계속 옮겨야 했기 때문이다.

 

http://188.166.173.208:30913/index.php?to=%7c%7c&from=877915113.txt

이렇게 연산자만 넣었을 때 보지 못했던 에러가 나왔다. 반면

 

http://188.166.173.208:30913/index.php?to=%7c%7c%20/flag.txt&from=877915113.txt

이렇게 명령어를 입력했을 때 cat, mv, ls 등등 기본적인 명령어들이 필터링이 되는 것을 확인했다.

한편으로는 연산자는 필터링이 되지 않는다는 것을 말해주기도 한다.

반면 bash명령어는 동작하는 것을 확인하였다.

 

일단 기본적인 명령어들이 필터링되어있기 때문에 base64로 인코딩하는 방법을 택했다.

인코딩 된 명령어를 다시 base64 명령어의 입력으로 주고 다시 이것을 bash 명령어의 입력을 주는 형태가 되겠다.

그래서 처음에는 /flag.txt 파일을 tmp디렉터리로 옮겨서 콘텐츠를 확인하면 될 것이라고 생각했다.

먼저 아래와 같이 명령어를 인코딩해준다.

 

위에서 설명한 대로 페이로드를 설정하면 아래와 같다.

%7c%7cbash<<<$(base64 -d<<<bXYgL2ZsYWcudHh0IC92YXIvd3d3L2h0bWwvZmlsZXMvdG1w)

 

하지만 위 방법은 먹히지 않았다.

배웠던 것을 생각해보면 기본적으로 디렉터리의 위치를 나타낼 때 필요한 '/' 나 '\' 같은 경우는

기본적으로 필터링될 가능성이 높다고 했다.

 

위처럼 '/'를 우회해주고 다시 인코딩을 하였다.

(잠깐 설명을 덧붙이자면 PATH 환경변수를 이용하고 슬라이 싱하여 이것의 제일 첫 글자인 '/'를 불러오는 것이다.)

 

%7c%7cbash<<<$(base64 -d<<<bXYgJHtQQVRIOjA6MX1mbGFnLnR4dCAke1BBVEg6MDoxfXZhciR7UEFUSDowOjF9d3d3JHtQQVRI
OjA6MX1odG1sJHtQQVRIOjA6MX1maWxlcyR7UEFUSDowOjF9dG1w)

이 또한 먹히지 않았다...

그러다가 혹시 공백 필터링 때문에?라는 생각이 들어서 base64와 -d 옵션 사이에 tab(%09)를 넣어주었다.

 

wow 드디어 실행은 되었지만 Permission denied... 좌절하는 순간

내가 멍청하다는 것을 알기까지 1초 정도 걸렸다.

error를 화면에 띄어주고 있었는데 괜히 어렵게 하고 있었다 ㅋㅋㅋ

cat /flag.txt 명령어를 인코딩하여 다시 보내주자.

 

flag를 얻을 수 있었다.

 

 

Reference

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection#bypass-with-variable-expansion