57

NDIS Packet of Death

Embed Size (px)

Citation preview

Page 1: NDIS Packet of Death
Page 2: NDIS Packet of Death

Windows Kernel, the final frontier Our mission: to explore strange new attack surfaces, to seek out new bugs and new 0-days. To boldly go where

(almost) no security researcher has gone before

Page 3: NDIS Packet of Death

NDIS PACKET OF DEATHTURNING WINDOWS’ COMPLEXITY AGAINST ITSELF

NITAY ARTENSTEIN CHECK POINT

Page 4: NDIS Packet of Death
Page 5: NDIS Packet of Death

AGENDA

1. INTO THE KERNEL

2. FINDING VULNERABILITIES

3. PWNAGE: CVE-2014-9383

Page 6: NDIS Packet of Death

AGENDA

1. INTO THE KERNEL

2. FINDING VULNERABILITIES

3. PWNAGE: CVE-2014-9383

Page 7: NDIS Packet of Death

USS WINTERPRISE PACKET FLOW

USERlAND

KERNEL

bridge / APPLICATION

NETWORK CARD

WINSOCK API

WINSOCK KERNEL

?

Page 8: NDIS Packet of Death

KERNEL

NETWORK CARD

MINIPORT DRIVER

FILTER DRIVER

PROTOCOL DRIVER

Page 9: NDIS Packet of Death

Filter Drivers• Handle all packets,

regardless of configuration

• Massive attack surface

• Small, easy to reverse engineer

“Being stuck in the middle is not THAT bad!”

Page 10: NDIS Packet of Death

KERNEL

NETWORK CARD

MINIPORT DRIVER

FILTER DRIVER

PROTOCOL DRIVER

SECURiTY

1. Third party code

Page 11: NDIS Packet of Death

KERNEL

NETWORK CARD

MINIPORT DRIVER

FILTER DRIVER

PROTOCOL DRIVER

SECURiTY

2. Too much complexity

Page 12: NDIS Packet of Death

NETWORK DRIVER INTERFACE SPECIFICATION

NETWORK CARD

MINIPORT DRIVER

FILTER DRIVER

PROTOCOL DRIVER

NDIS SECURiTY

3. API quality

Page 13: NDIS Packet of Death

The Windows network driver layers absolutely horrendous messes of conflicting layers of backward-compatible cruftemotional traumathe Windows network stack

🙀

Page 14: NDIS Packet of Death

Hostile Programming Environments• Bad API design

• Complicated memory management

• Inadequate documentation

• No helper functions

“They said kernel programming is good money”

Page 15: NDIS Packet of Death

NETWORK DRIVER INTERFACE SPECIFICATION

NETWORK CARD

MINIPORT DRIVER

FILTER DRIVER

PROTOCOL DRIVER

NDIS

SECURiTY

1. Third party code

2. Too much complexity

3. API quality

Page 16: NDIS Packet of Death
Page 17: NDIS Packet of Death

AGENDA

1. INTO THE KERNEL

2. FINDING VULNERABILITIES

3. PWNAGE: CVE-2014-9383

Page 18: NDIS Packet of Death

FACEOFF

GOOD EVIL

Page 19: NDIS Packet of Death

KeAcquireSpinLockRaiseToSynch KeBreakinBreakpoint KeEnterKernelDebugger KeFlushWriteBuffer KeGetBugMessageText KeRaiseIrqlToSynchLevel KeRemoveByKeyDeviceQueueIfBusy KeSetTimeUpdateNotifyRoutine IoAcquireCancelSpinLock IoAcquireRemoveLock IoAcquireRemoveLockEx IoAdjustPagingPathCount IoAllocateAdapterChannel IoAllocateController IoAllocateDriverObjectExtension IoAllocateErrorLogEntry IoAllocateIrp IoAllocateMdl IoAllocateWorkItem IoAssignArcName IoAssignResources IoAttachDevice IoAttachDeviceByPointer IoAttachDeviceToDeviceStack IoBuildAsynchronousFsdRequest IoBuildDeviceIoControlRequest IoBuildPartialMdl IoBuildSynchronousFsdRequest IoCallDriver IoCancelIrp IoCheckShareAccess IoCheckShareAccessEx IoCompleteRequest IoConnectInterrupt IoConnectInterruptEx IoCopyCurrentIrpStackLocationToNext IoCreateController IoCreateDevice IoCreateDeviceSecure […]

