SlideShare a Scribd company logo
Eternal ExploitsReverse Engineering of FuzzBunch and MS17-010
zerosum0x0
August 1983
Warning!
Presentation may contain classified information.
Those with active security clearances are forewarned.
TOP SECRET//SI/TK//NOFORN//ICATION//4201337//REL TO DEF CON
Spot The Fed
Champ 2018
Agenda
● Recap (~2 mins)
○ Equation Group (NSA)
○ Shadow Brokers
● SMBv1 Internals (~5 mins)
○ Network packets
○ Driver structures
● Exploits (~40 mins)
○ Blue
○ Champion
○ Romance
○ Synergy
● Payloads (~10 mins)
○ DoublePulsar
○ DarkPulsar
○ DanderSpritz
SMBv1 Internals
SMB Background
● Server Message Block
● 1983 - Invented by Barry Feigenbaum (IBM)
○ Also, NetBIOS
● Used EXTENSIVELY by Windows
○ "LanMan"
○ File Shares
● Extensible protocol
○ Transport for DCE/RPC
■ psexec
Server Message Block (v1)
● Header Block
○ Command
○ Flags (request/reply, unicode)
○ Errno
○ Signature
○ UID/TID/PID/MID
Server Message Block (v1)
● Header Block
○ Command
○ Flags (request/reply, unicode)
○ Errno
○ Signature
○ UID/TID/PID/MID
● Parameter Block
○ Contains a struct specific to the command
■ Fixed size WORD count
Server Message Block (v1)
● Header Block
○ Command
○ Flags (request/reply, unicode)
○ Errno
○ Signature
○ UID/TID/PID/MID
● Parameter Block
○ Contains a struct specific to the command
■ Fixed size WORD count
● Data Block
○ Misc. arbitrary info for the command
■ Variable size BYTE count
SMBv1 Dialects
● PC NETWORK PROGRAM 1.0
● MICROSOFT NETWORKS 1.03
● MICROSOFT NETWORKS 3.0
● LANMAN1.0
● Windows for Workgroups 3.1a
● LM1.2X002
● LANMAN2.1
● NT LM 0.12
● Cairo
Srv.sys - SMBv1
● SrvWorkQueues
● SrvBlockingWorkQueues
○ Any operation that may take awhile
■ SMB is designed for speed
Srv.sys - SMBv1
● SrvWorkQueues
● SrvBlockingWorkQueues
○ Any operation that may take awhile
■ SMB is designed for speed
● WORK_CONTEXT
○ C union mega-struct SMB info
Srv.sys - SMBv1
● SrvWorkQueues
● SrvBlockingWorkQueues
○ Any operation that may take awhile
■ SMB is designed for speed
● WORK_CONTEXT
○ C union mega-struct SMB info
● SMB may be “restarted” multiple times
○ Send to a blocking thread
○ Wait for more data
○ Change FspStartRoutine, re-queue
■ Back of the line...
SrvNet.sys - SMBv1/2/3 Networking
● Added in Vista+
● Handles the networking (WSK)
○ 139 - NetBIOS
○ 445 - SMB Direct
● Registered handlers (undocumented, but trivial)
○ Srv.sys
○ Srv2.sys
● Library exports
○ Memory look-aside lists
○ Auth checks
SMB Messages (of Interest)
● Negotiate
● Session Setup
● Tree Connect
● NT Create
● Transactions
struct CONNECTION
{
// ...
SMB_DIALECT SmbDialect;
// ...
UNICODE_STRING ClientOSType;
UNICODE_STRING ClientLanManType;
// ...
};
struct SESSION
{
// ...
PCONNECTION Connection;
// ...
UNICODE_STRING UserName;
UNICODE_STRING UserDomain;
// ...
USHORT MaxBufferSize;
USHORT Uid;
// ...
BOOLEAN IsNullSession;
BOOLEAN IsAdmin;
// ...
};
Administrative Trees (Shares)
● $ = generally hidden from UI
● C$
● D$
● ADMIN$
○ C:Windows
○ Administrator login required
● IPC$
○ Interprocess Communication Share
■ i.e. also, sometimes access to certain named pipes
○ Often, anonymous login allowed
struct TREECONNECT
{
// ...
USHORT Tid;
// ...
};
Transaction Life Cycle
● “IOCTL”
○ Perform variety of functions
■ Mostly file-system related
● Can be too large for one SMB
○ Primary
■ Intermediary response
○ Secondary(s)
● "Executed" once all parts are received
○ Like db transactions
○ Final response
Transaction Packet Layout
● An SMB inside an SMB
○ In addition to SMB Parameter/Data Blocks:
■ Transaction Setup
● For Primary trans
■ Transaction Parameter
■ Transaction Data
Transaction Type Processing
● Trans (Trans1)
○ Mailslots
○ MS-RAP
● Trans2
○ >8.3 shortnames
○ OS/2 to NT file stuff
○ Processed similar to Trans1
● NT Trans
○ Transaction Parameter/Data sizes
■ USHORT -> ULONG
● WriteAndX
Primary Transaction Data+Parameter
● Offset
○ How far into this SMB the TRANS data/parameter blocks begin
ParameterOffset DataOffset
Primary Transaction Data+Parameter
● Offset
○ How far into this SMB the TRANS data/parameter blocks begin
● Count
○ How much is in this particular SMB
ParameterOffset DataOffset
ParameterCount DataCount
Primary Transaction Data+Parameter
● Offset
○ How far into this SMB the TRANS data/parameter blocks begin
● Count
○ How much is in this particular SMB
● TotalCount
○ How much will be sent over all Primary/Secondary SMB
ParameterOffset DataOffset
ParameterCount DataCount
TotalParameterCount TotalDataCount
Primary Transaction Data+Parameter
● Offset
○ How far into this SMB the TRANS data/parameter blocks begin
● Count
○ How much is in this particular SMB
● TotalCount
○ How much will be sent over all Primary/Secondary SMB
● MaxCount
○ Maximum client buffer size to reserve for TRANS response
ParameterOffset DataOffset
ParameterCount DataCount
TotalParameterCount TotalDataCount
MaxParameterCount MaxDataCount
Secondary Transaction Data+Parameter
● Offset
○ How far into this SMB the TRANS data/parameter blocks begin
● Count
○ How much is in this particular SMB
● TotalCount
○ "MAY" be less than or equal to Primary SMB
● Displacement
○ An offset where to begin write operation into the server buffer
■ Generally, the cumulative total of preceding Primary+Secondary Count(s)
ParameterDisplacement DataDisplacement
struct TRANSACTION
{
// ...
PCONNECTION Connection;
PSESSION Session;
PTREECONNECT TreeConnect;
// ...
PCHAR InParameters;
PCHAR OutParameters; // often: = InParameters
PCHAR InData;
PCHAR OutData; // often: = InData
// ...
USHORT Tid;
USHORT Pid;
USHORT Uid;
USHORT OtherInfo; // MID (...or, FID)
// ...
};
_TRANSACTION Memory
● SrvAllocateTransaction()
○ MIN alloc size = 0x5000
■ Except, Trans1.Setup == 0
○ MAX alloc size = 0x10400
■ STATUS_INSUFF_SERVER_RESOURCES
_TRANSACTION Memory
● SrvAllocateTransaction()
○ MIN alloc size = 0x5000
■ Except, Trans1.Setup == 0
○ MAX alloc size = 0x10400
■ STATUS_INSUFF_SERVER_RESOURCES
● SrvFindTransaction()
○ UID - server, const
○ TID - server, const
○ PID - client, const
○ OtherInfo
■ MID - client, arbitrary
■ FID - server, const
Reference Counted Memory Blocks
● WORK_CONTEXT
● CONNECTION
● SESSION
● TREECONNECT
● TRANSACTION
EternalBlue
Extended Attributes (EA)
● Name/Value key-pair
○ Metadata attached to files
Extended Attributes (EA)
● Name/Value key-pair
○ Metadata attached to files
● OS/2 v1.2
○ Joint Microsoft/IBM OS
○ HPFS
Extended Attributes (EA)
● Name/Value key-pair
○ Metadata attached to files
● OS/2 v1.2
○ Joint Microsoft/IBM OS
○ HPFS
● Windows NT
○ NTFS
■ Alternate Data Streams
○ WSL
■ Linux filesystem emulation
● permissions, i.e. 0777
● Case-sensitivity
Extended Attributes (EA)
● Name/Value key-pair
○ Metadata attached to files
● OS/2 v1.2
○ Joint Microsoft/IBM OS
○ HPFS
● Windows NT
○ NTFS
■ Alternate Data Streams
○ WSL
■ Linux filesystem emulation
● permissions, i.e. 0777
● Case-sensitivity
● FEA vs. GEA
○ FEA = name+value
○ GEA = name
OS/2 FEA
struct FEA
{
BYTE fEA; // "Flags" = 0x0 or 0x80
BYTE cbName;
WORD cbValue;
// CHAR szName[cbName]; // null-terminator
// BYTE chValue[cbValue]; // no null-terminator
};
#define FEA_SIZE(ea) 
(sizeof(FEA) + (ea)->cbName + 1 + (ea)->cbValue)
OS/2 FEALIST
struct FEALIST
{
ULONG cbList; // 32-bit size
FEA list[]; // Loop over all using NEXT_FEA()
};
#define NEXT_FEA(ea) 
(char*)ea + FEA_SIZE(ea)
NT FEA
struct FILE_FULL_EA_INFORMATION
{
ULONG NextEntryOffset;
UCHAR Flags; // 0x0 or 0x80
UCHAR EaNameLength;
USHORT EaValueLength;
// CHAR EaName[EaNameLength]; // null-terminated
// BYTE EaValue[EaValueLength]; // not
// BYTE Alignment[+3 & ~3]; // align DWORD
};
NT FEA(LIST)
struct FILE_FULL_EA_INFORMATION
{
ULONG NextEntryOffset; // Parse list until == 0
UCHAR Flags; // 0x0 or 0x80
UCHAR EaNameLength;
USHORT EaValueLength;
// CHAR EaName[EaNameLength]; // null-terminated
// BYTE EaValue[EaValueLength]; // not
// BYTE Alignment[+3 & ~3]; // align DWORD
};
Demystifying MS17-010: Reverse Engineering the ETERNAL Exploits
Bug #1 - Integer Cast Error
ULONG FEALIST.cbList;
SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList));
Bug #1 - Integer Cast Error
ULONG FEALIST.cbList;
SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList));
Win7
HIDWORD LODWORD
Attacker 0001 0000
Valid Size
Vuln Size
NT Buffer Size
Bug #1 - Integer Cast Error
ULONG FEALIST.cbList;
SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList));
Win7
HIDWORD LODWORD
Attacker 0001 0000
Valid Size 0000 ff5d
Vuln Size
NT Buffer Size
Bug #1 - Integer Cast Error
ULONG FEALIST.cbList;
SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList));
Win7
HIDWORD LODWORD
Attacker 0001 0000
Valid Size 0000 ff5d
Vuln Size 0001 ff5d
NT Buffer Size
Bug #1 - Integer Cast Error
ULONG FEALIST.cbList;
SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList));
Win7
0x1ff5d (OS/2) > 0x10fe8 (NT)
HIDWORD LODWORD
Attacker 0001 0000
Valid Size 0000 ff5d
Vuln Size 0001 ff5d
NT Buffer Size 0001 0fe8
Assembly Analysis
x86/x64 ARM
Itanium DEC ALPHA
Demystifying MS17-010: Reverse Engineering the ETERNAL Exploits
Demystifying MS17-010: Reverse Engineering the ETERNAL Exploits
Demystifying MS17-010: Reverse Engineering the ETERNAL Exploits
Demystifying MS17-010: Reverse Engineering the ETERNAL Exploits
packet Trans2_Open2_Parameters
{
USHORT Flags;
USHORT AccessMode;
USHORT Reserved1;
SMB_FILE_ATTRIBUTES FileAttributes;
UTIME CreationTime;
USHORT OpenMode;
ULONG AllocationSize;
USHORT Reserved[5];
SMB_STRING FileName;
};
packet Trans2_Open2_Data
{
SMB_FEA_LIST ExtendedAttributeList;
};
Bug #2 - Oversized Trans/Trans2 Requests
● Need to send > WORD data
○ Bug trigger 0x10000 > 0xffff
● Trans2_Open2 is WORD
○ NT Trans allows DWORD!
● Can trick transaction dispatch tables
○ They all become generic _TRANSACTION
○ Primary transaction type doesn't matter
■ Final Secondary transaction
Bug #3 - Session Setup Allocation Error
● NT Security vs. Extended Security
○ 13 words vs. 12 words
● Certain flag values can confuse it
○ Reads SMB_DATA_BLOCK size at wrong offset
○ Can reserve large memory
■ Same pool tag as FEA: LSbf
● Free on demand
○ Close client socket
● Not really a "vuln" itself
○ Still in master branch
EternalBlue NonPagedPool Ingredients
● FEALIST overflow
○ Exploit
● Session Setup bug
○ Allocation
○ Hole
● SrvNet.sys network buffers
○ Primary Grooms
○ Secondary Grooms
○ FAKE SMB2
■ IDS bypass?
EternalBlue Grooming
● Step 0. Pre-Exploitation Memory Layout
○ SrvNet has lookaside memory, random stuff is in the pool
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 1. Send all of FEALIST except last Trans2 secondary
○ The NT FEA Buffer will not be reserved yet
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 2. Send initial N grooms
○ Use up all of SrvNet look-aside, forcing new pool allocations
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 2. Send initial N grooms
○ Use up all of SrvNet look-aside, forcing new pool allocations
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 2. Send initial N grooms
○ Use up all of SrvNet look-aside, forcing new pool allocations
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 2. Send initial N grooms
○ Use up all of SrvNet look-aside, forcing new pool allocations
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 2. Send initial N grooms
○ Use up all of SrvNet look-aside, forcing new pool allocations
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 2. Send initial N grooms
○ Use up all of SrvNet look-aside, forcing new pool allocations
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 3. Send allocation connection
○ Session Setup bug SMALLER than NT FEA Buffer Size
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 4. Send hole buffer connection
○ Session Setup bug SAME SIZE as NT FEA Buffer Size
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 5. Close allocation connection
○ Memory slot can now hold smaller miscellaneous allocations
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 5. Close allocation connection
○ Memory slot can now hold smaller miscellaneous allocations
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 6. Send final groom packets
○ Hopefully a groom is after the Hole buffer
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 6. Send final groom packets
○ Hopefully a groom is after the Hole buffer
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 6. Send final groom packets
○ Hopefully a groom is after the Hole buffer
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 6. Send final groom packets
○ Hopefully a groom is after the Hole buffer
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 6. Close Hole connection
○ Memory the same size as NT FEA Buffer is now available
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
EternalBlue Grooming
● Step 7. Send final FEALIST exploit fragment
○ Erroneously calculated to fit in the free Hole buffer, overflows into groom
Free pool memory
Random pool memory
SrvNet look-aside buffers
SrvNet "groom" buffer
Session setup "allocation" buffer
Session setup "hole" buffer
Exploit OS/2 to NT FEA overflow
struct _SRVNET_BUFFER
{
// ...
SRVNET_WSK_STRUCT* WskContext;
// ...
MDL MDL1; // MapSysVa = &Buffer
MDL MDL2;
CHAR Buffer[];
};
struct _SRVNET_BUFFER
{
// ...
SRVNET_WSK_STRUCT* WskContext;
// ...
MDL MDL1; // MapSysVa = &HAL
MDL MDL2;
CHAR Buffer[];
};
struct _SRVNET_BUFFER
{
// ...
SRVNET_WSK_STRUCT* WskContext;
// ...
MDL MDL1; // MapSysVa = &HAL
MDL MDL2;
CHAR Buffer[];
};
struct _SRVNET_BUFFER
{
// ...
SRVNET_WSK_STRUCT* WskContext;
// ...
MDL MDL1; // MapSysVa = &HAL
MDL MDL2;
CHAR Buffer[];
};
struct _SRVNET_WSK_STRUCT
{
// ...
PVOID FunctionTable[];
// ...
};
struct _SRVNET_WSK_STRUCT
{
// ...
PVOID FunctionTable[];
// ...
};
struct _SRVNET_WSK_STRUCT
{
// ...
PVOID FunctionTable[];
// ...
};
EternalBlue payload
EternalBlue payload
1. Hook syscall handler
○ DISPATCH_LEVEL IRQL
■ Many routines are off limits
EternalBlue payload
1. Hook syscall handler
○ DISPATCH_LEVEL IRQL
■ Many routines are off limits
2. On next syscall…
○ Transition from user mode
○ Run DOUBLEPULSAR backdoor
■ SrvTransaction2DispatchTable
EternalBlue payload
1. Hook syscall handler
○ DISPATCH_LEVEL IRQL
■ Many routines are off limits
2. On next syscall…
○ Transition from user mode
○ Run DOUBLEPULSAR backdoor
■ SrvTransaction2DispatchTable
3. Restore syscall handler
EternalBlue Patch
SrvOs2FeaListSizeToNt():
SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList));
EternalBlue Patch
SrvOs2FeaListSizeToNt():
SmbPutUlong (&FeaList->cbList, PTR_DIFF_LONG(fea, FeaList));
EternalChampion
Race Condition
● TRANSACTION.Executing
○ BOOLEAN locking mechanism
○ Checked during Secondary transactions
■ NOT SET if Primary has all data!
Race Condition
● TRANSACTION.Executing
○ BOOLEAN locking mechanism
○ Checked during Secondary transactions
■ NOT SET if Primary has all data!
● Modify executing TRANSACTION!
○ Info leak on single-core
○ Stack overwrite on multi-core
Race Condition
● TRANSACTION.Executing
○ BOOLEAN locking mechanism
○ Checked during Secondary transactions
■ NOT SET if Primary has all data!
● Modify executing TRANSACTION!
○ Info leak on single-core
○ Stack overwrite on multi-core
● CHAMPION
○ CHAMPIONS WIN RACES!
Leak a TRANSACTION
● Need a SMB which echos back Data
○ MS-RAP
■ WNetAccountSync
■ NetServerEnum2
○ NT_RENAME
■ Requires valid FID
● Primary Trans
○ Data > CONNECTION.MaxBufferSize
■ Requires restart (multiple response SMB)
■ Always winrar a Race!
● Secondary Trans sends more data
○ Increases DataCount
○ Use Displacement=0
SrvSmbQueryPathInformation(WorkContext)
{
UNICODE_STRING objectName;
if (subCommand == SMB_INFO_QUERY_EA_SIZE)
{
SrvQueueWorkToBlockingThread(WorkContext);
return SmbTransStatusInProgress;
}
if (subCommand == SMB_INFO_IS_NAME_VALID)
{
transaction->InData = &objectName;
}
// ...
}
SrvSmbQueryPathInformation(WorkContext)
{
UNICODE_STRING objectName;
if (subCommand == SMB_INFO_QUERY_EA_SIZE)
{
SrvQueueWorkToBlockingThread(WorkContext);
return SmbTransStatusInProgress;
}
if (subCommand == SMB_INFO_IS_NAME_VALID)
{
transaction->InData = &objectName;
}
// ...
}
STEP 1
SrvSmbQueryPathInformation(WorkContext)
{
UNICODE_STRING objectName;
if (subCommand == SMB_INFO_QUERY_EA_SIZE)
{
SrvQueueWorkToBlockingThread(WorkContext);
return SmbTransStatusInProgress;
}
if (subCommand == SMB_INFO_IS_NAME_VALID)
{
transaction->InData = &objectName;
}
// ...
}
STEP 2
STEP 1
Overwrite RIP/EIP to Shellcode
● After SMB_INFO_IS_NAME_VALID, send another secondary trans
○ Displacement = stack offset
● Overwrite RET WorkerThread to Stage 0 Shellcode
DataDisplacement = offset
RWX Shellcode Location
● No DEP (x86)
○ Write at LEAKED TRANSACTION->InData
● DEP (x64)
○ Write at LEAKED TRANSACTION->CONNECTION.ClientOSName
■ I.E. same Session Setup bug used in EBlue
EternalChampion RCE Trigger
● 8 SMB per TCP packet
Trans2 SMB_INFO_QUERY_EA_SIZE Restart
Trans2 Secondary SMB_INFO_IS_NAME_VALID InData = &stack
Trans2 Secondary DataDisplacement Overwrite RET
EternalChampion RCE Trigger
● 8 SMB per TCP packet
● 8 packets per attempt
Trans2 SMB_INFO_QUERY_EA_SIZE Restart
Trans2 Secondary SMB_INFO_IS_NAME_VALID InData = &stack
Trans2 Secondary DataDisplacement Overwrite RET
EternalChampion RCE Trigger
● 8 SMB per TCP packet
● 8 packets per attempt
● 42 attempts
Trans2 SMB_INFO_QUERY_EA_SIZE Restart
Trans2 Secondary SMB_INFO_IS_NAME_VALID InData = &stack
Trans2 Secondary DataDisplacement Overwrite RET
EternalChampion Shellcode
1. Loop CONNECTION.TransactionList
○ Find special identifier at start of Data buffer
■ AKA: egghunter
EternalChampion Shellcode
1. Loop CONNECTION.TransactionList
○ Find special identifier at start of Data buffer
■ AKA: egghunter
2. Copy primary payload from egg (DOUBLEPULSAR)
○ Access to pool functions
■ Can allocate large RWX space
○ Execute main stage
EternalChampion Shellcode
1. Loop CONNECTION.TransactionList
○ Find special identifier at start of Data buffer
■ AKA: egghunter
2. Copy primary payload from egg (DOUBLEPULSAR)
○ Access to pool functions
■ Can allocate large RWX space
○ Execute main stage
3. ++SrvBlockingWorkQueues->AvailableThreads
EternalChampion Shellcode
1. Loop CONNECTION.TransactionList
○ Find special identifier at start of Data buffer
■ AKA: egghunter
2. Copy primary payload from egg (DOUBLEPULSAR)
○ Access to pool functions
■ Can allocate large RWX space
○ Execute main stage
3. ++SrvBlockingWorkQueues->AvailableThreads
4. KPCR->Prcb.CurrentThread->StartAddress
○ Use global kernel data structures
○ Resume execution
■ JMP to srv!WorkerThread() loop
EternalChampion Patch
SrvSmbTransaction/SrvSmbNtTransaction():
if (all_data_received)
{
ExecuteTransaction(transaction);
}
else
{
// send interim response
}
EternalChampion Patch
SrvSmbTransaction/SrvSmbNtTransaction():
if (all_data_received)
{
transaction->Executing = TRUE;
ExecuteTransaction(transaction);
}
else
{
// send interim response
}
EternalRomance
PTRANSACTION SrvFindTransaction (
IN PCONNECTION Connection,
IN PSMB_HEADER SmbHeader,
IN USHORT Fid OPTIONAL)
{
if (SmbHeader->Command == SMB_COM_WRITE_ANDX)
OtherInfo = Fid;
else
OtherInfo = SmbHeader->Mid;
// search TransactionList by UID/TID/PID/OtherInfo
}
SrvSmbWriteAndX ( PWORK_CONTEXT )
{
transaction = SrvFindTransaction(connection, header, fid);
if (writeMode & SMB_WMODE_WRITE_RAW_NAMED_PIPE)
{
RtlCopyMemory(transaction->InData, ...);
transaction->InData += writeLength;
transaction->DataCount += writeLength;
}
}
Type Confusion Sequence
Type Confusion Sequence
Type Confusion Sequence
Pointer Shift Sequence
Pointer Shift Sequence
Pointer Shift Sequence
Pointer Shift Sequence
Info Leak
● Bug #1 - TRANS_PEEK_NMPIPE
○ Expects MaxParameterCount=16
■ But takes client value
○ MaxParameterCount to fill min. Space
○ MaxDataCount=1
Info Leak
● Bug #1 - TRANS_PEEK_NMPIPE
○ Expects MaxParameterCount=16
■ But takes client value
○ MaxParameterCount to fill min. Space
○ MaxDataCount=1
● Bug #2 - DataCount > MaxDataCount
○ Put >1 data in pipe
○ Peek
Paged Pool Grooming Methods
1. Fish-in-a-Barrel
○ “Remote API” (MS-RAP)
■ Fish/Dynamite
2. Matched Pairs
○ “Lattice”
■ Brides/Grooms → Romance?
3. Classic
○ “Sandwich”
■ Frag/Padding
● Each: 3 exploit attempts
Fish-In-A-Barrel
● SrvXsPortMemoryHeap - 1MiB
○ Private heap, Pre-allocated
■ No fighting in the paged pool with other kernel allocations
○ MS-RAP transactions only, Rarely used
■ Babby's first heap feng shui
● Removed in 7+
○ SMAP?
○ privesc??
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Fish-In-A-Barrel
Free Heap memory
Fish (victim)
Dynamite (exploit)
Matched Pairs “Lattice”
● All versions of Windows
○ Including, 7+
● Must overcome pool contention
○ Not a private heap
■ Normal, Paged Pool
■ PASSIVE_LEVEL
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Matched Pairs “Lattice”
Free Heap memory
Grooms
Brides (victim)
Exploit (pointer shift)
Write-What-Where Primitive
Write-What-Where Primitive
1. Exploit Transaction (PID=X)
○ Set VictimTrans->InData to &WHERE
○ Set VictimTrans->Executing to FALSE
○ Increase reference count!
■ Don’t want it to get freed
○ etc...
Write-What-Where Primitive
1. Exploit Transaction (PID=X)
○ Set VictimTrans->InData to &WHERE
○ Set VictimTrans->Executing to FALSE
○ Increase reference count!
■ Don’t want it to get freed
○ etc...
2. VictimTrans Secondary (MID=0)
○ Trans Data Block = WHAT[]
Read-Where Primitive
Read-Where Primitive
1. Exploit Transaction (PID=X)
○ Modify VictimTrans to point at LeakTrans
■ Address inferred by its contents
■ VictimTrans now modifies LeakTrans
Read-Where Primitive
1. Exploit Transaction (PID=X)
○ Modify VictimTrans to point at LeakTrans
■ Address inferred by its contents
■ VictimTrans now modifies LeakTrans
2. VictimTrans Trans_Secondary (MID=0)
○ LeakTrans->OutData = &WHERE
○ LeakTrans->Setup = TRANS_PEEK_NMPIPE
○ LeakTrans->MaxDataCount = size_t
Read-Where Primitive
1. Exploit Transaction (PID=X)
○ Modify VictimTrans to point at LeakTrans
■ Address inferred by its contents
■ VictimTrans now modifies LeakTrans
2. VictimTrans Trans_Secondary (MID=0)
○ LeakTrans->OutData = &WHERE
○ LeakTrans->Setup = TRANS_PEEK_NMPIPE
○ LeakTrans->MaxDataCount = size_t
3. LeakTrans Trans_Secondary
○ Echos back the LeakTrans->OutData
Quest for RWX NonPagedPool
1. Exploit Trans
○ Set VictimTrans->OutParameters = NULL
2. Send Secondary Victim Transaction
if (VictimTrans->OutParameters == NULL)
VictimTrans->OutParameters = WorkContext->ResponseBuffer;
3. Read Primitive
○ Read address just set
4. Write Primitive
○ Send shellcode
Quest to Execute the Shellcode
1. Locate Transaction2DispatchTable
○ FIND in srv.sys .data section (read primitive)
2. Hook a Trans2 subcommand
○ REPLACE a pointer in table (write primitive)
3. Fake Trans2 executes the hook
○ Subcommand = hooked index
○ Similar methodology as DOUBLEPULSAR
● Given:
○ Read/write primitives
○ Leaked TRANSACTION has CONNECTION pointer
Locate Transaction2DispatchTable
1. Read in LeakTrans->CONNECTION
Locate Transaction2DispatchTable
1. Read in LeakTrans->CONNECTION
2. CONNECTION->EndpointSpinLock
○ SrvGlobalSpinLocks
■ Inside PE .data section
Locate Transaction2DispatchTable
1. Read in LeakTrans->CONNECTION
2. CONNECTION->EndpointSpinLock
○ SrvGlobalSpinLocks
■ Inside PE .data section
3. Read backwards, SrvSmbWordCount
○ Illegal commands = -2 (0xfe)
○ If we see a bunch of fefe, we're close
Locate Transaction2DispatchTable
1. Read in LeakTrans->CONNECTION
2. CONNECTION->EndpointSpinLock
○ SrvGlobalSpinLocks
■ Inside PE .data section
3. Read backwards, SrvSmbWordCount
○ Illegal commands = -2 (0xfe)
○ If we see a bunch of fefe, we're close
4. Transaction2DispatchTable
○ Function pointers #0x14 == #0x15
■ SrvTransactionNotImplemented
EternalRomance Info Leak Patch #1
SrvSmbTransaction() Before:
if (subCommand == TRANS_PEEK_NMPIPE)
{
maxParameterCount = MAX(16, maxParameterCount);
}
SrvAllocateTransaction(&Transaction, ...);
Transaction->MaxParameterCount = maxParameterCount;
EternalRomance Info Leak Patch #1
SrvSmbTransaction() After:
if (subCommand == TRANS_PEEK_NMPIPE)
{
maxParameterCount = 16;
}
SrvAllocateTransaction(&Transaction, ...);
Transaction->MaxParameterCount = maxParameterCount;
MS17-010 Scanners
● Max TRANSACTION allocation size=0x10400
○ 0xC0000205 - STATUS_INSUFF_SERVER_RESOURCES
● Send MaxParameterCount+MaxDataCount > 0x10400
MS17-010 Scanners
● Max TRANSACTION allocation size=0x10400
○ 0xC0000205 - STATUS_INSUFF_SERVER_RESOURCES
● Send MaxParameterCount+MaxDataCount > 0x10400
○ Patch fixes MaxParameterCount to 16
■ Passes allocation routine!
○ Different NT error (i.e. invalid FID)
EternalRomance Info Leak Patch #2
SrvCompleteExecuteTransaction() New Code:
if (transaction->DataCount > transaction->MaxDataCount)
transaction->DataCount = transaction->MaxDataCount;
if (transaction->ParameterCount > transaction->MaxParameterCount )
transaction->ParameterCount = transaction->MaxParameterCount ;
EternalRomance RCE Patch #1
SrvSmbWriteAndX() Before:
RtlCopyMemory(transaction-> InData, ...);
transaction->InData += writeLength;
transaction->DataCount += writeLength;
EternalRomance RCE Patch #1
SrvSmbWriteAndX() After:
RtlCopyMemory(transaction-> InData + transaction->DataCount, ...);
transaction->InData += writeLength;
transaction->DataCount += writeLength;
EternalRomance RCE Patch #2
1. SrvSmbNtTransaction/SrvSmbTransaction() New Code:
SrvAllocateTransaction(&Transaction, ...)
Transaction->SecondaryCommand = /* 0x38 */
SMB_COM_NT_TRANS_SECONDARY;
SrvInsertTransaction(&Transaction);
EternalRomance RCE Patch #2
1. SrvSmbNtTransaction/SrvSmbTransaction() New Code:
SrvAllocateTransaction(&Transaction, ...)
Transaction->SecondaryCommand = /* 0x38 */
SMB_COM_NT_TRANS_SECONDARY;
SrvInsertTransaction(&Transaction);
2. SrvFindTransaction() New Code:
if (FoundTrans->SecondaryCommand != NewSmb->Command)
return NULL;
EternalSynergy
EternalSynergy 1.0.1
● Same buffalo overflow, read/writes, as EternalRomance
○ Matched pairs
○ "Classic"
● Same info leak as EternalChampion
○ NT_Rename Race Condition
■ TRANS_PEEK_NAMED_PIPE is fixed…
● Srv.sys is using NonPagedPoolNx for Work Items!
○ Needs DEP bypass
Quest for RWX Memory (via remote read)
● Given: Connection
Type Pointer Dereference Offset
WORK_QUEUE Connection->PreferredWorkQueue variadic
Quest for RWX Memory (via remote read)
● Given: Connection
Type Pointer Dereference Offset
WORK_QUEUE Connection->PreferredWorkQueue variadic
KTHREAD PreferredWorkQueue->IrpThread 0x198
Quest for RWX Memory (via remote read)
● Given: Connection
Type Pointer Dereference Offset
WORK_QUEUE Connection->PreferredWorkQueue variadic
KTHREAD PreferredWorkQueue->IrpThread 0x198
KPROCESS IrpThread->Process 0x220
Quest for RWX Memory (via remote read)
● Given: Connection
● Obtain: ProcessListEntry.Blink
○ nt!KiProcessListHead*
Type Pointer Dereference Offset
WORK_QUEUE Connection->PreferredWorkQueue variadic
KTHREAD PreferredWorkQueue->IrpThread 0x198
KPROCESS IrpThread->Process 0x220
PVOID KProcess->ProcessListEntry.Blink 0x240
* https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kprocess/index.htm
Quest for RWX Memory (via remote read)
● Given: Connection
● Obtain: ProcessListEntry.Blink
○ nt!KiProcessListHead*
● Search backwards by page size for 'MZ'
○ ntoskrnl.exe PE header
Type Pointer Dereference Offset
WORK_QUEUE Connection->PreferredWorkQueue variadic
KTHREAD PreferredWorkQueue->IrpThread 0x198
KPROCESS IrpThread->Process 0x220
PVOID KProcess->ProcessListEntry.Blink 0x240
* https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kprocess/index.htm
ntoskrnl.exe RWEXEC Section
● Remote read offset 0x250 into &ntoskrnl.exe
● Check section headers:
○ +0x08 == 0x1000 (Virtual Size: 4096)
○ +0x0C <= 0x800000 (Virtual Addr: 0x271000 &KxUnexpectedInterrupt)
○ +0x24 == 0xE80000A0 (Segment permissions: RWX)
Additional Research
● @sleepya_
○ https://github.com/worawit/MS17-010
● @n_joly
○ https://hitcon.org/2017/CMT/slide-files/d2_s2_r0.pdf
● @jennamagius and @zerosum0x0
○ https://keybase.pub/jennamagius/EternalBlue_RiskSense-Exploit-Analysis-and-Port-to-Microsoft-Windows-10.pdf
● @msftsecresponse
○ https://blogs.technet.microsoft.com/srd/2017/06/29/eternal-champion-exploit-analysis/
○ https://blogs.technet.microsoft.com/srd/2017/07/13/eternal-synergy-exploit-analysis/
● @swithak
○ https://swithak.github.io/SH20TAATSB18/Home/
● @francisckrs
○ https://speakerdeck.com/francisck/danderspritz-how-the-equation-groups-2013-tools-still-pwn-in-2017
● @msuiche
○ https://www.comae.io/reports/us-17-Suiche-TheShadowBrokers-Cyber-Fear-Game-Changers.pdf
Thanks!
zerosum0x0

