본문 바로가기

My Study/Exploit

Hackerschool level19

두문제 남았군요..

이번 문제 봐보겠습니다.
 gdb로 보니 소스코드가 짧아서 hint는 볼 필요가 없습니다.

위 소스가 전부 입니다. 그냥 눈에 보이는군요.
gets로 문자열을 입력받아 printf로 출력하는게 끝입니다.
gets.. 딱 봐도 공격해야할 함수라는 것을 알 수 있습니다. BOF취약점을 가지고 있는 함수이기 때문이죠.

문제가 level11이랑 별반 다를게 없어보이지만 이번 문제에서는 소스코드 내에 setreuid 함수가 존재하질 않습니다.
권한을 재설정 해주는 부분인데 말이죠. setreuid없이 백날 /bin/sh 쉘코드로 쉘을 떨쳐봤자 자기 쉘만 떨어지게 됩니다.

그러면 쉘코드를 다시 만들어 보겠습니다. 이번 문서는 공부하기 싫어서 문서라도 길게 작성해보려는 마음으로 작성하고 있답니다 ;;

쉘코드 만드는 과정을 따로 올려드렸기 때문에 자세한 과정은 그 문서를 보시면 됩니다.

먼저 우리에게 필요한 소스코드를 짜보겠습니다.

3100은 level20권한입니다. 이제 위 소스를 쉘코드로 만들겠습니다.

라이브러리를 사용하기 때문에 -static 옵션을 주어서 정적링크 시켰습니다.
컴파일은 정상적으로 됬고 실행시켜보니 쉘은 떨어집니다.
하지만 상식적으로 저렇게해서 setreuid가 작동되진 않겠죠.
이제 해당 바이너리 파일을 objdump로 보면서 어셈블리 코드를 뽑아내겠습니다.
우리가 어셈코드를 뽑아내야할 부분은 setreuid와 execve부분에서 뽑아내면 됩니다.

먼저 setreuid부분에서 찾아낸 부분입니다.

위 어셈코드를 간단하게 보시면
첫번째 인자 ( 3100 ) : ebx
두번째 인자 ( 3100 ) : ecx
에 넣고 0x46 시스템 콜을 하고 있습니다.

직접 어셈코드로 작성해보겠습니다.

mov $0xc1c,%ebx       // 0xc1c  =  3100
mov $0xc1c,%ecx
mov $0x46,%eax
int $0x80

위와 같이 될 수 있습니다.
이제 execve함수를 보시겠습니다.

마찬가지로 위 빨간색 네모 친 부분을 분석해보면
첫번째 인자 ( shell[0] )  : ebx
두번째 인자 ( shell )      : ecx
세번째 인자 ( 0 )           : edx
0xb 시스템 콜

위 정보를 토대로 어셈코드로 작성해보겠습니다.

push $0x0068732F       // /sh\0
push $0x6E69622F      //  /bin
mov %esp,%ebx        // 첫번째 인자 ebx로 넣음
push $0x0
push %ebx
mov %esp,%ecx        // 두번째 인자 ecx에 넣음
mov $0x0,%edx         // 세번째 인자 edx에 넣음
mov $0xb,%eax
int $0x80

위와 같이 됩니다.
어셈코드를 작성해서 컴파일 시켜서 정상 작동 되는지 확인해 보겠습니다.

위와 같이 코드를 짜고 
정상적으로 컴파일 되고 실행해보니 잘 실행되고 있는 것을 확인했습니다.
이제 objdump로 해당 코드를 보겠습니다.

빨간색 네모친 부분 부분이 제가 작성한 부분입니다. 그 앞뒤로는 함수 프롤로그 에필로그를 컴파일러가 붙혀주었습니다.
제가 만든 코드의 헥사덤프 부분을 보겠습니다. 노란색으로 네모 친 부분이 " 00 " 즉 NULL로 되어있습니다.
헥사덤프코드를 그대로 쉘코드로 쓰게 되면 " 00 "이라는 부분에서 멈춰버리게 됩니다.
그러면 이번에 해주어야할 작업은 저 " 00 " 으로 된 부분을 없애주는 것입니다.
어셈코드를 고치겠습니다.

위와 같이 어셈코드를 고쳐봤습니다.
objdump로 헥사덤프값을 보겠습니다. 과연 " 00 " 이 존재할까요??

성공입니다. 어딜봐도 NULL은 존재하질 않습니다.

실행도 정상적으로 잘 되군요. 쉘코드는 만들었습니다.

\x31\xdb\x31\xc9\x31\xc0\x31\xd2\x66\xbb\x1c\x0c\x66\xb9\x1c\x0c\xb0\x46\xcd\x80\x31\xc0\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80

길기도 합니다. 총 43byte입니다.

이제 해당 파일을 공격하겠습니다.
공격하기전에 잠시 스택을 그림으로 표현하고 넘어가겠습니다.

스택은 간단하군요. 그러면 제 쉘코드는 다행이도.. 43byte이므로 들어갈 수 있습니다.
43byte에 쉘코드 넣고 1바이트에 "A"넣고 리턴 주소는 buf의 처음 주소로 돌리면 됩니다.
buf의 처음 주소를 구해보겠습니다.

 gets의 첫번째 인자의 값을 보면 알 수 있습니다. 0xbffffae0이군요.
저 주소로 리턴 주소를 바꾸고 공격을 해보겠습니다.

쉘코드를 만들었으면 level11과 다를게 없는 문제인데 세그멘테이션 오류가 떴습니다.
왜 뜬지 모르겠군요. 제 방법이 틀린건 아닌데 말입니다. 그래서 제 쉘코드가 틀렸을 수도 있어서 
단순히 /bin/sh 만 하는 쉘코드(이전 단계들에서 전부 사용했던..)로 해보았습니다. 최소한 제 쉘은 떨어져야 정상이기 때문이죠.

그냥 쉘만 떨치는 것도 안됩니다. 왜 안되는지 이유좀 알려주세요 ㅜㅜ
혹시나해서 랜덤스택인가? 라는 생각에..

조사를 해봤지만 주소가 똑같습니다. 랜덤스택은 아니었습니다.
gcc 버전, 리눅스 버전이 level11과 전부 같은데 왜 안되는지..;;

아무튼 더이상 이 방법은 안될꺼 같습니다. 그래서 처음으로 에그쉘을 사용해보았습니다.
환경변수에 쉘코드를 등록시켜놓고 그 환경변수 주소로 리턴값을 바꾸는 방법입니다.
만약 스택에서 코드실행이 불가능하다면 에그쉘을 사용하는 방법도 막히게 되겠죠.

일단 에그쉘 소스코드에 제가 만든 쉘코드를 넣어주고 해당 소스를 컴파일 시켜 실행시키겠습니다.
제가 컴파일 시킨 에그쉘 소스코드 입니다.( 궁금할 건 없지만 필요하시면 보세요 )
주소가 나왔습니다. 리턴 주소를 저 주소로 바꿔주고 공격을 하겠습니다.

성공입니다. 이것 참.. ;; 스택에서 코드실행은 가능했군요.
혹시 위에서 왜 세그멘테이션 오류라도 뜨는지 이유를 아시는 분은 댓글로 좀 알려주세요~!
초보인 저에게 가르침을... ㅜ_ㅜ..

'My Study > Exploit' 카테고리의 다른 글

RTL로 푼 해커스쿨 level11  (4) 2010.04.07
Hackerschool level20  (0) 2010.03.30
Hackerschool level18  (0) 2010.03.24
Hackerschool level17  (0) 2010.03.23
Hackerschool level16  (0) 2010.03.23