KERNEL API

1000+

Functions

NdisAcquireReadWriteLock NdisAcquireSpinLock NdisAdjustBufferLength NdisAllocateBuffer NdisAllocateBufferPool NdisAllocateFromBlockPool NdisAllocateFromNPagedLookasideList NdisAllocateMemory NdisAllocateMemoryWithTag NdisAllocatePacket NdisAllocatePacketPool NdisAllocatePacketPoolEx NdisAllocateSpinLock NdisAnsiStringToUnicodeString NdisBufferLength NDIS_BUFFER_LINKAGE NDIS_BUFFER_TO_SPAN_PAGES NdisBufferVirtualAddress NdisBufferVirtualAddressSafe NdisChainBufferAtBack NdisChainBufferAtFront NdisCloseConfiguration NdisCloseFile NdisCopyBuffer NdisCopyFromPacketToPacket NdisCreateBlockPool NdisDeleteNPagedLookasideList NdisDestroyBlockPool NdisDprAcquireSpinLock NdisDprAllocatePacket NdisDprFreePacket NdisDprReleaseSpinLock NdisEqualMemory NdisEqualString NdisEqualUnicodeString NdisFillMemory NdisFlushBuffer NdisFreeBuffer NdisFreeBufferPool […]

NDIS 5

500+

Functions

MiniportCheckForHangEx MiniportDevicePnPEventNotify MiniportDriverUnload MiniportInitializeEx MiniportHaltEx MiniportPause MiniportResetEx MiniportRestart MiniportSetOptions MiniportShutdownEx NdisMDeregisterMiniportDriver NdisMGetDeviceProperty NdisMNetPnPEvent NdisMPauseComplete NdisMQueryAdapterInstanceName NdisMRegisterMiniportDriver NdisMRemoveMiniport NdisMResetComplete NdisMResetMiniport NdisMRestartComplete NdisMSetMiniportAttributes NdisMAllocateSharedMemory NdisMFreeSharedMemory NdisGetPhysicalAddressHigh NdisGetPhysicalAddressLow NdisSetPhysicalAddressHigh NdisSetPhysicalAddressLow NdisGetSharedDataAlignment NdisRegisterProtocolDriver NdisDeregisterProtocolDriver NdisOpenAdapterEx NdisCompleteBindAdapterEx NdisCloseAdapterEx NdisCompleteUnbindAdapterEx NdisUnbindAdapter NdisCompleteNetPnPEvent NdisQueryAdapterInstanceName NdisQueryBindInstanceName NdisReEnumerateProtocolBindings […]

NDIS 6

500+

Functions

Page 20: NDIS Packet of Death

FIRST ATTACK: PACKET CONFUSION

GOOD EVIL

Page 21: NDIS Packet of Death

FIRST ATTACK: PACKET CONFUSION

GOOD MINIPORT DRIVER

FILTER DRIVER

PROTOCOL DRIVER

PACKET PACKET

PACKET PACKET

TASK: INTERCEPT PACKET, INSPECT CONTENTS

Page 22: NDIS Packet of Death

NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle);

NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet); NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);

// Inspect packet here

NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

FIRST ATTACK: PACKET CONFUSION

GOOD

Page 23: NDIS Packet of Death

FIRST ATTACK: PACKET CONFUSION

GOOD

[The receive function] the received data as soon as it is copiedsystem performance. Instead, the driver must

Page 24: NDIS Packet of Death

NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle);

NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet); NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);

pPersistentData.Packet = MyPacket;

QueueForLaterProcessing(pPersistentData);

NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

FIRST ATTACK: PACKET CONFUSION

GOOD

Page 25: NDIS Packet of Death

FIRST ATTACK: PACKET CONFUSION

EVIL

API DOCUMENTATION SAMPLE CODE

STACKOVERFLOW.COM SITES FROM THE 90’s

Page 26: NDIS Packet of Death

FIRST ATTACK: PACKET CONFUSION

If we need to queue this packet we will also have to copy over the per-packet information. This is because data is available only for the duration of this receive indication call

EVIL

Page 27: NDIS Packet of Death

FIRST ATTACK: PACKET CONFUSION

EVIL

