cnit 127: exploit development ch 16: fault injection
TRANSCRIPT
CNIT 127: Exploit Development
Ch 16: Fault Injection
Fault Injection
• Long used to verify the fault tolerance of hardware, such as– Automobile and airplane components– Coffee makers
• Faults are injected through– Pins of integrated circuits– Bursts of EMI (Electromagnetic Interference)– Altered voltage levels, etc.
QA (Quality Assurance)
• Engineers test software for weaknesses with fault injection
• Automating these tests makes their work much more efficient
• They also use manual auditing techniques– Reverse engineering– Source code auditing
Topics
• Design Overview• Fault Monitoring• Putting It Together
Design Overview
Input Generation
• Select input that uses esoteric and untested software features
• This request uses the uncommon .ida filetype– An ISAPI filter included in IIS web server
Generating Input
• Manual generation– Build inputs in a text editor– Time-consuming, but produces best results
• Automated generation– Creating fake input with a program– May waste time on buggy input
Generating Input
• Live capture– Inject faults directly into live network traffic– Requires complex adjustment of data size fields,
checksums, etc.
• Fuzz generation– Researchers noticed core dumps when using a
dial-up modem during a thunderstorm– Random data injection found many new faults
Fault Injection
• Open-source apps– Can be recompiled with special added code to
improve fuzzing– Such as American Fuzzy Lop (link Fuzz 15)
• Closed-source apps– Only input data is modified
Modification Engines
• To find buffer overflows– Inject variable-sized data to elements– Use non-alphanumeric characters to delimit
elements– Inject into elements, without altering delimiters
Defeating Input Sanitization
• Repeat existing characters instead of injecting new ones
Fault Delivery
• Nagel algorithm– Delays transmission of small datagrams so they can
be grouped together– Enabled by default in Windows– Must be disabled with NO_DELAY flag
• Link Ch 16a
Fault Monitoring
Using a Debugger
• Good for interactive fault testing• Capture every exception, if possible
– Instead of passing them to the application first ("First chance")
• Access-violation exceptions are the most important– Indicate that data structures used to read or write
to RAM were corrupted
CNIT 127: Exploit Development
Ch 17: The Art of Fuzzing
Static Analysis
• Analyzing code that is not running• Source code or binary• Many bugs found this way are unimportant in
practice– Because there is no input from the user that
"reaches" the buggy code– There's no easy way to determine the reachability
of a bug from static analysis
Fuzzing is Scalable
• An SMTP fuzzer can test any SMTP server• No need to rewrite it• Very simple strings may apply to many
protocols– Such as "../" * 5000
Weaknesses in Fuzzers
• Some parts of code won't be hit by a fuzzer– Because it requires special input values we don't
know about
• Fuzzing gets very slow if many parameters vary
• Fuzzing should be supplemented by static analysis and runtime binary analysis
SPIKE
• Builds a network packet by adding data one field at a time to a "spike" data structure
• Automatically fills in size fields, checksums, etc.
• Has various sending programs– Such as generic_send_tcp
SPIKE Functions
• s_string("Hello, world!");– Adds the literal string Hello World! to the spike
• s_string_variable("MESSAGE");– Adds a series of varying strings to the spike– The first one is MESSAGE
• s_readline();– Reads a message from the server
Very Simple SPIKE Script
• Enough to fuzz "Vulnerable Server"
X-Query (for Unix)
• Capture with WireShark
Spike Script (Partial)
CNIT 127: Exploit Development
Ch 18: Source Code Auditing
Cscope
• A source code browsing tool• Useful for large code trees,
such as the whole Linux kernel
• Many useful search functions• Links Ch 18a, 18b
Ctags
• Indexes source code• Works in many
languages– Link Ch 18c
Automated Source Code Analysis Tools
Splint
• Badly out-of date (last revised in 2007)• Output a little hard to understand
– Links Ch 18d, 18e
• Many available, specialized by language• Link Ch 18f
• Easy to use• Finds about half the obvious vulnerabilities
we've exploited
Heap Overflow
Finds Some Vulnerabilities
• But not the overflow!
Format String Vulnerability
• It doesn't find it at all!
Vulnerability Classes
Generic Logic Errors
• Requires good understanding of an application– And internal structures and classes
• Example: wildcard certificates– Pascal-based CA will sell a certificate for *\
0.evil.com– C-based browser will see it as *, a wildcard
• Link Ch 18g
(Almost) Extinct Bug Classes
• Unbounded memory copy functions– strcpy(), sprintf(), strcat(), gets(), …
• Hunted nearly to extinction
Root Cause (from Microsoft)
Bypassing ASLR & DEP
Format Strings
• Easy to find with a code audit– Although cppcheck failed
• Often found in logging code• Vulnerable only if attacker controls the format
string
Generic Incorrect Bounds-Checking
• Coder attempts to check limits, but does it incorrectly
• Example: Snort RCP Processor (2003)– Processes a series of RPC fragments– Checks each fragment to make sure it's not larger
than the buffer– But it should check the total size of all combined
fragments
Snort RCP Processor (2003)
Loop Constructs
• Coders often use intricate loops, and loops within loops
• Complex interactions can lead to insecurities• Led to a buffer overflow in Sendmail
• Link Ch 18h
Demonstration Exploit
• Link Ch 18i
Off-by-One Vulnerabilities
• Often caused by improper null-termination of strings
• Frequently found in loops or introduced by common string functions
• Can lead to arbitrary code execution
Example from Apache
• When both if statements are true– Space allocated is one byte too small– memcpy will write one null out of bounds
OpenBSD ftp Daemon
• If last character is a quote, it can be written past the bounds of the input buffer
strncat()
• Strncat always null-terminates its output string
• Will write a null byte out of bounds unless the third argument is equal to the remaining space in the buffer minus one byte
Non-Null Termination Issues
• If a string is not terminated with a null– Memory after the string is interpreted as part of
the string– May increase length of string– String writes may corrupt memory outside the
string buffer– Can lead to arbitrary code execution
strncpy()• If there's not enough space in the destination
buffer– strncpy() won't null-terminate the string it writes
• Example– strncpy won't null-terminate buffer if input is long– strcpy command is unsafe
Skipping Past Null-Termination
• String-processing loops that process more than one character at a time– Or where assumptions about string length are
made
• Can make it possible to write past end of a buffer– Possible arbitrary code execution
Example from Apache
• This line is intended to skip past :// in a URL– cp += 3
But Not All Schemes End in ://
• If the URI is ldap:a – The null byte is skipped
Signed Comparison Vulnerabilities
• Coder attempts to check input length• But uses a signed integer variable• Or two different integer types or sizes
– C sometimes converts them both to signed integers before comparing them
• Following example from Apache– Led to code execution on Windows and BSD Unix
Example from Apache
• bufsize is a signed integer– Remaining space in the buffer
• r->remaining is signed– Chunk size from the request
• len_to_read should be the smaller of the two– Negative chunk size tricks the code into performing a large
memcpy later, because it's cast to unsigned
Integer Conversions
• Link Ch 18l
• A hashed password can begin with 0e– Like 0e123dca2343f869ab478374cb358274
• PHP reads that as scientific notation– 0^123…– Always zero (link Ch 18j)
Free Login
• 1/256 passwords start with 0e• You can use any password like this to log in to
any account with a hash like that• You'll get in after 256 tries if you can predict
the hash– Or 65,536 tries if you can't
Double Free Vulnerabilities
• Freeing the same memory chunk twice• Can lead to memory corruption and arbitrary
code execution
Out-of-Scope Memory Usage Vulnerabilities
• Use of a memory region before or after it is valid
• Also called "Dangling Pointer"– Image from Wikipedia
• Link Ch 18k)
Uninitialized Variable Usage
• Static memory in the .data or .bss sections of an executable are initialized to null on program startup
• But memory on the stack or heap is not
Example
• If data is null– test is never assigned any value– But test is still freed
Exploitation
• The "uninitialized" data in test is not random• It comes from previous variables and function
calls• It may be controlled by the attacker• So the free() leads to a controllable memory
write– Arbitrary code execution
Use After Free Vulnerabilities
• Heap buffers are temporary– Released with free()
• But a program may use a pointer after free()– If there are more than one variable used to point
to the same object
• Allows an attacker to write to RAM– Possible arbitrary code execution
Multithreaded Issues and Re-Entrant Safe Code
• A global variable is used by more than one thread, without proper locking– A variable might be changed unexpectedly by
another thread
• Such issued won't appear until the server is under heavy load– May remain as intermittent software bugs that are
never verified