program security part 1

187
Program Security Program Security Part 1 Part 1 Insecure Code Insecure Code Non-malicious Program Non-malicious Program Flaws Flaws

Upload: stormy

Post on 16-Jan-2016

22 views

Category:

Documents


0 download

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 Presentation

TRANSCRIPT

Page 1: Program Security Part 1

Program SecurityProgram SecurityPart 1Part 1

Insecure CodeInsecure Code

Non-malicious Program FlawsNon-malicious Program Flaws

Page 2: Program Security Part 1

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

Page 3: Program Security Part 1

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.

Page 4: Program Security Part 1

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.

Page 5: Program Security Part 1

55

Look at the Typical Intrusion PatternLook at the Typical Intrusion Pattern

Page 6: Program Security Part 1

66

A Growing ProblemA Growing Problem

Page 7: Program Security Part 1

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”

Page 8: Program Security Part 1

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

Page 9: Program Security Part 1

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

Page 10: Program Security Part 1

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.

Page 11: Program Security Part 1

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++.

Page 12: Program Security Part 1

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!

Page 13: Program Security Part 1

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

Page 14: Program Security Part 1

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.

Page 15: Program Security Part 1

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.

Page 16: Program Security Part 1

1616

Language Usage StatisticsLanguage Usage Statistics

Source: http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

Page 17: Program Security Part 1

1717

ContinuedContinued

Page 18: Program Security Part 1

1818

Long Term TrendsLong Term Trends

Page 19: Program Security Part 1

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.

Page 20: Program Security Part 1

Information LeakageInformation LeakageAttacksAttacks

Page 21: Program Security Part 1

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

Page 22: Program Security Part 1

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

Page 23: Program Security Part 1

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.

Page 24: Program Security Part 1

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

Page 25: Program Security Part 1

2525

Or, Use the x/16dw Command in gdbOr, Use the x/16dw Command in gdb

Page 26: Program Security Part 1

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.

Page 27: Program Security Part 1

2727

Can We Leak More Information?Can We Leak More Information?

Page 28: Program Security Part 1

2828

Or Even More?Or Even More?

Page 29: Program Security Part 1

2929

And More Leakage!And More Leakage!

Page 30: Program Security Part 1

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.

Page 31: Program Security Part 1

Control Hijacking AttacksControl Hijacking Attacks

Page 32: Program Security Part 1

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.

Page 33: Program Security Part 1

Buffer Overflow AttacksBuffer Overflow Attacks

These are sometimes distinguished by These are sometimes distinguished by where the buffer resideswhere the buffer resides

Page 34: Program Security Part 1

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.

Page 35: Program Security Part 1

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

Page 36: Program Security Part 1

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.

Page 37: Program Security Part 1

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.

Page 38: Program Security Part 1

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.

Page 39: Program Security Part 1

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.

Page 40: Program Security Part 1

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

Page 41: Program Security Part 1

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.

Page 42: Program Security Part 1

4242

No Problem With ex2.c As 41No Problem With ex2.c As 411010= 29= 291616

Page 43: Program Security Part 1

4343

ex2a.c Runs OK - So Nothing is Overwritten ex2a.c Runs OK - So Nothing is Overwritten That Hurts the RunThat Hurts the Run

Page 44: Program Security Part 1

4444

But, For ex2b.c, Something is Corrupted As But, For ex2b.c, Something is Corrupted As the Run Crashesthe Run Crashes

Page 45: Program Security Part 1

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.

Page 46: Program Security Part 1

4646

ex3.cex3.c

23 A s OK

24 A s are not OK

Page 47: Program Security Part 1

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"

Page 48: Program Security Part 1

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

Page 49: Program Security Part 1

4949

Locate the Return Address in the FrameLocate the Return Address in the Frame

Return Address

Page 50: Program Security Part 1

5050

Examine Address and Observe It Is in mainExamine Address and Observe It Is in main

Page 51: Program Security Part 1

5151

23 A s OK23 A s OK

Page 52: Program Security Part 1

5252

24 A s Causes a Segmentation Fault24 A s Causes a Segmentation Fault

Corruption for 24 A s

Page 53: Program Security Part 1

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.

Page 54: Program Security Part 1

Stack-based OverflowsStack-based Overflows

Called "Smashing the stack"Called "Smashing the stack"

Page 55: Program Security Part 1

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.

Page 56: Program Security Part 1

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.

Page 57: Program Security Part 1

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

Page 58: Program Security Part 1

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.

Page 59: Program Security Part 1

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.

Page 60: Program Security Part 1

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.

Page 61: Program Security Part 1

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.

Page 62: Program Security Part 1

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.

Page 63: Program Security Part 1

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.

Page 64: Program Security Part 1

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.

Page 65: Program Security Part 1

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; }

Page 66: Program Security Part 1

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

Page 67: Program Security Part 1

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

Page 68: Program Security Part 1

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.

Page 69: Program Security Part 1

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.

Page 70: Program Security Part 1

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; }

Page 71: Program Security Part 1

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

Page 72: Program Security Part 1

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.

Page 73: Program Security Part 1

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.

Page 74: Program Security Part 1

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..

Page 75: Program Security Part 1

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

Page 76: Program Security Part 1

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.

Page 77: Program Security Part 1

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.

Page 78: Program Security Part 1

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.

Page 79: Program Security Part 1

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..

Page 80: Program Security Part 1

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.

Page 81: Program Security Part 1

8181

Guide To Intel x86 Register NamesGuide To Intel x86 Register Names

