orang

 

함수, 상수등이 들어가는 코드영역 전역변수가 들어가는 DATA와 BSS영역 동적할당되는 HEAP과 마지막으로 지역변수가 들어가는 STACK

 

kernel 영역은 사용자의 접근을 허가 하지 않는다.

 

1. stack 영역은 프로그램이 자동으로 사용하는 임시 메모리 영역이다.

지역(local) 변수, 매개변수(parameter), 리턴 값 등 잠시 사용되었다가 사라지며 함수 호출시 생성되고 함수가 끝나면 반환 된다.

 

2. heap 영역은 동적으로 메모리를 할당 할 때 쓰는 메모리 영역으로 메모리 주소 값에 의해 참조 및 사용되는 영역이다.

 

3. data, bss 영역은 전역변수(global), 정적변수(static), 배열(array), 구조체(structure) 등이 저장된다.

프로그램이 실행 될 때 생성되고 프로그램이 종료 되면 시스템에 반환 된다.

변수가 초기화 되면 데이터 영역, 초기화 되지 않으면 bss영역이다.

 

4. code 영역은 코드자체를 구성하는 메모리 영역으로 기계어 명령어들과 어셈블리 코드가 자리한다.

 

스택은 위에서 아래로 힙은 아래에서 위로 자라며 사이에 라이브러리 영역이 존재한다.

 

 

 

 

 

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

GOT Overwrite  (0) 2020.04.24
PLT & GOT 정리  (0) 2020.04.24
RTL(Return to libc) & chaining  (0) 2020.04.23
Fake EBP  (0) 2020.04.22
SFPO(Stack Frame Pointer OverFlow)  (0) 2020.04.22

GOT overwrite란 dynamic link방식으로 컴파일된 바이너리가 공유 라이브러리를 호출할때 사용되는 PLT&GOT 중 GOT 값을 변조하여 내가 의도한 함수를 호출 하도록 하는 기법이다.

ex) printf -> system

 

간단한 예를 들어보자

#include <stdio.h>

int main()
{
	print("/bin/sh");
}

print 함수를 필요로하는 코드이다.

 

이 코드를 gdb로 확인해보면 printf를 plt로 호출하는 printf@plt 부분을 찾을수 있을 것이다.

gdb를 이용해 printf@plt부분을 디스어셈블 해보면

 

jmp   *0x00000000

push  $0x0

jmp    0x00000000

 

로 구성되어져 있는 것을 확인 할수 있다.

첫번째 jmp는 GOT안에 있는 값을 가리킨다.

*0x00000000 이값을 system 함수의 주소 값으로 바꿔주면 된다.

 

그렇게 jmp 부분값을 overwrite 하여 system 함수로 바꿔주고 실행시킨다면 PLT에서는 변조된 값을 불러오게 된다.

printf("/bin/sh"); -> system("/bin/sh");

 

이렇게 PLT&GOT과정에서 GOT값을 사용자가 덮어씌움으로써 GOT Overwrite가 일어난다.

직접 실습 해보는 걸 추천한다.

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

메모리 영역  (0) 2020.04.26
PLT & GOT 정리  (0) 2020.04.24
RTL(Return to libc) & chaining  (0) 2020.04.23
Fake EBP  (0) 2020.04.22
SFPO(Stack Frame Pointer OverFlow)  (0) 2020.04.22

PLT(Procedure Linkage Table) : 외부 프로시저를 연결해주는 테이블. PLT를 통해 다른 라이브러리에 있는 프로시저를 호출해 사용할 수 있다.

 

GOT(Global Offset Table) : PLT가 참조할 때 사용하는 테이블 프로시저들의 주소들이 들어 있다.

 

-Procedure란 함수와 비슷한 개념이지만 함수는 리턴값이 있지만 프로시저는 리턴 값이 없다.

 

어떤식으로 사용되는가?

C언어에서 printf, system 같은 외부라이브러리 함수를 사용하기 위해 PLT가 호출되면 PLT는 외부 프로시저(다른 라이브러리에 있는 함수)를 호출하기 위해 프로시저들의 주소가 있는 GOT를 참조한다.

 

C system함수 사용요망 -> PLT 호출 -> GOT참조 -> 프로시저들의 주소(함수의 주소)

 

사실 함수를 처음 호출 할 경우 GOT는 함수의 주소를 가지고 있지 않기에 일련의 과정을 거쳐 주소를 알아낸다.

두번 째 호출 부터는 알아낸 함수 주소로 바로 jmp 한다.

 

PLT와 GOT에 있어 중요한 링커에 대해 설명하겠다.

 

어떤 코드를 작성한다고 예를 들었을때 코드를 짰다고 해서 이게 실행이 되는것이 아니다.

컴파일이라는 과정을 거쳐야 실행이 된다.

 

컴파일을 통해 오브젝트 파일을 생성한다.(오브젝트 파일 자체로는 실행 불가)

