level11의 ID와 PW는 아래와 같습니다.


ID : level11

PW : what!@#$?


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


먼저 hint 파일을 살펴보면 다음과 같습니다.


[그림 1] level11 hint 파일


힌트 파일의 내용은 attackme의 프로그램 소스코드로 추정되고 이를 토대로 exploit을 시켜야 함을 암시하는 것 같습니다.

우리가 사용할 기법은 Return To Library입니다.

여기서 필요한 요소는 총 세 가지 입니다.


(1) 프로그램 내에서 사용하는 Library 중 system 함수의 주소

(2) system 함수 내에 '/bin/sh'의 주소

(3) 우리가 이용할 Return의 주소


이제 GDB를 이용하여 소스코드를 자세하게 분석하여 봅시다.


[그림 2] gdb run Error


하지만 한 가지 주의사항이 있습니다.
[그림 2]를 보면 gdb run Error인데, 이는 owner만이 gdb로 분석할 수 있는 것으로 추측됩니다.(혹은 root 이거나)

때문에 우리는 attackme 파일을 tmp에 복사하여 그것으로 분석해야 합니다.

작성자는 tmp에 atm라는 이름으로 복사하여 분석을 진행하였습니다.


[그림 3] atm를 gdb로 열어본 모습


(1) 메인을 요약해보면 0x108만큼 스택의 공간을 마련합니다.

(2) 기타적인 작업...

(3) 우리가 입력한 값을 strcpy의 인자값으로 넣어 실행시키고, (ebp-0x108)의 값을 eax에 넣어 push해주는 것을 볼 수 있습니다.

(4) 이후 이를 print해줍니다.


먼저 main에 break point를 걸어주고 run을 해준 후, p system 을 입력하여 프로그램 내에서 사용하는 library 내의 system 주소를 가져올 수 있습니다. 우리는 system 함수의 주소가 0x4203f2c0임을 알 수 있습니다.

[그림 4] system 함수의 주소


system 함수의 주소를 알아냈으니 우리는 이제 /bin/sh 의 주소를 알아낼 소스코드를 작성하여 봅시다.

우리가 system 함수의 주소가 0x4203f2c00 이므로 그 주소로부터 1 Byte 씩 하나씩 shift하여 8 Byte씩 비교하여 hex로 "/bin/sh"를 찾아냅니다. 이 주소를 print 하는 프로그램입니다.

[그림 5] /bin/sh의 위치를 찾아내는 C 코드


이제 이 소스코드를 실행시키면 atm 실행파일 내의 system 함수에서 사용하는 /bin/sh의 주소를 찾아내어 프린트 해줍니다.

/bin/sh의 주소는 [그림 6]과 같습니다.


[그림 6] system 함수에서 하용하는 /bin/sh 주소


이제 다음으로 우리는 사용할 ret 주소를 찾아내야 합니다.

[그림 7]에서는 main에서 strcpy 실행 이후에 break point를 잡아 esp에서부터 300Byte의 값을 나타낸 것입니다.

A를 256개를 채운 그림입니다.

[그림 8] main+53에서 멈춘 Stack 모습


[그림 8]에서 RET은 main 함수의 return 0의 RET으로 추정됩니다.

이를 추측한 계기는, RET 앞의 (1)번이 argc일 것으로 추정하였고, argc가 2일 것으로 추정되었습니다.

그렇다면 (2)번은 argv[0]일 것으로 추측하여 한 번 살펴보았습니다. 살펴본 결과는 [그림 9]와 같습니다.

[그림 9] argv[0]임을 확인


현재 [그림 9]에서 보듯이 argv[0]이고 이 다음 주소의 값은 argv[1]의 값입니다.

그렇다면 우리가 덮어써야 할 부분은 A가 256개가 아닌 3칸(4Byte씩)을 더 한 268Byte 떨어진 부분임을 알 수 있습니다.


필요한 세 가지 요소를 모두 찾았습니다. 그럼 이제 Exploit을 해야 하는데, 이를 더 간편하게 하기 위해서는 python 코드로 하는 것도 나쁘지 않아 보입니다. [그림 10]은 SecuMaster 동아리 현 부회장(2016년)의 도움을 받아 작성한 소스입니다.

[그림 10] exploit python 코드


sysaddr는 system 함수의 주소, binsh_addr는 /bin/sh의 주소를 저장하는 변수입니다.

그리고 이를 struct.pack을 이용하여 리틀 엔디언으로 저장합니다.

페이로드는 268개의 A(혹은 nop, \x90) + system address + "4Byte 쓰레기 값 혹은 다른 리턴 값" + binsh address

로 작성하면 됩니다.

[그림 11] exploit 코드를 실행한 모습


이제 코드를 실행하면 권한이 상승된 shell을 얻은 것을 볼 수 있습니다.



'WARGAMES > FTZ' 카테고리의 다른 글

level15_FTZ_SIMPLE BOF기법  (0) 2016.08.24
level14_FTZ_SIMPLE BOF기법  (0) 2016.08.10
level13_FTZ_RTL기법  (0) 2016.08.08
level12_FTZ_RTL기법  (0) 2016.08.07
level10_FTZ  (0) 2016.07.21
level09_FTZ  (0) 2016.07.21
level08_FTZ  (0) 2016.01.07
level07_FTZ  (0) 2016.01.07

+ Recent posts