program security part 1
DESCRIPTION
Program Security Part 1. Insecure Code Non-malicious Program Flaws. Perimeter defense (firewalls) Intrusion detection (after the fact) Over-reliance on cryptography Penetrate and patch techniques Penetration testing. Traditional Security Is Reactive. Problems With Reactive Responses. - PowerPoint PPT PresentationTRANSCRIPT
Program SecurityProgram SecurityPart 1Part 1
Insecure CodeInsecure Code
Non-malicious Program FlawsNon-malicious Program Flaws
22
Traditional Security Is ReactiveTraditional Security Is Reactive
Perimeter Perimeter defense defense (firewalls)(firewalls)
Intrusion Intrusion detection (after detection (after the fact)the fact)
Over-reliance on Over-reliance on cryptographycryptography
Penetrate and Penetrate and patch techniquespatch techniques
Penetration Penetration testingtesting
33
Problems With Reactive ResponsesProblems With Reactive Responses
Firewalls, cryptography, and intrusion detection Firewalls, cryptography, and intrusion detection do not protect you against the ability of a hacker do not protect you against the ability of a hacker to exploit architectural (i.e. design) flaws or to exploit architectural (i.e. design) flaws or coding flaws in a program.coding flaws in a program.
As we will see, design and coding flaws can As we will see, design and coding flaws can open the gates to penetration attempts. open the gates to penetration attempts. Moreover, there are a lot of ways these flaws Moreover, there are a lot of ways these flaws can be exploited.can be exploited.
44
Penetrate and Patch Has Been the NormPenetrate and Patch Has Been the Norm
Discover flaws after deploymentDiscover flaws after deployment Often by attackersOften by attackers
Patches may have security flaws themselves!Patches may have security flaws themselves! Estimates run as high as 15% have flawsEstimates run as high as 15% have flaws
Patches provide road maps to vulnerabilitiesPatches provide road maps to vulnerabilities Attackers only have to reverse engineer the Attackers only have to reverse engineer the
patches in order to create attacks.patches in order to create attacks. A major problem is that many users fail to A major problem is that many users fail to
deploy patches.deploy patches.
55
Look at the Typical Intrusion PatternLook at the Typical Intrusion Pattern
66
A Growing ProblemA Growing Problem
77
Software Is The Main ProblemSoftware Is The Main Problem
“We wouldn’t have to spend so much time and effort on network security if we didn’t have such bad software security.”
Bruce Schneider
“Applied Cryptography”
“Secrets & Lies: Digital Security in a Networked World”
88
HackersHackers
““Malicious hacker’s don’t create security Malicious hacker’s don’t create security holes; they simply exploit them. Security holes; they simply exploit them. Security holes and vulnerabilities – the real root holes and vulnerabilities – the real root cause of the problem – are the result of cause of the problem – are the result of bad software design and implementation.”bad software design and implementation.”
John Viega & Gary McGrawJohn Viega & Gary McGraw
99
Developers Aren’t ReadyDevelopers Aren’t Ready
““64% of developers are not confident in 64% of developers are not confident in their ability to write secure applications.”their ability to write secure applications.”
Bill Gates, RSA Conference 2005Bill Gates, RSA Conference 2005
“ “ Have you ever written a program section Have you ever written a program section with a security hole? How did you know?”with a security hole? How did you know?”
Mark G. Graff & Kenneth R. van WykMark G. Graff & Kenneth R. van Wyk
1010
An Industry ProblemAn Industry Problem
There is no software liability – no incentive for There is no software liability – no incentive for secure software.secure software.
Most developers never learned to produce secure Most developers never learned to produce secure code.code.
Secure code often takes a performance hit – i.e. the Secure code often takes a performance hit – i.e. the software runs about 1/3 slower – something many software runs about 1/3 slower – something many users don’t want to tolerate.users don’t want to tolerate.
Writing secure code also takes a lot more time – Writing secure code also takes a lot more time – hence, development costs are higher than usual.hence, development costs are higher than usual.
Consequently, the longer development times and the Consequently, the longer development times and the longer running times discourage developers from longer running times discourage developers from writing secure code.writing secure code.
1111
Complexity Is An Additional ProblemComplexity Is An Additional Problem
Software products are growing in size.Software products are growing in size. Windows XP has 40 million lines of code –Windows XP has 40 million lines of code –
A page is typically 52 lines of code.A page is typically 52 lines of code. So, we are talking about ~1539 reams of standard So, we are talking about ~1539 reams of standard
one-sided xerox paper!one-sided xerox paper!
Typically there are 5-50 bugs per Typically there are 5-50 bugs per KLOCKLOC (a (a thousand lines of code.)thousand lines of code.)
10% of the bugs result in security faults.10% of the bugs result in security faults. 40,000 KLOC*5*10% = 25,000 security bugs 40,000 KLOC*5*10% = 25,000 security bugs
(lower bound)(lower bound) One difficulty is that software is often written in One difficulty is that software is often written in
low-level languages such as C/C++.low-level languages such as C/C++.
1212
Some Security Problems With ProgramsSome Security Problems With Programs
CODING BUGS – 50%CODING BUGS – 50% Information leakageInformation leakage Control hijackingControl hijacking Buffer overflowBuffer overflow Smashing the stackSmashing the stack Command injectionCommand injection Cross-site scriptingCross-site scripting Integer overflowInteger overflow Race conditionsRace conditions
Formatted stringsFormatted strings Segment overwriteSegment overwrite Heap overflowsHeap overflows Incomplete mediationIncomplete mediation SQL injectionSQL injection PHP includePHP include Non-trusted inputNon-trusted input
Realize these problems are not mutually exclusive!
1313
Some Security Problems With ProgramsSome Security Problems With Programs
DESIGN FLAWS – 50%DESIGN FLAWS – 50%
Cryptography misuseCryptography misuse Lack of compartmentalizationLack of compartmentalization More privilege used than necessaryMore privilege used than necessary Relying on secret algorithmsRelying on secret algorithms Sharing resourcesSharing resources Usability problemsUsability problems
1414
Non-malicious Program ErrosNon-malicious Program Erros
Many of these problems are non-malicious, but Many of these problems are non-malicious, but they can be exploited to do nasty things.they can be exploited to do nasty things.
A system exploit could be: Attacker can execute arbitrary code Attacker can gain access to a system Attacker can put the system in an illegal state Attacker can crash the program causing, for
example, a denial of service.
1515
WarningWarning Examples can come from various operating Examples can come from various operating
systems, languages, and browsers.systems, languages, and browsers. Realize that almost all operating systems and Realize that almost all operating systems and
languages have problems - they're just not all languages have problems - they're just not all the same vulnerabilities.the same vulnerabilities.
UNIX/LINUX is an operating system that is used UNIX/LINUX is an operating system that is used on a lot for servers.on a lot for servers.
C/C++ are languages that are used a lot for C/C++ are languages that are used a lot for development purposes as they allow low level development purposes as they allow low level manipulation of the hardware.manipulation of the hardware.
Internet Explorer is a browser used by many Internet Explorer is a browser used by many people.people.
1616
Language Usage StatisticsLanguage Usage Statistics
Source: http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
1717
ContinuedContinued
1818
Long Term TrendsLong Term Trends
1919
Some Commonly Exploitable Flaws
A vulnerability is a program flaw (or bug) that when exercised has a security implication
Notice that two things need to be true in order to have a system exploit. There has to be a flaw or a bug That flaw can be exploited by an attacker to weaken
the security of a system Many examples of program flaws are shown on slide
12-13.
There are others as we will see.
Information LeakageInformation LeakageAttacksAttacks
2121
A Simple ExampleA Simple Example Where’s the error in this program?Where’s the error in this program?
int main () {int main () {
int array[5] = {1,2,3,4,5};int array[5] = {1,2,3,4,5};
printf(“%d\n”, array[5]);printf(“%d\n”, array[5]);
}}
Program output:Program output:
>gcc –o badindex badindex.c >gcc –o badindex badindex.c
> ./badindex> ./badindex
What happens?What happens?
gcc --- UNIX C compiler -o badindex --- store compiled code in a file called buffer (which is executable) buffer.c --- the source code ./buffer --- invokes buffer in the current directory
2222
A Run on cs.hiram.edu (OS - Linux)A Run on cs.hiram.edu (OS - Linux)
The next memory location contents after array[4] is the output - namely 134513680
2323
How Do You Know It Is The Next Memory How Do You Know It Is The Next Memory Location After Array?Location After Array?
Hex for the output value 134513680 which is in array[5]’s location.
2424
Doing The Calculation To Verify ThatDoing The Calculation To Verify That08048410080484101616 = 134513680 = 134513680
Remember from cpsc 171 that a hex number Remember from cpsc 171 that a hex number can be converted to binary easily:can be converted to binary easily:
08048410080484101616
= 0000 1000 0000 0100 1000 0100 0001 0000= 0000 1000 0000 0100 1000 0100 0001 0000
= 2^27 + 2^18 + 2^15 + 2^10 + 2^4 = 2^27 + 2^18 + 2^15 + 2^10 + 2^4
= 134217728 + 262144 + 32768 + 1024 + 16= 134217728 + 262144 + 32768 + 1024 + 16
= 134513680= 134513680
2525
Or, Use the x/16dw Command in gdbOr, Use the x/16dw Command in gdb
2626
What Happened To The Last Program?What Happened To The Last Program?
The information leakage exists because C does The information leakage exists because C does not check array bounds - C++ doesn't either!not check array bounds - C++ doesn't either!
Thus, whatever was in the position where Thus, whatever was in the position where array[5] should be will be output.array[5] should be will be output.
Do array out of bounds errors always produce Do array out of bounds errors always produce access to a memory location?access to a memory location? No, we will see other possibilities.No, we will see other possibilities. This example just leaks information.This example just leaks information. There are worst consequences as we will see There are worst consequences as we will see
soon.soon.
2727
Can We Leak More Information?Can We Leak More Information?
2828
Or Even More?Or Even More?
2929
And More Leakage!And More Leakage!
3030
And, At Last It Terminates!And, At Last It Terminates!
Observe that to use this information you do need to know how to read the machine code that is output!
But, that's no big deal for a hacker who has patience to check out the code.
Note: Some people call this a buffer overflow problem, but some prefer to think of it as an information leakage problem.
Control Hijacking AttacksControl Hijacking Attacks
3232
Control Hijacking(or, Why to Avoid C Like the Plague)
A control hijacking attack causes a program to crash or it injects new code into a running process that changes the developers' flow of control.
Crashing is what is desired, for example, when a Denial of Service attack is being conducted.
There are many ways to hijack a C program. The most common technique is the buffer
overflow: writing outside the bounds of a specified chunk of memory.
Buffer Overflow AttacksBuffer Overflow Attacks
These are sometimes distinguished by These are sometimes distinguished by where the buffer resideswhere the buffer resides
3434
Code Injection Via Buffer Overflows Extremely common bug.
First major exploit in 1988: Morris Worm exploited fingerd and used a buffer overflow to insert code.
10 years later: over 50% of all CERT advisories: 1997: 16 out of 28 CERT advisories. 1998: 9 out of 13 advisories 1999: 6 out of 12 advisories
Often leads to the total compromise of a host because of arbitrary code execution
Fortunately: exploit requires expertise and patience to determine just how to do this for a specific program.
3535
What Is a Buffer Overflow?What Is a Buffer Overflow? Definition: When a program allows Definition: When a program allows
data to be copied to a location in data to be copied to a location in memory that exceeds the size of memory that exceeds the size of the reserved destination area a the reserved destination area a buffer overflowbuffer overflow occurs. occurs.
Consider:Consider:
short C;short C;
char A(C);char A(C);
short B=3;short B=3;
..
..
..
gets(A); gets(A);
AA AA AA AA AA AA AA AA BB BB
00 00 00 00 00 00 00 00 00 33
AA AA AA AA AA AA AA AA BB BB
oo vv ee rr ff ll oo ww ss 00
3636
What Can Be Done When A Buffer Overflow What Can Be Done When A Buffer Overflow Is Not Detected?Is Not Detected?
Excess bytes can be inserted into memory next to the Excess bytes can be inserted into memory next to the buffer area.buffer area.
Those bytes can Those bytes can Corrupt the original program causing it to crash.Corrupt the original program causing it to crash.
Often this technique is used in Denial-of-Service Often this technique is used in Denial-of-Service (DoS) attacks.(DoS) attacks.
Be malicious code that is inserted at this point and, Be malicious code that is inserted at this point and, as we will see, there are often ways to make this as we will see, there are often ways to make this code executable.code executable.
Buffer overflows are the most common type of memory Buffer overflows are the most common type of memory corruption.corruption.
3737
Some Real-world Buffer Overflow ExamplesSome Real-world Buffer Overflow Examples Morris WormMorris Worm
Took down most of Internet in 1988Took down most of Internet in 1988 Exploited a buffer overflow in Exploited a buffer overflow in fingerdfingerd Subsequent worms used overflow attacks also.Subsequent worms used overflow attacks also.
MS07-004 Internet ExplorerMS07-004 Internet Explorer Buffer overflow in VML (a language used to produce Buffer overflow in VML (a language used to produce
vector graphics – stands for Vector Markup Language)vector graphics – stands for Vector Markup Language) Allowed remote code executionAllowed remote code execution Not the first overflow in IE or other browsers.Not the first overflow in IE or other browsers.
Word 2000Word 2000 Using Find/Replace with the Replace field larger than Using Find/Replace with the Replace field larger than
200 characters caused a crash and wiped out any 200 characters caused a crash and wiped out any unsaved data.unsaved data.
3838
More Buffer Overflow ExamplesMore Buffer Overflow Examples
In July 2000, a vulnerability to buffer overflow In July 2000, a vulnerability to buffer overflow attack was discovered in Microsoft Outlook and attack was discovered in Microsoft Outlook and Outlook Express.Outlook Express.
A programming flaw made it possible for an A programming flaw made it possible for an attacker to compromise the integrity of the target attacker to compromise the integrity of the target computer by simply sending an e-mail message. computer by simply sending an e-mail message.
Unlike the typical e-mail virus, users could not Unlike the typical e-mail virus, users could not protect themselves by not opening attached protect themselves by not opening attached files; in fact, the user did not even have to open files; in fact, the user did not even have to open the message to enable the attack. the message to enable the attack.
3939
More Buffer Overflow ExamplesMore Buffer Overflow Examples
The programs' message header mechanisms had a The programs' message header mechanisms had a defect that made it possible for senders to overflow defect that made it possible for senders to overflow the area with extraneous data, which allowed them the area with extraneous data, which allowed them to execute whatever type of code they desired on the to execute whatever type of code they desired on the recipient's computers. recipient's computers.
Because the process was activated as soon as the Because the process was activated as soon as the recipient downloaded the message from the server, recipient downloaded the message from the server, this type of buffer overflow attack was very difficult to this type of buffer overflow attack was very difficult to defend. defend.
Microsoft has since created a patch to eliminate the Microsoft has since created a patch to eliminate the vulnerability.vulnerability.
4040
Some More Buffer Overflows
A buffer overflow in Apple’s Quicktime
(January 7, 2007)
http://www.us-cert.gov/cas/techalerts/TA07-005A.html
Buffer overflows in Mozilla products (December 20, 2006)
http://www.us-cert.gov/cas/techalerts/TA06-354A.html
4141
More Buffer Overflow ExamplesMore Buffer Overflow Examples
Other examples include:Other examples include: RTF formatRTF format .doc files.doc files Acrobat products - .pdf, Photoshop etc.Acrobat products - .pdf, Photoshop etc. Blaster wormBlaster worm and the list goes on and on ....and the list goes on and on ....
As we will see, these examples can be hard to As we will see, these examples can be hard to find.find.
4242
No Problem With ex2.c As 41No Problem With ex2.c As 411010= 29= 291616
4343
ex2a.c Runs OK - So Nothing is Overwritten ex2a.c Runs OK - So Nothing is Overwritten That Hurts the RunThat Hurts the Run
4444
But, For ex2b.c, Something is Corrupted As But, For ex2b.c, Something is Corrupted As the Run Crashesthe Run Crashes
4545
ex2b.c ex2b.c
Obviously, any values can be written past the Obviously, any values can be written past the declared bounds of array.declared bounds of array.
However, as no input is involved, a hacker can't However, as no input is involved, a hacker can't change any values in order to obtain control.change any values in order to obtain control.
But, these examples show that if user input is But, these examples show that if user input is allowed, this same concept can be used to allowed, this same concept can be used to corrupt the return address or other elements on corrupt the return address or other elements on the stack.the stack.
4646
ex3.cex3.c
23 A s OK
24 A s are not OK
4747
15 a's Initialized With A Null At the End15 a's Initialized With A Null At the End61611616 is ASCII Code for "a" is ASCII Code for "a"
4848
15 a's Initialized With A Null At the End15 a's Initialized With A Null At the End61611616 is ASCII Code for "a" is ASCII Code for "a"
Word address where buffer starts
4949
Locate the Return Address in the FrameLocate the Return Address in the Frame
Return Address
5050
Examine Address and Observe It Is in mainExamine Address and Observe It Is in main
5151
23 A s OK23 A s OK
5252
24 A s Causes a Segmentation Fault24 A s Causes a Segmentation Fault
Corruption for 24 A s
5353
Observe Security Faults Exposed HereObserve Security Faults Exposed Here
The return address has been located and, The return address has been located and, consequently, could be corrupted by the input.consequently, could be corrupted by the input. Another return address could be inserted.Another return address could be inserted. The existing return address could be corrupted The existing return address could be corrupted
causing a crash.causing a crash.
If the stack area allows execution, a hacker If the stack area allows execution, a hacker could insert malicious code at this point.could insert malicious code at this point.
Stack-based OverflowsStack-based Overflows
Called "Smashing the stack"Called "Smashing the stack"
5555
Stack-based Buffer OverflowsStack-based Buffer Overflows
Stack-based buffer overflows were the first type Stack-based buffer overflows were the first type of vulnerability that was described as a separate of vulnerability that was described as a separate class, in 1996. class, in 1996.
How to exploit this vulnerability was described in How to exploit this vulnerability was described in the Phrack article "Smashing the Stack for Fun the Phrack article "Smashing the Stack for Fun and Profit," by Aleph1, a.k.a. Elias Levy.and Profit," by Aleph1, a.k.a. Elias Levy.
Phrack is an underground e-zine written by and is an underground e-zine written by and for hackers that was first published in 1985. for hackers that was first published in 1985.
It has a wide circulation which includes both It has a wide circulation which includes both hackers and computer security professionals. hackers and computer security professionals.
5656
Stack-based Buffer Overflows Stack-based Buffer Overflows
Since the Phrack article's release, these stack-Since the Phrack article's release, these stack-based buffer overflows have been considered based buffer overflows have been considered the most common type of remotely exploitable the most common type of remotely exploitable programming errors found in software programming errors found in software applications. applications.
As with other overflows, the problem here is the As with other overflows, the problem here is the mixing of data and control information when the mixing of data and control information when the executable image is loaded into memory.executable image is loaded into memory.
Thus, by incorrectly changing data, it is Thus, by incorrectly changing data, it is sometimes possible to change program sometimes possible to change program execution flow. execution flow.
5757
Memory Layout ProcessMemory Layout Process (and how it affects security) (and how it affects security)
A process can be laid out in memory in any way A process can be laid out in memory in any way the host operating system chooses.the host operating system chooses.
But, nearly all contemporary systems observe a But, nearly all contemporary systems observe a few common conventions.few common conventions.
Generally, a process is organized into the Generally, a process is organized into the following major areas:following major areas: Program codeProgram code Program dataProgram data Program stackProgram stack
5858
Program Code SectionProgram Code Section
Includes compiled code for the running program and Includes compiled code for the running program and additional code to use the shared libraries needed by additional code to use the shared libraries needed by the program.the program.
Shared libraries are usually not mapped into areas Shared libraries are usually not mapped into areas contiguous with the program code.contiguous with the program code.
Anything in the section is assumed to be Anything in the section is assumed to be executable.executable.
Consequently, recalling from CPSC 171, in the fetch-Consequently, recalling from CPSC 171, in the fetch-decode-execute cycle, when the program counter decode-execute cycle, when the program counter points to a sequence of bytes, those bytes are points to a sequence of bytes, those bytes are assumed to be an executable. assumed to be an executable.
5959
Program Data SectionProgram Data Section
Stores program variables that aren't local to Stores program variables that aren't local to functions. functions.
Includes both global and static variables.Includes both global and static variables. Contains a dynamic memory region, called the Contains a dynamic memory region, called the
"program heap" for storing dynamically allocated "program heap" for storing dynamically allocated variables.variables.
6060
Program StackProgram Stack First, what is a stack?First, what is a stack? A A stackstack is an abstract data type used for the ordered is an abstract data type used for the ordered
storage and retrieval of data with a distinguished end storage and retrieval of data with a distinguished end called the top and two associated operations:called the top and two associated operations: push() - Add an element at the top of the stackpush() - Add an element at the top of the stack pop() - Remove the top element of the stack and return its pop() - Remove the top element of the stack and return its
value.value.
Stacks are also called last-in, first-out (LIFO) data Stacks are also called last-in, first-out (LIFO) data structures.structures.
A good physical example of a stack is the A good physical example of a stack is the mechanism in many cafeterias that holds and mechanism in many cafeterias that holds and dispense trays or dishes.dispense trays or dishes.
6161
Stack OverflowsStack Overflows These are buffer overflows in which the target buffer These are buffer overflows in which the target buffer
is located on the program stack.is located on the program stack. These are the most understood security attacks and, These are the most understood security attacks and,
historically, the most straightforward type of buffer historically, the most straightforward type of buffer overflow to exploit.overflow to exploit.
We'll examine how the program stack works We'll examine how the program stack works Note: Note: This material is covered in CPSC 252: This material is covered in CPSC 252: Computer Computer OrganizationOrganization
and then how attackers can exploit it.and then how attackers can exploit it. Note: The program stack is also called the "Note: The program stack is also called the "runtime runtime
stackstack", the "", the "call stackcall stack", or just the "", or just the "stackstack" when talking " when talking about a program.about a program.
6262
How The Program Stack WorksHow The Program Stack Works The runtime stack provides the underpinnings The runtime stack provides the underpinnings
necessary for the functions used in every structured necessary for the functions used in every structured programming language.programming language.
Functions can be called in arbitrary order.Functions can be called in arbitrary order. Functions can be recursive - i.e. they can call Functions can be recursive - i.e. they can call
themselves or, after a chain of calls, be called themselves or, after a chain of calls, be called again.again.
The runtime stack supports this functionality with The runtime stack supports this functionality with activation recordsactivation records or or function framesfunction frames..
Activation records contain the return address for the Activation records contain the return address for the function, local variables, the saved machine state function, local variables, the saved machine state (i.e. register contents) , and function parameters.(i.e. register contents) , and function parameters.
6363
How The Program Stack WorksHow The Program Stack Works
Because runtime stacks are an integral part of Because runtime stacks are an integral part of how programs work, they are implemented by how programs work, they are implemented by the CPU assistance by the use of a special the CPU assistance by the use of a special register that points to the top of the stack.register that points to the top of the stack.
On Intel x86 CPUs, this register is called ESP On Intel x86 CPUs, this register is called ESP (extended stack pointer).(extended stack pointer).
On most modern CPUs , the stack grows On most modern CPUs , the stack grows downward - i.e. it starts at a high address in downward - i.e. it starts at a high address in virtual memory and grows towards a lower virtual memory and grows towards a lower address.address.
6464
How The Program Stack WorksHow The Program Stack Works
Every time a function is called, the program Every time a function is called, the program creates a new stack frame (or activation record) creates a new stack frame (or activation record) which is a reserved block of contiguous memory which is a reserved block of contiguous memory that a function uses for storing the necessary that a function uses for storing the necessary information.information.
This block of memory is reserved for exclusive This block of memory is reserved for exclusive use by the function until it returns, at which time use by the function until it returns, at which time it is removed from the stack.it is removed from the stack.
6565
How The Program Stack WorksHow The Program Stack Works Consider the following snippet of code:Consider the following snippet of code:int B(int a, int b) {int B(int a, int b) {
int x,y;int x,y;x = a*a; y = b*b;x = a*a; y = b*b;return (x*y); }return (x*y); }
int A(int p, int q) {int A(int p, int q) {int c;int c;c = p * q * B(p,p);c = p * q * B(p,p);return c; }return c; }
int main (int argc, char **argv, int main (int argc, char **argv, char char **envp) {**envp) {
int ret;int ret;ret = A(1,2);ret = A(1,2);return ret; }return ret; }
6666
Stack While In AStack While In A
When the function A is When the function A is entered, a stack frame for entered, a stack frame for A is allocated and placed A is allocated and placed on the top of the stack as on the top of the stack as shown.shown.
The diagram is simplified, The diagram is simplified, because main is not the because main is not the first function on the call first function on the call stack as system functions stack as system functions are called first to set up are called first to set up the environment for the the environment for the process.process.
A's stack A's stack frameframe
main's main's stack framestack frame
0xBFFFFC00
0xFFFFF00
stack base
Stack grows this way
6767
Stack While In BStack While In B When the function B is When the function B is
called from A and B is called from A and B is entered, a stack frame for entered, a stack frame for B is allocated and placed B is allocated and placed on the top of the stack as on the top of the stack as shown.shown.
When B finishes, it returns When B finishes, it returns to A and B's stack frame is to A and B's stack frame is popped off of the stack.popped off of the stack.
The stack again looks like The stack again looks like the one on the previous the one on the previous slide and ESP is restored slide and ESP is restored to its previous value.to its previous value.
A's stack A's stack frameframe
main's main's stack framestack frame
0xBFFFFC00
0xFFFFF00
stack base
Stack grows this way
B's stack frame
6868
Internal State Information In Stack FrameInternal State Information In Stack Frame
This varies among processor architectures, but This varies among processor architectures, but usually it includes the previous function's frame usually it includes the previous function's frame pointer and a return address.pointer and a return address.
The return address is saved so that when the The return address is saved so that when the currently running function returns, the CPU knows currently running function returns, the CPU knows where execution should continue.where execution should continue.
Also, the frame pointer must be restored so that local Also, the frame pointer must be restored so that local variable accesses remain consistent after a function variable accesses remain consistent after a function has called a subfunction that allocates its own stack has called a subfunction that allocates its own stack frame.frame.
The stack pointer must also be restored to its The stack pointer must also be restored to its previous state.previous state.
6969
Using The Stack Frame DataUsing The Stack Frame Data
Each function manages its own stack frame which is sized Each function manages its own stack frame which is sized by how many local variables are present and the size of by how many local variables are present and the size of each variable.each variable.
Local variables need to be accessed directly as the Local variables need to be accessed directly as the function requires them.function requires them.
Thus, pop and push can be inefficient to use.Thus, pop and push can be inefficient to use. Consequently, many programs make use of another Consequently, many programs make use of another
register called EBP (extended base pointer) which points register called EBP (extended base pointer) which points to the beginning of the stack frame.to the beginning of the stack frame.
Variables can then be accessed by a fixed offset from the Variables can then be accessed by a fixed offset from the EBP.EBP.
Note - many programs do this, but it is not required.Note - many programs do this, but it is not required.
7070
How The Program Stack WorksHow The Program Stack Works Consider the following snippet of code Consider the following snippet of code int B(int a, int b) {int B(int a, int b) {
int x,y;int x,y;x = a*a; y = b*b;x = a*a; y = b*b;return (x*y); }return (x*y); }
int A(int p, int q) {int A(int p, int q) {int c;int c;c = p * q * B(p,p);c = p * q * B(p,p);return c; }return c; }
int main (int argc, char **argv, int main (int argc, char **argv, char char **envp) {**envp) {
int ret;int ret;ret = A(1,2);ret = A(1,2);return ret; }return ret; }
7171
A Possible Stack Layout When B Is CalledA Possible Stack Layout When B Is Called
int yint y
int xint x
saved EBP - base pointersaved EBP - base pointer
saved EIP - return point in Asaved EIP - return point in A
B's argument aB's argument a
B's argument bB's argument b
int cint c
saved EBP - base pointersaved EBP - base pointer
saved EIP - return point in mainsaved EIP - return point in main
A's argument pA's argument p
A's argument qA's argument q
int ret etc.int ret etc.
Note that local Note that local variables are arranged variables are arranged contiguously in contiguously in memory.memory.
B's stack frame B's stack frame
A's stack frameA's stack frame
Start of main's stack Start of main's stack frameframe
7272
Smashing The StackSmashing The Stack
As local variables are contiguous in memory, if a As local variables are contiguous in memory, if a program has a vulnerability allowing data to be program has a vulnerability allowing data to be written past the end of a local stack buffer, the written past the end of a local stack buffer, the data overwrites adjacent variables.data overwrites adjacent variables.
These adjacent variables can include other local These adjacent variables can include other local variables, program stack information, and even variables, program stack information, and even function arguments. function arguments.
Depending on how many bytes can be written, Depending on how many bytes can be written, attackers might also be able to corrupt variables, attackers might also be able to corrupt variables, state information in previous stack frames, and state information in previous stack frames, and return addresses.return addresses.
7373
Overwriting The Return AddressOverwriting The Return Address
Of the two variables, the frame pointer and the Of the two variables, the frame pointer and the return address, the return address is most useful return address, the return address is most useful to attackers.to attackers.
If a buffer overflow can overwrite the saved If a buffer overflow can overwrite the saved return address, the program can be redirected to return address, the program can be redirected to an arbitrary point after the executing function an arbitrary point after the executing function returns.returns.
Several scenarios are possible when execution Several scenarios are possible when execution is redirected by overwriting the return address.is redirected by overwriting the return address.
7474
Where Is The Program Typically Where Is The Program Typically Redirected?Redirected?
Redirect to the code section of the application being run.Redirect to the code section of the application being run. Redirect to some code in a shared library that does Redirect to some code in a shared library that does
something such as run commands via the shell.something such as run commands via the shell. Redirect to an area of memory containing data the Redirect to an area of memory containing data the
attacker controls, such as a global variable, a stack attacker controls, such as a global variable, a stack location, or a static buffer.location, or a static buffer. In this situation, the attacker fills the targeted return location with In this situation, the attacker fills the targeted return location with
a small stub of position independent code to do something such a small stub of position independent code to do something such as connecting back to the attacker and spawning a shell on the as connecting back to the attacker and spawning a shell on the connected socket.connected socket.
This code is commonly referred to as This code is commonly referred to as shellcodeshellcode..
7575
An Aside About Linux and ShellsAn Aside About Linux and Shells
A A shell shell for Linux (or Unix) is a user program or an for Linux (or Unix) is a user program or an environment provided for user interaction.environment provided for user interaction.
A shell is an command language interpreter that A shell is an command language interpreter that executes commands read from the standard input executes commands read from the standard input device (keyboard) or from a file. device (keyboard) or from a file.
These reside in the directory (folder in Windows' These reside in the directory (folder in Windows' terminology) /binterminology) /bin
The most used shells areThe most used shells are
bash - Bourne again shell (default on cs.hiram.edu)bash - Bourne again shell (default on cs.hiram.edu)
csh - C shellcsh - C shell
ksh - Korn shellksh - Korn shell
7676
ShellcodeShellcode Buffer overflows are usually exploited by directing Buffer overflows are usually exploited by directing
execution to a known location in memory where attacker-execution to a known location in memory where attacker-controlled data is stored.controlled data is stored.
For an exploit to be successful, this location must contain For an exploit to be successful, this location must contain executable machine code that allows attacks to perform executable machine code that allows attacks to perform malicious activities.malicious activities.
This is done by constructing small snippets of machine This is done by constructing small snippets of machine code designed to launch a shell, connect back to the code designed to launch a shell, connect back to the originating user, or do whatever the attacker chooses.originating user, or do whatever the attacker chooses.
Today the most common trend in shellcode construction Today the most common trend in shellcode construction uses stubs capable of loading additional components on uses stubs capable of loading additional components on demand over a connected socket, as needed by an attack demand over a connected socket, as needed by an attack on the other end. on the other end.
7777
Writing The CodeWriting The Code At the most basic level, shellcode is a small chunk of At the most basic level, shellcode is a small chunk of
position-independent code that uses system APIs to position-independent code that uses system APIs to achieve an attacker's objectives.achieve an attacker's objectives.
To see how this is done, consider the simple case of To see how this is done, consider the simple case of spawning a shell in UNIX.spawning a shell in UNIX.
In this case, the code to run is roughly the following:In this case, the code to run is roughly the following:char *args[] = {"/bin/sh", NULL};char *args[] = {"/bin/sh", NULL};execve("/bin/sh", args, NULL);execve("/bin/sh", args, NULL);
This code spawns a command shell when it runs.This code spawns a command shell when it runs. If this code were run in a network service, the socket If this code were run in a network service, the socket
descriptor the user is connected with would need to be descriptor the user is connected with would need to be duplicated over stdin, stdout, and optionally stderr as duplicated over stdin, stdout, and optionally stderr as well.well.
7878
Writing The CodeWriting The Code
To construct the machine code required to spawn the To construct the machine code required to spawn the shell, we need to understand how this code works at a shell, we need to understand how this code works at a lower level.lower level.
The The execve execve function is exported by the standard C function is exported by the standard C library, so a normal program would first locate the libc library, so a normal program would first locate the libc execveexecve implementation with a little help from the implementation with a little help from the loader, and then call it.loader, and then call it.
Because this functionality could be difficult to duplicate Because this functionality could be difficult to duplicate in reasonably sized shellcode, generally we need to in reasonably sized shellcode, generally we need to look for a simpler solution.look for a simpler solution.
As it turns out, As it turns out, execveexecve is also a system call on UNIX is also a system call on UNIX systems, and all the libc function does is perform the systems, and all the libc function does is perform the system call.system call.
7979
Writing The CodeWriting The Code
Invoking system calls on an Intel-based operating Invoking system calls on an Intel-based operating system, usually involves building an argument list (in system, usually involves building an argument list (in registers or on the stack, depending on the operating registers or on the stack, depending on the operating system) and then asking the kernel to perform a system system) and then asking the kernel to perform a system call on behalf of the process.call on behalf of the process.
This can be done with a variety of methods.This can be done with a variety of methods. For Intel systems, the system call functionality can relyFor Intel systems, the system call functionality can rely
on a software interrupt, initiated by the on a software interrupt, initiated by the intint instruction; instruction; a call gate, invoked with an a call gate, invoked with an lcalllcall; ; or special purpose machine support, such as or special purpose machine support, such as sysentersysenter..
8080
Writing The CodeWriting The Code
For Linux and many BSD variants, the For Linux and many BSD variants, the int 128int 128 interrupt is reserved for system calls.interrupt is reserved for system calls.
When the interrupt is generated, the kernel handles When the interrupt is generated, the kernel handles it, determines that the process needs some system it, determines that the process needs some system function performed, and carries out the required function performed, and carries out the required task.task.
The procedure for Linux systems is as follows:The procedure for Linux systems is as follows:1. Put the system call parameters in general purpose 1. Put the system call parameters in general purpose
registers starting at registers starting at EBX; EBX; If a system call requires more If a system call requires more than 5, put them on the stack.than 5, put them on the stack.
2. Put the system call number of the desired system call in 2. Put the system call number of the desired system call in EAXEAX..
3. Use the 3. Use the int 128int 128 instruction to perform the system call. instruction to perform the system call.
8181
Guide To Intel x86 Register NamesGuide To Intel x86 Register Names
Slide just shows how complicated the Intel x86 register structure is.
8282
Finding The Code In MemoryFinding The Code In Memory Usually on Intel x86 CPUs, the strings or data Usually on Intel x86 CPUs, the strings or data
required by shellcode are supplied alongside the required by shellcode are supplied alongside the code and their addresses are calculated code and their addresses are calculated independently.independently.
To understand how this works, consider the To understand how this works, consider the semantics of the semantics of the callcall instruction. instruction.
This function implicitly saves a return address on This function implicitly saves a return address on the stack, which is the address of the first byte the stack, which is the address of the first byte after the call construction.after the call construction.
Thus, shellcode is often constructed using the Thus, shellcode is often constructed using the format on the next slide.format on the next slide.
8383
Finding The Code In MemoryFinding The Code In Memoryjmp endjmp endcode: ...shellcode ...code: ...shellcode ...end: call codeend: call code.string "/bin/sh".string "/bin/sh" This example jumps to the end of the code and then This example jumps to the end of the code and then
uses uses callcall to run code located directly after the to run code located directly after the jmpjmp instruction.instruction.
What is the point of this indirection?What is the point of this indirection? Basically, the relative address of the string Basically, the relative address of the string "/bin/sh""/bin/sh" is on the stack because of the call is on the stack because of the call instruction implicitly pushing a return address on the instruction implicitly pushing a return address on the stack.stack.
Hence the address of the string can be calculated Hence the address of the string can be calculated automatically, regardless of where the shellcode is automatically, regardless of where the shellcode is located in the target application.located in the target application.
8484
Finding The Code In MemoryFinding The Code In Memory Combining this with the information in the previous section, Combining this with the information in the previous section, execveexecve shellcode would look something like: shellcode would look something like:
jmp endjmp endcode: code: popl %ebx ; popl %ebx ; EBX = pathname argumentEBX = pathname argumentxorl %eax, %eax; xorl %eax, %eax; zero out EAXzero out EAXmovl %eax, %edx; movl %eax, %edx; EDX = envpEDX = envppushl %eax; pushl %eax; put NULL in argv arrayput NULL in argv arraypushl %ebx; pushl %ebx; put "/bin/sh" in argv arrayput "/bin/sh" in argv arraymovl %esp, %ecx; movl %esp, %ecx; ECX = argvECX = argvmovb $0x0b, %al; movb $0x0b, %al; 0x0b = execve system call0x0b = execve system callint $0x80; int $0x80; system callsystem callcall codecall code.string "/bin/sh".string "/bin/sh"
8585
Finding The Code In MemoryFinding The Code In Memory
You should observe that the code to start a shell You should observe that the code to start a shell is fairly straightforward.is fairly straightforward.
You simply need to fill the registers EBX, ECX, You simply need to fill the registers EBX, ECX, and EDX with and EDX with pathnamepathname, , argvargv, and , and envpenvp respectively, and then invoke a system call.respectively, and then invoke a system call.
This example is a simple shellcode snippet, but This example is a simple shellcode snippet, but more complex shellcode is based on the same more complex shellcode is based on the same principles.principles.
8686
Simplified Example of TechniqueSimplified Example of Technique
8787
Example ContinuedExample Continued
Source: David Lie ECE1776
8888
Another Example - Memory OrganizationAnother Example - Memory Organization
Text Text segment has codesegment has code DataData segment has static segment has static
variablesvariables HeapHeap segment has segment has
dynamic datadynamic data StackStack segment hassegment has
Dynamic local variablesDynamic local variables Parameters to functionsParameters to functions Return addressReturn address
stack
heap
data
text
high address
low address
SP
Source of next 11 slides: Warren Page, Ohio University
8989
Simplified Stack ExampleSimplified Stack Example
high
void func(int a, void func(int a, int b){int b){
char buffer[10];char buffer[10];
}}
void main(){void main(){
func(1, 2);func(1, 2);
}}
::
buffer
ret
a
b
return address
low
SP
SP
SP
SP
9090
Smashing the StackSmashing the Stack
high
What happens if buffer What happens if buffer overflows?overflows?
::
buffer
a
b
ret…
low
SP
SP
SP
SP
retoverflow
Program “returns” to Program “returns” to wrong locationwrong location
NOT!
???
A crash is likelyA crash is likelyoverflow
9191
Smashing the StackSmashing the Stack
high
With code injection, With code injection,
attacker can run any attacker can run any
code on affected code on affected
systemsystem
::
mal. code
a
b
low
SP
SP
SP
SP
retret
9292
Stack Smashing ExampleStack Smashing Example Program asks for a serial number that attacker does Program asks for a serial number that attacker does
not knownot know Attacker also does not have source codeAttacker also does not have source code Attacker does have the executable (exe)Attacker does have the executable (exe)
Program quits on incorrect serial numberProgram quits on incorrect serial number
9393
ExampleExample By trial and error, attacker discovers an By trial and error, attacker discovers an
apparent buffer overflowapparent buffer overflow
Note that 0x41 is “A”Note that 0x41 is “A” Looks like Looks like retret overwritten by 2 bytes! overwritten by 2 bytes!
9494
ExampleExample Next, disassemble Next, disassemble bo.exebo.exe to find to find
The goal is to exploit buffer overflow to jump The goal is to exploit buffer overflow to jump
to address to address 0x4010340x401034
9595
ExampleExample
We find that 0x401034 is “@^P4” in ASCIIWe find that 0x401034 is “@^P4” in ASCII
Byte order is reversed? Why?Byte order is reversed? Why? x86 processors are “little-endian” x86 processors are “little-endian”
9696
ExampleExample
Reverse the byte order to “4^P@” and…Reverse the byte order to “4^P@” and…
Success! We’ve bypassed serial number Success! We’ve bypassed serial number check by exploiting a buffer overflowcheck by exploiting a buffer overflow
Overwrote the return address on the stackOverwrote the return address on the stack
9797
ExampleExample
Attacker did not require access to the source codeAttacker did not require access to the source code Only tool used was a disassembler to determine Only tool used was a disassembler to determine
address to jump toaddress to jump to But, can find address by trial and errorBut, can find address by trial and error
This is necessary if attacker does not have exeThis is necessary if attacker does not have exe For example, a remote attackFor example, a remote attack All that is needed is patience, time, and a All that is needed is patience, time, and a
knowledge of how different programs are laid knowledge of how different programs are laid out in memory!out in memory!
9898
ExampleExample Source code of the buffer overflowSource code of the buffer overflow
Flaw easily Flaw easily found by found by attackerattacker
Even without Even without the source the source code!code!
Non-trusted InputNon-trusted Input
100100
Input Validation
Before using an input value check that it is safe: NULL, Out of range, invalid format, too long,
too short, etc… Err on the side of caution:
I know this will be safe vs I can’t think of a way to break this…
E.g. whitelist safe inputs, rather than blacklist dangerous ones.
101101
ex8.cex8.c
int main(int argc, char *argv[]) { int valid = 0; /* 0=false */ char str1[8]; char str2[8]; gets(str1); gets(str2); if (strncmp(str1,str2,8) == 0) valid = 1; /* 1 = true */ printf("buffer1:str1(%s),str2(%s), valid(%d)\n", str1, str2,valid); if (valid == 0) /* zero is viewed as false */ printf("No match - deny access\n"); if (valid != 0) /*any nonzero value is viewed as true */ printf("Match - allow access\n"); }
102102
strncmpstrncmp
2.14.11 strncmp2.14.11 strncmp Declaration: Declaration: int strncmp (const char *int strncmp (const char *str1str1, const char , const char
**str2str2, size_t , size_t nn)) Compares at most the first Compares at most the first nn bytes of bytes of str1str1 and and
str2str2. . Stops comparing after the null character. Stops comparing after the null character.
Returns zero if the first Returns zero if the first nn bytes (or null bytes (or null terminated length) of terminated length) of str1str1 and and str2str2 are equal. are equal.
Returns less than zero or greater than zero if Returns less than zero or greater than zero if str1str1 is less than or greater than is less than or greater than str2str2 respectively. respectively.
http://www.acm.uiuc.edu/webmonkeys/book/c_guide/
103103
See Input to Locate str1 and str2 in MemorySee Input to Locate str1 and str2 in Memory
str2 str1
104104
Now You Can See Why BADINPUT and Now You Can See Why BADINPUT and BADINPUTBADINPUT PassesBADINPUTBADINPUT Passes
str2 str1
105105
Security ProblemSecurity Problem
Note that discovering this flaw, allows someone Note that discovering this flaw, allows someone to enter a password protected site or database, to enter a password protected site or database, when they don't know the password!when they don't know the password!
Note the number 8 is irrelevant.Note the number 8 is irrelevant. Any number chosen would cause similar Any number chosen would cause similar
problems.problems.
106106
Writing Over A Local Variable - A Simple Writing Over A Local Variable - A Simple Attack Via InputAttack Via Input
int authenticate(char *username, char int authenticate(char *username, char *password){*password){
int authenticated;int authenticated;
char buffer[1094];char buffer[1094];
authenticated = verify_password authenticated = verify_password (username, password);(username, password);
if (authenticated == 0) {if (authenticated == 0) {
sprintf(buffer, "bad password for sprintf(buffer, "bad password for username %s\n";username %s\n";
log("%s", buffer); }log("%s", buffer); }
return authenticated; }return authenticated; }
107107
What Is IntendedWhat Is Intended
authenticated = verify_password authenticated = verify_password (username, password);(username, password);
After asking the user for the username and After asking the user for the username and password, these are checked in the password file.password, these are checked in the password file.
Supposedly, if the username and password are not Supposedly, if the username and password are not correct, then a 0 is returned signaling correct, then a 0 is returned signaling falsefalse; ; otherwise a 1 is returned signaling otherwise a 1 is returned signaling truetrue..
Note: Computers typically interpret any non-zero Note: Computers typically interpret any non-zero integer as integer as true.true.
108108
The Layout For The ProgramThe Layout For The Program Not all compilers layout the program the same.Not all compilers layout the program the same. Some rearrange variables for optimization purposes.Some rearrange variables for optimization purposes. Thus, without studying specific compilers, you can't Thus, without studying specific compilers, you can't
conclusively determine from source code how conclusively determine from source code how variables are laid out in the source frame.variables are laid out in the source frame.
Unfortunately, attackers study different compilers and Unfortunately, attackers study different compilers and there are web sites that post this information.there are web sites that post this information.
For this example, let's assume that For this example, let's assume that authenticatedauthenticated is located at the top of the stack.is located at the top of the stack.
Thus, Thus, authenticated authenticated is at a higher memory is at a higher memory location than the variable location than the variable buffer.buffer.
109109
Off-by-one Length MiscalculationOff-by-one Length Miscalculation The The authenticate authenticate function has a buffer overflow function has a buffer overflow
possibility because the possibility because the sprintf sprintf function doesn't limit the function doesn't limit the amount of data it writes to the output buffer.amount of data it writes to the output buffer.
Thus, if the Thus, if the username username string is 1024 bytes since a null string is 1024 bytes since a null character is written at the end of the string, the data is character is written at the end of the string, the data is written past the end of the buffer variable and into the written past the end of the buffer variable and into the authenticated authenticated variable.variable.
The The authenticatedauthenticated variable is a state variable variable is a state variable indicating whether the user was able to successfully log in.indicating whether the user was able to successfully log in.
The overflow makes this variable nonzero andThe overflow makes this variable nonzero and the the program treats the attacker as successfully authenticatedprogram treats the attacker as successfully authenticated
110110
Is This A Good Attack Technique?Is This A Good Attack Technique?
Overwriting adjacent local variables is a handy Overwriting adjacent local variables is a handy attack technique, but it's not generally applicable.attack technique, but it's not generally applicable.
The technique depends on The technique depends on What variables are available to overwrite.What variables are available to overwrite. How the compiler orders the variables in memory.How the compiler orders the variables in memory. What the program does after the overflow happens.What the program does after the overflow happens.
A more general technique is to target the saved A more general technique is to target the saved state information in every stack frame - namelystate information in every stack frame - namely The saved frame pointerThe saved frame pointer The saved return addressThe saved return address
111111
Common Security Bugs Like buffer overflows, the most common reason for
security bugs is invalid assumptions. An adversary will look for these assumptions
and find ways to invalidate them. Adversaries can often control program inputs:
Direct input: command line, keyboard, … Function calls Config files Network packets Web forms…
Bug: it is common to assume input is “benign”
112112
Example: system() Web forms are often processed by scripts that
need to run other programs on the server. Usually scripts use C’s system() or popen() Bug: these calls invoke a shell. Command separators like “|” and “;” allow the
user to run other commands on the server.
Form.cgi:# … start html …system(“grep $test file”);# … do other stuff …
Attacker inputs:“; cat /etc/passwd”
Web Server runs:“grep ; cat /etc/passwd file”
Structured Exception HandlingStructured Exception Handling
114114
Structured Exception Handling (SEH) AttacksStructured Exception Handling (SEH) Attacks
The Windows operating systems can be vulnerable to The Windows operating systems can be vulnerable to a slight variation on the traditional stack overflow a slight variation on the traditional stack overflow attacks because of the way they handle exceptions.attacks because of the way they handle exceptions.
Programs can register a handler to act on errors Programs can register a handler to act on errors (called (called exceptions exceptions ))in a consistent manner.in a consistent manner.
Exception handling is a feature of many modern Exception handling is a feature of many modern languages and was popularized by the C++ language.languages and was popularized by the C++ language.
C++'s exception handling is significantly more C++'s exception handling is significantly more complex than SEH and is implemented on top of SEH complex than SEH and is implemented on top of SEH in Window environments.in Window environments.
115115
How Does SEH Work?How Does SEH Work?
When a thread causes an exception to be When a thread causes an exception to be thrown, the thread has a chance to catch that thrown, the thread has a chance to catch that exception and recover.exception and recover.
When a function registers an exception handler, When a function registers an exception handler, it's placed at the top of a chain of currently it's placed at the top of a chain of currently registered exception handlers.registered exception handlers.
When an exception is thrown, the chain is When an exception is thrown, the chain is traversed from the top until an applicable traversed from the top until an applicable handler is found for the thrown exception.handler is found for the thrown exception.
If no appropriate handler is found, the process is If no appropriate handler is found, the process is generally terminated.generally terminated.
116116
Exploiting Stack Overflows With SEHExploiting Stack Overflows With SEH
On Windows, the exception handler registration On Windows, the exception handler registration structures are located on the program stack and structures are located on the program stack and a series of pointers point into the various a series of pointers point into the various records.records.
If an attacker can trigger a stack overflow that If an attacker can trigger a stack overflow that overwrites a handler and then force some sort of overwrites a handler and then force some sort of exception, the exception handler registrations exception, the exception handler registrations are examined.are examined.
One of these can then jump to code controlled One of these can then jump to code controlled by an attacker.by an attacker.
117117
Attempting To Prevent OverflowAttempting To Prevent Overflow Example: Example: void process string (char *src) {void process string (char *src) {
char dest[32];char dest[32];for (i = 0; src[i] && (i <= for (i = 0; src[i] && (i <=
sizeof(dest)); i++)sizeof(dest)); i++)dest[i] = src[i];dest[i] = src[i];
......
The code attempts to prevent an overflow if The code attempts to prevent an overflow if srcsrc has more has more than 32 characters.than 32 characters.
However, it can write one element out of bounds into However, it can write one element out of bounds into destdest because i can become because i can become sizeof(dest)sizeof(dest) or 32, but the or 32, but the indices are only valid for 0, 1, ..., 31.indices are only valid for 0, 1, ..., 31.
So So dest[32]dest[32], an unknown memory location, is set to , an unknown memory location, is set to src[32] src[32] which contains unknown data.which contains unknown data.
118118
Attempting To Prevent OverflowAttempting To Prevent Overflow Another example:Another example:int get_user(char *user) {int get_user(char *user) {char buf[1024];char buf[1024];if (strlen(user) > sizeof(buf)if (strlen(user) > sizeof(buf)
die("error: user string too long\n");die("error: user string too long\n");strcpy(buf,user);strcpy(buf,user);
......strlenstrlen returns the number of characters in a C string, but it returns the number of characters in a C string, but it
doesn't count the NULL terminating character.doesn't count the NULL terminating character.In the function above, if the supplied user string is exactly In the function above, if the supplied user string is exactly
1024 characters, 1024 characters, strlenstrlen returns 1024, returns 1024, sizeofsizeof returns returns 1024, and the length check passes.1024, and the length check passes.
Therefore, the Therefore, the strcpystrcpy function writes 1024 bytes of string function writes 1024 bytes of string data plus the trailing NULL character.data plus the trailing NULL character.
119119
Suppose Error Handling Doesn’t Exist in a Suppose Error Handling Doesn’t Exist in a Language?Language?
Check “error conditions” on return values E.g. malloc(), open(), etc…
Catch exceptions or declare them Think about where to handle errors
Fix locally? Propagate to caller? Fail-stop?
Off-by-one ErrorsOff-by-one Errors
121121
Off-by-one Errors - Problem.
Off-by-one errors occur when a programmer takes the proper precautions in terms of bounds checking, but maybe puts a 512 where she should have put a 511.
Can happen to the best programmers no matter how well-informed they are about buffer overflows.
Usually off-by-one errors can do no more than crash the program. They can be made to compromise security-sensitive data. But any buffer overflow is a security risk.
122122
Off-by-one Errors - Recommendations. If you have a 512 byte buffer you can only store 511
characters in the string (the last character is a NULL). If you use scanf() to read into a buffer you also have to
account for the NULL: use scanf(“%511s”, &My512ByteBuffer) instead of scanf(“%512s”, &My512ByteBuffer) or scanf(“%s”,
&MY512ByteBuffer) which are both unsafe. If you declare an array as int A[100], remember that you
can’t access A[100], the highest index you can access is A[99] and the lowest is A[0].
The best defense against off-by-one errors of any kind is a thorough combination of testing and code inspection.
123123
Off-by-one Errors In The CodingOff-by-one Errors In The Coding
On operating systems running on Intel x86 machines, On operating systems running on Intel x86 machines, these off by one errors can cause crashes and are often these off by one errors can cause crashes and are often exploitable because the least significant byte of the saved exploitable because the least significant byte of the saved frame pointer can be overwritten.frame pointer can be overwritten.
Recalling how the runtime stack is organized, this means Recalling how the runtime stack is organized, this means the restored base pointer is incorrect by up to 255 bytes the restored base pointer is incorrect by up to 255 bytes when the function returns.when the function returns.
If the new base pointer points to some user-controllable If the new base pointer points to some user-controllable data (such as a character buffer), users can then specify data (such as a character buffer), users can then specify local variable values from the previous stack frame as well local variable values from the previous stack frame as well as the saved base pointer and the return address.as the saved base pointer and the return address.
What does this allow?What does this allow?
124124
Off-by-one Errors In The CodingOff-by-one Errors In The Coding
When the calling function returns, an arbitrary When the calling function returns, an arbitrary return address might be specified, and total control return address might be specified, and total control over the program can be seized.over the program can be seized.
Off-by-one errors can also be exploitable when the Off-by-one errors can also be exploitable when the element is written out of bounds into another element is written out of bounds into another variable used by that function.variable used by that function.
The security implications of the off-by-one error in The security implications of the off-by-one error in this situation depend on how the adjacent variable this situation depend on how the adjacent variable is used subsequent to the overflow.is used subsequent to the overflow.
If the variable is an integer, it's truncated and the If the variable is an integer, it's truncated and the program could make incorrect calculations based program could make incorrect calculations based on its value.on its value.
125125
Off-by-one Errors In The CodingOff-by-one Errors In The Coding
The adjacent variable might also affect the The adjacent variable might also affect the security model directly.security model directly.
For example, it might be a user ID, allowing For example, it might be a user ID, allowing users to receive permissions they aren't entitled users to receive permissions they aren't entitled to.to.
Although these types of exploits are Although these types of exploits are implementation specific, their impact can be implementation specific, their impact can be severe as generalized attacks.severe as generalized attacks.
Heap OverflowsHeap Overflows
127127
Heap OverflowsHeap Overflows
Heap overflows are a more recent advance in Heap overflows are a more recent advance in exploitation.exploitation.
Although common now, general heap Although common now, general heap exploitation techniques didn't surface until July exploitation techniques didn't surface until July 2000.2000.
These techniques were originally presented by These techniques were originally presented by an accomplished security researcher known as an accomplished security researcher known as Solar Designer.Solar Designer.
His original advisory is available at His original advisory is available at http://www.openwall.com/advisories/OW-002-netscape-jpeg/
128128
Heap ManagementHeap Management To understand how heap exploitation works, we To understand how heap exploitation works, we
need to be familiar with how the heap is managed.need to be familiar with how the heap is managed. Although heap implementations vary widely, some Although heap implementations vary widely, some
common elements are present in most algorithms. common elements are present in most algorithms. Essentially, when a call to Essentially, when a call to mallocmalloc or a or a similarsimilar
memory allocation is made, some memory is memory allocation is made, some memory is fetched from the heap and returned to the user.fetched from the heap and returned to the user.
When this memory is deallocated by using When this memory is deallocated by using free, free, the system must mark it as free so that it can be the system must mark it as free so that it can be used later.used later.
129129
Heap ManagementHeap Management Consequently, a state must be kept for regions of Consequently, a state must be kept for regions of
memory that are returned to the callers so that memory that are returned to the callers so that memory can be handed out and reclaimed efficiently.memory can be handed out and reclaimed efficiently.
Most implementations return a block of memory to the Most implementations return a block of memory to the user which is preceded by a header describing some user which is preceded by a header describing some basic characteristics of the block as well as some basic characteristics of the block as well as some additional information about adjacent block. additional information about adjacent block.
The block header usually includes the following:The block header usually includes the following: Size of current blockSize of current block Size of previous blockSize of previous block Whether the block is free or in useWhether the block is free or in use Possibly some additional flagsPossibly some additional flags
130130
Heap ManagementHeap Management Free blocks are often chained together using a Free blocks are often chained together using a
standard data structure, such as a singly or standard data structure, such as a singly or doubly linked list.doubly linked list.
Most heap implementations define a minimum Most heap implementations define a minimum size of a block big enough to hold pointers to size of a block big enough to hold pointers to previous and next elements in a list and use this previous and next elements in a list and use this space to hold pointers when the block isn't in space to hold pointers when the block isn't in use.use.
The next slide shows the two basic block The next slide shows the two basic block structures specific to libc structures specific to libc mallocmalloc implementations.implementations.
131131
Heap ManagementHeap Management
Previous sizePrevious size
Current size FlagsCurrent size Flags
User dataUser data
Previous sizePrevious size
Current size FlagsCurrent size Flags
List forward pointerList forward pointer
List backward pointerList backward pointer
Free spaceFree space
GLIBC in-use chunk GLIBC free chunk
Note that the organization of blocks in this way means that triggering an overflow results in corrupting header information for allocated memory chunks as well as list management data.
132132
Exploiting Heap OverflowsExploiting Heap Overflows
The ability to modify header data and list The ability to modify header data and list pointers arbitrarily through a buffer overflow pointers arbitrarily through a buffer overflow gives attackers the opportunity to disrupt the gives attackers the opportunity to disrupt the management of heap blocks.management of heap blocks.
These disruptions can be used to manipulate These disruptions can be used to manipulate block headers and to leverage the heap block headers and to leverage the heap maintenance algorithms, especially the list maintenance algorithms, especially the list maintenance of free blocks.maintenance of free blocks.
Let's describe the standard technique for doing Let's describe the standard technique for doing this in depth.this in depth.
133133
Exploiting Heap OverflowsExploiting Heap Overflows1. Blocks marked as free are assumed to contain list 1. Blocks marked as free are assumed to contain list
pointers to next and previous blocks in the free chunks pointers to next and previous blocks in the free chunks list.list.
2. When a block is freed, it's often coalesced with adjacent 2. When a block is freed, it's often coalesced with adjacent blocks if they are also free.blocks if they are also free.
3. Because two blocks are being merged into one, the 3. Because two blocks are being merged into one, the heap algorithm removes the next chunk that was heap algorithm removes the next chunk that was originally on the free list, adjusts the size of the chunk originally on the free list, adjusts the size of the chunk being freed to reflect that it's now bigger, and then adds being freed to reflect that it's now bigger, and then adds the new larger chunk onto the free list.the new larger chunk onto the free list.
4. An overflow buffer sets the list pointers in the corrupted 4. An overflow buffer sets the list pointers in the corrupted chunk to locations useful to the attacker.chunk to locations useful to the attacker.
134134
Exploiting Heap OverflowsExploiting Heap Overflows
5. The overflow buffer sets the list pointers in the 5. The overflow buffer sets the list pointers in the corrupted chunk to locations useful to an corrupted chunk to locations useful to an attacker.attacker.
6. When the unlink operation is performed, an 6. When the unlink operation is performed, an attacker-supplied, fixed-size value is written to attacker-supplied, fixed-size value is written to an attacker-determined memory location.an attacker-determined memory location.
Being able to overwrite a memory location with a Being able to overwrite a memory location with a controllable value is usually all that attackers controllable value is usually all that attackers need to gain control of a process.need to gain control of a process.
135135
Exploiting Heap OverflowsExploiting Heap Overflows To understand why unlinking a chunk leads to an To understand why unlinking a chunk leads to an
arbitrary overwrite, consider the following code for arbitrary overwrite, consider the following code for unlinking an element from a doubly linked list:unlinking an element from a doubly linked list:
int unlink(ListElement *element) {int unlink(ListElement *element) {ListElement *next = element->next;ListElement *next = element->next;
ListElement *prev = element->prev;ListElement *prev = element->prev;next->prev = prev;next->prev = prev;prev->next = next;prev->next = next;return 0; }return 0; }
If the If the element->nextelement->next and and element->prevelement->prev values can be specified by an overflow, the code values can be specified by an overflow, the code unwittingly updates arbitrary memory locations with unwittingly updates arbitrary memory locations with corrupted values.corrupted values.
136136
Exploiting Heap OverflowsExploiting Heap Overflows
Many useful values can be overwritten to enable Many useful values can be overwritten to enable attackers to compromise an application.attackers to compromise an application.
Some popular targets are:Some popular targets are:1. 1. Global offset table (GOT)/process linkage table (PLT)Global offset table (GOT)/process linkage table (PLT)
UNIX ELF binaries use several loader structures to UNIX ELF binaries use several loader structures to resolve called functions from libraries into addresses.resolve called functions from libraries into addresses. These structures enable shared libraries to be located These structures enable shared libraries to be located
anywhere in memory so that the application doesn't anywhere in memory so that the application doesn't need static addresses for API functions at compile need static addresses for API functions at compile time.time.
By targeting these structures, attackers can redirect By targeting these structures, attackers can redirect execution to an arbitrary location when a certain API execution to an arbitrary location when a certain API function is called (for example function is called (for example freefree))
137137
Exploiting Heap OverflowsExploiting Heap Overflows
2. 2. Exit handlersExit handlers Exit handlers are a table of function pointers that are called Exit handlers are a table of function pointers that are called
when the process exits in a UNIX operating system.when the process exits in a UNIX operating system. By overwriting one of these values, it's possible to gain By overwriting one of these values, it's possible to gain
arbitrary execution when the process calls the arbitrary execution when the process calls the exitexit function or returns to the function or returns to the mainmain function. function.
3. 3. Lock pointersLock pointers Windows uses a set of function pointers in the process Windows uses a set of function pointers in the process
environment block (PEB) to prevent unsynchronized environment block (PEB) to prevent unsynchronized modification of process information by competing threads. modification of process information by competing threads.
These lock pointers can be overwritten and then triggered These lock pointers can be overwritten and then triggered by certain types of exceptional conditions.by certain types of exceptional conditions.
138138
Exploiting Heap OverflowsExploiting Heap Overflows4. 4. Exception handler routinesException handler routines
The Windows PEB maintains an address for the unhandled The Windows PEB maintains an address for the unhandled exception filter routine.exception filter routine.
The routine is called when an exception isn't handled The routine is called when an exception isn't handled successfully by any other exception handler.successfully by any other exception handler.
A common technique is to use the list maintenance code to A common technique is to use the list maintenance code to overwrite the unhandled exception routine when updating one overwrite the unhandled exception routine when updating one part of the list (such as the previous element) and then cause part of the list (such as the previous element) and then cause a memory access violation when updating the next element.a memory access violation when updating the next element.
This technique ensures that the unhandled exception filter is This technique ensures that the unhandled exception filter is called immediately, assuming that another exception handler called immediately, assuming that another exception handler doesn't successfully catch the resulting access violation doesn't successfully catch the resulting access violation exception.exception.
139139
Exploiting Heap OverflowsExploiting Heap Overflows
5. 5. Function pointersFunction pointers Applications use function pointers for various Applications use function pointers for various
reasons, such as calling functions from reasons, such as calling functions from dynamically loaded libraries, for C++ virtual dynamically loaded libraries, for C++ virtual member functions, or for abstracting low-level member functions, or for abstracting low-level worker functions in opaque structures.worker functions in opaque structures.
Overwriting application specific function pointers Overwriting application specific function pointers can provide a reliable exploit against an can provide a reliable exploit against an application.application.
140140
Global And Static Data OverflowsGlobal And Static Data Overflows
Global and static variablesGlobal and static variables are used to store data are used to store data that persists between different function calls, so that persists between different function calls, so they are generally stored in a different memory they are generally stored in a different memory segment than stack and heap variables are.segment than stack and heap variables are.
Normally, these locations don't contain general Normally, these locations don't contain general program runtime data structures, such as stack program runtime data structures, such as stack activation records and heap chunk data, so activation records and heap chunk data, so exploiting an overflow in this segment requires exploiting an overflow in this segment requires application specific attacks similar to the application specific attacks similar to the authenticateauthenticate function. function.
141141
Global And Static Data OverflowsGlobal And Static Data Overflows
Exploitability depends on what variables can be Exploitability depends on what variables can be corrupted with the buffer overflow occurs and corrupted with the buffer overflow occurs and how the variables are used.how the variables are used.
For example, if pointer variables can be For example, if pointer variables can be corrupted, the likelihood of exploitation corrupted, the likelihood of exploitation increases, as this corruption introduces the increases, as this corruption introduces the possibility for arbitrary memory updates.possibility for arbitrary memory updates.
Function Point VulnerabilitiesFunction Point Vulnerabilities
143143
Function Pointer VulnerabilitiesFunction Pointer Vulnerabilities
Incomplete MediationIncomplete Mediation
145145
Incomplete Mediation These are cases where access should have been
controlled/checked but was not, as a result the access is “unmediated” e.g.: The “debug” mode for sendmail Recent do_brk vulnerability in Linux 2.4.22 kernels
Incorrect checking of arguments allows a user to map pages from kernel into process address space Undocumented system calls (in windows) allow direct
access to protected structures
Somewhat less common than code-injection, but still common enough
These missed checks are not always obvious
146146
Incomplete Incomplete MMediationediation
Incomplete Incomplete mmediation ediation fflawlaw — often — often nonmalicious nonmalicious but but with serious security consequenceswith serious security consequences
Incomplete Incomplete mmediationediation::
Sensitive data Sensitive data are are in exposed due to an in exposed due to an uncontrolled condition where access is not checkeduncontrolled condition where access is not checked
Example - A real world example documented in an Example - A real world example documented in an article:article:
http://www.informit.com/articles/article.aspx?p=31782&seqNum=2
147147
The problem arises because of the following:The problem arises because of the following:
Input is validated on client.Input is validated on client. Input is not checked on serverInput is not checked on server Why bother since input was checked on client?Why bother since input was checked on client? The The useruser edits URL directly, changing price edits URL directly, changing price and and
total costtotal cost..
148148
User uses forged URL to access serverUser uses forged URL to access server The server takes The server takes $$25 as the total cost25 as the total cost
Surprise! This really worked. Surprise! This really worked. The attacker could have ordered Objects from The attacker could have ordered Objects from
Things in any quantity at any price. Things in any quantity at any price. And yes, this code was running on the web site for And yes, this code was running on the web site for
a while before the problem was detected. a while before the problem was detected. From a security perspective, the most serious From a security perspective, the most serious
concern about this flaw was the length of time that concern about this flaw was the length of time that it could have run undetected. it could have run undetected.
Had the whole world suddenly made a rush to Had the whole world suddenly made a rush to Things's web site and bought Objects at a fraction Things's web site and bought Objects at a fraction of their price, Things probably would have noticed. of their price, Things probably would have noticed.
149149
But, Things is large enough that it would never have But, Things is large enough that it would never have detected a few customers a day choosing prices that detected a few customers a day choosing prices that were similar to (but smaller than) the real price, say were similar to (but smaller than) the real price, say 30 percent off. 30 percent off.
The e-commerce division would have shown a The e-commerce division would have shown a slightly smaller profit than other divisions, but the slightly smaller profit than other divisions, but the difference probably would not have been enough to difference probably would not have been enough to raise anyone's eyebrows; the vulnerability could raise anyone's eyebrows; the vulnerability could have gone unnoticed for years. have gone unnoticed for years.
Fortunately Things hired a consultant to do a routine Fortunately Things hired a consultant to do a routine review of its code, and the consultant found the error review of its code, and the consultant found the error quickly. quickly.
150150
This web program design flaw is easy to imagine This web program design flaw is easy to imagine in other web settings. in other web settings.
Those of us interested in security must ask Those of us interested in security must ask ourselves how many similar problems are there ourselves how many similar problems are there in running code today? in running code today?
And how will those vulnerabilities ever be found?And how will those vulnerabilities ever be found?
151151
Another Example of a Missing Check
/* 2.4.5/drivers/char/drm/i810_dma.c */
if(copy_from_user(&d, arg, sizeof(arg)))
return –EFAULT;
if(d.idx > dma->buf_count)
return –EINVAL;
buf = dma->buflist[d.idx];
Copy_from_user(buf->virtual, d.address, d.used);
Missing lower bounds check for d.idx, what if d.idx < 0? This allows attacker to put arbitrary kernel address into
buf, and then copy arbitrary data (in d.used) into that address
Concurrency and Race Concurrency and Race ConditionsConditions
153153
Concurrency and Race ConditionConcurrency and Race Condition ConcurrencyConcurrency
Execution of multiple flows (threads, Execution of multiple flows (threads, processes, tasks, etc)processes, tasks, etc)
If not controlled can lead to nondeterministic If not controlled can lead to nondeterministic behaviorbehavior
Race conditionsRace conditions Software defect/vulnerability resulting from Software defect/vulnerability resulting from
unanticipated execution ordering of concurrent unanticipated execution ordering of concurrent flowsflowsE.g., two people simultaneously try to modify E.g., two people simultaneously try to modify
the same account (withdrawing money)the same account (withdrawing money)
154154
Race ConditionRace Condition Necessary properties for a race conditionNecessary properties for a race condition
Concurrency propertyConcurrency propertyAt least two control flows executing At least two control flows executing
concurrentlyconcurrently Shared object propertyShared object property
The concurrent flows must access a The concurrent flows must access a common shared common shared race objectrace object
Change state propertyChange state propertyAt least one control flow must alter the At least one control flow must alter the
state of the race objectstate of the race object
155155
Race WindowRace Window
A code segment that accesses the race object in a A code segment that accesses the race object in a way that opens a window of opportunity for race way that opens a window of opportunity for race conditioncondition Sometimes referred to as a Sometimes referred to as a critical sectioncritical section
Traditional approachTraditional approach Ensure race windows do not overlapEnsure race windows do not overlap
Make them mutually exclusiveMake them mutually exclusiveLanguage facilities – Language facilities – synchronization primitives synchronization primitives
(SP)(SP) Deadlock Deadlock is a risk related to SPis a risk related to SP
i.e. Denial of service is the result!i.e. Denial of service is the result!
156156
Race Conditions
A race condition occurs when there is a nonzero time interval between checking some property and when it needs to hold true.
Race conditions are often called Time of Check / Time of Use (TOCTOU) vulnerabilities.
157157
Example Ghostscript creates a lot of temporary files:
name = mktemp("/tmp/gs_XXXXXXXX");
fp = fopen(name,"w"); Attacker creates symlink
/tmp/gs_12345A -> /etc/passwd
between call to mktmp and fopen, when root
is running gs (just has to happen once!) Ghostscript (as root) overwrites /etc/passwd.
158158
Diebold Case Study
Feldman et al. demonstrated exploitable vulnerabilities in the AccuVote-TS DRE system.
On reboot, the terminal checks
CF card for the bootloader. If fboot.nb0 exists, boot from
(unauthenticated) CF card. The CF card slot is protected by
a hotel mini-bar key. CF Cards are used to upload
ballot definitions, and download
results.
159159
Time of Check, Time of UseTime of Check, Time of Use
Source of race conditionsSource of race conditions Trusted (tightly coupled threads of execution) Trusted (tightly coupled threads of execution)
or untrusted control flows (separate or untrusted control flows (separate application or process)application or process)
TOCTOU race conditionsTOCTOU race conditions Can occur during file I/OCan occur during file I/O Forms a RW by first Forms a RW by first checkingchecking some race some race
object and then object and then usingusing it it
160160
TTime-of-check to Time-of-use Errorsime-of-check to Time-of-use Errors ( (TOCTTOUTOCTTOU)) TTime-of-check to time-of-use fime-of-check to time-of-use flawlaw — often — often
nnonmalicious, onmalicious, but with serious security consequences but with serious security consequences A.A.K.AK.A. synchronization flaw / serialization flaw. synchronization flaw / serialization flaw TOCTTOU — mTOCTTOU — mediation with “bait and switch”ediation with “bait and switch”
Non-computing example:Non-computing example:Swindler shows buyer real Rolex watch (Swindler shows buyer real Rolex watch (baitbait))
and aand after buyer pays, fter buyer pays, switchesswitches real Rolex to a real Rolex to a forged oneforged one
In computing:In computing:Change Change of a resource (e.g., data) of a resource (e.g., data) between time between time
access checked and time access usedaccess checked and time access usedQ: Q: Any examples of TOCTTOU Any examples of TOCTTOU
problems fromproblems from computing?computing?
161161
TTime-of-check to Time-of-use Errorsime-of-check to Time-of-use Errors ( (TOCTTOUTOCTTOU))
A: E.g., DBMS/OS: A: E.g., DBMS/OS: concurrencyconcurrency problem: problem: X is 10 initiallyX is 10 initially
a. a. pgm1 reads value of X pgm1 reads value of X b. b. pgm1 adds X = X+ 5pgm1 adds X = X+ 5
c. c. pgm1 writes X pgm1 writes X d. d. pgm2 reads X pgm2 reads X
e. pgm2 e. pgm2 adds 3 to Xadds 3 to X f. pgm2 f. pgm2 writes X writes X If the order of execution is a, b, d, c, e, f thenIf the order of execution is a, b, d, c, e, f then X X
ends up with value 1ends up with value 133If the order of execution is a, b, d, e, f, c thenIf the order of execution is a, b, d, e, f, c then X ends up with value 15X ends up with value 15
Any other possibilities?Any other possibilities?
162162
Concurrency Vulnerabilities Involve the time between time-of-check to time-of-use
where the attacker is able to manipulate the system state in a way to gain access or privileges.
In a recent Usenix Security 2005 paper some authors demonstrated a similar file system race: Programs like the print daemon, run as root. To determine
whether you are allowed to print a file or not, they check the ownership of the file
To cause the race to happen, try to print a file in a VERY deep directory structure with a sym-link at the end, so it takes a long time to open the file.
Initially point the sym-link to a file you own. After the print daemon has checked the permissions, the OS spends a long time opening the file. At this time, switch the sym-link to point at a file that doesn’t belong to you and print it out.
163163
More recently (in Linux 2.2.x and 2.4.x) there was a ptrace-kmod exploit: Ptrace is a facility used by debuggers to observe
and modify another process, can stop the process, examine memory, and inject code
Normally, a user process cannot ptrace a root process.
A user process can attach to a root setuid process before it becomes root.
However, a race condition allows the tracing process to remain attached even if the setuid process takes on its root privileges, thus the tracing process inherits control over a root process.
Exploits for these are rarer, since the flaws are very difficult to find.
164164
Timing Attacks: Example
Consider the following pwd checking code:
int password-check( char *inp, char *pwd)
if (strlen(inp) != strlen(pwd)) return 0;
for( i=0; i < strlen(pwd); ++i)
if ( *inp[i] != *pwd[i] ) return 0;
return 1; A simple timing attack will expose the password
one character at a time.
165165
Correct CodeCorrect Code
int password-check( char *inp, char *pwd) {
oklen = ( strlen(inp) == strlen(pwd) ) ;
for( ok=1, i=0; i < strlen(pwd) ; ++i)
ok = ok & ( inp[i] == pwd[i] ) ;
return ok & oklen;
} Make the function take the same amount of time
no matter what
Formatted String ErrorsFormatted String Errors
167167
Format String Bugs
int func(char *user_input) {
printf( user_input );
} Problem: what if user =
“%s%s%s%s%s%s%s” Most likely program will crash… If not, program will print memory contents. Correct form:
int func(char *user) {
fprintf(stdout,“%s”,user);
}
168168
Format-string Overflows
char outbuf[512], errmsg[512];
sprintf(errmsg, “Illegal cmd: %.400s”, input);
printf(outbuf, errmsg);
How could we use format strings to overflow
outbuf? input = “%512x|Any 394 byte overflow value”
169169
Exploit
Important things about format strings:
printf(“%4$c”, ‘a’, ‘b’, ‘c’, ‘d’) prints ‘d’.
printf(“%42x%n”, 0, &var) sets var=42. Suppose we want to change the byte at address
ADDR to VALU, and know that the buffer with the format string is POS-4 words up the stack:
buf = “%VALUx%POS$hhnxxADDR”
170170
Preventing Format-string Bugs Correct usage, input validation, snprintf
www.usenix.org/events/sec01/cowanbarringer.html
FormatGuard: count arguments to printf, parameters in format string.
Tainting: reject format strings from “untrusted” sources, strings with %n, etc…
Whitelisting: allow writes only to programaddressable locations.
www.cs.washington.edu/homes/miker/format_string.pdf
Integer OverflowInteger Overflow
172172
What is Integer Overflow?What is Integer Overflow?
Integer overflow is the result of trying to place Integer overflow is the result of trying to place into computer memory an integer that is too large into computer memory an integer that is too large for the integer data type in a given system. for the integer data type in a given system.
Integer overflow can result in a request for Integer overflow can result in a request for dynamically allocated memory that is far too large dynamically allocated memory that is far too large or too small than that which is needed by the or too small than that which is needed by the program. program.
An integer overflow often passes undetected and An integer overflow often passes undetected and the condition may lead to a security breach the condition may lead to a security breach through a buffer overflow or other malicious code. through a buffer overflow or other malicious code.
173173
Release Date: 2008-06-10 Release Date: 2008-06-10
A vulnerability has been reported in OpenOffice, A vulnerability has been reported in OpenOffice, which can be exploited by malicious people to which can be exploited by malicious people to compromise a user's system.compromise a user's system.
The vulnerability is caused due to an integer overflow The vulnerability is caused due to an integer overflow error in "rtl_allocateMemory()" and can be exploited to error in "rtl_allocateMemory()" and can be exploited to cause heap-based buffer overflows via a specially cause heap-based buffer overflows via a specially crafted document.crafted document.
Successful exploitation may allow execution of Successful exploitation may allow execution of arbitrary code.arbitrary code.
The vulnerability is reported in versions 2.0 to 2.4.The vulnerability is reported in versions 2.0 to 2.4.
174174
Public Advisory: 09.09.08Public Advisory: 09.09.08Apple QuickTime PICT Integer Overflow Apple QuickTime PICT Integer Overflow
VulnerabilityVulnerability Quicktime is Apple's media player product, and
is used to render video and other media. The PICT file format was developed by Apple
Inc. in 1984. PICT files can contain both object oriented
images and bitmaps. Remote exploitation of an integer overflow in
Apple Inc.'s QuickTime could allow an attacker to execute arbitrary code in the security context of the current user.
175175
QuickTime is vulnerable to an integer overflow vulnerability when handling malformed PICT files.
This issue results in heap corruption which can lead to arbitrary code execution.
An attacker would need to host a web page containing a malformed PICT file.
Upon visiting the malicious web page exploitation would occur.
Alternatively a malicious PICT file could be attached to an e-mail.
176176
Apple Inc.'s QuickTime versions 7.4.5 and 7.4 have been confirmed to be vulnerable to this issue. Older versions are also suspected to be vulnerable.
iDefense recommends disabling the QuickTime Plug-in and altering the .pic and .pict file type associations within the registry.
Apple has released QuickTime 7.5.5 which resolves this issue.
More information is available via Apple's QuickTime Security Update.
Dangers of Reusing CodeDangers of Reusing Code
178178
Old Code Used For New Purposes - Problem
Often old code is reused in new projects. Even if the old code was thoroughly tested and written in a safe manner, it might not have accounted for things that the new code expects it to support, like international character sets.
179179
Old Code Used For New Purposes - Consequences.
“HELLO” in ASCII is 0x48-0x45-0x4C-0x4C-0x4F “HELLO” in UNICODE is
0x00-0x48- 0x00-0x45-0x00-0x4C-0x00-0x4C-0x00-
0x4F The old code might tell the new code to give it no more than
5 characters because it uses a 5-byte buffer. The new code gives it 5 characters, but in UNICODE
instead of ASCII, so they fill 10 bytes. (The assumption that 5 characters = 5 bytes is a
dangerous one.)
180180
• This is more common and more easily exploitable than you might think.
A “Venetian exploit” can hijack a program with a
reasonably sized buffer overflow even if UNICODE format forces the attacker to have half of his attack code bytes be zeros.
181181
Old Code For New Purposes - Recommendations
Enumerate and challenge all assumptions you’ve made about the interaction between old code and new.
Test thoroughly. Test old code when you’re using it for new purposes,
even if you tested it before. If your software allows the user to use UNICODE
then do all of the testing you did for ASCII with UNICODE as well.
Include the old code in code inspection, even if you inspected it before.
182182
SummarySummary
We've looked at some basic vulnerabilities that We've looked at some basic vulnerabilities that can be exploited in code.can be exploited in code.
Most of our examples came from C code and Most of our examples came from C code and Linux, but only because C and Linux are more Linux, but only because C and Linux are more open and there are not too many variations (as open and there are not too many variations (as with Java, Windows, etc.)with Java, Windows, etc.)
Have we explored all possible types of problems?Have we explored all possible types of problems? No way! Hackers spend a huge amount of time No way! Hackers spend a huge amount of time
locating these vulnerabilities and they share them locating these vulnerabilities and they share them amongst themselves.amongst themselves.
183183
All Sorts Of Other Far-fetched But Deadly-Serious Things You Should Think About -
Consequences. Your software might be a UNIX utility that spawns two
processes. One sets an environment variable to either “CHUCKY”
or “CHEESE”, and the second reads it. The reading process doesn’t bother to check the size
before it puts it in a buffer because it is just an environment variable you made up and is guaranteed to have six characters, right? There is no user I/O involved.
184184
But an attacker can force a race condition that changes the environment variable between when one process writes it and when the
other process reads it. They give the environment variable more than
six characters causing a buffer overflow. (Add getenv() to the long list of dangerous library functions.)
185185
All Sorts Of Other Far-fetched But Deadly-SeriousThings You Should Think About -
Recommendations. Challenge all of your assumptions like an
attacker would. Never assume that a well inspected and
thoroughly tested piece of software is absolutely defect free.
As long as programmers use C there will always be problems, hopefully just not as many if we train programmers properly.
Also, remember other languages have problems also and there is a lot of legacy code out there!
186186
For More Details
The following three papers show some of the deep details needed to exploit vulnerabilities.
I covered parts of these, particularly the first one.
http://insecure.org/stf/smashstack.html http://www.w00w00.org/files/articles/heaptut.txt http://www.milw0rm.com/papers/3
Be Sure You Can Explain the Following Be Sure You Can Explain the Following Types of Attacks That Impact Program Types of Attacks That Impact Program
SecuritySecurity
Information leakageInformation leakage Control hijackingControl hijacking Buffer overflowBuffer overflow Code injectionCode injection Stack-based overflowStack-based overflow Non-trusted inputNon-trusted input Structured exception Structured exception
handlinghandling Off-by-one errorsOff-by-one errors
Heap overflowHeap overflow Function pointer Function pointer
problemsproblems Incomplete mediationIncomplete mediation Concurrency and race Concurrency and race
conditionsconditions Formatted string errorsFormatted string errors Integer overflowInteger overflow Reused old codeReused old code
187187