외부에서 불러온 함수(ex : system, printf)의 구현 코드를 모르기 때문에 실행 불가능하다.

이를 해결하기 위해서 함수의 실행 코드를 오브젝트 파일과 연결해 줘야 한다.

함수의 실행 코드는 함수의 구현 코드를 컴파일 한 오브젝트 파일, 즉 라이브러리에 존재한다.

이 라이브러리를 오브젝트 파일과 연결해 주는 링킹 작업이 필요 한데 여기에는 2가지 방법이 있다.

 

 

1. Static link

2. Dynamic link

 

static link 부터 알아보자

static은 정적이라는 뜻으로 앞서 설명한 라이브러리 파일을 내가 구현한 코드 와 함께 묶어서 만든 실행 파일이다.

실행 파일 안에 모든 코드가 포함 되기에 라이브러리 연동 과정이 필요 없지만 크기가 커지는 단점이 있다.

 

dynamic link는 동적 링크라는 뜻으로 라이브러리를 메모리 공간에 매핑하고 여러프로그램에서 공유해 사용하는 방식이다.

 

앞서 PLT&GOT에서 함수를 처음 호출 할 경우 GOT는 함수의 주소를 가지고 있지 않기에 일련의 과정을 거친다 하였다.

함수를 처음 호출 할 경우 Linker가 dl_resolve라는 함수를 사용해 필요한 함수의 주소를 알아오고, GOT에 그 주소를 써준 후 해당 함수를 호출한다.

 

참조 : https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/ 

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

메모리 영역  (0) 2020.04.26
GOT Overwrite  (0) 2020.04.24
RTL(Return to libc) & chaining  (0) 2020.04.23
Fake EBP  (0) 2020.04.22
SFPO(Stack Frame Pointer OverFlow)  (0) 2020.04.22

RTL은 Return-to-libc란 라이브러리를 반환한다는 뜻이며 NX bit(Non executable Stack) 스택상에서 코드 실행 불가능 일때 사용한다.

 

우리가 코드를 작성해서 실행 할때 사용되는 함수들은 모두 라이브러리에 들어있다.

RTL은 ret에 라이브러리 함수를 덮어 씌워 이것이 실행되도록 하는데 중점을 두고 있다.

 

RTL을 사용하기 위해서는 ret보다 높은 주소에 코드를 덮어 씌울 수 있어야 한다.

현재 상태의 스택이다.

함수 에필로그가 실행되면서 EBP는 원래 EBP로 이동하게 되고 ESP는 SFP를 가리키게 된다.

ret 명령어가 실행되며 pop eip가 실행된다.

여기서 ret에는 사전에 라이브러리에 있는 함수 주소를 넣어 두었다.

jmp eip를 통해 그대로 값이 불러진다. 이는 call명령으로 부르는게 아닌 그저 ret를 변조하여 함수를 호출한 것이기에 스택에 그대로 쌓이게 된다.(ret에 의한 함수 호출은 call과 다르게 return address 를 남기지 않는다.)

system함수가 실행되면서 esp는 SFP(함수)를 가리키게 된다.

 

중간 의미없는 것을 지나쳐 leave명령어에서 pop ebp로 ebp는 또 어딘가로 날아가고

esp는 더미 값을 가리키게 된다.

 

여기서 ret가 수행되면 esp는 SFP함수의 인자를 가리키게 되고 eip는 dummy를 가리키고 실행하게 된다.

여기서 RTL chaining이 발생할수 있다.

dummy값에 pop-ret 가젯을 넣는다면 '인자의 주소' 혹은 '인자의 값'을 건너뛰고 그뒤 4바이트를 다시금 ret로 참조하게 된다.

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

GOT Overwrite  (0) 2020.04.24
PLT & GOT 정리  (0) 2020.04.24
Fake EBP  (0) 2020.04.22
SFPO(Stack Frame Pointer OverFlow)  (0) 2020.04.22
BOF(Buffer Over Flow)  (0) 2020.04.22

https://ravidusash.tistory.com/115

 

SFPO(Stack Frame Pointer OverFlow)

SFP overflow 공격은 SFP에 한바이트 만큼 overflow를 일으키는 공격 기법이다. SFP overflow를 설명하기전에 stack frame pointer overflow에 대해서 먼저 알고 넘어가자 SFP에서 S는 Stack을 의미하며 스택이란..

blog.ravidusash.kr

본 기법은 leave-ret에 대한 이해가 필요하다 전 글인 SFPO에서 leave-ret을 먼저 이해하고 보도록 하자

 

Fake EBP란 EBP 조작과 leave-ret Gadget을 이용한 공격기법이다.

SFP는 쉘코드의 위치주소 - 4를 ret는 leave-fet 가젯을 갖도록 하여 공격을 수행한다.

이 상태에서 함수 에필로그가 실행 되면 

 

