Bufferflow

advertisement
A generic buffer overflow takes place when a buffer that has been assigned a specific storage
space contains more data than it can handle. Programs and applications are vulnerable because
boundary checks are not completely done or they are skipped completely in most cases.
Programming languages such as C are vulnerable. As some functions, such as strcat(), strcpy(),
sprint(), vsprintf(), bcopy(), gets(), and scanf(), in C language do not check for buffer size, they
can be exploited.
In this chapter, we will learn about buffer overflows, types of buffer overflows, and buffer
overflow steps. We will also learn about smashing the stack, mutating a buffer overflow exploit,
and identifying buffer overflow detection tools and buffer overflow countermeasures tools.
17.1 Understand buffer overflows (BoF)
Exam Focus: Understand buffer overflows (BoF). Objective includes:






Understand buffer overflows (BoF) and examples of buffer overflows.
Understand stack-based buffer overflow.
Know heap-based buffer overflow.
Understand stack operations.
Identify buffer overflow steps.
Analyze attacking a real program.
Buffer overflow
Buffer overflow is a condition in which an application receives more data than it is configured to
accept. It helps attackers not only to execute a malicious code on the target system, but also to
install backdoors on the target system for further attacks. Buffer overflow attacks are almost
always due to sloppy programming or poor memory management by the application developers.
A generic buffer overflow takes place when a buffer that has been assigned a specific storage
space contains more data than it can handle. Programs and applications are vulnerable because
boundary checks are not completely done or they are skipped completely in most cases.
Programming languages such as C are particularly vulnerable, since functions, such as strcat(),
strcpy(), sprint(), vsprintf(), bcopy(), gets(), and scanf(),do not check for buffer size, and can
therefore be exploited.
Types of buffer overflow
The primary types of buffer overflow are:




Stack-based buffer overflow
Format string overflow
Heap-based buffer overflow
Integer overflow
Stack-based buffer overflow
A stack is the Last in First Out (LIFO) abstract data type and data structure. It can have any
abstract data type as an element. It is like a buffer that holds all the information that is needed by
the function.
A stack-based buffer overflow attack uses a memory object known as a stack. The hacker
develops the code which reserves a specific amount of space for the stack. If the input of the user
is longer than the amount of space reserved for it within the stack, the stack will overflow. An
attacker injects malicious code on the stack and overflows the stack to overwrite the return
pointer to switch the flow of control to the malicious code.
Stack buffer overflow attacks
Buffer overflows, also known as 'smash the stack' are a favorite exploit for hackers. Both
commercial and in-house applications are susceptible to buffer overflow attacks. Here are
common ways for a stack buffer overflow attack to occur:



Overwriting a local variable that is near the buffer in memory on the stack to change the
behavior of the program which may benefit the attacker.
Overwriting the return address in a stack frame. Once the function returns, execution will
resume at the return address as specified by the attacker, usually a user input filled buffer.
Overwriting a function pointer, or exception handler, which is subsequently executed.
It is very important for developers, and QA professionals to understand how buffer overflows
work so they can plan for vulnerability testing on home-grown applications prior to deployment.
Format string overflow
A format string overflow attack is caused by the use of unfiltered user input. It can be used to
crash a program or to execute harmful code. It modifies the flow of an application by using string
formatting library features to access other memory space. Vulnerabilities occur due to the direct
use of user-supplied data as formatting string input for certain C/C++ functions. A format string
attack is related to the buffer overflow and integer overflow attacks.
Heap-based buffer overflow attack
Heap is an area of memory used by an application. Memory on the heap is dynamically allocated
by the application at run-time and typically contains program data. Exploitation is performed by
corrupting this data in specific ways to cause the application to overwrite internal structures such
as linked list pointers.
In a heap-based buffer overflow attack, an attacker overflows a buffer that is placed on the lower
part of heap, overwriting other dynamic variables, which can have unexpected and unwanted
effects.
If an application copies data without first checking whether it fits into the target destination, the
attacker could supply the application with a piece of data that is large, overwriting heap
management information. In most environments, this may allow the attacker to control over the
execution of the program.
Integer overflow
Integer overflow, or integer wrapping, is a potential problem in a program. It works upon the fact
that the value that can be held in a numeric datatype is limited by the data type's size in bytes.
When a value is placed into a data type that is too small to hold it, the high-order bits are
dropped, and only the low-order bits are stored.
How hackers exploit buffer overflow
In a nutshell, here's how hackers exploit buffer overflows
1. Determine the presence and location of buffer overflow vulnerability.
2. Write more data into the buffer than it can handle and overwrite the return address of a
function.
3. Change the execution flow to the hacker code.
Example:
An attacker assumes that a string function is exploited and sends a long string as the input. This
string causes a segmentation error by overflowing the buffer. The return pointer of the function is
overwritten, and the attacker becomes successful in changing the flow of the execution. A user
should know the exact address and size of the stack and make the return pointer point to his code
for execution if he has to insert code in the input.
Other ways to exploit code