PACKET

METADATA

BUFFER

PACKET

METADATA

BUFFER

PACKET

METADATA

BUFFER

ATTACKER CONTROLLED

PACKET SIZE

Page 28: NDIS Packet of Death

if (NDIS_GET_PACKET_HEADER_SIZE(Packet) BufferSize){ memcpy( Buffer, PacketBuffer, NDIS_GET_PACKET_HEADER_SIZE(Packet) );}

FIRST ATTACK: PACKET CONFUSION

GOOD EVIL

40

1337

Page 29: NDIS Packet of Death

GOOD EVIL

0 1

“Much, MUCH better than a green rubber lizard”

Page 30: NDIS Packet of Death

SECOND ATTACK: PACKET OVERWRITE

GOOD EVIL

Page 31: NDIS Packet of Death

SECOND ATTACK: PACKET OVERWRITE

GOOD

PACKET DATA

TASK: APPEND DATA TO END OF PACKET

BUFFER BUFFER BUFFER

Page 32: NDIS Packet of Death

SECOND ATTACK: PACKET OVERWRITE

GOOD

BUFFER

END OF PACKET

DATA

Page 33: NDIS Packet of Death

SECOND ATTACK: PACKET OVERWRITE

EVIL

API DOCUMENTATION SAMPLE CODE

Remove all MDLs [memory buffers] from the end of the chain, where the last byte of the MDL isn’t part of the packet buffer

Page 34: NDIS Packet of Death

SECOND ATTACK: PACKET OVERWRITE

EVIL

BUFFER

END OF PACKET

BUFFER IN USE

Page 35: NDIS Packet of Death

BUFFER

END OF PACKET

BUFFER IN USE

EVILGOOD

DATA

SECOND ATTACK: PACKET OVERWRITE

Page 36: NDIS Packet of Death

GOOD EVIL

0 2

“Thank God that hairy chests are acceptable in the 60s”

Page 37: NDIS Packet of Death

THIRD ATTACK: death by protocol

GOOD EVIL

Page 38: NDIS Packet of Death

THIRD ATTACK: death by protocol

TASK: DEFRAGMENT IPv6 PACKETS

GOOD

Page 39: NDIS Packet of Death

KeAcquireSpinLockRaiseToSynch KeBreakinBreakpoint KeEnterKernelDebugger KeFlushWriteBuffer KeGetBugMessageText KeRaiseIrqlToSynchLevel KeRemoveByKeyDeviceQueueIfBusy KeSetTimeUpdateNotifyRoutine IoAcquireCancelSpinLock IoAcquireRemoveLock IoAcquireRemoveLockEx IoAdjustPagingPathCount IoAllocateAdapterChannel IoAllocateController IoAllocateDriverObjectExtension IoAllocateErrorLogEntry IoAllocateIrp IoAllocateMdl IoAllocateWorkItem IoAssignArcName IoAssignResources IoAttachDevice IoAttachDeviceByPointer IoAttachDeviceToDeviceStack IoBuildAsynchronousFsdRequest IoBuildDeviceIoControlRequest IoBuildPartialMdl IoBuildSynchronousFsdRequest IoCallDriver IoCancelIrp IoCheckShareAccess IoCheckShareAccessEx IoCompleteRequest IoConnectInterrupt IoConnectInterruptEx IoCopyCurrentIrpStackLocationToNext IoCreateController IoCreateDevice IoCreateDeviceSecure […]

KERNEL API

1000+

Functions

NdisAcquireReadWriteLock NdisAcquireSpinLock NdisAdjustBufferLength NdisAllocateBuffer NdisAllocateBufferPool NdisAllocateFromBlockPool NdisAllocateFromNPagedLookasideList NdisAllocateMemory NdisAllocateMemoryWithTag NdisAllocatePacket NdisAllocatePacketPool NdisAllocatePacketPoolEx NdisAllocateSpinLock NdisAnsiStringToUnicodeString NdisBufferLength NDIS_BUFFER_LINKAGE NDIS_BUFFER_TO_SPAN_PAGES NdisBufferVirtualAddress NdisBufferVirtualAddressSafe NdisChainBufferAtBack NdisChainBufferAtFront NdisCloseConfiguration NdisCloseFile NdisCopyBuffer NdisCopyFromPacketToPacket NdisCreateBlockPool NdisDeleteNPagedLookasideList NdisDestroyBlockPool NdisDprAcquireSpinLock NdisDprAllocatePacket NdisDprFreePacket NdisDprReleaseSpinLock NdisEqualMemory NdisEqualString NdisEqualUnicodeString NdisFillMemory NdisFlushBuffer NdisFreeBuffer NdisFreeBufferPool […]

