Over the past couple of months, Shadow brokers have published quite a few exploits aimed at Windows based servers. This post is going to summarize the main points of the Eternal Exploits that were served up on a platter. These will include EternalBlue (EB), EternalChampion (EC), EternalRomance (ER) and EternalSynergy (ES).
All four of these exploits utilize the Windows SMB Remote code execution Vulnerability however, each have different characteristics. The CVEs assigned to each of these are as follows: CVE-2017-0143,CVE-2017-0144, CVE-2017-0145, CVE-2017-0146, and CVE-2017-0148. This post has four main parts. We will deep-dive into the vulnerability, followed by a discussion of how the vulnerability was weaponized to create Read/Write/eXecute primitives that are used as building blocks throughout the exploit. We will then walk through their execution and see how these primitives were used to deliver a full exploit. Finally, we will briefly discuss the effect of recent mitigations on the presented exploit techniques.
Root Cause Analysis
The root cause of these exploits lies in functionality of Microsoft’s Server Message Block (SMB) version 1. The SMB headers consist of 4 basic parts, the UID, PID, TID and OtherInfo. The exploit happens when the command type of the SMB message is not considered when its determining if that message is part of the transaction. This means that if the header fields match the corresponding transaction fields, then the message would be considered part of that transaction.
The OtherInfo field in the SMB is where the MID or Multiplex ID is stored. The MID is used to multiplex groups of commands that belong to the same logical thread. The caveat to this however is that in the case of a SMB_COM_WRITE_ANDX message, the MID is replaced with an FID. This causes an issue because if there is an existing SMB_COM_WRITE_ANDX transaction containing the FID, then the new SMB message with a matching MID will be included blindly into that transaction.
Incoming SMB messages are copied by an initial handler, into the corresponding transaction buffer. This buffer is called the InData buffer. Here comes the cool part! The SMB_COM_TRANSACTION_SECONDARY handler automatically thinks that the InData address is the beginning of the buffer however, if you remember the SMB_COM_WRITE_ANDX transaction, these are automatically assumed to be the end of the existing data and the InData is updated accordingly!
This means that an attacker can utilize this to inject a SMB_COM_TRANSACTION_SECONDARY message into the SMB_COM_WRITE_ANDX transaction and cause the InData to point past the start of the buffer. This in turn causes the buffer overflow during the copy action.
1. Allocate a transaction using SMB_COM_TRANSACTION
2. The SMB_COMWRITE_ANDX message is sent and is designed specifically to exploit the confusion caused by the Buffer overflow
3. The SMB_COM_TRANSACTION_SECONDARY message is sent aimed at the exact same transaction. This causes the InData to point to the victim transaction where the target write address is computed.
4. That incoming message is written with enough data to cause the dataDisplacement to spew into the neighboring transaction. The memory layout begins to overwrite the victim transaction’s OtherInfo field.
This process continues to corrupt all fields that contain the same or other transactions based on what value the attacker used in the OtherInfo field and can be predicted. This means that if you know the value, you can tell what fields in all transactions will be corrupted.
The attacker can now leverage this attack by overwriting the victim transaction and pointing it to the write address. This enables the attacker to modify the memory contents using arbitrary write primitive.
Similar vector as the ES exploit but instead of focusing on WRX through buffer overflow, EC aims to utilize an information leak and then follows that up with remote code execution.
1. Multiple SMBs sent via a single packet to the server
a. The primary transaction request for the NT RENAME. Important note: this will be immediately executed
b. Secondary Transaction which will cause a race condition for the primary transaction
c. A bunch of Primary Transaction requests are now sent to flood the pool with srv!TRANSACTIONs. The purpose of this flood is to get one of these transactions to allocated immediately after the srv!TRANSACTION because these track the Primary Transaction Request.
The primary request is assumed to have ALL expected data so that means that DataCount == TotalDataCount. This means that because this is assumed, the parameter validation for the Secondary Transaction is lackadaisical at best and will assume that all data will fit in the InData buffer allocation.
It is now important to note that because there is a race condition caused by step one, the secondary transaction request handler is useless because it is already being executed by the ExecuteTransaction. Now the ExecuteTransaction copies all the DataCount bytes from the InData which is now incrementally larger and is then sent back to the client resulting in an out-of-bounds data leak. The end result is that the connection data is then leaked back to the client.
EternalRomance uses a very similar attack vector as EternalSynergy with the exception that to get the exploit to execute, it uses an attack called Double Pulsar.
Double Pulsar is a persistent backdoor that uses the SMB vulnerability to download malware from a remote site. The malware first generates two sets of IP addresses; one internal IP and one public IP. After the attacker connects to the machine via port 445, it utilizes the similar EternalSynergy and exploits SMB. Through this communication, the attacker can send the WannaCry Ransomware.