DongDD's IT

Buffer overflow - Stack corruption 본문

IT 보안/System

Buffer overflow - Stack corruption

DongDD 2017. 9. 5. 17:01

Buffer overflow


Stack overflow


- stack overflow는 기본적으로 프로그램의 오류 중 buffer overflow의 한 종류이다.

- stack이 프로그램 실행 시 할당된 사이즈를 넘어갈 때 일어난다.

- 이러한 stack overflow로 인해 취약점이 생길 수 있다.



- 기본적으로 stack에 이러한 순서로 쌓이게 된다.

- buffer가 20bytes라면 그 뒤에 4bytes의 sfp, 함수가 끝난 후 돌아갈 return값 4bytes, parameter 이런 순으로적재가 된다.


Saved frame pointer(SFP) : 함수의 실행이 끝나고 이전 함수로 돌아가기 위해 이전 함수의 ebp를 저장해둠


Stack corruption에서는 RET의 값을 변조시켜 함수가 끝난 후 return할 위치를 바꿔준다.


buffer가 20byte라면 buffer를 채운 후 sfp 4byte를 채운 후 ret값을 변조할 수 있게 된다.



Stack overflow example1) argument strcpy


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
int main(int argc, char *argv[])
{
    char buf[20];
    strcpy(buf, argv[1]);
    printf("buf = %s\n", buf);
}
 
void vuln()
{
    system("/bin/sh");
}
 
cs


위와 같이 argument를 받아 strcpy를 사용하는 경우 이 취약점을 이용할 수 있다.


ubuntu 16.04에서는 stack corruption을 막아 놓았기 때문에 gcc 옵션중 -fno-stack-protector 와 -mpreferred-stack-boundary 옵션을 사용해 컴파일해 예제를 만들었다.


실제 저 프로그램에서는 vuln이라고 만들어 놓은 함수를 실행할 수 없다.

하지만 stack corruption을 이용한다면 저 vuln함수를 실행해 system함수를 호출할 수 있게 된다.



gdb를 이용하여 코드안에 있는 함수들을 확인할 수 있다.

여기 vuln 함수의 주소는 "0x804849a"라고 나와있다.

이것을 이용해 저 함수를 강제로 시작할 수 있다.


먼저 payload 작성을 해보도록 하자.

소스코드에서 buf가 20byte로 선언된 것을 볼 수 있다.

그 뒤에는 4byte의 sfp가 있고 그 뒤에 ret값을 변조시킬 수 있게 된다.

즉, ret 4byte에 vuln함수의 시작 주소를 넣어준다면 함수가 끝난 후 vuln함수로 return 하게 될 것이다.


Payload

payload = 24 bytes(dummy) + "\x9a\x84\x04\x08"을 argument 값으로 넣어 준다면 함수가 끝난 후 vuln함수로 넘어가게 될 것이다. 



위에서 작성한 Payload를 이용하여 vuln함수를 호출해 vuln함수내 system 함수가 실행되는 모습이다.


Stack overflow example2) scanf



1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
int main(int argc, char *argv[])
{
    char buf[20];
    scanf("%s",buf);
    printf("buf = %s\n", buf);
}
 
void vuln()
{
    system("/bin/sh");
}
 
cs


위 예제와 비슷한 예제이다. 대신 strcpy 대신 scanf를 통해 입력받아 vuln함수를 실행시키는 예제로 작성해보았다.


위 예제와 같은 형식으로 payload를 만들 수 있다. 이 예제 또한 ubuntu16.04에서 실행한 예제라 gcc 옵션으로 두가지를 넣어서 컴파일했다.



이 프로그램에서 vuln 함수의 주소는 0x80484c6으로 되어있다.

위 예제와 마찬가지로 payload를 작성하면 된다.


Payload


payload = 24 bytes(dummy) + "\c6\x84\x04\x08"



위와 같은 payload를 이용해 vuln함수로 넘어가 system함수를 호출하는 모습을 볼 수 있었다.



방어기술


1. Stack Guard

- Return address와 변수 사이에 특정 값을 저장해두었다가 그 값이 변경되었을 경우 오버플로우로 가정해 프로그램을 중단시키는 기술


2. Stack Shield

- Return address를 Global RET라는 특수 스택에 저장했다가 함수 종료 시 저장된 값과 ret값을 비교해 다르면 오버플로우로 가정해 프로그램을 중단시키는 기술


3. ASLR(Address Space Layout Randomization)

- 프로그램 실행 시 마다 주소를 random으로 배치해 공격자가 원하는 메모리 주소를 찾기 어렵게 하는 기술

'IT 보안 > System' 카테고리의 다른 글

Format String Bug - format string, FSB, Example  (0) 2018.01.17
Comments