Slide just shows how complicated the Intel x86 register structure is.

Page 82: Program Security Part 1

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.

Page 83: Program Security Part 1

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.

Page 84: Program Security Part 1

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"

Page 85: Program Security Part 1

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.

Page 86: Program Security Part 1

8686

Simplified Example of TechniqueSimplified Example of Technique

Page 87: Program Security Part 1

8787

Example ContinuedExample Continued

Source: David Lie ECE1776

Page 88: Program Security Part 1

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

Page 89: Program Security Part 1

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

Page 90: Program Security Part 1

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

Page 91: Program Security Part 1

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

Page 92: Program Security Part 1

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

Page 93: Program Security Part 1

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!

Page 94: Program Security Part 1

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

Page 95: Program Security Part 1

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”

Page 96: Program Security Part 1

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

Page 97: Program Security Part 1

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!

Page 98: Program Security Part 1

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!

Page 99: Program Security Part 1

Non-trusted InputNon-trusted Input

Page 100: Program Security Part 1

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.

Page 101: Program Security Part 1

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"); }

Page 102: Program Security Part 1

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/

Page 103: Program Security Part 1

103103

See Input to Locate str1 and str2 in MemorySee Input to Locate str1 and str2 in Memory

str2 str1

Page 104: Program Security Part 1

104104

Now You Can See Why BADINPUT and Now You Can See Why BADINPUT and BADINPUTBADINPUT PassesBADINPUTBADINPUT Passes

str2 str1

Page 105: Program Security Part 1

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.

Page 106: Program Security Part 1

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; }

Page 107: Program Security Part 1

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.

Page 108: Program Security Part 1

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.

Page 109: Program Security Part 1

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

Page 110: Program Security Part 1

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

Page 111: Program Security Part 1

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”

Page 112: Program Security Part 1

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”

Page 113: Program Security Part 1

Structured Exception HandlingStructured Exception Handling

Page 114: Program Security Part 1

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.

Page 115: Program Security Part 1

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.

Page 116: Program Security Part 1

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.

Page 117: Program Security Part 1

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.

Page 118: Program Security Part 1

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.

Page 119: Program Security Part 1

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?

Page 120: Program Security Part 1

Off-by-one ErrorsOff-by-one Errors

Page 121: Program Security Part 1

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.

Page 122: Program Security Part 1

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.

Page 123: Program Security Part 1

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?

Page 124: Program Security Part 1

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.

Page 125: Program Security Part 1

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.

Page 126: Program Security Part 1

Heap OverflowsHeap Overflows

Page 127: Program Security Part 1

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/

Page 128: Program Security Part 1

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.

Page 129: Program Security Part 1

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

Page 130: Program Security Part 1

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.

Page 131: Program Security Part 1

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.

Page 132: Program Security Part 1

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.

Page 133: Program Security Part 1

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.

Page 134: Program Security Part 1

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.

Page 135: Program Security Part 1

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.

Page 136: Program Security Part 1

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))

Page 137: Program Security Part 1

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.

Page 138: Program Security Part 1

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.

Page 139: Program Security Part 1

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.

Page 140: Program Security Part 1

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.

Page 141: Program Security Part 1

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.

Page 142: Program Security Part 1

Function Point VulnerabilitiesFunction Point Vulnerabilities

Page 143: Program Security Part 1

143143

Function Pointer VulnerabilitiesFunction Pointer Vulnerabilities

Page 144: Program Security Part 1

Incomplete MediationIncomplete Mediation

Page 145: Program Security Part 1

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

Page 146: Program Security Part 1

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

Page 147: Program Security Part 1

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..

Page 148: Program Security Part 1

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.

Page 149: Program Security Part 1

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.

Page 150: Program Security Part 1

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?

Page 151: Program Security Part 1

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

Page 152: Program Security Part 1

Concurrency and Race Concurrency and Race ConditionsConditions

Page 153: Program Security Part 1

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)

Page 154: Program Security Part 1

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

Page 155: Program Security Part 1

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!

Page 156: Program Security Part 1

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.

Page 157: Program Security Part 1

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.

Page 158: Program Security Part 1

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.

Page 159: Program Security Part 1

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

Page 160: Program Security Part 1

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?

Page 161: Program Security Part 1

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?

Page 162: Program Security Part 1

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.

Page 163: Program Security Part 1

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.

Page 164: Program Security Part 1

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.

Page 165: Program Security Part 1

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

Page 166: Program Security Part 1

Formatted String ErrorsFormatted String Errors

Page 167: Program Security Part 1

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);

}

Page 168: Program Security Part 1

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”

Page 169: Program Security Part 1

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”

Page 170: Program Security Part 1

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

Page 171: Program Security Part 1

Integer OverflowInteger Overflow

Page 172: Program Security Part 1

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.

Page 173: Program Security Part 1

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.

Page 174: Program Security Part 1

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.

Page 175: Program Security Part 1

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.

Page 176: Program Security Part 1

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.

Page 177: Program Security Part 1

Dangers of Reusing CodeDangers of Reusing Code

Page 178: Program Security Part 1

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.

Page 179: Program Security Part 1

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.)

Page 180: Program Security Part 1

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.

Page 181: Program Security Part 1

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.

Page 182: Program Security Part 1

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.

Page 183: Program Security Part 1

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.

Page 184: Program Security Part 1

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.)

Page 185: Program Security Part 1

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!

Page 186: Program Security Part 1

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

Page 187: Program Security Part 1

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