More Related Content

PPTX
Eternal blue Vulnerability
PPTX
OWASP AppSecCali 2015 - Marshalling Pickles
PPTX
Fat 32 file system
PPT
XSS - Attacks & Defense
PDF
BeagleBone Black Bootloaders
PDF
Java Deserialization Vulnerabilities - The Forgotten Bug Class (RuhrSec Edition)
PPTX
The History of DNS
PDF
IntelON 2021 Processor Benchmarking
Eternal blue Vulnerability
OWASP AppSecCali 2015 - Marshalling Pickles
Fat 32 file system
XSS - Attacks & Defense
BeagleBone Black Bootloaders
Java Deserialization Vulnerabilities - The Forgotten Bug Class (RuhrSec Edition)
The History of DNS
IntelON 2021 Processor Benchmarking

What's hot (20)

PPTX
關於SQL Injection的那些奇技淫巧
PPTX
PDF
BPF - in-kernel virtual machine
PPTX
Understanding Stack Overflow
PDF
Windows 10 Nt Heap Exploitation (English version)
PPTX
ZeroNights 2018 | I <"3 XSS
PPTX
Windows Registry Forensics with Volatility Framework
PDF
Heap exploitation
PDF
DNS exfiltration using sqlmap
PDF
Exploiting Deserialization Vulnerabilities in Java
PPT
Epoll - from the kernel side
PPTX
Malware analysis
PDF
BPF: Tracing and more
PDF
Linux Binary Exploitation - Return-oritend Programing
PDF
Database Firewall with Snort
PPTX
Dns(Domain name system)
PDF
Advanced SQL injection to operating system full control (whitepaper)
PDF
Windows attacks - AT is the new black
PDF
Packet sniffing & ARP Poisoning
PDF
Not a Security Boundary
關於SQL Injection的那些奇技淫巧
BPF - in-kernel virtual machine
Understanding Stack Overflow
Windows 10 Nt Heap Exploitation (English version)
ZeroNights 2018 | I <"3 XSS
Windows Registry Forensics with Volatility Framework
Heap exploitation
DNS exfiltration using sqlmap
Exploiting Deserialization Vulnerabilities in Java
Epoll - from the kernel side
Malware analysis
BPF: Tracing and more
Linux Binary Exploitation - Return-oritend Programing
Database Firewall with Snort
Dns(Domain name system)
Advanced SQL injection to operating system full control (whitepaper)
Windows attacks - AT is the new black
Packet sniffing & ARP Poisoning
Not a Security Boundary
Ad

