*초보자가 작성한 글이므로 완벽하지 않을 수 도 있습니다
부족한 점이 있다면 지적해주시고 고쳐주시면 감사하겠습니다*
----------------------------------------------------------------------------------------------
0xb000000(낮은 주소) 0xbffffff(높은 주소)
낮은주소 높은주소
Stack Heap Bss Data Text
* 스택은 거꾸로 자랍니다! 변수를 선언하면 선언할수록 메모리의 높은주소 에서 메모리의 낮은 주소로 향합니다! 이 부분은 직접 gdb로 분석 해보시다 보면 이해가 가실겁니다! *
이러한 식으로 메모리 구조가 이루어져있고 이번에 포스팅할 게시글은
Stack 을 이용한 버퍼 오버플로우를 소개하겠습니다
[ 버퍼 오버플로우 - 버퍼를 초과시켜서 공격자가 원하는 대로 프로그램의 흐름을 만들어 작동시키는 것 입니다!]
Stack은 프로그래밍을 할때 함수 내부에서 선언하는 변수들이 들어가게 됩니다
또 한 스택은 먼저 들어간것은 가장 나중에 뺄 수 있습니다!
버스기사 님들의 동전을 생각하면 되겠네요 동전을 넣어가면 점점 쌓이게 되고
그 동전을 빼려고 하면 위에서 부터 뺄수 잇겠지요 ?
(너무 진지하게 아래서 나오잖아요! 라곤 생각하지 맙시다! 그냥 저렇게 생각하시라구요!)
아니면 설거지를 하고 접시를 차곡차곡쌓는다 할때 먼저 설거지가 끝난 순서대로 접시를 쌓아 올리겠죠 ? 그 접시를 사용하려면 위에 접시부터 빼야지 아래 접시부터 빼서 쓰지는 않잖아요! 그런겁니다!
스택의 이러한 입출 방식을 기억하고 있으셔야지 좀 더 이해가 쉬우실겁니다!
자 이제 버퍼 오버플로우에서 버퍼란 ?
데이터를 일시적으로 저장하는 메모리의 영역을 뜻합니다!
또한 스택 안에서 생성이 됩니다!
또한 버퍼 오버플로우는 C , C++ , 어셈블리어 에서만 주로 발생을 하지
Java , Perl , Python 같은 언어들은 메모리를 자체적으로 관리하기 때문에 버퍼 오버플로우가 발생하지 않는다고 합니다! C#의 경우는 보호 기능을 제공하구요
자 이제 여기서 버퍼 오버플로우가 어느 상황에서 발생하느냐!
[본 소스는 해커스쿨에서 제공하는 FTZ LEVEL 9 입니다]
버퍼 오버 플로우를 간단하게 이해하고 사용해보기 위하여 만들어진 소스네요!
buf , buf2에 각각 10의 크기가 할당 되어 있습니다!
[*주의* 데이터 영역의 전역 변수는 " 메모리의 낮은 주소 " 에서 " 메모리의 높은 주소 " 로 자라납니다
스택 영역은 " 메모리의 높은 주소 " 에서 "메모리의 낮은 주소" 로 자라납니다!
이번 글에서 다룰 영역은 --스택-- 영역입니다!"
자 그렇다면 아주 간단하게 스택을 만들어보죠
/---------------------------------------/
| |
| buf 2 [10] |
| buf [10] |
| |
/-----------------------------------------/
이러한 식으로 스택이 들어간다는 소리입니다!
만약에 여기서 1,2,3,4,5 = buf 2 A,B,C,D,E = buf 이렇게 들어간다면 어떻게 될까요 ?
/---------------------------/ 메모리 높은 주소
| ret |
/---------------------------/
| sfb |
/---------------------------/
| 5 |
| 4 |
| 3 |
| 2 |
| 1 |
/---------------------------/
| E |
| D |
| C |
| B |
| A |
/---------------------------/ 메모리 낮은 주소
높은 주소에서 낮은 주소로 자란다는 것이 어떤것인지 이해 하셨을거라 생각하겠습니다!
자 다시 한번 저 소스의 스택을 보죠!
/---------------------------/ 메모리 높은 주소
| ret |
/---------------------------/
| sfb |
/---------------------------/
| buf2 [10] |
/---------------------------/
| buf [10] |
/---------------------------/
ret와 sfb는 각각 4바이트를 가지고있습니다!
근데 소스를 보면
stdin으로 40만큼의 크기를 buf에 넣어버리네요!
근데 지금 buf에는 10의 크기가 할당 되어 있습니다
여기서 만약 10을 넘는 크기를 넣어주면 어떻게 될까요 ?
좀 더 편히 설명하기 위해서 buf 에는 5의 크기가 할당 되어 있고 5를 넘는 크기를 넣어 준다고 가정 하겠습니다! (단순히 크기만 10에서 5로 바뀌어서 설명하는겁니다!)
buf 에다가 8를 넣어보겠습니다!
/---------------------------/ 메모리 높은 주소
| ret[4] |
/---------------------------/
| sfb[4] |
/---------------------------/
| 5 |
| 4 |
| H | buf2[5]
| G |
| F |
/---------------------------/
| E |
| D |
| C | buf[5]
| B |
| A |
/---------------------------/ 메모리 낮은 주소
buf 에서만 입력한 영어들이 buf2 까지 올라갔네요! 입력된 것을 모두 저장하기 위해서 buf 에만 할당한 스택을 넘어서 buf2 라는 다음 메모리 영역까지 사용을 해버렸습니다.
근데 위에 sfb 와 ret 라는 친구들이 보이지요 ?
만약 buf[5] 와 buf2 [5]의 합 크기 10 을 넘어선 값을 입력하게 된다면..?
sfp와 ret 까지 침범하게 될겁니다 .
자 여기서 sfp와 ret가 무엇이냐 ?
sfp - 함수 프롤로그에서 push ebp 에 의해서 저장된 ebp에 값입니다!
[함수에서 지역변수들이 사용될 때 EBP가 기준으로 사용이 됩니다.
그런데 함수를 하나만 사용하는것이 아니잖아요 ? 다른 함수로 넘어갔다가 다시 돌아올 때 함수가 시작햇을 당시 처음의 EBP 주소로 이동하기 위해서 저장해두는 값입니다!]
ret - 함수가 임무를 수행하고 끝마친뒤 다음에 실행되어야할 " 명령이 위치한 메모리의 주소" 를 뜻합니다
만약 근데 버퍼 오버플로우가 일어나서 ret 부분에 공격자가 원하는 공격이 위치한 메모리의 주소로 덮어씌어버린다면?
공격자가 원하는 공격을 하도록 흐름이 바뀌겟지요 ?
[gcc = GNU에서 만든 C컴파일러 이고 전처리기 , 컴파일러 ,어셈블러, 링커를 호출해주는 역할을 한다]
gcc 2.96 이상 버전으로 업그레이드 되면서 버퍼의 각 변수뒤에 dummy값이 생기게 되었습니다
아까 와 같은 스택을 gcc2.96 이상에서 컴파일 하게 된다면
/---------------------------/ 메모리 높은 주소
| ret[4] |
/---------------------------/
| sfb[4] |
/---------------------------/
| ? |
| ? |
| ? | dummy[?]
| ? |
| ? |
/---------------------------/
| 5 |
| 4 |
| 3 | buf2[5]
| 2 |
| 1 |
/---------------------------/
| ? |
| ? |
| ? | dummy[?]
| ? |
| ? |
/---------------------------/
| E |
| D |
| C | buf[5]
| B |
| A |
/---------------------------/ 메모리 낮은 주소
이러한 식으로 버퍼의 각 변수 뒤에 dummy값이 형성이 됩니다
그리고 이러한 dummy값 때문에 오버플로우를 일으켜서 ret에 덮어 씌우는 작업이
좀 더 어려워졌습니다
자 이제 여기서 dummy 값을 정확히 파악하기 위해서 gdb를 이용해 분석을 합니다.
[어셈블리와 gdb 사용법에 대해서 공부를 해야합니다 ]
gdb를 분석한 뒤 dummy 값을 찾아낸 뒤에 자신이 공격을 할 주소의 자신이 원하는 흐름대로 프로그램을 이끌어갈 주소를 넣으면
이것이 바로 버퍼 오버플로우 공격입니다
여기까지가 스택을 이용한 버퍼 오버플로우의 기본이였습니다 . 감사합니다
'시스템 기법 정리' 카테고리의 다른 글
Format String Attack (FSB) (0) | 2016.05.30 |
---|---|
ASLR를 해제하는 여러가지 방법 (0) | 2016.05.29 |
plt , got , rtl chain , ASLR (0) | 2016.05.28 |
버퍼 오버플로우 - 2 RTL (개념 정리, 기초) (0) | 2016.05.27 |
버퍼 오버 플로우 역사 및 정리 (0) | 2016.05.24 |