Advanced Buffer Overflow Technique Greg Hoglund

Advanced Buffer Overflow
Technique
Greg Hoglund
Attack Theory
•
•
•
•
•
Formalize the Attack Method
Re-Use of Attack Code
Separate the Deployment from the Payload
Payloads can be chosen for desired effect
Details and Restraints of both Payload and
Deployment code
Exploits
• A “BUG” in Software
• New bugs reported every day
• automated testing tools
– USSR Labs
• “Exploit” is code that takes advantage of a
bug in order to cause an effect
What can happen?
• Machine Crash
• kernel exception
• VIP process
•
•
•
•
•
Application Crash (most common)
Recoverable Exception
Mobile Code (deadly)
File Access (read or write)
Denial of Service
Exploits can be grouped
• Some bugs are all the same
• Some bugs keep coming back
–
–
–
–
improper filtering
bounds checking
bad authentication
impersonation
• In other words, need better testing
Entry -vs- Effect
• The attack payload is not the same as the
entry point
• Missle -vs- Warhead analogy
• The Delivery Mechanism can be decoupled
from the Payload
Exploits come in 2 parts
• Injection Vector (deployment)
– the actual entry-point, usually tied explicity
with the bug itself
• Payload (deployed)
– usually not tied to bug at all - limited only by
imagination. Some restraints.
Injection Vector
•
•
•
•
•
Target Dependant
OS Dependant
Application Version Dependant
Protocol Dependant
Encoding Dependant
Payload
• Independent of Injection Vector
• Still Depends on Machine, Processor, etc.
• With some exceptions
• Mobile Code, Just like a Virus
• Once established, can spread by any means
– trust
– scanning for more bugs
Payload
• Denial of Service
– use as launching point (arp spoofing)
• Remote Shell (common)
– covert channel or ‘netcat’ like
• Worm/Virus
– extremely dangerous
• Rootkit (common - stealth)
Injector/Payload Pairs
• One injector works on ‘n qualified hosts’
• Example - IIS Injector works on ~20% of
Web Hosts.
• Payload
– Remote Shell for control
– Shutdown Machine
– Shutdown ALL Machines on subnet
Types of Injection
• Content Based
– characters inserted into a data stream that result
in the remote process doing something it
shouldn’t. Process is still in control.
• Buffer Overflow
– poor programming practice subverts
architecture of code execution. Process loses
control.
Types of Injection
• Trust Based
–
–
–
–
Boot virus/ Floppy/ CD (parasite process)
MACRO virus
Email Attachments (Melissa, etc)
Web Browsing (exploit user’s trust, etc)
• click thru
Governments write Injector
Code?
• 1995 US Defense Intelligence Agency
Report
– Cuban Military targets US w/ custom virii
• University of Havana, team of less than 20 computer
experts
– Russian KGB
• prior to 1991 coup attempt, KGB has virii intended
to shut down US computers in times of war
Mobile code in Global 2000?
• 1995 E&Y report
– 67% of companies hit bit virus
• 1996 E&Y report
– 63% of companies hit by virus
• 1996 UK Information Security Breaches
Survey
– 51% of companies hit by virus
How hard can it hit?
• NCSA 1997 report
– 33% of all machines infected with virus
– average cost of recovery ~$8000 US dollars
• November 1988 Morris Worm
– strikes ~6,000 computers (10% of Internet at
time) within hours
– spreads via Buffer Overflow in fingerd
– spreads via Sendmail exploit
How hard can it hit?
• 1989, “WANK” Worm
– Hits NASA Goddard Space Center
– spreads to US DOE High Energy Physics
network (HEPNET)
– 2 weeks to clean all systems
Buffer Overflow Injection
• Overflow the Stack
• Overflow the Heap
• Goal: Must control the value of the
instruction pointer (processor specific)
• Goal: Get the Instruction Pointer to point to
a user-controlled buffer.
Challenges
• Injector/Payload size restrictions
– tight coding requirements
• Injector and Payload in same buffer
– cannot step on each other
• Guessing Address Values
– sometimes called ‘offsets’
• NULL characters, BAD characters
– use encoding and stack tricks
Stack Injection
• Stack is used for execution housekeeping as
well as buffer storage.
• Stack-based buffer must be filled in
direction of housekeeping data.
• Must overwrite the housekeeping data
Address Housekeeping
•IP
•A
•B
•C
•D
•SP
•BP
•IP
•DI
•SI
•FLAG
•code
•heap
•stack
Stack Overflow
00 40 20 08
00 40 20 0C
00 40 20 10
00 40 20 14
00 40 20 18
00 40 20 1C
The Problem with NULL
00 40 20 08
00 40 20 0C
00 40 20 10
00 40 20 14
00 40 20 18
00 40 20 1C
•STOPS
NULL must be PAST
housekeeping data
00 40 20 08
00 40 20 0C
00 40 20 10
00 40 20 14
00 40 20 18
00 40 20 1C
•OK
Little and Big Endian
• On Intel x86 (Little Endian), Values are
stored ‘backwards’ - least significant byte
goes first:
• 00 40 10 FF is stored as:
FF 10 40 00
We store address in housekeeping
data
00 40 21 04
00 40 21 00
00 40 20 0C
00 40 20 08
00 40 20 04
00 40 20 00
CD
6840
4500
7F
0C 20
Original
Address
New Address
Injection is Complete
• We control the instruction pointer
04 21 40 00
New Address
Where to put the payload
00 40 21 04
00 40 21 00
00 40 20 0C
00 40 20 08
00 40 20 04
00 40 20 00
04 21 40 00
New Address
Confined Payload
• Byte Compression
• Use only preloaded functions
– Payload doesn’t need to build jumptables
– Useable functions must be loaded
• Use Hardcoded addresses
– Payload designed for a specific process with
predictable features
• Data portion of payload needs to be small
Using more stack for payload
77 40 20 08
77 40 20 0C
77 40 20 10
77 40 20 14
77 40 20 18
77 40 20 1C
0D 45 68 77
NO NULL in
Address
•OK
Much Larger Payload
When does the address contain a
NULL character
• Lowland Address - starts with 00
– stack is in lowland on Windows NT
• usually 00 40 XX XX
– limits size of payload
• Highland Address - no zeros in address
– stack is in highland under Linux
– unlimited payload size
Large payload, Lowland address
• We cannot use a lowland address directly,
because it limits our payload
• We can use a CPU register
• We can use stack values that remain
undamaged
A register points to the stack
•A
•B
•C
•D
•SP
•BP
•IP
•DI
•SI
•FLAG
•code
•heap
•stack
Call thru a Register
• Call eax, call ebx, etc
–
–
–
–
FF D0 = call eax
FF D3 = call ebx
FF D1 = call ecx
etc, etc
Push a register then return
• Push register
– push eax = 50
– push ebx = 53
– etc
• Then RET
– RET = C3
Guessing where to go
• We jump to the wrong address
– crashes software
– payload doesn’t execute
• Use NOP (no-op) - a single byte instruction
– NOP = 90
• Fill buffer with NOP’s
– “NOP Sled”
NOP Sled
•End up at payload
Inject the Payload into the HEAP
• When the stack is limited in size
• Store part on the payload on stack, the other
on the heap
• Protocol Headers
– HTTP headers
• Recent Transactions
• Open Files
Execute code on the heap
•A
•B
•C
•D
•SP
•BP
•stack
•IP
•DI
•SI
•FLAG
•code
•heap
Trespassing the HEAP
• Two C++ objects near one another
• Any buffer that can overwrite a pointer
– function pointer
– string pointer (alter behavior w/o mobile code)
Overwrite the VTABLE
• C++ objects have a virtual function table
•Vtable pointer
•Member variables
grow away from
vtable pointer (NT)
Overwrite VTABLE
• Must have 2 C++ Objects (on heap)
•Overwrite vtable ptr
Where do I make the VTABLE
point?
Your own VTABLE
• The VTABLE has addresses for all virtual
functions in the class. This usually includes
a destructor - which will be called when the
object is destroyed (deallocated from
memory)
• Overwrite any function that works
Injection is complete
• Kernel level overflows all over in NT
• Off by one errors causing frame pointer
overwrite
• Multi-stage attacks where you must first get
the target into a state before attempting
overflow
• The effects of URL or MIME encoding
Now for the Payload
•
•
•
•
Using Loaded Functions
Encoding our own data
Loading new functions & DLL’s
Making a shell
The Payload
•NOP Sled
•Real Code
•DATA
Getting Bearings
– Call RELOC:
– RELOC: pop edi
• EB 00 00 00 00
– edi now has our code address
– we can use this as an offset to our data
Reverse Short Call
• NO NULL Bytes
– RELOC: jmp RELOC2
– Call RELOC:
– RELOC2: pop edi
• EB FF FF FF FE
XOR Protection
• Cannot have NULL’s in data portion
•XOR every
BYTE
XOR again to decode
•Begin decode
Hardcoded Function Calls
•code
Pros/Cons to hard coding
• PRO: makes code smaller
• CON: what if function isn’t always in same
place?
– Dynamically loaded DLL’s
• PRO: some DLL’s are *usually* always in
the same place
– KERNEL32.DLL
Dynamic Function Loading
• Use LoadLibrary() and GetProcAddress()
– usually always in same place
– hard coding usually works
• Load New DLL’s
• Find any function by ASCII name
– handy
Load Function by Name
•getprocaddress
•Function name
stored here
Build a jumptable
•getprocaddress
Use Jumptable
HASH Loading (el8)
• Process already has ASCII names of all
loaded functions stored in process-header
• We can locate any loaded function by
checking the CRC of each loaded ASCII
name
• We do not need to store function names in
our DATA section - only CRC’s
– makes payload smaller!
PE Header
•PE OFFSET
•Optional Header
•ASCII NAME
•Address
Check CRC’s
•CRC
Limited Character Set means
Limited Instruction Set
• Payload is filtered
– MIME
– URL
• alphanumeric only (email headers)
– short jumps (difficult to maintain)
– pop/push
– subtract
The Bridge
•Avoids jump
instruction
•size must be
calculated exactly
Load New DLL
WININET.DLL
• Use DLL functions
– InternetOpenURL()
– InternetReadFile()
•
•
•
•
Does all the hard work
Makes payload smaller
Download and Execute any file, anywhere
File stored anonymously - hard to trace
WS2_32.DLL
•
•
•
•
•
•
Socket
bind
listen
send
recv
accept
Interrupt Calls
• Don’t require addresses
• Small
• Easy to use
–
–
–
–
–
Load register with call number
Load register with argument pointer
interrupt (2 bytes long)
CD 2E (interrupt 2E)
CD 80 (interrupt 80)
Remote Command Shell
• Spawn a process
– CreateProcessA (kernel32 function)
– INT 80 (linux) (execve syscall)
• Pipe the output thru socket
– Named pipes (~5 functions)
– Connect in or out over any TCP socket
Covert Channel
• If exploited process is root or SYSTEM
– TDI or NDIS hook
– session over ACK packets or ICMP
• IIS
– Patch any point where URL requests are
handled
– no kernel required
WORMS
• Payload searches for new hosts to attack
• Trust Exploitation
–
–
–
–
sniff passwords on wire
SMB sessions to other NT hosts
NT Registry Alteration
NFS/Drive Sharing
• Consider survivability of Payload
– what % of hosts are eligible?
Lysine Deficiency
•
•
•
•
Worm will die if certain condition is not met
Existance of File
Existance of Network Entity
Floppy in floppy drive (testing lab)
RECAP
• Injection is not the same as payload
• Payloads can perform
–
–
–
–
Denial of Service
WORM
Remote Shell
Rootkit
RECAP
• Injection has many challenges
–
–
–
–
NULL characters
Stack size
Highland/Lowland address
Calling thru CPU registers
RECAP
• Filters limit what we can use in a payload
• Limited OP-CODE sets can still be used to
build fully functional programs
RECAP
•
•
•
•
Our payload is encoded
We can build jumptables
We can load new DLL’s and Functions
We can hard-code addresses or load them
dynamically
• We can use Lysine Deficiency to keep
Worms from spreading uncontrolled
Thank You
Your mind is your primary weapon
http://www.rootkit.com
[email protected]