buffer over flow란?

해석 해보면 '버퍼'라는 것이 넘쳐 흐른다는 의미를 가지고 있다.

 

C언어를 예로 살펴 보면 버퍼에 데이터를 입력 받을 때 할당된 크기만큼 받으면 문제가 발생하지 않는다.

 

 

하지만 할당된 크기보다 많은 양의 데이터를 받으면 버퍼의 허용치를 넘게 되어 다른 변수나 메모리를 덮어 씌우게 되는데 이를 버퍼 오버 플로우라고 하는 것이다.

 

buffer over flow는 stack overflow와 heap overflow가 있는데 둘다 어렵다. 추후 문제를 통해서 다루어 보겠다.

 

buffer overflow를 방지하기 위해서는 입력받는 데이터 크기와 버퍼 크기의 값을 확인해 주어야 한다.

'Basic Concepts > System' 카테고리의 다른 글

Fake EBP  (0) 2020.04.22
SFPO(Stack Frame Pointer OverFlow)  (0) 2020.04.22
RET Sled  (0) 2020.04.22
NOP Sled  (0) 2020.04.10
경쟁상태(race condition)  (0) 2020.02.25

설명하기에 앞서 Return Address는 ret gadget과 같은 말이다.

 

NOP Sledf랑 비슷해 보이는 RET Sled, ret sled란 무엇일까?

 

RET Sled란 RET를 여러번 호출해서 스택상의 위치를 계속 옮기는 작업이다.

RET는 무엇인가?

RET는 어셈블리어 명령어로 두가지로 구성된다.

 

pop eip, jmp eip

 

pop과 jmp는 많이 들어봐서 익숙할 것이다.

 

pop eip를 통해 stack pointer가 가리키는 값을 eip에 저장하고

jmp eip를 통해 eip에 저장된 그 위치로 이동하는 일을 수행한다.

ret가 실행됬을때의 ESP, EIP

(stack pointer는 ret가 실행되기전 leave명령어의 pop ebp가 실행된 후 RET+4를 가리킨다.)

 

leave 명령어로 인해 base pointer는 caller가 가지고 있던 값으로 복귀 되고 스택의 top은 return address를 가리키게 된다.

이때 ret의 명령어를 이용해 pop eip로 eip에 Return Address를 넣고 jmp eip로 retrun address로 이동하여 해당 주소에 있는 명령들이 실행되게 된다.

 

RET Sled는 이를 이용하여 ret 명령어를 계속해서 실행하는 것이다.

 

이를 이용하면 원하는 위치에 명령어를 넣고 실행시킬수 있다.

 

예시를 간단히 설명하겠다.

 

 

return address에 ret명령어의 주소가 있다면 ret가 한번 더 실행되고 pop eip가 일어나며 eip에는 뒤에 있는 주소가 들어가게 된다.

이를 계속 반복하여 원하는 위치를 ESP가 가리킬때 pop eip와 jmp eip를 통해 쉘같은 것들을 실행 시킬수 있는 것이다.

'Basic Concepts > System' 카테고리의 다른 글

SFPO(Stack Frame Pointer OverFlow)  (0) 2020.04.22
BOF(Buffer Over Flow)  (0) 2020.04.22
NOP Sled  (0) 2020.04.10
경쟁상태(race condition)  (0) 2020.02.25
스택(Stack)과 스택프레임(Stack Frame)  (0) 2020.01.26

NOP Sled 기법

 

NOP Slide = NOP Sled

미끄러지는 NOP이라는, NOP 썰매라는 뜻이며 NOP는 어셈블리어로 0x90으로 아무것도 하지 않는다는 명령어이다.

NOP은 0x90으로 표현되며 그 갯수 만큼의 주소 공간을 확보할수 있다.

그래서 NOP으로 shellcode의 앞부분을 채우면 정확하지 아니한 근처값의 주소여도 쉘코드가 실행되게 할수 있다.

 

앞주소를 0x90(NOP)로 채우면 아무것도 수행하지 않고 지나간 후 내가 의도한 값에 도달하기에 NOP Sled, NOP Slide라 불리어 진다.

'Basic Concepts > System' 카테고리의 다른 글

SFPO(Stack Frame Pointer OverFlow)  (0) 2020.04.22
BOF(Buffer Over Flow)  (0) 2020.04.22
RET Sled  (0) 2020.04.22
경쟁상태(race condition)  (0) 2020.02.25
스택(Stack)과 스택프레임(Stack Frame)  (0) 2020.01.26

-경쟁상태

둘 이상의 입력 또는 순서 등이 결과값에 영향을 줄 수 있는 상태를 말한다. 입력 변화의 타이밍이나 순서가 예상과 다르게 작동하면서 정상적인 결과가 나오지 않을 위험이 있는데 이를 경쟁 위험이라고 지칭 한다.

 

컴퓨터 메모리 또는 스토리지에서 데이터를 읽고 쓰는 명령들이 같은 순간이라고 해도 될정도로 순식간에 처리된다.

 

그 일련의 과정 중 이전 데이터가 여전히 있는 동안 데이터의 일부 또는 전부를 덮어 씌우려 할 때 경쟁 상태가 발생한다.

 

 

process 1 process 2 memory value
A   0
Flip value   1
  A 1
  Flip value 0

 

