A Buffer Overflow Study
Attacks & Defenses
Pierre-Alain FAYOLLE, Vincent GLAUME
ENSEIRB
Networks and Distributed Systems
2002
Contents
I Introduction to Buffer Overflows 5
1 Generalities 6
1.1 Process memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.1 Global organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.2 Function calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2 Buffers, and how vulnerable they may be . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2 Stack overflows 12
2.1 Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2 Illustration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.1 Basic example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.2 Attack via environment variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2.3 Attack using gets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3 Heap overflows 18
3.1 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.1.1 Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.1.2 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2 Motivations and Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3 Overwriting pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.1 Difficulties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.3.2 Interest of the attack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.3.3 Practical study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.4 Overwriting function pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.4.1 Pointer to function: short reminder . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.4.2 Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.4.3 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.5 Trespassing the heap with C + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.5.1 C++ Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.5.2 Overwriting the VPTR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.5.3 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.6 Exploiting the malloc library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.6.1 DLMALLOC: structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.6.2 Corruption of DLMALLOC: principle . . . . . . . . . . . . . . . . . . . . . . . . . 34
II Protection solutions 37
4 Introduction 38
1
5 How does Libsafe work? 39
5.1 Presentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.2 Why are the functions of the libC unsafe ? . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.3 What does libsafe provide ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6 The Grsecurity Kernel patch 41
6.1 Open Wall: non-executable stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.2 PaX: non-executable stack and heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.2.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.3 Escaping non-executable stack protection: return into libC . . . . . . . . . . . . . . . . . 45
7 Detection: Prelude 47
7.1 Prelude and Libsafe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
7.2 Shellcode detection with Prelude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
7.2.1 Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
7.2.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
7.3 A new danger: plymorphic shellcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
7.3.1 Where the danger lies... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
7.3.2 How to discover it ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
III First steps toward security 50
8 Installations 51
8.1 Installing Libsafe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
8.2 Patching the Linux Kernel with Grsecurity . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.3 Compile time protection: installing Stack Shield . . . . . . . . . . . . . . . . . . . . . . . 53
8.4 Intrusion Detection System: installing Prelude . . . . . . . . . . . . . . . . . . . . . . . . 54
9 Protections activation 55
9.1 Setting up Libsafe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
9.1.1 LD
PRELOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
9.1.2 /etc/ld.so.preload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
9.2 Running Prelude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
9.2.1 Libsafe alerts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
9.2.2 Shellcode attack detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
IV Tests: protection and performance 59
10 Protection efficiency 60
10.1 Exploits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
10.1.1 Stack overflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
10.1.2 Heap overflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
10.2 Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
10.2.1 Zero protection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
10.2.2 Libsafe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
10.2.3 Open Wall Kernel patch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
10.2.4 PaX Kernel patch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
10.2.5 Stack Shield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
10.3 Synthesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
2
11 Performance tests 66
11.1 Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
11.2 Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
11.3 Miscellaneous notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
V A solution summary 68
12 Programming safely 69
13 Libsafe 70
13.1 Limitations of libsafe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
13.2 Benefits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
14 The Grsecurity patch 73
14.1 A few drawbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
14.2 Efficiency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
VI Glossary 79
VII Appendix 84
A Grsecurity insallation: Kernel configuration screenshots 85
B Combining PaX and Prelude 89
B.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
B.2 PaX logs analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
C Performance tests figures 100
3
Introduction
On november 2, 1988 a new form of threat appeared with the Morris Worm, also known as the Internet
Worm. This famous event caused heavy damages on the internet, by using two common unix programs,
sendmail and fingerd. This was possible by exploiting a buffer overflow in fingerd. This is probably one
of the most outstanding attacks based on buffer overflows.
This kind of vulnerability has been found on largely spread and used daemons such as bind, wu-ftpd,
or various telnetd implementations, as well as on applications such as Oracle or MS Outlook Express. . .
The variety of vulnerable programs and possible ways to exploit them make clear that buffer overflows
represent a real threat. Generally, they allow an attacker to get a shell on a remote machine, or to obtain
superuser rights. Buffer overflows are commonly used in remote or local exploits.
The first aim of this document is to present how buffer overflows work and may compromise a system
or a network security, and to focus on some existing protection solutions. Finally, we will try to point
out the most interesting sets to secure an environment, and compare them on criteria such as efficiency
or performance loss.
We are both third year computer science students at ENSEIRB (French national school of engineering),
specialized in Networks and Distributed Systems. This study has been performed during our Network
Administration project.
4
评论1