NDIS 6

500+

Functions

PROTOCOL HELPERS

0

Functions

“No worries Spock, I got all the RFCs in my head”

Page 40: NDIS Packet of Death

THIRD ATTACK: death by protocol

GOOD

RFC 2460 (IPv6)

RFC 790 (IPv4)

RFC 791 (IPv4)

RFC 826 (ARP)

RFC 1034 (DNS)

RFC 768 (UDP)

RFC 793 (TCP)

RFC 792 (ICMP)

Page 41: NDIS Packet of Death

GOOD EVIL

0 3

“I keep this around for when Spock is not on board”

Page 42: NDIS Packet of Death

AGENDA

1. INTO THE KERNEL

2. FINDING VULNERABILITIES

3. PWNAGE: CVE-2014-9383

Page 43: NDIS Packet of Death

PREMISE:

1. MORE COMPLEXITY == MORE BUGS

2. EDGE CASES ARE THE MOST DIFFICULT TO TEST

CONCLUSION:

LOOK FOR BUGS IN COMPLICATED AND UNCOMMON USE CASES

BUG HUNTING 101

EVIL

Page 44: NDIS Packet of Death

A Word About IPv6• Insanely complicated protocol

• Nobody’s using it

• Has isoteric features that REALLY nobody uses

• NDIS drivers still have to support those features

“Anybody order pizza?”

Page 45: NDIS Packet of Death

BONUS: YOU GET TO SET THE SIZE OF THE

EXTENSION HEADER

SECURiTY

1. Complicated!

Page 46: NDIS Packet of Death

RFC 2460

A node may use the IPv6 Fragment header to fragment the packet at the source and have it reassembled at the destination.However, is discouraged

EVIL

SECURiTY

2. Unused!

Page 47: NDIS Packet of Death

About CVE-2014-9383• RCE vulnerability in Bitdefender

NDIS filter driver

• Patched last month

• Disclaimer: No ASLR bypass (requires another vuln)

• Another disclaimer: Statistical attack, works 50% of the time

“Next time Iet me write a Linux driver”

Page 48: NDIS Packet of Death

CVE-2014-9383

EVILGOOD

PACKET

DEFRAGMENTED

PACKET

TASK: DEFRAGMENT IPv6 PACKETS

Page 49: NDIS Packet of Death

CVE-2014-9383

EVILGOOD

Buffer 1

Buffer 2

SIZE CALCULATION:

HEADERS

ARBITRARY SIZE

HDR HDR HDR HDR

OVERFLOW

MAXSIZE

Page 50: NDIS Packet of Death

CVE-2014-9383

EVILGOOD

EXPLOITABILITY

PACKET OBJECT

FUNCTION POINTERS

OVERFLOWED BUFFER

Page 51: NDIS Packet of Death

MergedPacket = ExAllocatePoolWithTag(0, MAX_HEADER_SIZE + BufSize1 + Bufsize2, ‘ TAG’);

HeaderSize = CalculateHeaderSize(Packet1);

memcpy(MergedPacket, Packet1, HeaderSize);Packet1 += HeaderSize;

memcpy(MergedPacket, Packet1, BufSize1);memcpy(MergedPacket, Packet2, BufSize2);GOOD EVIL

CVE-2014-9383

Page 52: NDIS Packet of Death
Page 53: NDIS Packet of Death

“Damn, we’ve exhausted our special effects budget on the previous memes”

Page 54: NDIS Packet of Death

Bonus: DIY with NDISaster• Identifies the main handler functions in NDIS drivers

• Generates a Windbg script for packet capture

• Incorporates the output from Windbag back to IDA

• Identifies the main functions per protocol

• Still no support for NDIS 6!

Page 55: NDIS Packet of Death
Page 56: NDIS Packet of Death

github.com/nitayart/NDISaster

QUESTIONS?

Page 57: NDIS Packet of Death

THANK YOU