Similar to Demystifying MS17-010: Reverse Engineering the ETERNAL Exploits (20)

PPTX
Building an Automated Behavioral Malware Analysis Environment using Free and ...
PDF
Network operating systems
PDF
Network operating systems
PDF
Filip palian mateuszkocielski. simplest ownage human observed… routers
PDF
Simplest-Ownage-Human-Observed… - Routers
PPTX
Samba
PPT
16aug06.ppt
PPTX
Symbian OS - Client Server Framework
PDF
Linux Network Management
PDF
Workshop on CIFS / SMB Protocol Performance Analysis
PDF
unix interprocess communication
PPT
Servers and Processes: Behavior and Analysis
PPT
DISTRIBUTED FILE SYSTEM- Design principles, consistency models
PPT
Introduction to distributed file systems
PPT
ODP
Using samba
PDF
Debugging Ruby Systems
PDF
Overview of FreeBSD PMC Tools
PDF
Hacking the swisscom modem
PDF
High Availability With DRBD & Heartbeat
Building an Automated Behavioral Malware Analysis Environment using Free and ...
Network operating systems
Network operating systems
Filip palian mateuszkocielski. simplest ownage human observed… routers
Simplest-Ownage-Human-Observed… - Routers
Samba
16aug06.ppt
Symbian OS - Client Server Framework
Linux Network Management
Workshop on CIFS / SMB Protocol Performance Analysis
unix interprocess communication
Servers and Processes: Behavior and Analysis
DISTRIBUTED FILE SYSTEM- Design principles, consistency models
Introduction to distributed file systems
Using samba
Debugging Ruby Systems
Overview of FreeBSD PMC Tools
Hacking the swisscom modem
High Availability With DRBD & Heartbeat
Ad

