반응형

[프로그램 동작]

Exploit.c에서 badfilebuffer를 쓴다. 그리고 stack.c에서 badfile를 열고 str에 읽는다. Badfile의 값이 써진 strbof의 인자로 넘겨준다.

Stack.c에서 bof 함수는 인자로 받은 strbuffer에 복사한다. 하지만 strcpyNULL을 만나기 전까지의 문자열을 복사하고 복사할 문자열의 길이는 검사하지 않는다. 따라서 buffer의 크기가 24이고, str의 길이는 517이므로 buffer의 스택을 넘어선다.

이때 bof 함수의 return addressshellcode의 주소를 넣어 shellcode가 실행되게 한다.

 

Gdb를 통해 strcpy가 실행되는 곳에 break를 하였고, bof함수를 disas하여 strcpy0x20크기의 buffer인자가 전달되는 것을 알 수 있다.

따라서 buffer의 크기는 32byte임을 알 수 있다.

 

gdb를 통하여 ebp0xbfffeab8임을 알 수 있고, ebp의 주소에서 0x20만큼 빼주어 buffer의 시작 위치를 알 수 있다. 그리고 이를 토대로 bof return address가 실제와 일치하는지 disas main을 하여 비교를 하면 0x08048574로 같음을 알 수 있다.

 

Buffer의 크기는 32이고 saved edp for bof의 크기는 4이므로 buffer[36]부터가 return address of bof임을 알 수 있다. Exploit.c에서 “memcpy(buffer+sizeof(buffer)-sizeof(shellcode), shellcode, sizeof(shellcode));”를 하여, buffer의 맨 끝에 shellcode를 넣었다.

따라서 정확한 shellcode의 주소를 몰라도 return address 이후와 buffer 이전의 아무 주소 값이나 return address of bof에 넣어준다면 shellcodebuffer의 맨 끝에 있으므로 실행이 될 것이다.

시스템이 Little endian이므로

주소값을 반대로 넣어준다. Buffer의 크기는 32byte이고 saved ebp or bof 4byte이므로 *(buffer +36)return address를 가리키므로, *(buffer +36)부터 차례로 주소를 넣어준다.

이것을 실행하면 원하는 shellcode가 동작하는 것을 볼 수 있다.

 

 

[취약점 메모리 구조]

Bof 함수의 strcpy(buffer, str)이 취약점이다. 먼저 bof 함수 인자인 str이 쌓이고 그 다음에 Return Address of bof, Saved ebp of bof, buffer가 쌓인다. Buffer32byte이고 saved ebp of bof4byte, return address of bof 4byte, str 517bye이다.

Str의 크기가 buffer보다 크고, strcpy는 문자열의 길이를 체크하지 않으므로 str의 값들이 buffer스택 위로 덮어쓰여진다.

 

- Exploit 실행 후 메모리 구조

Exploit이 실행되면, overflow로 인하여 bofreturn address0xbfffeb68(return address 위의 랜덤주소, buffer의 마지막에 shellcode가 있다)이 들어간다.

그리고 NOP 명령어가 실행되다가 buffer의 끝에 있는 shellcode를 실행한다.

 

[취약점 보완]

프로그래머가 스택의 다른 영역을 침범하지 않게 코드상으로 영역을 명확히 명시하거나 입력 받는 데이터의 크기를 확인하거나 buffer overflow에 취약한 함수를 사용하지 못하게 한다.

 Buffer overflow에 취약하지 않은 함수를 사용한다. Strcpy(buffer, str)strncpy(buffer, str, sizeof(buffer)-1)함수로 대체 사용하여 복사할 크기를 지정하여 overflow가 생기지 않도록 한다.

 

 

Strncpy를 사용하여 복사할 크기를 지정해주었을 때 공격이 실패하고 정상적으로 “Returned Properly”가 수행되는 것을 알 수 있다.

또는 sizeof(buffer)BUF_SIZE이나 24로 명확하게 적어준다.

 

인자로 받는 데이터의 크기를 체크한다. bof함수의 인자로 int size값을 받아 str의 크기를 체크하여 오버플로우를 방지한다. Bof(char*str, int size)의 형태로 받는다.

크기가 buffer보다 클 때 warning을 출력하고 exit한다.

 

 

스택 쉴드 기법을 사용하여 함수가 호출될 때 그 함수의 Return Address를 특수 스택에 저장을 하고 함수 종료 시 저장해둔 Return Addresss와 비교를 하여 값이 다르면 프로그램을 종료시킨다.

 

해제한 ASLR(Address Space Layout Randomize)기법을 다시 사용하여 각 프로세스 안의 스택이 임의의 주소에 위치하도록 한다.

해제한 NX bit를 활성화하여 스택/힙 영역의 실행권한을 제거하여 쉘의 실행을 방지한다.

해제한 Stack Guard기법을 사용하여 스택에 Canary 값을 넣고 이 값이 변조되었는지 검사하여 오버플로우를 체크한다.

728x90
반응형

'공부 > 보안' 카테고리의 다른 글

간단한 Android game app hacking  (0) 2021.05.03
SEED Lab Return-to-Libc Attack  (0) 2021.05.03
SystemProperties로 에뮬레이터 탐지  (0) 2021.05.03
BOF 원정대 level 16  (0) 2021.05.03
BOF 원정대 level 18  (0) 2021.05.03
블로그 이미지

아상관없어

,