INTRODUCTION TO
EXPLOIT
DEVELOPMENT
Nathan Ritchey and Michael Tucker
Who Am I (Nathan Ritchey)
Have Bachelors in Computer Science
Member of CSG
Working on Masters with focus on Information
Assurance
Some Interests
Who Am I (Michael Tucker)
Graduate from UTD
Member of CSG and the CTF team
Vulnerability analysis for Raytheon
Definitions
Reverse Engineering
Vulnerability Analysis
Exploitation
Reverse Engineering (RE)
A systematic methodology for analyzing the
design of an existing device or system, either as
an approach to study the design or as a
prerequisite for re-design.
Vulnerability Analysis (VA)
Vulnerability analysis, also known as
vulnerability assessment, is a process that
defines, identifies, and classifies the security
holes (vulnerabilities) in a computer, network,
or communications infrastructure.
Exploitation
“An exploit (from the verb to exploit, in the meaning of using
something to one’s own advantage) is a piece of software, a
chunk of data, or sequence of commands that takes
advantage of a bug, glitch or vulnerability in order to cause
unintended or unanticipated behavior to occur on computer
software, hardware, or something electronic (usually
computerized). Such behavior frequently includes such things
as gaining control of a computer system or allowing privilege
escalation or a denial-of-service attack.” - Wikipedia
What’s the Difference?
Reverse Engineering
The act of figuring out the design and implementation of the
system.
Vulnerability Analysis
The act of finding flaws and weaknesses in any part of said system.
Exploitation Development
The act of turning said vulnerability into an actual means of
compromising the system’s confidentiality, integrity, and/or
availability.
Hacking
Utilization of the exploit.
The Payoff
“Turning a software vulnerability into an exploit can be hard.
Google, for example, rewards security researchers for
finding vulnerabilities in its Chrome web browser. The payouts
Google make are in the range of $500 to $3000. However it
also runs competitions for security specialists to present
exploited vulnerabilities. These exploits are rewarded much
larger sums, as much as $60,000. The difference in payouts
reflects the magnitude of the task when trying to exploit
a vulnerability.”
-[Link]
Legality
It’s alright to develop, but seek legal expertise
to implement.
Are you connected to the internet?
Are you accessing a remote system?
Do you have permission to access that
system?
Look at “How to Disclose or Sell an Exploit
Without Getting in Trouble” by Jim Denaro
Illegal Examples
Sony PlayStation 3
Target
Heartland
Home Depot
Adobe
Pinball on Windows XP
First hands-on example
Reverse Engineer the Pinball game
Conduct Vulnerability Analysis
Exploit the Pinball Game
More In Depth Example
Exploitation
Memory Corruption
Buffer Overflow
Shell Code
NOP Sled
What is Memory Corruption
Memory corruption is one of the most
intractable class of programming errors, for two
reasons: The source of the memory
corruption and its manifestation may be far
apart, making it hard to correlate the cause
and the effect.
Memory Corruption
Code Injection
Where do we inject the malicious code?
How should we generate malicious code
(Shellcode)?
How should we redirect execution flow?
Memory Corruption
Redirection of execution flow
In x86, one way is to control a register called EIP,
also known as the instruction pointer register.
This register is how the x86 architecture knows
which instruction to run next.
EIP, however, is not directly controlled by the
user.
But how does one control EIP?
With a vulnerability of course!
Buffer Overflows
Any instance where a program writes
beyond the end of the allocated
memory for any buffer.
A perfect example can be shown with
strcpy() stack overflow.
gets() and read() are other examples
Stack Overflow
The Stack
0x00000000
#include <string.h>
void do_something(char *Buffer)
{
char MyVar[100];
strcpy(MyVar,Buffer);
}
int main (int argc, char **argv)
{
do_something(argv[1]);
}
0xFFFFFFF
Stack Overflow
The Stack
0x00000000
#include <string.h>
void do_something(char *Buffer)
{
char MyVar[100];
strcpy(MyVar,Buffer);
}
int main (int argc, char **argv)
{
do_something(argv[1]);
}
1st Step: Mark controlled input 0xFFFFFFF
Stack Overflow
The Stack
0x00000000
#include <string.h>
void do_something(char *Buffer)
{
char MyVar[100];
strcpy(MyVar,Buffer);
}
int main (int argc, char **argv)
{
do_something(argv[1]);
}
2nd Step: Mark Vulnerable code 0xFFFFFFF
Stack Overflow
The Stack
0x00000000
#include <string.h>
void do_something(char *Buffer)
{
char MyVar[100];
strcpy(MyVar,Buffer);
}
int main (int argc, char **argv)
{ ESP ->
do_something(argv[1]); EBP ->
}
Last Step: Analyze!
0xFFFFFFF
Stack Overflow
The Stack
0x00000000
#include <string.h>
void do_something(char *Buffer)
{
char MyVar[100];
strcpy(MyVar,Buffer);
} ESP ->
Saved EIP
int main (int argc, char **argv)
{ argv[1]
EBP ->
do_something(argv[1]);
}
0xFFFFFFF
Stack Overflow
The Stack
0x00000000
#include <string.h> ESP ->
void do_something(char *Buffer)
MyVar[100]
{
char MyVar[100];
strcpy(MyVar,Buffer); Saved EBP
}
Saved EIP
int main (int argc, char **argv)
{ argv[1]
EBP ->
do_something(argv[1]);
}
0xFFFFFFF
Stack Overflow
The Stack
0x00000000
#include <string.h> ESP ->
void do_something(char *Buffer)
AAAAAAAAAA\n
{
char MyVar[100];
strcpy(MyVar,Buffer); Saved EBP
}
Saved EIP
int main (int argc, char **argv)
{ argv[1]
EBP ->
do_something(argv[1]);
}
Case 1: Input “A” ten times 0xFFFFFFF
Stack Overflow
The Stack
0x00000000
#include <string.h> ESP ->
AAAAAAAAAA
void do_something(char *Buffer) AAAAAAAAAA
{ AAAAAAAAAA
char MyVar[100]; …
strcpy(MyVar,Buffer); AAAA(EBP)
}
Saved EIP
int main (int argc, char **argv)
{ argv[1]
EBP ->
do_something(argv[1]);
}
Case 2: Input “A” 103 times 0xFFFFFFF
Stack Overflow
The Stack
0x00000000
#include <string.h> ESP ->
AAAAAAAAAA
void do_something(char *Buffer) AAAAAAAAAA
{ AAAAAAAAAA
char MyVar[100]; …
strcpy(MyVar,Buffer); AAAA(EBP)
}
AAA\n(EIP)
int main (int argc, char **argv)
{ argv[1]
EBP ->
do_something(argv[1]);
}
Case 3: Input “A” 107 times 0xFFFFFFF
Stack Overflow
The Stack
0x00000000
#include <string.h> ESP ->
AAAAAAAAAA
void do_something(char *Buffer) AAAAAAAAAA
{ AAAAAAAAAA
char MyVar[100]; …
strcpy(MyVar,Buffer); AAAA(EBP)
}
AAA\n(EIP)
int main (int argc, char **argv)
{ argv[1]
EBP ->
do_something(argv[1]);
}
EIP Control: But now what? 0xFFFFFFF
Stack Overflow Hands-on
Desktop/Simple/Stack 2(White Box)
Desktop/Simple/Stack 1(Black Box)
How much harder is it to do without source
code?
Can you think of other ways to get control?
Shell Code(Code Injection)
Machine code used as the payload in the
exploitation of a software bug. While in a
program flow, shell code becomes its natural
continuation.
Example
Shell Code
The Stack
0x00000000
#include <string.h> ESP ->
void do_something(char *Buffer) Shell Code
{ “[Link]”
char MyVar[100];
strcpy(MyVar,Buffer); (EBP)
}
(EIP)
int main (int argc, char **argv)
{ argv[1]
EBP ->
do_something(argv[1]);
}
Change: Put Shell Code in
0xFFFFFFF
place of “A”’s
Shell Code
The Stack
0x00000000
#include <string.h> ESP ->
Shell Code
void do_something(char *Buffer) “[Link]”
{ AAAA
char MyVar[100]; …
strcpy(MyVar,Buffer); AAAA(EBP)
}
AAA\n(EIP)
int main (int argc, char **argv)
{ argv[1]
EBP ->
do_something(argv[1]);
}
Change: Put padding to
0xFFFFFFF
still cause overflow
Shell Code
The Stack
0x00000000
#include <string.h> ESP ->
Shell Code
void do_something(char *Buffer) “[Link]”
{ AAAA
char MyVar[100]; …
strcpy(MyVar,Buffer); AAAA(EBP)
}
Shell Code Location(EIP)
int main (int argc, char **argv)
{ argv[1]
EBP ->
do_something(argv[1]);
}
Modify: Change EIP to where
0xFFFFFFF
the Shell Code is
Shell Code
The Stack
0x00000000
#include <string.h> ESP ->
Shell Code
void do_something(char *Buffer) “[Link]”
{ AAAA
char MyVar[100]; …
strcpy(MyVar,Buffer); AAAA(EBP)
}
Shell Code Location(EIP)
int main (int argc, char **argv)
{ argv[1]
EBP ->
do_something(argv[1]);
}
Problem!: Why won’t this work?
0xFFFFFFF
Stack Armor
Windows has a native defense that adds
“0x00” to the front addresses in the stack.
Strcpy, will stop on any “0x00” that is comes
across because it is considered end of string.
This prevents us from just pointing to our shell
code!
Now what?
Gadgets
Gadgets are pieces of code borrowed from
the loaded program image or libraries to
circumvent the defenses.
Used heavily in “Return to libc” and “ROP/JOP”
So all we need is a simple gadget to get us
back to our Shell Code!
Gadgets
A simple gadget that we can use is “jmp esp”
Also known as a “Return to register”.
This gadget allows us to go to the top of the stack,
where our shell code just happens to be located.
So what we must do is find where a jmp esp is and then
have EIP pointed there.
How do we find such a gadget though?
[Link] from the Immunity Debugger can help us here!
!mona jmp –r esp
Shell Code with Gadget
The Stack
0x00000000
ESP ->
Shell Code
Change: Modify EIP to gadget “[Link]”
AAAA
Possibilities: Found from [Link] …
jmp esp AAAA(EBP)
call esp Gadget Location(EIP)
push esp ; ret(ROP) argv[1]
EBP ->
0xFFFFFFF
Shell Code with Gadget
The Stack
0x00000000
Success! ESP ->
Shell Code
“[Link]”
Defeat: The stack armor was AAAA
defeated using …
the gadget! AAAA(EBP)
Pwn!: The shell code is then Gadget Location(EIP)
executed argv[1]
EBP ->
0xFFFFFFF
Shell Code Hands-on
Desktop/Advanced/[Link]
Using your new knowledge of buffer overflows,
shell code, and gadgets get “[Link]” to run
by controlling [Link]
One thing to note is not all of the addresses
[Link] finds are usable, why?
How could we improve reliability of our
exploits?
NOP Sled
Easy to jump to the wrong address where shell
code is located.
The Address can change per system!
NOP (“no operation”) helps with this issue
Can jump anywhere in NOP Sled and just
slide into the malicious shell code.
In x86 this is 0x90
NOP Sled
The Stack
0x00000000
ESP ->
\x90\x90\x90\x90
Change: Add 0x90 before and Shell Code
“[Link]”
after shell code \x90\x90\x90\x90
\x90\x90\x90\x90(EBP)
Finalized exploit, with reliability! Gadget Location(EIP)
argv[1]
EBP ->
0xFFFFFFF
Preventing Stack Overflow
Stack Guard(Stack cookies)
Stack Shield
ProPolice
DEP(W XOR X)
ASLR
Easy RM to MP3 Converter
Going to use knowledge of buffer overflows in a
practical example.
Goals:
1. Figure out what files the converter can take
2. Crash the Converter using malicious input within the
files you’ve scoped.
3. Take control and execute the “[Link]” shell code!
~Hints~
1. Sometimes not all gadgets will work.
2. [Link]/Immunity is your friend, use it!
The Game of Defenses
So what does one do when there are so many
defenses in place?
Defeat them one at a time of course!
Sadly we do not have enough time to show how
to defeat all defenses, but at least there’s time
for one more.
Stack Cookie
Stack cookies are a defense in which in the
case that a buffer overflow were to occur, the
canary would trip a function call into
preventing the vulnerability from happening.
In other words, it’s like a trip-wire mechanism.
Stack Cookie
The Stack
0x00000000
ESP ->
MyVar[100]
Change: Now there’s a cookie
in the stack. \x01\x02\x03\x04(cookie)
(EBP)
What happens if we try to
overflow MyVar again? (EIP)
argv[1]
EBP ->
0xFFFFFFF
Stack Cookie
The Stack
0x00000000
ESP ->
AAAAAAAAAA
AAAAAAAAAA
Uh Oh!: We did our buffer …
overflow, but the AAAA(cookie)
cookie also got AAAA(EBP)
overwritten. AAAA(EIP)
argv[1]
EBP ->
Failed: The stack cookie will
now cause the program
to exit. 0xFFFFFFF
Stack Cookie By-Pass
So now what? The cookie has foiled our
malicious plans of running calculator!
Well it just so happens that there’s not only one
way to control the flow of code in a program.
SEH, Exception Handlers
It just so happens that below us in the stack are
exception handler chains.
Exception handlers are special subroutines
called into execution when exceptions occur
during the state of the program.
Some examples would be division by zero or
out of memory conditions.
Exception Handler Chain
The Stack
Pointer to next SEH record
Exception
*Pointer to Exception Handler
Handler1
Pointer to next SEH record
*Pointer to Exception Handler Exception
Handler2
0xFFFFFFFF
Default exception handler MSVCRT!
exhandler
Exception Handler Chain
So what is our goal? The Stack
nSEH
Well it just so Exception
happens that if you *SEH
Handler1
control *SEH, you
once again control nSEH
the flow of the Exception
*SEH
program(EIP). Handler2
But how does one 0xFFFFFFFF
do that? MSVCRT!
*EH
exhandler
With a vulnerability
of course!
Stack Cookie By-Pass
The Stack
0x00000000
ESP ->
AAAAAAAAAA
Change: Now let’s AAAAAAAAAA
add the chain to …
the stack.
AAAA(cookie)
Let’s continue our AAAA(EBP)
vulnerability by AAAA(EIP)
continuing the
overflow even argv[1]
EBP ->
further than
before.
nSEH
Exception
*SEH Handler
Stack Cookie By-Pass
The Stack
0x00000000
ESP ->
AAAAAAAAAA
Flow Hijack: We AAAAAAAAAA
now control the …
SEH’s pointer!
AAAA(cookie)
Using this we can AAAA(EBP)
now use a AAAA(EIP)
gadget to get
back to Shell AAAA
EBP ->
Code. AAAA
AAAA(nSEH)
Let’s modify our
exploit a bit. AAAA(SEH) ????
Stack Cookie By-Pass
The Stack
0x00000000
Change: We ESP ->
\x90\x90\x90
moved the shell …
code down
\x90\x90\x90\x90(cookie)
below our SEH
chain. \x90\x90\x90\x90(EBP)
\x90\x90\x90\x90(EIP)
So what kind of AAAA(argv[1])
gadget do we EBP ->
want in this case? AAAA(nSEH)
Pop reg
Well Pop Pop Ret Gadget location(SEH) Pop reg
will do! [Link] ret
Stack Cookie By-Pass
The Stack
0x00000000
Using “pop pop
ESP ->
ret” will let us \x90\x90\x90
move back to the …
nSEH in the stack. \x90\x90\x90\x90(cookie)
\x90\x90\x90\x90(EBP)
If it just so happens
that if we replace \x90\x90\x90\x90(EIP)
nSEH with “jmp AAAA(argv[1])
0x6” EBP ->
Jmp 0x6(nSEH) Pop reg
We then get to Pop reg
hop exactly six Gadget location(SEH) ret
places foward, [Link]
and run [Link]!
Final Exploit
The Stack
0x00000000
ESP ->
\x90\x90\x90
…
\x90\x90\x90\x90(cookie)
\x90\x90\x90\x90(EBP)
\x90\x90\x90\x90(EIP)
\x90\x90\x90\x90(argv[1])
EBP ->
\xeb\x06\x90\x90(nSEH) Pop reg
Pop reg
Gadget location(SEH) ret
\x90\x90\x90\x90
[Link]
DVD X Player 5.5 Pro
Stack Cookie and Armor? Oh my!
Can you get around it?
~Hints~
1. For an Exception handler to trigger you must
cause an exception in the first place.
2. [Link] has a command that may help in this
case!
Questions?
[Link] cheat sheet
Mona’s Help command:
!mona help
Create a pattern: !mona pattern_create <size>
!mona pattern_create 512
Find offset in pattern: !mona pattern_offset <hex>
!mona pattern_offset 41314132, finds the offset in the
pattern of A1A2
Find all jump based gadgets(jmp esp, push esp retrn):
!mona jmp –r esp, finds all jump gadgets for the register esp.
Find all seh gadgets(pop pop retn):
!mona seh