More from Priyanka Aash (20)

PPTX
AI Code Generation Risks (Ramkumar Dilli, CIO, Myridius)
PDF
From Chatbot to Destroyer of Endpoints - Can ChatGPT Automate EDR Bypasses (1...
PDF
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
PDF
Oh, the Possibilities - Balancing Innovation and Risk with Generative AI.pdf
PDF
Lessons Learned from Developing Secure AI Workflows.pdf
PDF
Cyber Defense Matrix Workshop - RSA Conference
PDF
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
PDF
Securing AI - There Is No Try, Only Do!.pdf
PDF
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
PDF
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
PDF
10 Key Challenges for AI within the EU Data Protection Framework.pdf
PDF
Techniques for Automatic Device Identification and Network Assignment.pdf
PDF
Keynote : Presentation on SASE Technology
PDF
Keynote : AI & Future Of Offensive Security
PDF
Redefining Cybersecurity with AI Capabilities
PDF
Demystifying Neural Networks And Building Cybersecurity Applications
PDF
Finetuning GenAI For Hacking and Defending
PDF
(CISOPlatform Summit & SACON 2024) Kids Cyber Security .pdf
PDF
(CISOPlatform Summit & SACON 2024) Regulation & Response In Banks.pdf
PDF
(CISOPlatform Summit & SACON 2024) Cyber Insurance & Risk Quantification.pdf
AI Code Generation Risks (Ramkumar Dilli, CIO, Myridius)
From Chatbot to Destroyer of Endpoints - Can ChatGPT Automate EDR Bypasses (1...
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Oh, the Possibilities - Balancing Innovation and Risk with Generative AI.pdf
Lessons Learned from Developing Secure AI Workflows.pdf
Cyber Defense Matrix Workshop - RSA Conference
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Securing AI - There Is No Try, Only Do!.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Keynote : Presentation on SASE Technology
Keynote : AI & Future Of Offensive Security
Redefining Cybersecurity with AI Capabilities
Demystifying Neural Networks And Building Cybersecurity Applications
Finetuning GenAI For Hacking and Defending
(CISOPlatform Summit & SACON 2024) Kids Cyber Security .pdf
(CISOPlatform Summit & SACON 2024) Regulation & Response In Banks.pdf
(CISOPlatform Summit & SACON 2024) Cyber Insurance & Risk Quantification.pdf

Recently uploaded (20)

PPTX
Programs and apps: productivity, graphics, security and other tools
PPTX
SOPHOS-XG Firewall Administrator PPT.pptx
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
1. Introduction to Computer Programming.pptx
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
OMC Textile Division Presentation 2021.pptx
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Heart disease approach using modified random forest and particle swarm optimi...
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
Tartificialntelligence_presentation.pptx
PDF
Mushroom cultivation and it's methods.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
A Presentation on Artificial Intelligence
PPTX
Spectroscopy.pptx food analysis technology
PDF
Empathic Computing: Creating Shared Understanding
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Network Security Unit 5.pdf for BCA BBA.
Programs and apps: productivity, graphics, security and other tools
SOPHOS-XG Firewall Administrator PPT.pptx
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Agricultural_Statistics_at_a_Glance_2022_0.pdf
1. Introduction to Computer Programming.pptx
MIND Revenue Release Quarter 2 2025 Press Release
Spectral efficient network and resource selection model in 5G networks
OMC Textile Division Presentation 2021.pptx
Digital-Transformation-Roadmap-for-Companies.pptx
Heart disease approach using modified random forest and particle swarm optimi...
Diabetes mellitus diagnosis method based random forest with bat algorithm
Tartificialntelligence_presentation.pptx
Mushroom cultivation and it's methods.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
A Presentation on Artificial Intelligence
Spectroscopy.pptx food analysis technology
Empathic Computing: Creating Shared Understanding
Per capita expenditure prediction using model stacking based on satellite ima...
Unlocking AI with Model Context Protocol (MCP)
Network Security Unit 5.pdf for BCA BBA.

Demystifying MS17-010: Reverse Engineering the ETERNAL Exploits

  • 1. Eternal ExploitsReverse Engineering of FuzzBunch and MS17-010 zerosum0x0 August 1983
  • 2. Warning! Presentation may contain classified information. Those with active security clearances are forewarned. TOP SECRET//SI/TK//NOFORN//ICATION//4201337//REL TO DEF CON
  • 4. Agenda ● Recap (~2 mins) ○ Equation Group (NSA) ○ Shadow Brokers ● SMBv1 Internals (~5 mins) ○ Network packets ○ Driver structures ● Exploits (~40 mins) ○ Blue ○ Champion ○ Romance ○ Synergy ● Payloads (~10 mins) ○ DoublePulsar ○ DarkPulsar ○ DanderSpritz
  • 6. SMB Background ● Server Message Block ● 1983 - Invented by Barry Feigenbaum (IBM) ○ Also, NetBIOS ● Used EXTENSIVELY by Windows ○ "LanMan" ○ File Shares ● Extensible protocol ○ Transport for DCE/RPC ■ psexec
  • 7. Server Message Block (v1) ● Header Block ○ Command ○ Flags (request/reply, unicode) ○ Errno ○ Signature ○ UID/TID/PID/MID
  • 8. Server Message Block (v1) ● Header Block ○ Command ○ Flags (request/reply, unicode) ○ Errno ○ Signature ○ UID/TID/PID/MID ● Parameter Block ○ Contains a struct specific to the command ■ Fixed size WORD count
  • 9. Server Message Block (v1) ● Header Block ○ Command ○ Flags (request/reply, unicode) ○ Errno ○ Signature ○ UID/TID/PID/MID ● Parameter Block ○ Contains a struct specific to the command ■ Fixed size WORD count ● Data Block ○ Misc. arbitrary info for the command ■ Variable size BYTE count
  • 10. SMBv1 Dialects ● PC NETWORK PROGRAM 1.0 ● MICROSOFT NETWORKS 1.03 ● MICROSOFT NETWORKS 3.0 ● LANMAN1.0 ● Windows for Workgroups 3.1a ● LM1.2X002 ● LANMAN2.1 ● NT LM 0.12 ● Cairo
  • 11. Srv.sys - SMBv1 ● SrvWorkQueues ● SrvBlockingWorkQueues ○ Any operation that may take awhile ■ SMB is designed for speed
  • 12. Srv.sys - SMBv1 ● SrvWorkQueues ● SrvBlockingWorkQueues ○ Any operation that may take awhile ■ SMB is designed for speed ● WORK_CONTEXT ○ C union mega-struct SMB info
  • 13. Srv.sys - SMBv1 ● SrvWorkQueues ● SrvBlockingWorkQueues ○ Any operation that may take awhile ■ SMB is designed for speed ● WORK_CONTEXT ○ C union mega-struct SMB info ● SMB may be “restarted” multiple times ○ Send to a blocking thread ○ Wait for more data ○ Change FspStartRoutine, re-queue ■ Back of the line...
  • 14. SrvNet.sys - SMBv1/2/3 Networking ● Added in Vista+ ● Handles the networking (WSK) ○ 139 - NetBIOS ○ 445 - SMB Direct ● Registered handlers (undocumented, but trivial) ○ Srv.sys ○ Srv2.sys ● Library exports ○ Memory look-aside lists ○ Auth checks
  • 15. SMB Messages (of Interest) ● Negotiate ● Session Setup ● Tree Connect ● NT Create ● Transactions
  • 16. struct CONNECTION { // ... SMB_DIALECT SmbDialect; // ... UNICODE_STRING ClientOSType; UNICODE_STRING ClientLanManType; // ... };
  • 17. struct SESSION { // ... PCONNECTION Connection; // ... UNICODE_STRING UserName; UNICODE_STRING UserDomain; // ... USHORT MaxBufferSize; USHORT Uid; // ... BOOLEAN IsNullSession; BOOLEAN IsAdmin; // ... };
  • 18. Administrative Trees (Shares) ● $ = generally hidden from UI ● C$ ● D$ ● ADMIN$ ○ C:Windows ○ Administrator login required ● IPC$ ○ Interprocess Communication Share ■ i.e. also, sometimes access to certain named pipes ○ Often, anonymous login allowed
  • 20. Transaction Life Cycle ● “IOCTL” ○ Perform variety of functions ■ Mostly file-system related ● Can be too large for one SMB ○ Primary ■ Intermediary response ○ Secondary(s) ● "Executed" once all parts are received ○ Like db transactions ○ Final response
  • 21. Transaction Packet Layout ● An SMB inside an SMB ○ In addition to SMB Parameter/Data Blocks: ■ Transaction Setup ● For Primary trans ■ Transaction Parameter ■ Transaction Data
  • 22. Transaction Type Processing ● Trans (Trans1) ○ Mailslots ○ MS-RAP ● Trans2 ○ >8.3 shortnames ○ OS/2 to NT file stuff ○ Processed similar to Trans1 ● NT Trans ○ Transaction Parameter/Data sizes ■ USHORT -> ULONG ● WriteAndX
  • 23. Primary Transaction Data+Parameter ● Offset ○ How far into this SMB the TRANS data/parameter blocks begin ParameterOffset DataOffset
  • 24. Primary Transaction Data+Parameter ● Offset ○ How far into this SMB the TRANS data/parameter blocks begin ● Count ○ How much is in this particular SMB ParameterOffset DataOffset ParameterCount DataCount
  • 25. Primary Transaction Data+Parameter ● Offset ○ How far into this SMB the TRANS data/parameter blocks begin ● Count ○ How much is in this particular SMB ● TotalCount ○ How much will be sent over all Primary/Secondary SMB ParameterOffset DataOffset ParameterCount DataCount TotalParameterCount TotalDataCount
  • 26. Primary Transaction Data+Parameter ● Offset ○ How far into this SMB the TRANS data/parameter blocks begin ● Count ○ How much is in this particular SMB ● TotalCount ○ How much will be sent over all Primary/Secondary SMB ● MaxCount ○ Maximum client buffer size to reserve for TRANS response ParameterOffset DataOffset ParameterCount DataCount TotalParameterCount TotalDataCount MaxParameterCount MaxDataCount
  • 27. Secondary Transaction Data+Parameter ● Offset ○ How far into this SMB the TRANS data/parameter blocks begin ● Count ○ How much is in this particular SMB ● TotalCount ○ "MAY" be less than or equal to Primary SMB ● Displacement ○ An offset where to begin write operation into the server buffer ■ Generally, the cumulative total of preceding Primary+Secondary Count(s) ParameterDisplacement DataDisplacement
  • 28. struct TRANSACTION { // ... PCONNECTION Connection; PSESSION Session; PTREECONNECT TreeConnect; // ... PCHAR InParameters; PCHAR OutParameters; // often: = InParameters PCHAR InData; PCHAR OutData; // often: = InData // ... USHORT Tid; USHORT Pid; USHORT Uid; USHORT OtherInfo; // MID (...or, FID) // ... };
  • 29. _TRANSACTION Memory ● SrvAllocateTransaction() ○ MIN alloc size = 0x5000 ■ Except, Trans1.Setup == 0 ○ MAX alloc size = 0x10400 ■ STATUS_INSUFF_SERVER_RESOURCES
  • 30. _TRANSACTION Memory ● SrvAllocateTransaction() ○ MIN alloc size = 0x5000 ■ Except, Trans1.Setup == 0 ○ MAX alloc size = 0x10400 ■ STATUS_INSUFF_SERVER_RESOURCES ● SrvFindTransaction() ○ UID - server, const ○ TID - server, const ○ PID - client, const ○ OtherInfo ■ MID - client, arbitrary ■ FID - server, const
  • 31. Reference Counted Memory Blocks ● WORK_CONTEXT ● CONNECTION ● SESSION ● TREECONNECT ● TRANSACTION
  • 33. Extended Attributes (EA) ● Name/Value key-pair ○ Metadata attached to files
  • 34. Extended Attributes (EA) ● Name/Value key-pair ○ Metadata attached to files ● OS/2 v1.2 ○ Joint Microsoft/IBM OS ○ HPFS
  • 35. Extended Attributes (EA) ● Name/Value key-pair ○ Metadata attached to files ● OS/2 v1.2 ○ Joint Microsoft/IBM OS ○ HPFS ● Windows NT ○ NTFS ■ Alternate Data Streams ○ WSL ■ Linux filesystem emulation ● permissions, i.e. 0777 ● Case-sensitivity
  • 36. Extended Attributes (EA) ● Name/Value key-pair ○ Metadata attached to files ● OS/2 v1.2 ○ Joint Microsoft/IBM OS ○ HPFS ● Windows NT ○ NTFS ■ Alternate Data Streams ○ WSL ■ Linux filesystem emulation ● permissions, i.e. 0777 ● Case-sensitivity ● FEA vs. GEA ○ FEA = name+value ○ GEA = name
  • 37. OS/2 FEA struct FEA { BYTE fEA; // "Flags" = 0x0 or 0x80 BYTE cbName; WORD cbValue; // CHAR szName[cbName]; // null-terminator // BYTE chValue[cbValue]; // no null-terminator }; #define FEA_SIZE(ea) (sizeof(FEA) + (ea)->cbName + 1 + (ea)->cbValue)
  • 38. OS/2 FEALIST struct FEALIST { ULONG cbList; // 32-bit size FEA list[]; // Loop over all using NEXT_FEA() }; #define NEXT_FEA(ea) (char*)ea + FEA_SIZE(ea)
  • 39. NT FEA struct FILE_FULL_EA_INFORMATION { ULONG NextEntryOffset; UCHAR Flags; // 0x0 or 0x80 UCHAR EaNameLength; USHORT EaValueLength; // CHAR EaName[EaNameLength]; // null-terminated // BYTE EaValue[EaValueLength]; // not // BYTE Alignment[+3 & ~3]; // align DWORD };
  • 40. NT FEA(LIST) struct FILE_FULL_EA_INFORMATION { ULONG NextEntryOffset; // Parse list until == 0 UCHAR Flags; // 0x0 or 0x80 UCHAR EaNameLength; USHORT EaValueLength; // CHAR EaName[EaNameLength]; // null-terminated // BYTE EaValue[EaValueLength]; // not // BYTE Alignment[+3 & ~3]; // align DWORD };
  • 42. Bug #1 - Integer Cast Error ULONG FEALIST.cbList; SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList));
  • 43. Bug #1 - Integer Cast Error ULONG FEALIST.cbList; SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList)); Win7 HIDWORD LODWORD Attacker 0001 0000 Valid Size Vuln Size NT Buffer Size
  • 44. Bug #1 - Integer Cast Error ULONG FEALIST.cbList; SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList)); Win7 HIDWORD LODWORD Attacker 0001 0000 Valid Size 0000 ff5d Vuln Size NT Buffer Size
  • 45. Bug #1 - Integer Cast Error ULONG FEALIST.cbList; SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList)); Win7 HIDWORD LODWORD Attacker 0001 0000 Valid Size 0000 ff5d Vuln Size 0001 ff5d NT Buffer Size
  • 46. Bug #1 - Integer Cast Error ULONG FEALIST.cbList; SmbPutUshort(&FeaList->cbList, PTR_DIFF_SHORT(fea, FeaList)); Win7 0x1ff5d (OS/2) > 0x10fe8 (NT) HIDWORD LODWORD Attacker 0001 0000 Valid Size 0000 ff5d Vuln Size 0001 ff5d NT Buffer Size 0001 0fe8
  • 52. packet Trans2_Open2_Parameters { USHORT Flags; USHORT AccessMode; USHORT Reserved1; SMB_FILE_ATTRIBUTES FileAttributes; UTIME CreationTime; USHORT OpenMode; ULONG AllocationSize; USHORT Reserved[5]; SMB_STRING FileName; }; packet Trans2_Open2_Data { SMB_FEA_LIST ExtendedAttributeList; };
  • 53. Bug #2 - Oversized Trans/Trans2 Requests ● Need to send > WORD data ○ Bug trigger 0x10000 > 0xffff ● Trans2_Open2 is WORD ○ NT Trans allows DWORD! ● Can trick transaction dispatch tables ○ They all become generic _TRANSACTION ○ Primary transaction type doesn't matter ■ Final Secondary transaction
  • 54. Bug #3 - Session Setup Allocation Error ● NT Security vs. Extended Security ○ 13 words vs. 12 words ● Certain flag values can confuse it ○ Reads SMB_DATA_BLOCK size at wrong offset ○ Can reserve large memory ■ Same pool tag as FEA: LSbf ● Free on demand ○ Close client socket ● Not really a "vuln" itself ○ Still in master branch
  • 55. EternalBlue NonPagedPool Ingredients ● FEALIST overflow ○ Exploit ● Session Setup bug ○ Allocation ○ Hole ● SrvNet.sys network buffers ○ Primary Grooms ○ Secondary Grooms ○ FAKE SMB2 ■ IDS bypass?
  • 56. EternalBlue Grooming ● Step 0. Pre-Exploitation Memory Layout ○ SrvNet has lookaside memory, random stuff is in the pool Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 57. EternalBlue Grooming ● Step 1. Send all of FEALIST except last Trans2 secondary ○ The NT FEA Buffer will not be reserved yet Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 58. EternalBlue Grooming ● Step 2. Send initial N grooms ○ Use up all of SrvNet look-aside, forcing new pool allocations Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 59. EternalBlue Grooming ● Step 2. Send initial N grooms ○ Use up all of SrvNet look-aside, forcing new pool allocations Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 60. EternalBlue Grooming ● Step 2. Send initial N grooms ○ Use up all of SrvNet look-aside, forcing new pool allocations Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 61. EternalBlue Grooming ● Step 2. Send initial N grooms ○ Use up all of SrvNet look-aside, forcing new pool allocations Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 62. EternalBlue Grooming ● Step 2. Send initial N grooms ○ Use up all of SrvNet look-aside, forcing new pool allocations Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 63. EternalBlue Grooming ● Step 2. Send initial N grooms ○ Use up all of SrvNet look-aside, forcing new pool allocations Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 64. EternalBlue Grooming ● Step 3. Send allocation connection ○ Session Setup bug SMALLER than NT FEA Buffer Size Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 65. EternalBlue Grooming ● Step 4. Send hole buffer connection ○ Session Setup bug SAME SIZE as NT FEA Buffer Size Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 66. EternalBlue Grooming ● Step 5. Close allocation connection ○ Memory slot can now hold smaller miscellaneous allocations Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 67. EternalBlue Grooming ● Step 5. Close allocation connection ○ Memory slot can now hold smaller miscellaneous allocations Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 68. EternalBlue Grooming ● Step 6. Send final groom packets ○ Hopefully a groom is after the Hole buffer Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 69. EternalBlue Grooming ● Step 6. Send final groom packets ○ Hopefully a groom is after the Hole buffer Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 70. EternalBlue Grooming ● Step 6. Send final groom packets ○ Hopefully a groom is after the Hole buffer Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 71. EternalBlue Grooming ● Step 6. Send final groom packets ○ Hopefully a groom is after the Hole buffer Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 72. EternalBlue Grooming ● Step 6. Close Hole connection ○ Memory the same size as NT FEA Buffer is now available Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 73. EternalBlue Grooming ● Step 7. Send final FEALIST exploit fragment ○ Erroneously calculated to fit in the free Hole buffer, overflows into groom Free pool memory Random pool memory SrvNet look-aside buffers SrvNet "groom" buffer Session setup "allocation" buffer Session setup "hole" buffer Exploit OS/2 to NT FEA overflow
  • 74. struct _SRVNET_BUFFER { // ... SRVNET_WSK_STRUCT* WskContext; // ... MDL MDL1; // MapSysVa = &Buffer MDL MDL2; CHAR Buffer[]; };
  • 75. struct _SRVNET_BUFFER { // ... SRVNET_WSK_STRUCT* WskContext; // ... MDL MDL1; // MapSysVa = &HAL MDL MDL2; CHAR Buffer[]; };
  • 76. struct _SRVNET_BUFFER { // ... SRVNET_WSK_STRUCT* WskContext; // ... MDL MDL1; // MapSysVa = &HAL MDL MDL2; CHAR Buffer[]; };
  • 77. struct _SRVNET_BUFFER { // ... SRVNET_WSK_STRUCT* WskContext; // ... MDL MDL1; // MapSysVa = &HAL MDL MDL2; CHAR Buffer[]; };
  • 78. struct _SRVNET_WSK_STRUCT { // ... PVOID FunctionTable[]; // ... };
  • 79. struct _SRVNET_WSK_STRUCT { // ... PVOID FunctionTable[]; // ... };
  • 80. struct _SRVNET_WSK_STRUCT { // ... PVOID FunctionTable[]; // ... };
  • 82. EternalBlue payload 1. Hook syscall handler ○ DISPATCH_LEVEL IRQL ■ Many routines are off limits
  • 83. EternalBlue payload 1. Hook syscall handler ○ DISPATCH_LEVEL IRQL ■ Many routines are off limits 2. On next syscall… ○ Transition from user mode ○ Run DOUBLEPULSAR backdoor ■ SrvTransaction2DispatchTable
  • 84. EternalBlue payload 1. Hook syscall handler ○ DISPATCH_LEVEL IRQL ■ Many routines are off limits 2. On next syscall… ○ Transition from user mode ○ Run DOUBLEPULSAR backdoor ■ SrvTransaction2DispatchTable 3. Restore syscall handler
  • 88. Race Condition ● TRANSACTION.Executing ○ BOOLEAN locking mechanism ○ Checked during Secondary transactions ■ NOT SET if Primary has all data!
  • 89. Race Condition ● TRANSACTION.Executing ○ BOOLEAN locking mechanism ○ Checked during Secondary transactions ■ NOT SET if Primary has all data! ● Modify executing TRANSACTION! ○ Info leak on single-core ○ Stack overwrite on multi-core
  • 90. Race Condition ● TRANSACTION.Executing ○ BOOLEAN locking mechanism ○ Checked during Secondary transactions ■ NOT SET if Primary has all data! ● Modify executing TRANSACTION! ○ Info leak on single-core ○ Stack overwrite on multi-core ● CHAMPION ○ CHAMPIONS WIN RACES!
  • 91. Leak a TRANSACTION ● Need a SMB which echos back Data ○ MS-RAP ■ WNetAccountSync ■ NetServerEnum2 ○ NT_RENAME ■ Requires valid FID ● Primary Trans ○ Data > CONNECTION.MaxBufferSize ■ Requires restart (multiple response SMB) ■ Always winrar a Race! ● Secondary Trans sends more data ○ Increases DataCount ○ Use Displacement=0
  • 92. SrvSmbQueryPathInformation(WorkContext) { UNICODE_STRING objectName; if (subCommand == SMB_INFO_QUERY_EA_SIZE) { SrvQueueWorkToBlockingThread(WorkContext); return SmbTransStatusInProgress; } if (subCommand == SMB_INFO_IS_NAME_VALID) { transaction->InData = &objectName; } // ... }
  • 93. SrvSmbQueryPathInformation(WorkContext) { UNICODE_STRING objectName; if (subCommand == SMB_INFO_QUERY_EA_SIZE) { SrvQueueWorkToBlockingThread(WorkContext); return SmbTransStatusInProgress; } if (subCommand == SMB_INFO_IS_NAME_VALID) { transaction->InData = &objectName; } // ... } STEP 1
  • 94. SrvSmbQueryPathInformation(WorkContext) { UNICODE_STRING objectName; if (subCommand == SMB_INFO_QUERY_EA_SIZE) { SrvQueueWorkToBlockingThread(WorkContext); return SmbTransStatusInProgress; } if (subCommand == SMB_INFO_IS_NAME_VALID) { transaction->InData = &objectName; } // ... } STEP 2 STEP 1
  • 95. Overwrite RIP/EIP to Shellcode ● After SMB_INFO_IS_NAME_VALID, send another secondary trans ○ Displacement = stack offset ● Overwrite RET WorkerThread to Stage 0 Shellcode DataDisplacement = offset
  • 96. RWX Shellcode Location ● No DEP (x86) ○ Write at LEAKED TRANSACTION->InData ● DEP (x64) ○ Write at LEAKED TRANSACTION->CONNECTION.ClientOSName ■ I.E. same Session Setup bug used in EBlue
  • 97. EternalChampion RCE Trigger ● 8 SMB per TCP packet Trans2 SMB_INFO_QUERY_EA_SIZE Restart Trans2 Secondary SMB_INFO_IS_NAME_VALID InData = &stack Trans2 Secondary DataDisplacement Overwrite RET
  • 98. EternalChampion RCE Trigger ● 8 SMB per TCP packet ● 8 packets per attempt Trans2 SMB_INFO_QUERY_EA_SIZE Restart Trans2 Secondary SMB_INFO_IS_NAME_VALID InData = &stack Trans2 Secondary DataDisplacement Overwrite RET
  • 99. EternalChampion RCE Trigger ● 8 SMB per TCP packet ● 8 packets per attempt ● 42 attempts Trans2 SMB_INFO_QUERY_EA_SIZE Restart Trans2 Secondary SMB_INFO_IS_NAME_VALID InData = &stack Trans2 Secondary DataDisplacement Overwrite RET
  • 100. EternalChampion Shellcode 1. Loop CONNECTION.TransactionList ○ Find special identifier at start of Data buffer ■ AKA: egghunter
  • 101. EternalChampion Shellcode 1. Loop CONNECTION.TransactionList ○ Find special identifier at start of Data buffer ■ AKA: egghunter 2. Copy primary payload from egg (DOUBLEPULSAR) ○ Access to pool functions ■ Can allocate large RWX space ○ Execute main stage
  • 102. EternalChampion Shellcode 1. Loop CONNECTION.TransactionList ○ Find special identifier at start of Data buffer ■ AKA: egghunter 2. Copy primary payload from egg (DOUBLEPULSAR) ○ Access to pool functions ■ Can allocate large RWX space ○ Execute main stage 3. ++SrvBlockingWorkQueues->AvailableThreads
  • 103. EternalChampion Shellcode 1. Loop CONNECTION.TransactionList ○ Find special identifier at start of Data buffer ■ AKA: egghunter 2. Copy primary payload from egg (DOUBLEPULSAR) ○ Access to pool functions ■ Can allocate large RWX space ○ Execute main stage 3. ++SrvBlockingWorkQueues->AvailableThreads 4. KPCR->Prcb.CurrentThread->StartAddress ○ Use global kernel data structures ○ Resume execution ■ JMP to srv!WorkerThread() loop
  • 105. EternalChampion Patch SrvSmbTransaction/SrvSmbNtTransaction(): if (all_data_received) { transaction->Executing = TRUE; ExecuteTransaction(transaction); } else { // send interim response }
  • 107. PTRANSACTION SrvFindTransaction ( IN PCONNECTION Connection, IN PSMB_HEADER SmbHeader, IN USHORT Fid OPTIONAL) { if (SmbHeader->Command == SMB_COM_WRITE_ANDX) OtherInfo = Fid; else OtherInfo = SmbHeader->Mid; // search TransactionList by UID/TID/PID/OtherInfo }
  • 108. SrvSmbWriteAndX ( PWORK_CONTEXT ) { transaction = SrvFindTransaction(connection, header, fid); if (writeMode & SMB_WMODE_WRITE_RAW_NAMED_PIPE) { RtlCopyMemory(transaction->InData, ...); transaction->InData += writeLength; transaction->DataCount += writeLength; } }
  • 116. Info Leak ● Bug #1 - TRANS_PEEK_NMPIPE ○ Expects MaxParameterCount=16 ■ But takes client value ○ MaxParameterCount to fill min. Space ○ MaxDataCount=1
  • 117. Info Leak ● Bug #1 - TRANS_PEEK_NMPIPE ○ Expects MaxParameterCount=16 ■ But takes client value ○ MaxParameterCount to fill min. Space ○ MaxDataCount=1 ● Bug #2 - DataCount > MaxDataCount ○ Put >1 data in pipe ○ Peek
  • 118. Paged Pool Grooming Methods 1. Fish-in-a-Barrel ○ “Remote API” (MS-RAP) ■ Fish/Dynamite 2. Matched Pairs ○ “Lattice” ■ Brides/Grooms → Romance? 3. Classic ○ “Sandwich” ■ Frag/Padding ● Each: 3 exploit attempts
  • 119. Fish-In-A-Barrel ● SrvXsPortMemoryHeap - 1MiB ○ Private heap, Pre-allocated ■ No fighting in the paged pool with other kernel allocations ○ MS-RAP transactions only, Rarely used ■ Babby's first heap feng shui ● Removed in 7+ ○ SMAP? ○ privesc??
  • 120. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 121. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 122. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 123. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 124. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 125. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 126. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 127. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 128. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 129. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 130. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 131. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 132. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 133. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 134. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 135. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 136. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 137. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 138. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 139. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 140. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 141. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 142. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 143. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 144. Fish-In-A-Barrel Free Heap memory Fish (victim) Dynamite (exploit)
  • 145. Matched Pairs “Lattice” ● All versions of Windows ○ Including, 7+ ● Must overcome pool contention ○ Not a private heap ■ Normal, Paged Pool ■ PASSIVE_LEVEL
  • 146. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 147. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 148. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 149. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 150. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 151. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 152. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 153. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 154. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 155. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 156. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 157. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 158. Matched Pairs “Lattice” Free Heap memory Grooms Brides (victim) Exploit (pointer shift)
  • 160. Write-What-Where Primitive 1. Exploit Transaction (PID=X) ○ Set VictimTrans->InData to &WHERE ○ Set VictimTrans->Executing to FALSE ○ Increase reference count! ■ Don’t want it to get freed ○ etc...
  • 161. Write-What-Where Primitive 1. Exploit Transaction (PID=X) ○ Set VictimTrans->InData to &WHERE ○ Set VictimTrans->Executing to FALSE ○ Increase reference count! ■ Don’t want it to get freed ○ etc... 2. VictimTrans Secondary (MID=0) ○ Trans Data Block = WHAT[]
  • 163. Read-Where Primitive 1. Exploit Transaction (PID=X) ○ Modify VictimTrans to point at LeakTrans ■ Address inferred by its contents ■ VictimTrans now modifies LeakTrans
  • 164. Read-Where Primitive 1. Exploit Transaction (PID=X) ○ Modify VictimTrans to point at LeakTrans ■ Address inferred by its contents ■ VictimTrans now modifies LeakTrans 2. VictimTrans Trans_Secondary (MID=0) ○ LeakTrans->OutData = &WHERE ○ LeakTrans->Setup = TRANS_PEEK_NMPIPE ○ LeakTrans->MaxDataCount = size_t
  • 165. Read-Where Primitive 1. Exploit Transaction (PID=X) ○ Modify VictimTrans to point at LeakTrans ■ Address inferred by its contents ■ VictimTrans now modifies LeakTrans 2. VictimTrans Trans_Secondary (MID=0) ○ LeakTrans->OutData = &WHERE ○ LeakTrans->Setup = TRANS_PEEK_NMPIPE ○ LeakTrans->MaxDataCount = size_t 3. LeakTrans Trans_Secondary ○ Echos back the LeakTrans->OutData
  • 166. Quest for RWX NonPagedPool 1. Exploit Trans ○ Set VictimTrans->OutParameters = NULL 2. Send Secondary Victim Transaction if (VictimTrans->OutParameters == NULL) VictimTrans->OutParameters = WorkContext->ResponseBuffer; 3. Read Primitive ○ Read address just set 4. Write Primitive ○ Send shellcode
  • 167. Quest to Execute the Shellcode 1. Locate Transaction2DispatchTable ○ FIND in srv.sys .data section (read primitive) 2. Hook a Trans2 subcommand ○ REPLACE a pointer in table (write primitive) 3. Fake Trans2 executes the hook ○ Subcommand = hooked index ○ Similar methodology as DOUBLEPULSAR ● Given: ○ Read/write primitives ○ Leaked TRANSACTION has CONNECTION pointer
  • 168. Locate Transaction2DispatchTable 1. Read in LeakTrans->CONNECTION
  • 169. Locate Transaction2DispatchTable 1. Read in LeakTrans->CONNECTION 2. CONNECTION->EndpointSpinLock ○ SrvGlobalSpinLocks ■ Inside PE .data section
  • 170. Locate Transaction2DispatchTable 1. Read in LeakTrans->CONNECTION 2. CONNECTION->EndpointSpinLock ○ SrvGlobalSpinLocks ■ Inside PE .data section 3. Read backwards, SrvSmbWordCount ○ Illegal commands = -2 (0xfe) ○ If we see a bunch of fefe, we're close
  • 171. Locate Transaction2DispatchTable 1. Read in LeakTrans->CONNECTION 2. CONNECTION->EndpointSpinLock ○ SrvGlobalSpinLocks ■ Inside PE .data section 3. Read backwards, SrvSmbWordCount ○ Illegal commands = -2 (0xfe) ○ If we see a bunch of fefe, we're close 4. Transaction2DispatchTable ○ Function pointers #0x14 == #0x15 ■ SrvTransactionNotImplemented
  • 172. EternalRomance Info Leak Patch #1 SrvSmbTransaction() Before: if (subCommand == TRANS_PEEK_NMPIPE) { maxParameterCount = MAX(16, maxParameterCount); } SrvAllocateTransaction(&Transaction, ...); Transaction->MaxParameterCount = maxParameterCount;
  • 173. EternalRomance Info Leak Patch #1 SrvSmbTransaction() After: if (subCommand == TRANS_PEEK_NMPIPE) { maxParameterCount = 16; } SrvAllocateTransaction(&Transaction, ...); Transaction->MaxParameterCount = maxParameterCount;
  • 174. MS17-010 Scanners ● Max TRANSACTION allocation size=0x10400 ○ 0xC0000205 - STATUS_INSUFF_SERVER_RESOURCES ● Send MaxParameterCount+MaxDataCount > 0x10400
  • 175. MS17-010 Scanners ● Max TRANSACTION allocation size=0x10400 ○ 0xC0000205 - STATUS_INSUFF_SERVER_RESOURCES ● Send MaxParameterCount+MaxDataCount > 0x10400 ○ Patch fixes MaxParameterCount to 16 ■ Passes allocation routine! ○ Different NT error (i.e. invalid FID)
  • 176. EternalRomance Info Leak Patch #2 SrvCompleteExecuteTransaction() New Code: if (transaction->DataCount > transaction->MaxDataCount) transaction->DataCount = transaction->MaxDataCount; if (transaction->ParameterCount > transaction->MaxParameterCount ) transaction->ParameterCount = transaction->MaxParameterCount ;
  • 177. EternalRomance RCE Patch #1 SrvSmbWriteAndX() Before: RtlCopyMemory(transaction-> InData, ...); transaction->InData += writeLength; transaction->DataCount += writeLength;
  • 178. EternalRomance RCE Patch #1 SrvSmbWriteAndX() After: RtlCopyMemory(transaction-> InData + transaction->DataCount, ...); transaction->InData += writeLength; transaction->DataCount += writeLength;
  • 179. EternalRomance RCE Patch #2 1. SrvSmbNtTransaction/SrvSmbTransaction() New Code: SrvAllocateTransaction(&Transaction, ...) Transaction->SecondaryCommand = /* 0x38 */ SMB_COM_NT_TRANS_SECONDARY; SrvInsertTransaction(&Transaction);
  • 180. EternalRomance RCE Patch #2 1. SrvSmbNtTransaction/SrvSmbTransaction() New Code: SrvAllocateTransaction(&Transaction, ...) Transaction->SecondaryCommand = /* 0x38 */ SMB_COM_NT_TRANS_SECONDARY; SrvInsertTransaction(&Transaction); 2. SrvFindTransaction() New Code: if (FoundTrans->SecondaryCommand != NewSmb->Command) return NULL;
  • 182. EternalSynergy 1.0.1 ● Same buffalo overflow, read/writes, as EternalRomance ○ Matched pairs ○ "Classic" ● Same info leak as EternalChampion ○ NT_Rename Race Condition ■ TRANS_PEEK_NAMED_PIPE is fixed… ● Srv.sys is using NonPagedPoolNx for Work Items! ○ Needs DEP bypass
  • 183. Quest for RWX Memory (via remote read) ● Given: Connection Type Pointer Dereference Offset WORK_QUEUE Connection->PreferredWorkQueue variadic
  • 184. Quest for RWX Memory (via remote read) ● Given: Connection Type Pointer Dereference Offset WORK_QUEUE Connection->PreferredWorkQueue variadic KTHREAD PreferredWorkQueue->IrpThread 0x198
  • 185. Quest for RWX Memory (via remote read) ● Given: Connection Type Pointer Dereference Offset WORK_QUEUE Connection->PreferredWorkQueue variadic KTHREAD PreferredWorkQueue->IrpThread 0x198 KPROCESS IrpThread->Process 0x220
  • 186. Quest for RWX Memory (via remote read) ● Given: Connection ● Obtain: ProcessListEntry.Blink ○ nt!KiProcessListHead* Type Pointer Dereference Offset WORK_QUEUE Connection->PreferredWorkQueue variadic KTHREAD PreferredWorkQueue->IrpThread 0x198 KPROCESS IrpThread->Process 0x220 PVOID KProcess->ProcessListEntry.Blink 0x240 * https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kprocess/index.htm
  • 187. Quest for RWX Memory (via remote read) ● Given: Connection ● Obtain: ProcessListEntry.Blink ○ nt!KiProcessListHead* ● Search backwards by page size for 'MZ' ○ ntoskrnl.exe PE header Type Pointer Dereference Offset WORK_QUEUE Connection->PreferredWorkQueue variadic KTHREAD PreferredWorkQueue->IrpThread 0x198 KPROCESS IrpThread->Process 0x220 PVOID KProcess->ProcessListEntry.Blink 0x240 * https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kprocess/index.htm
  • 188. ntoskrnl.exe RWEXEC Section ● Remote read offset 0x250 into &ntoskrnl.exe ● Check section headers: ○ +0x08 == 0x1000 (Virtual Size: 4096) ○ +0x0C <= 0x800000 (Virtual Addr: 0x271000 &KxUnexpectedInterrupt) ○ +0x24 == 0xE80000A0 (Segment permissions: RWX)
  • 189. Additional Research ● @sleepya_ ○ https://github.com/worawit/MS17-010 ● @n_joly ○ https://hitcon.org/2017/CMT/slide-files/d2_s2_r0.pdf ● @jennamagius and @zerosum0x0 ○ https://keybase.pub/jennamagius/EternalBlue_RiskSense-Exploit-Analysis-and-Port-to-Microsoft-Windows-10.pdf ● @msftsecresponse ○ https://blogs.technet.microsoft.com/srd/2017/06/29/eternal-champion-exploit-analysis/ ○ https://blogs.technet.microsoft.com/srd/2017/07/13/eternal-synergy-exploit-analysis/ ● @swithak ○ https://swithak.github.io/SH20TAATSB18/Home/ ● @francisckrs ○ https://speakerdeck.com/francisck/danderspritz-how-the-equation-groups-2013-tools-still-pwn-in-2017 ● @msuiche ○ https://www.comae.io/reports/us-17-Suiche-TheShadowBrokers-Cyber-Fear-Game-Changers.pdf