TheGreenBow IPSec VPN Client tgbvpn.sys patch released

September 14, 2009

Redirection:

http://evilcodecave.blogspot.com/2009/09/thegreenbow-ipsec-vpn-client-tgbvpnsys.html


On USB Coding #5

November 17, 2007

Hi,

In the previous post We talked about the general foundamentals of USB Coding, many other thing should be said, for example about Power Management, but this will became a commentary upon USB_WDF.doc provided by Microsoft, our scope is a general overview of USB Coding and related USB Security/Forensics.

USB Security can be divided into two parts:

1) Intrusion Risk Security of USB Device Drivers
2) Forensics of USB Secure Devices

As you have seen USB Data Transactions does not have any kind of Encryption or Anti-Sniff protection by Default. Actually USB devices are extremely diffused,
these devs are applied in every kind of periferials, also in Secure Devices such as Fingerprint, Hardware Protectors, Sensitive Data Auth Devices and many many i
mportant as you know Usb is spreaded also for Mass Storage Devices. And where there are large collection of data born the problem of Sensitive Information Protection
and consequently we have to consider the Forensics Attacks that could be performed.

Around here you can download many USB-Tracers / UsbSniffers, such as Usbtrace and SnoopyPro, which sets an UsbFilter Driver and are make you able dump the entire code transaction. Let’s take a look at the general architecture..

Every Device Sniffer is based upon Data Filtering, because we need obviously to have a Dynamic Capture System, so he only way is to dispose a Filter Driver, this is the case of our USB Sniffer.

So we need to provide a Filter PNP Filter Driver, this kind of driver can be coded in two different ways, the Classical one without using any Framework, or by using KMDF, which is more easy and fast to code (just you have to provide WdfFdoInitSetFilter during EvtDeviceAdd Event)

We will follow the first “old school” way.

As every Filter Driver we the skeleton is based on a DeviceEntry, Device Adding, Dispatching and Unloading, so let’s view in detail each one of them.

NTSTATUS DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)

in this nothing special, but inside the Method we have to provide, an IRP stack filtering context, that can be stored into an lookaside list

ExInitializeNPagedLookasideList(
&g_ContextLookasideList, NULL, NULL, 0, sizeof(IRP_STACK_CONTEXT),
IRP_STACK_CONTEXT_TAG, 0 );

After defining our context, as usual there is the Dispatch Procedure creation, in the particular case of a PNP Filter are used:

DriverObject->MajorFunction[IRP_MJ_PNP] = FilterDispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = FilterDispatchPower;
DriverObject->DriverExtension->AddDevice = FilterAddDevice;

Cause the presence of multiple DeviceObject, is also necessary a Mutex, to synchronize all threads:

ExInitializeFastMutex(&ControlMutex);

Now is time to Add our Filter, so let’s study FilterAddDevice:

NTSTATUS
FilterAddDevice(
PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT PhysicalDeviceObject
)
At this point we are dealing directly with the PnP system, we need to determine if we need to be in the driver stack for the device, and next we have to initialize this device object.

{

PDEVICE_EXTENSION deviceExtension;
ULONG deviceType = FILE_DEVICE_UNKNOWN;

deviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
deviceType = deviceObject->DeviceType;
ObDereferenceObject(deviceObject);

This because windows check if the filter attached to a storage device doesn’t specify the same DeviceType as the device that’s attempts to attach to it.

Now we can attach our Filter

IoCreateDevice (DriverObject,
sizeof (DEVICE_EXTENSION),
NULL, // No Name
deviceType,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&deviceObject);

Jump in the stack:

deviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack (deviceObject, PhysicalDeviceObject);

this is to define the supported I/O of our driver

deviceObject->Flags |= deviceExtension->LowerDeviceObject->Flags &
(DO_BUFFERED_IO | DO_DIRECT_IO |
DO_POWER_PAGABLE );

Device properties can be retrieved by calling

IoGetDeviceProperty(PhysicalDeviceObject,
DevicePropertyPhysicalDeviceObjectName, 0,
NULL, &nameLength);

Essentially we need a copy (slighty modified) of Next Lower Device’s Driver Object (FDO) so all transactions will pass also on our device. These are the modifications

deviceExtension->ModifiedLowerDriverObject.MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = FdoHookDispatchInternalIoctl;
deviceExtension->ModifiedLowerDriverObject.MajorFunction[IRP_MJ_PNP] = FdoHookDispatchPnp;

and next we save our copy

InterlockedExchangePointer(
(PVOID * )&( (deviceExtension->LowerDeviceObject)->DriverObject ),
&deviceExtension->ModifiedLowerDriverObject
);

Now we can grab all IRPs with FilterDispatchAny

NTSTATUS
FilterDispatchAny (
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)

PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

if (irpStack->MajorFunction == IRP_MJ_PNP)
{
const char * MinorFunctionName = PnPMinorFunctionString(irpStack->MinorFunction);
if (MinorFunctionName != NULL)
LogTheCapturedIrp();

it’s important to remember that this is only a filter, so we don’t need to know ALL about data transactions, so unknown IRPs are delivered untouched.

NTSTATUS
FilterDispatchPnp (
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)

if( irpStack->MinorFunction == IRP_MN_QUERY_INTERFACE )
{
if( IsEqualGUIDAligned(
*irpStack->Parameters.QueryInterface.InterfaceType,
USB_BUS_INTERFACE_HUB_GUID
)
)
LogTheCapturedIrp();

with USB_BUS_INTERFACE_HUB_GUID we obtain the interface for USB Hub drivers

In the next post we will see the final part of the Filter Driver.

See you to the next post.. 🙂