프로세스1은 비트 플립을  수행하여 메모리값을 0->1 프로세스2도 비트플립을 수행하여 메모리값을 1->0으로 변경시킨다.

 

 

 

여기서 경쟁상태가 발생하여 두 프로세스가 겹치면 어떻게 될까?

process 1 process 2 memory value
A   0
  A 0
Flip value   1
  Flip value 1

 

메모리 값이 0이어야 하는 마지막 경우의 메모리 값은 1이 되어 있다. 이는 프로세스1이 동시 비트플립을 수행하고 있다는 것을 프로세스2가 파악하지 못하기 때문에 나온 결과이다.

 

 

-경쟁 상태로 인한 취약점

프로그램이 둘 이상의 작업을 동시 수행 하도록 하면 공격자는 교착 상태 또는 스레드 블록 상황을 만들기 위해 시작 시점과 보안 제어가 적용 되는 시점 사이의 시간 간격을 활용 할 수 있다.

(교착상태는 소프트웨어 시스템의 정지를 스레드 블록은 응용 프로그램 성능에 영향을 줄 수 있다.)

 

 

- 대응 방안

메모리 또는 스토리지 엑세스의 직렬화를 통해 경쟁 상태를 방지 할 수 있다.

 

 

webhacking.kr의 60번 문제가 네트워크에서 이를 이용하여 해결하는 문제다.

 

'Basic Concepts > System' 카테고리의 다른 글

SFPO(Stack Frame Pointer OverFlow)  (0) 2020.04.22
BOF(Buffer Over Flow)  (0) 2020.04.22
RET Sled  (0) 2020.04.22
NOP Sled  (0) 2020.04.10
스택(Stack)과 스택프레임(Stack Frame)  (0) 2020.01.26

스택(Stack)

스택은 제한적으로 데이터를 액세스 할 수 있으며, FILO(First in Last Out) 구조를 띄고 있다.

스택은 STACK의 탑 부분에서 데이터를 액세스 할 수 있다.

또한 데이터가 액세스 될때 스택의 주소 값은 점차 줄어든다.

(스택은 커널의 반대 방향으로 자라기 때문이다.)

 

프로세스에서 스택 메모리의 역할

1. 함수 내의 로컬 변수를 임시로 저장한다.

2. 함수를 호출 할 시에 파라미터를 전달한다.

3. 복귀 주소를 저장한다.

stack

 

PUSH와 POP을 이용해 데이터를 액세스 하며 제일 위에 있는 데이터를 우선적으로 뺀다.

 

스택포인터(SP)

중앙처리 장치 안에는 스택에 데이터가 채워지면 그 위치를 가리키는 레지스터인 스택 포인터(SP)가 있다.

STACK은 PUSH와 POP에 의해 액세스 되며 그에 따라 스택 포인터의 값이 증가하거나 감소한다.

 

스택 프레임(Stack Frame)

스택 프레임은  ESP(Stack Pointer)가 아닌 EBP(Base Poinet)를 사용하여 스택 내의 로컬 변수, 파라미터, 복귀 주소에 접근하는 기법이다.

 

ESP는 프로그램 안에서 위치가 매번 변하기 때문에 기준점을 잡고 MOV EBP , ESP와 같이 어셈블리어를 사용하여 ESP 값이 EBP에 저장되게 한다.

스택 프레임의 구조

 

PUSH EBP;

PUSH EBP, ESP;

.

.

.

MOV ESP, EBP;

POP EBP;

RETN;

 

함수 시작(EBP를 사용하기 위해 기존 값을 스택에 저장)

현재의 ESP를 EBP에 저장

 

함수 본문 다른 것들이 실행 중

 

ESP를 정리(함수 시작했을 때의 값으로 돌림)

리턴되기 전에 원래 EBP 값으로 복원

함수 끝

 

간단한 코드를 예로 들어보겠다.

#include <stdio.h>

long add(long a, long b) {

 long x=a, y=b;

 return (x+y);

}

 

int main(int argc char* argv []) {

 long a=1, b=2;

 printf("% d\n", add(a, b));

 return 0;

시작하자마자 메인 함수는 스택 프레임을 생성시킨다.

1. long a, long b는 main 함수의 로컬 변수 이므로 스택에 공간을 만들고 값(1과 2)을 입력한다.

2. printf()함수를 스택에서 처리한다(역순으로 처리 하기 때문에 b, a, add()순으로 스택에 들어간다.).

3. add 함수를 호출하고 add함수 스택프레임에 x, y를 공간을 만들어 저장하고 값(x=a=1, y=b=2)을 입력한다.

4. 결과 값을 메인함수에게 돌려주고 printf() 처리 완료 및 add 함수 스택 프레임을 지운다.

5. main 함수를 처리한다.

 

main함수에서 add함수를 호출하고 add함수의 일련의 과정을 처리한 후 main함수 스택 프레임으로 돌아온다.

 

큰흐름은 5가지 단계이니 이를 참조하여 디버깅 툴을 사용해 직접 확인해보는것이 좋을 듯하다.

 

 

'Basic Concepts > System' 카테고리의 다른 글

SFPO(Stack Frame Pointer OverFlow)  (0) 2020.04.22
BOF(Buffer Over Flow)  (0) 2020.04.22
RET Sled  (0) 2020.04.22
NOP Sled  (0) 2020.04.10
경쟁상태(race condition)  (0) 2020.02.25

+ Recent posts