You are on page 1of 76

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 shouldnt. 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 users 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
A B C D SP BP IP DI SI FLAG

code

IP

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 STOPS

00 40 20 10
00 40 20 14

00 40 20 18
00 40 20 1C

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 CD20 40 00 0C 68 45 7F

Original Address New Address

00 40 20 04
00 40 20 00

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 04 21 40 00 New Address

00 40 20 04
00 40 20 00

Confined Payload
Byte Compression Use only preloaded functions
Payload doesnt 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 NO NULL in Address OK

77 40 20 10
77 40 20 14 0D 45 68 77

77 40 20 18
77 40 20 1C

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
stack

IP DI SI FLAG

code

heap

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 doesnt execute

Use NOP (no-op) - a single byte instruction


NOP = 90

Fill buffer with NOPs


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 & DLLs 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 NULLs 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 isnt always in same place?
Dynamically loaded DLLs

PRO: some DLLs 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 DLLs 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 CRCs
makes payload smaller!

PE Header
PE OFFSET

Optional Header ASCII NAME Address

Check CRCs

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
Dont 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 DLLs 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 hoglund@ieway.com

You might also like