mov esp, ebp가 실행되어 esp는 ebp와 같아질 것이고 pop ebp가 실행되어 ebp는 미리 조작 해 두었던 위치값으로 이동할 것이다.

ret에 의해 pop eip가 실행되어 leave-ret을 가리키며 jmp eip로 이를 수행하게 된다.

그렇게 esp는 leave 명렁어대로 mov esp, ebp 다시금 ebp가 가리키는 곳으로 이동하게 된다.

pop ebp가 실행되어 ebp는 어디론가 가고 esp는 sehllcode를 가리키게 된다.

ret명령어에서 pop eip가 실행 되어 eip가 쉘코드 주소르 가리키게 되고 jmp eip를 통해 쉘이 실행된다.

이렇게 우리는 FEBP를 통해 쉘을 획득 할 수 있다.

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

PLT & GOT 정리  (0) 2020.04.24
RTL(Return to libc) & chaining  (0) 2020.04.23
SFPO(Stack Frame Pointer OverFlow)  (0) 2020.04.22
BOF(Buffer Over Flow)  (0) 2020.04.22
RET Sled  (0) 2020.04.22

SFP overflow 공격은 SFP에 한바이트 만큼 overflow를 일으키는 공격 기법이다.

 

SFP overflow를 설명하기전에 stack frame pointer overflow에 대해서 먼저 알고 넘어가자

 

SFP에서 S는 Stack을 의미하며 스택이란 함수의 return address, 지역 변수 등이 저장 및 사용되는 곳이다.

스택은 FILO(First In Last Out) 후입선출구조로 마지막에 들어간게 제일 먼저 꺼내지는 특징을 지닌다.

스택은 높은주소에서 낮은 주소로 자란다.

들어올때는 1/2/3

나갈때는 3/2/1

 

F는 Frame을 뜻하며 SF스택 프레임이란 ESP가 아닌 EBP를 이용해서 스택 내 변수들이나 복귀 주소 파라미터에 접근하는 방식을 의미한다.

 

스택 프레임은 함수의 영역을 표시하는데 이때 함수 프롤로그와 에필로그라는 것을 수행한다.

프롤로그는 push ebp와 mov ebp, esp 구성되어져 있다.

함수가 호출되면 그 영역을 설정하기 위한 것으로 ebp를 push하는 행위는 이전 함수의 ebp주소를 스택에 저장시키는 행위이다.

mov ebp, esp는 esp를 ebp로 복사함으로써 불리어진 함수의 ebp를 새로 설정해주는 것이다.

ebp를 기점으로 함수의 ret주소나 argc, argv, 변수등을 쉽게 알수 있다.

 

SFPO에서는 에필로그를 중점으로 다룬다.

에필로그는 leave-ret 두함수로 구성되어져 있으며 두 함수도 각각 2가지로 구성되어져있다.

 

leave는 mov esp, ebp와 pop ebp로 이루어져 있다.

mov esp, ebp esp가 ebp가 가리키는 주소로 이동하고 이는 sfp에 위치한다.

pop ebp를 이용하여 이전 함수의 ebp로 되돌려 놓는다.

 

ret는 pop eip, jmp eip로 이루어져 있다.

pop eip가 일어나면 eip가 주소를 받아 jmp eip를 통해 그 주소로 이동한다.

 

본격적으로 SFPO에 관하여 설명하도록 하겠다.(이하 FPO)

FPO는 SFP의 하위 1바이트를 변조하였을 때 일어난다.

FPO를 하기 위해서는 2가지 전제조건이 갖추어 져야 한다.

 

1. main() 외에 서브함수가 하나이상 있어야 한다.

2. 서브함수에서 SFP의 하위 1바이트가 오버플로우로 접근 가능해야한다.

 

스택에서 에필로그가 실행 되었을때의 모습이다.

leave 함수 mov esp, ebp가 실행되면

 

 

ebp esp는 같아지고 pop ebp가 수행된다.

SFP값은 사전에 값을 변조해두어 EBP가 내가 원하는 곳을 향하게 된다.(값을 변조하는데 사용된것이 SFP overflow다)

 

 

 다음으로 ret 명령이 실행되며 pop eip가 실행된다.

esp가 가리키던곳을 eip가 가리키게 되고 esp는 또 이동한다! 

jmp eip가 실행되면 어떻게 되겠는가?

서브함수를 종료하고 main함수로 넘어온다.

main함수에 도착했는데 main의 에필로그가 실행될 차례이다.(여기서 감이 온다면 당신은 이해한것이다)

leave 명령어 mov esp, ebp

pop ebp

ret명령어 pop eip

jmp eip

이렇게 내가 원하는 곳으로 이동하게 된다.

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

RTL(Return to libc) & chaining  (0) 2020.04.23
Fake EBP  (0) 2020.04.22
BOF(Buffer Over Flow)  (0) 2020.04.22
RET Sled  (0) 2020.04.22
NOP Sled  (0) 2020.04.10

+ Recent posts