Wednesday, August 5, 2009

Reverse Engineering Named Pipes

Named Pipes fall under the category of Interprocess Communications. This type of communication is typically used to share data between processes on the same computer or remote computers on the local network. Named Pipes interaction model is very similar to normal sockets except the communication happens over SMB/CIFS.

Detecting the use of named pipes is made rather simple thanks to the pipelist.exe tool released by sysinternals. Here is some sample output of the tool in action:

PipeList v1.01
by Mark Russinovich
http://www.sysinternals.com

Pipe Name Instances Max Instances
--------- --------- -------------
TerminalServer\AutoReconnect 1 1
InitShutdown 2 -1
lsass 6 -1
protected_storage 2 -1
ntsvcs 4 -1
scerpc 2 -1
net\NtControlPipe1 1 1
SfcApi 2 -1
net\NtControlPipe2 1 1
net\NtControlPipe3 1 1
...


This displays the pipe name and number of instances. It also shows the user the number of max instances of the named pipe. A max instance value of -1 means the pipe can handle multiple instances simultaneously.

It is important to note that named pipes can be handled in two distinct ways when it comes to the security of those pipes. Firstly a LPSECURITY_ATTRIBUTES structure can be setup to define the security attributes of the named pipe. This influences the security restrictions put upon the named pipe and the amount of access allowed to clients interacting with the named pipe. Many times you will see the security descriptor given a NULL value which defines the default ACL (Access Control List). Additionally it is important to check if the named pipe is contained within the registry key HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/lanmanserver/parameters/NullSessionsPipes. This key is used to determine the amount of authorization required for the named pipe. If the named pipe appears in this key it will allow Null Sessions which means no authentication is required to access the named pipe.

Now we know that named pipes are in use. But we need to track them down to find out what applications created them. Luckily sysinternals comes to the rescue once again with the tool filemon. Normally people think of filemon as a way of tracking which files are read from and written to during a processes execution. This tool also provides the option to monitor processes for named pipe creation and interaction. The option is available under the Volumes menu item. With the named pipe option checked you will then see all instances of interaction or creation of named pipes. (Note: Recently filemon and regmon were combined into Process Monitor for modern Windows Operating Systems such as Windows 2000 and up. Filemon does however, still work for the processes described above.)

Now hopefully, you have discovered which applications create a specific named pipe. Here comes the fun part. Finding the location within the binary code that actually creates the named pipe and interacts with clients.

When looking through the binary code the first thing to do is inspect the imports for CreateNamedPipe(). This the function used to create the named pipe. The following MSDN link describes the function and arguments better than I ever could: http://msdn.microsoft.com/en-us/library/aa365150(VS.85).aspx

Interacting with a client is rather simple. The ReadFile API is passed an hPipe handle which is created from the CreateNamedPipe() function. This will read data from the connected client. Additionally WriteFile is used to write reply messages back to the client. As you can see this is similar to socket communications except its just using normal file system related APIs to accomplish the job. So to find the code which interacts with the client connections following the hPipe value through the code should lead you down the right path. Additionally, clients communicate with the named pipe server using the CreateFile API to establish a connection and again using ReadFile and WriteFile to communicate accordingly .

Tuesday, December 23, 2008

Uninitialized Memory Project

Recently Daniel Hodson and myself have been working extensively on a project regarding the automated discovery of uninitialized variable vulnerabilities. Daniel has been doing a ton of research into the area and I've been working on an old bug class which I discovered about a year ago which is related to the subject.

Daniel recently did a talk at Ruxcon 2008 on the topic which included some details of my bug class and went in depth about the intracacies of exploiting uninitialized memory vulnerabilities and methods which can be employed to discover them in an automated fashion.

Collaboratively we will be publishing a paper which will hopefully be included in the next issue of Phrack. Keep an eye out for updates regarding the project on this blog. I'll be posting more as we get all our research completed and the paper written.

Tuesday, November 25, 2008

Reversing COM Objects

I've been working with a specific COM object lately trying to debug a potential vulnerability in it. So I thought I would mention a little bit about reversing COM objects. COM objects utilize specific methods for creation. Typically the functions CoCreateInstance() or CoCreateInstanceEx() are used to create these objects. There are more ways to create objects such at CoGetClassObject() but I'll leave that up to you to look into a little further. The following is the MSDN description of CoCreateInstance():

STDAPI CoCreateInstance(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID * ppv
);

rclsid

[in] CLSID associated with the data and code that will be used to create the object.

pUnkOuter

[in] If NULL, indicates that the object is not being created as part of an aggregate. If non-NULL, pointer to the aggregate object's IUnknown interface (the controlling IUnknown).

dwClsContext

[in] Context in which the code that manages the newly created object will run. The values are taken from the enumeration CLSCTX.

riid

[in] Reference to the identifier of the interface to be used to communicate with the object.

ppv

[out] Address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains the requested interface pointer. Upon failure, *ppv contains NULL.

Return Values

S_OK

An instance of the specified object class was successfully created.

REGDB_E_CLASSNOTREG

A specified class is not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX enumeration is not registered or the values for the server types in the registry are corrupt.

CLASS_E_NOAGGREGATION

This class cannot be created as part of an aggregate.

E_NOINTERFACE

The specified class does not implement the requested interface, or the controlling IUnknown does not expose the requested interface.


and here is the description of CoCreateInstanceEx()