Shellcode:is a small piece of code that is used as payload when software vulnerability is
exploited. As buffers overflow easily if the conditions match, they are considered as soft
targets for attackers. Buffer overflow shellcodes are written in assembly language. They
exploit vulnerabilities in stack and heap memory management.
No operation (NOP) sleds: There are many CPUs that have a No Operation (NOP)
instruction. Essentially, they are set of instructions that effectively do nothing at all. A
NOP-sled is the oldest and most widely known technique for successfully exploiting a
stack buffer overflow. It solves the problem of finding the exact address of the buffer by
effectively increasing the size of the target area. To do this, much larger sections of the
stack are corrupted with the HYPERLINK "http://en.wikipedia.org/wiki/No-op" \o "Noop" no-op machine instruction.
Because of the popularity of this technique, many vendors of HYPERLINK
"http://en.wikipedia.org/wiki/Intrusion_prevention_system" \o "Intrusion prevention
system" intrusion prevention systems will search for this pattern of no-op machine
instructions in an attempt to detect shellcode in use. In addition, because exploits using
this technique still must rely on some amount of luck that they will guess offsets on the
stack that are within the NOP-sled region, they have a higher risk of being detected. An
incorrect guess will usually result in the target program crashing and alert the application
or system administration team to a possible NOP attack.
Canaries: Canaries or canary words are known values that are placed between a buffer
and control data on the stack to monitor buffer overflows. When the buffer overflows, the
first data to be corrupted will be the canary, and a failed verification of the canary data is
therefore an alert of an overflow, which can then be handled, for example, by invalidating
the corrupted data.
17.2 Reasons for buffer overflow attacks, and skills required to program buffer overflow exploits
Exam Focus: Reasons for buffer overflow attacks, and skills required to program buffer overflow
exploits. Objective includes:



Examine smashing the stack.
Understand how to mutate a buffer overflow exploit.
Learn how to identify buffer overflows.
Smash the stack
Recall that a 'smash the stack' is a buffer overflow situation. On many C implementations, it is
possible to corrupt the execution stack by writing past the end of an array declared auto in a
routine. Code that does this is said to smash the stack, and can cause return from the routine to
jump to a random address. The function will then jump to whatever address is on the stack when
the function has been performed. Buffer overflow permits a user to change the return address of
a function. This almost always results in corruption of adjacent data on the stack, and in cases
where the overflow was triggered by mistake, will often cause the program to crash or operate
incorrectly.
If the affected program is running with special privileges, or accepts data from untrusted network
hosts such as a "http://en.wikipedia.org/wiki/Webserver" \o "Webserver" webserver, then the bug
is a potential security vulnerability. If the stack buffer is filled with data supplied from an
untrusted user then that user can corrupt the stack in such a way as to inject executable code into
the running program and take control of the process. Once the stack is smashed, an attacker can
create a backdoor using tools like inetd, Trivial FTP (TFTP), or Netcat in order to make raw and
interactive connections. This is one of the oldest and more reliable methods for
"http://en.wikipedia.org/wiki/Hacker_(computer_security)" \l "Classifications" \o "Hacker
(computer security)" black hat hackers to gain unauthorized access to a computer.
Reasons for buffer overflow attacks
Buffer overflow attacks depend on the lack of boundary testing and a machine that can execute a
code that resides in the data/stack segment. The lack of boundary is common and the program
usually ends with the segmentation fault or bus error. The offender must create the data to be fed
to the application to exploit buffer overflow for gaining access to or escalate privileges. Random
data will produce a segmentation fault or bus error, never a remote shell or the execution of a
command.
C library functions that cause buffer overflow attacks
C programs are critically vulnerable to buffer overflow attacks. C library functions, such as
gets(), strcpy(), strcat(), sprintf(), vsprintf(), etc. are responsible for buffer overflow in most
cases. The scanf() function can also be the reason of a buffer overflow attack.
Identifying buffer overflows
Take the following steps to identify buffer overflows:
1. Run a web server on the local machine and issue requests with long tags-all long tags end
with "$$$$$".
2. Search core dump for "$$$$$" in order to determine the overflow location if the web
server crashes.
3. Use automated tools, such as codeBlocker, eEye Retina, etc., and disassemblers and
debuggers.
4. Construct an exploit by using IDA-Pro.
Detect buffer overflows in a program
There are at least two ways to detect buffer overflows:
1. Source code: In this case, the hacker can verify the presence of boundary checks after
looking for strings declared as local variables in functions or methods. Improper use of
standard functions should be checked, especially those related to strings and input/output.
2. Feed the application with huge amounts of data and check for the abnormal behavior.
SmashGuard
SmashGuard is a hardware-based solution for stack-smashing buffer overflow. At each function
call, SmashGuard keeps a copy of the function Return Address written to the program stack in a
LIFO buffer on the CPU. Just before the function is completed, the Return Address of the
function is compared with the address at the top of the stack. If both addresses match, the
program flow continues without any interruption. However, if both addresses do not match each
other, an error is displayed.
Skills required to program buffer overflow exploits
The following skills are required to program buffer overflow attacks:





Understanding of stack and heap memory processes
Understanding of the working of system calls at the machine code level
Understanding of assembly and machine language
Understanding of C and Perl programming language
Understanding of compiling and debugging tools such as gdb
Testing for format string conditions
Format string vulnerabilities manifest in the Web server, application servers, Web application
using C/C++ based code, and CGI scripts written in C. Input parameters are manipulated by an
attacker to include %x or %n. The attacker checks instances of code (assembly fragments) to
identify the presence of a format string vulnerability. The address of a format type specifier
being pushed on the stack is clearly visible before a call to print is made when the disassembly is
examined using IDA Pro.
17.3 Testing for heap overflow conditions: heap.exe, and understand OllyDbg debugger
Exam Focus: Testing for heap overflow conditions: heap.exe, and understand OllyDbg debugger.
Objective includes:




Test for heap overflow conditions: heap.exe.
Understand steps for testing stack overflow in OllyDbg debugger.
Identify buffer overflow detection tools.
Understand defense against buffer overflows.
Testing for heap overflow conditions
The variants of the heap overflow (heap corruption) vulnerability including those that permit
overwriting function pointers and exploit memory management structures for arbitrary code
execution are identified. Longer input strings than expected are supplied to test for heap
overflows. When debugging a windows program, a heap overflow can appear in several different
forms. The most common one being a pointer exchange taking place after the heap management
routine comes into action.
Testing a stack overflow in OllyDbg debugger
To test a stack overflow in OllyDbg debugger:
1. Attach a debugger to the target application or process, and generate malformed input for
the application.
2. Subject the application to malformed input, and inspect responses in a debugger.
For example, an attacker can take the following steps to overwrite the instruction pointer and
control program execution:
1. Test "sample.exe" for stack overflow.
2. Launch "sample.exe" in a debugger. A large sequence of characters such as "A" can be
provided in the argument field.
3. Open the executable with the supplied arguments and continue execution. EIP contains
the value "41414141". The value represents the hexadecimal "AAAA".
BoF detection tools


BOU (Buffer Overflow Utility): An attacker can use the BOU tool to test Web apps for
buffer overflow conditions. The tool requires to input the "request" file that is to be tested
and how much of the code that should be attacked. The tool takes a request file to be
tested and outputs all of the activity to STDOUT depending on the level of verbosity
specified.
Flawfinder: Flawfinder is a buffer overflow detection tool written in Python by David
Wheeler. It uses a built-in database for C/C++ functions that are vulnerable to buffer
overflow attacks. Flawfinder is used to check vulnerabilities for buffer overflow risks as




