IT/시스템 보안과 해킹

버퍼 오버플로우

하품하는천둥 2016. 6. 29. 21:21


1. 메모리 구조와 어셈블리어의 기본


- 여기서는 리눅스 6.2로 실습 ( 최신 OS에서는 버퍼 오버플로우에 대한 대비책이 존재)



메모리의 기본 구조


상위 메모리 주소(0xffff)

Env/Argv Strings : 환경 변수와 명령 창의 데이터가 저장

 Env/Argv Pointers : 위와 비슷;;

 Args

스택영역  : 가장 낮은 부분에 스택 포인터 위치

 

 힙 영역 : 동적으로 할당된 데이터가 저장

데이터(.bss)  : 초기화되지 않은 변수

데이터(.data) : 초기화된 변수

코드(.text)

하위 메모리 주소(0x0000)


** 스택 영역은 아래로 자라고, 힙 영역은 위쪽으로 자란다.



Intel 8086 registers

19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 (bit position)
Main registers
  AH AL AX (primary accumulator)
  BH BL BX (base, accumulator)
  CH CL CX (counter, accumulator)
  DH DL DX (accumulator, other functions)
Index registers
0 0 0 0 SI Source Index
0 0 0 0 DI Destination Index
0 0 0 0 BP Base Pointer
0 0 0 0 SP Stack Pointer
Program counter
0 0 0 0 IP Instruction Pointer
Segment registers
CS 0 0 0 0 Code Segment
DS 0 0 0 0 Data Segment
ES 0 0 0 0 ExtraSegment
SS 0 0 0 0 Stack Segment
Status register
  - - - - O D I T S Z - A - P - C Flags




GENERAL PURPOSE REGISTERS

8086 CPU has 8 general purpose registers, each register has its own name:

  • AX - the accumulator register (divided into AH / AL):
    • Generates shortest machine code
    • Arithmetic, logic and data transfer
    • One number must be in AL or AX
    • Multiplication & Division
    • Input & Output

 

  • BX - the base address register (divided into BH / BL).

 

  • CX - the count register (divided into CH / CL):
    • Iterative code segments using the LOOP instruction
    • Repetitive operations on strings with the REP command
    • Count (in CL) of bits to shift and rotate

 

  • DX - the data register (divided into DH / DL):
    • DX:AX concatenated into 32-bit register for some MUL and DIV operations
    • Specifying ports in some IN and OUT operations

 

  • SI - source index register:
    • Can be used for pointer addressing of data
    • Used as source in some string processing instructions
    • Offset address relative to DS

 

  • DI - destination index register:
    • Can be used for pointer addressing of data
    • Used as destination in some string processing instructions
    • Offset address relative to ES

 

  • BP - base pointer:
    • Primarily used to access parameters passed via the stack
    • Offset address relative to SS
    • SS 레지스터와 함께 사용되어 스택 내의 변수 값을 읽는 데 사용

 

  • SP - stack pointer:
    • Always points to top item on the stack
    • Offset address relative to SS
    • Always points to word (byte at even address)
    • An empty stack will had SP = FFFEh


SEGMENT REGISTERS

  • CS - points at the segment containing the current program.
  • DS - generally points at segment where variables are defined.
  • ES - extra segment register, it's up to a coder to define its usage.
  • SS - points at the segment containing the stack.



메모리와 어셈블리어를 테스트해 볼 sample.c 코드

[sample.c]

int function (int a, int b) {

char buffer[10];

a = a + B;

return a;

}


void main() {

int c;

c = function( 1, 2);

}


***

gcc -S -o sample.a sample.c

vi sample.a

 - or use gedit etc


실행 결과

    .file    "sample.c"
    .text
    .globl    function
    .type    function, @function
function:
.LFB0:
    .cfi_startproc
    pushl    %ebp        // 7
    .cfi_def_cfa_offset 8       
    .cfi_offset 5, -8       
    movl    %esp, %ebp        // 8
    .cfi_def_cfa_register 5       
    subl    $16, %esp        // 9
    movl    12(%ebp), %eax        // 10
    addl    %eax, 8(%ebp)        // 11
    movl    8(%ebp), %eax       
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE0:
    .size    function, .-function
    .globl    main
    .type    main, @function
main:
.LFB1:
    .cfi_startproc
    pushl    %ebp        // 1
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp        // 2
    .cfi_def_cfa_register 5
    subl    $16, %esp        // 3
    pushl    $2        // 4
    pushl    $1        // 5
    call    function        // 6
    addl    $8, %esp        // 17
    movl    %eax, -4(%ebp)        //
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE1:
    .size    main, .-main
    .ident    "GCC: (Debian 4.9.2-10) 4.9.2"
    .section    .note.GNU-stack,"",@progbits


*****

숫자를 붙여둔 순서대로 실행

** 위 내용과 밑에서 설명하는 내용이 약간 다를 수 있다.


1. pushl %ebp    // push long

- 최초의 프레임 포인터(ebp)가 할당될 값을 스택에 저장


2. movel %esp, %ebp

 - 현재의 SP(Stack Pointer) 값을 EBP 레지스트리에 저장


실습 : 셀 코드 생성하기


OS : 와우 리눅스 6.2

필요 요소 : gcc, gdb

실습 내용 : 셀 코드를 기계어로 생성


[shell.c]


#include <stdio.h>

#include <unistd.h>


int main() {

char * name [2];

name [0] = "/bin/sh";

name [1] = 0;

execve( name [0], name, NULL);

}


컴파일 및 gdb를 이용하여 셀 분석

gcc -0 shell shell.c

gdb shell

disass main