HRESULT CoCreateInstanceEx(
REFCLSID rclsid,
IUnknown * punkOuter,
DWORD dwClsCtx,
COSERVERINFO * pServerInfo,
ULONG cmq,
MULTI_QI * pResults
);

Parameters

rclsid

[in] CLSID of the object to be created.

punkOuter

[in] When non-NULL, indicates the instance is being created as part of an aggregate, and punkOuter is to be used as the new instance's controlling IUnknown. Aggregation is currently not supported cross-process or cross-machine. When instantiating an object out of process, CLASS_E_NOAGGREGATION will be returned if punkOuter is non-NULL.

dwClsCtx

[in] Values taken from the CLSCTX enumeration.

pServerInfo

[in] Information about the computer on which to instantiate the object. May be NULL, in which case the object is instantiated on the local computer or at the computer specified in the registry under the class's RemoteServerName named value, according to the interpretation of the dwClsCtx parameter. See the CLSCTX documentation for details).

cmq

[in] Number of MULTI_QI structures in pResults. Must be greater than zero.

pResults

[in] Array of MULTI_QI structures. Each structure has three members: the identifier for a requested interface (pIID), the location to return the interface pointer (pItf) and the return value of the call to QueryInterface (hr).

Return Values

This function supports the standard return value E_INVALIDARG, as well as the following:

S_OK

Indicates success.

REGDB_E_CLASSNOTREG

A specified class is not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX enumeration is not registered or the values for the server types in the registry are corrupt.

CLASS_E_NOAGGREGATION

This class cannot be created as part of an aggregate.

CO_S_NOTALLINTERFACES

At least one, but not all of the interfaces requested in the pResults array were successfully retrieved. The hr field of each of the MULTI_QI structures in pResults indicates with S_OK or E_NOINTERFACE whether the specific interface was returned.

E_NOINTERFACE

None of the interfaces requested in the pResults array were successfully retrieved.


If you see calls to these functions it will provide your first clue about the object. Firstly you will have a pointer to the CLSID in memory which can be useful in identifying what object is being created. It is possible this will be dynamic in which case the only way to really know which CLSID is being used would be using a debugger and setting a break point at CoCreateInstance() or CoCreateInstanceEx(). This information alone should give you a fair amount of details about the object. You can use oleview to look at the interfaces of the object and get an idea of what methods the object provides.

So now you know which object is being created, you know what methods it provides. How do you find the code which implements these methods? Well the first thing to know is that we are looking for a virtual function table. Another important piece of information to know is that COM objects must support the IUnknown interface. Given this information we could start looking for references into the this pointer and looking at indirect calls. I would say though that the best way would be to use runtime debugging to find the vtable. The reason being you can step through the code at creation and quickly find the vtable. This method also allows you to set breakpoints on the functions within the vtable so that you can see which methods are being used. There are definitely other ways to go about this but this is perhaps the easiest method.

Anyway, this post is getting rather long so I will give it a break for now. I may post more on this subject later on.

Saturday, November 22, 2008

IDC Scripting Reference

I've been doing a fair amount of IDC scripting lately and just thought I would mention that I found a great resource for IDC functions hosted at http://d-dome.net/idapython. The documentation is a little bit vague here and there but for the most part this is one of the best IDC references I've found. It was originally meant as a reference for idapython but the reference maps directly to the IDC scripting APIs.

So what am I working on? Right now I'm working on a simple IDC which is basically an extension of bugscam by Halvar Flake. The purpose behind it all is to find vulnerabilities in an automated way within a binary. So far I've implemented simple function searching using cross references to find all locations of where a certain function is called. Also I got some code to do some stack frame analysis on the functions which call the potentially vulnerable function. Next I plan on adding some code to find integer casting and truncation issues along with a few other features.

I'll likely release the IDC script once I've done some in depth testing. So keep an eye out.

IDA Pro Book Review



I just thought I would start out with a book review. Recently I finished reading the IDA Pro Book by Chris Eagle. Chris did an absolutely amazing job on this book. He clearly explains things even in simple terms so that even the beginners can understand the concepts he discusses through out the book. Advanced users will also benefit from reading this book. I sure did.

The book explains a lot of the undocumented features within IDA. From start to finish the book is a fun read and very informative. I learned a lot about IDA which is a tool I've been using for several years. After reading the book I feel I have a much better understanding of IDA and how it all works behind the scenes.

Several topics are covered in the book from basic usage of IDA starting with very simple examples, methods of creating signatures for statically linked libraries, dealing with structures and unions, cross references, and the book just gets progressively more in depth as you continue reading. Also, writing IDC scripts and Plugins using the IDA SDK is explained in great details with lots of useful sample code and examples.

I would definitely recommend this book to anyone who uses IDA Pro on a regular basis or plans on using it regularly. This is the best book published on the topic of IDA Pro and I've read a few others which do not even compare to the quality of this book.

First Post

Many of you may know me from my other blog (http://vulnfun.blogspot.com) which is about software vulnerabilities. Mainly that blog is related to source code auditing techniques and some of the more interesting and rarely discussed topics within that area. The purpose of this blog is going to focus on reverse engineering techniques.

On this blog I plan to release some IDC scripts and plugins. I also want to discuss some of the tactics and problem solving techniques I use while reverse engineering binaries. For the most part I only reverse Microsoft, Linux and BSD binaries so don't expect a whole lot of information regarding reversing malware although a lot of the techniques will also apply to that area.