well as format string problems, race conditions, potential shell metacharacter, and poor
random number acquisition.
OllyDbg: OllyDbg is a 32-bit assembler level debugger for Microsoft Windows, which is
used to debug a stack overflow attack. It is used to debug multithread applications. It can
be attached to running programs and configurable disassembler. It is used to If you are
running OllyDbg on Windows Vista or above, you will need to ensure that you run it
using the "Run as Administrator" option, available when you right-click on the
executable or shortcut. If you don't run the program with Administrative privileges, you
won't be able to properly perform your debugging tasks.
RATS (Rough Auditing Tool for Security): RATS (Rough Auditing Tools for
Security) is a buffer overflow detection tool that is used to find out potentially dangerous
function calls. It is used to differentiate between heap- and stack-allocated buffers. RATS
can be used in C, C++, Python, Perl, and PHP programming languages.
ITS4: ITS4 is a buffer overflow detection tool developed by Cigital to check C/C++
code. It is a command-line tool that is used to check for potentially dangerous function
calls. ITS4 also generates a report describing potential problems and providing possible
suggestions. It also checks Time-of-Check-Time-of-Use problems.
BufferShield: is used to detect and prevent the exploitation of buffer overflows. It is
used to detect code execution on the stack, default heap, dynamic heap, virtual memory,
and data segments.
Tools that can prevent buffer overflow vulnerabilities:


Data Execution Prevention (DEP): is a security feature included in Microsoft Windows
operating systems, which is intended to prevent an application or service from executing
code from a non-executable memory region. This helps prevent certain exploits that store
code via a buffer overflow; for example, DEP runs in two modes: hardware-enforced
DEP for CPUs that can mark memory pages as non-executable, and software-enforced
DEP with a limited prevention for CPUs that do not have hardware support. Softwareenforced DEP does not protect from execution of code in data pages, but instead from
another type of attack (SEH overwrite).
Enhanced Mitigation Experience Toolkit (EMET): is used so that it becomes more
difficult for an attacker to exploit the vulnerabilities of software and access the system. It
supports mitigation techniques that prevent common attack techniques that primarily
relate to stack overflow and involve use of malware for interacting with operating
systems.
Defense against buffer overflows
The following serve as defense against buffer overflows:




Performing manual auditing of the code
Using compiler techniques
Using safer C library support
Disabling stack execution
Preventing BoF attacks
The following measures are taken to prevent BoF attacks:






Using type safe languages such as Java and ML
Implementing run-time checking
Using address obfuscation
Randomizing location of functions in libc
Performing static source code analysis
Marking stack as non-execute, random stack location
Programming countermeasures
The following are programming countermeasures:













Programs should be designed with security in mind.
Stack execution should be disabled.
The code should be tested and debugged in order to find errors.
The use of dangerous functions, such as gets, strcpy, etc. should be prevented.
Using "safer" compilers such as StackGuard should be considered.
Return addresses should be prevented from being overwritten.
Arguments should be validated and the amount of code that runs with the root privilege
should be reduced.
All sensitive information should be prevented from being overwritten.
Static or dynamic source code analyzers should be used at the source code level in order
to check the code for the overflow problems.
The compiler should be changed at the compiler level. The compiler level bounds
checking or protects addresses from overwriting.
The rules should be changed at the operating system level for which memory pages are
permitted to hold executable data.
Safe libraries should be used.
Tools that can detect buffer overflow vulnerabilities should be used.
17.4 Understand buffer overflow countermeasures tools and buffer overflow pen testing
Exam Focus: Understand buffer overflow countermeasures tools and buffer overflow pen testing.
Objective includes:


Identify buffer overflow countermeasures tools.
Understand buffer overflow pen testing.
Countermeasures against buffer overflow
The countermeasures against buffer overflow are as follows:

Perform manual auditing of the code.




Stack execution should be disabled.
Take the support of the functions which are not the cause of the buffer overflow.
Take compiler support. For example, Java automatically checks if an array index is
within the proper bounds. Use compilers, such as Java instead of C to avoid buffer
overflow attacks.
Use tools, such as StackGuard and Immunix System to avoid buffer overflows.
Countermeasures against IIS buffer overflow attacks
A network administrator should take the following steps to protect a Web server from IIS buffer
overflow attacks:





Conduct frequent scans for server vulnerabilities.
Install the upgrades of Microsoft service packs.
Implement effective firewalls.
Apply URLScan and IISLockdown utilities.
Remove the IPP printing capability.
Buffer overflow pen testing
A buffer overflow takes place when a program tries to store more data in a static buffer than
intended. The additional data overwrites and corrupts adjacent blocks of memory, and can allow
an attacker to take control of the flow of execution and inject arbitrary instructions. Overflow
vulnerabilities are more commonly found in applications developed in the C/C++ language;
newer languages, such as C# provide additional stack protection for the careless developer.
Recent examples of overflows in web applications include mnoGoSearch and Oracle E-Business
Suite.
Buffer overflows can often be located through black-box testing by feeding increasingly larger
values into form inputs, header and cookie fields. In the case of ISAPI applications, a 500 error
message (or time-out) in response to a large input may indicate a segmentation fault at the server
side. The environment should first be fingerprinted to determine if the development language is
prone to overflow attacks as overflows are more common to compiled executable files than
scripted applications. Note that most of the popular web development languages (Java, PHP,
Perl, Python) are interpreted languages in which the interpreter handles all memory allocation.
Format string attacks occur when certain C functions process inputs containing formatting
characters (%). The printf/fprint/sprintf, syslog() and setproctitle() functions are known to
misbehave when dealing with formatting characters. In some cases, format string bugs can lead
to an attacker gaining control over the flow of execution of a program.
Skills of a penetration tester
The following are skills of a penetration tester:


Understand working of a buffer overflow attack.
Understand memory management in various operating environments.


Understand programming languages.
Proficiently run debuggers, disassemblers, and fuzzers.
Steps for buffer overflow penetration testing
The following steps are taken for buffer overflow penetration testing:
1. Search for call to insecure library functions that may result in buffer overflow if not used
properly.
2. Use tools such as RATS and Flawfinder to perform static code analysis.
3. Use disassemblers such as IDA Pro and OllyDbg to reverse engineer the application.
These tools are required to analyze code of compiled software to recognize buffer
overflow condition.
4. Identify the buffer overflow condition by attaching a debugger to the target application,
supplying a large input data, and inspecting responses in a debugger.
5. Repeat the last step with different inputs of variable length.
6. Supply format type specifiers such as %x or %s in the input.
7. Use fuzzing techniques that gives invalid, unexpected, or random data to the application
inputs and observing application behavior.
8. Use fuzzing tools such as Spike and Brute Force Binary Tester (BFB) for automated
fuzzing testing.
Chapter Summary
In this chapter, we learned about buffer overflows, types of buffer overflow, and buffer overflow
steps. This chapter focused on smashing the stack, mutating a buffer overflow exploit, and
identifying buffer overflow detection tools and buffer overflow countermeasures tools.
Glossary
BoF
Buffer Overflows
Buffer overflow
Buffer overflow is a condition in which an application receives more data than it is configured to
accept.
BufferShield
BufferShield is used to detect and prevent the exploitation of buffer overflows.
Flawfinder
Flawfinder is a buffer overflow detection tool written in Python by David Wheeler. It uses a
built-in database for C/C++ functions that are vulnerable to buffer overflow attacks.
Format string overflow attack
A format string overflow attack is caused by the use of an unfiltered user input. It can be used to
crash a program or to execute harmful code.
Heap
Heap is an area of memory used by an application. It is assigned dynamically at the run time
with functions, such as malloc().
ITS4
ITS4 is a buffer overflow detection tool developed by Cigital to check C/C++ code. It is a
command-line tool that is used to check for potentially dangerous function calls.
.
OllyDbg
OllyDbg is a 32-bit assembler level debugger for Microsoft Windows, which is used to debug a
stack overflow attack. It is used to debug multithread applications.
OllyDbg
32-bit assembler level debugger for Microsoft Windows
RATS
RATS (Rough Auditing Tools for Security) is a buffer overflow detection tool that is used to find
out potentially dangerous function calls.
Shellcode
Shellcode is a small piece of code that is used as payload when software vulnerability is
exploited.
Download