The Equation Group’s post-exploitation tools (DanderSpritz and more) Part 1
This blog post was originally hosted on Kudelski Security’s research blog. It is still available here.
Since the April 14th leak of the Equation Group’s hacking tools, I have been busy testing (and decompiling / reversing) the tools, understanding and documenting capabilities, and identifying potential indicators of compromise (IOCs).
In the first part of this series I will provide an overview of the DanderSpritz post-exploitation framework that was included Shadow Broker’s April 2017 release. I will also provide technical details on how the DanderSpritz framework gathers system and network information, bypasses AV, disables security auditing, and provides critical information about the target machine to the operator.
Later blog posts in this series will cover additional DanderSpritz capabilities and technical details as to how they function. In part two, I will provide details on how DanderSpritz and its tools can be used to gain persistence, to install a keylogger, dump passwords, capture network traffic, edit Windows event logs, and more.
The goal of this blog post is to provide details on the capabilities of the DanderSpritz framework and other tools that were included in the leak, not to provide an overview of the FuzzBunch exploitation framework (and its exploits) or the DoublePulsar backdoor. Many other organizations have already written detailed blogs posts about those subjects.
The DanderSpritz framework is a full featured post-exploitation framework used by the Equation Group after a machine or network has been successfully compromised. The framework includes several tools for data gathering, gaining persistence, and moving laterally within an environment. Think of it as the nation state version of Metasploit’s Meterpreter but with automated Anti-Virus detection & avoidance, and ton of (previously) undetectable tools to dump passwords, gather information, gain persistence, and move laterally.
The DanderSpritz framework was leveraged by the Equation Group after successfully exploiting a machine and deploying the PeddleCheap “implant”. The “traditional” path to get to the post-exploitation stage is as follows:
- Exploit the machine using EternalBlue (or other highly effective exploit)
- Build the implant Dynamic Link Library (DLL) or executable using pc_prep (PleddleCheap prep).
- pc_prep allows the operator to configure callback IPs and ports, proxy information (including proxy IPs, usernames & passwords) and keys to use for network traffic encryption.
- Use DoublePulsar (or other backdoors) to load the DLL into memory
- Receive the PeddleCheap callback with DanderSpritz and begin post-exploitation work.
DanderSpritz User Interface Overview
DanderSpritz and PeddleCheap interaction (callback, listening, and port knocking).
The DanderSpritz framework includes a fully functional GUI which allows the operator to listen for callbacks, connect to a listening PeddleCheap instance (more on this later), and “port knock” (yes, really) to trigger a PeddleCheap call back:
Once the machine being attacked calls back (using PeddleCheap), the DanderSpritz payload is sent to the host and information gathering begins.
The DanderSpritz post-exploitation framework has a GUI which provides the operator access to quick a few “easy to use” plugins as shown below:
Network map / network viewer
The DanderSpritz framework has graphical components which allows operators to quickly view other systems on the same subnet / VLAN as the target machine and potentially run commands as as other users (to be used for lateral movement, think PSEXEC):
View running / suspicious processes
Operators can also quickly view running processes. The application has the ability to filter processes based on certain criteria (such as: safe, security products, Core OS, Malicious, Unknown) and take several actions, including getting the security token from the process:
As you can see in the screenshot above, DanderSpritz can provide a lot of information about running processes including privileges and modules being loaded.
When selecting a specific module, operators can access additional information about its current location in memory, hashes, and more:
Operators can also use DanderSpritz to quickly browse the target machine’s file system and get any files that may be of interest (leveraging the already established C&C connection for exfiltration):
The framework also includes the capability to take and view screenshots of what is currently displayed on the target machine.
Technical Details — Information Gathering, AV Bypasses, security auditing bypasses, and more!
The very first thing the DanderSpritz framework does when connecting to a target machine is kick off an information gathering “survey” using the appropriately named survey.py python script.
The survey script collects, stores, and displays the information to the operator via the “terminal” within the DanderSpritz GUI. The first thing it does is collect IP, DNS, and mac address information and displays it to the operator so they can confirm they are connected to the correct target:
The survey script collects, stores, and displays the following information:
- Network interface information (IPs, mac addresses, DNS servers, etc)
- Operating System Information (Architecture, Version, Platform, Service pack and if Terminal Services is installed)
- Currently running processes
- List of hardware drivers
- Installed software & packages (It also seems to extract software keys. Perhaps the EQ is tight on software budgets?)
- All file & folders in the “Program Files” directory
- Running services
- Checks for Personal Protection Products (PSPs), essentially, it checks what AV is installed
- If “actions” are required to continue exploitation (such as automatically adding exceptions to AV system configurations), they are automatically performed.
- Checks the security auditing configuration
- And offers the operator the option to “dork” (temporarily disable) security auditing
- Network information (routing tables, ARP tables, NetBIOS data, etc)
- Scheduled tasks
- Performs a persistence checks (identifies if any EQ implants or software is installed persistently)
- Dumps passwords
- Memory & Disk usage information
- Connected USB drives and other USB devices
- Files modified recently
Once the survey module ends, DanderSpritz begins running several “monitor” modules which monitor for processes, file creations, network connections, and any changes to the system (diffed hourly). These monitors are used to warn the operator of any activity that may be related to a defender attempting to analyze the machine or collect forensic information.
All of this information is collected, stored, and logged for later usage in the “DSZOPSDISK”’s log file directory (D:\DSZOPSDISK\logs by default). Interestingly, if you re-connect to a machine that you’ve used DanderSpritz on before, DanderSpritz will check its target history, determine the likelihood that this is a previous target (based on the machines MAC addresses),and lets you make a selection:
AntiVirus checks and bypasses (checkpsp.py)
The survey script collects and provides the operator a lot of information that is useful in determining the likelihood that they would be detected. Before doing anything that could be detected, the framework looks for known Personal Protection Products (PSPs) using the checkpsp.py python script:
In the screenshot above, you can see that DanderSpritz recognized that I’ve been on the target previously and checked for changes in the PSPs configuration.
The checkpsp.py script has capabilities including:
- Identifying the PSP being used
- Collecting & storing PSP configuration information (used to highlight changes in the PSPs configuration later)
- Taking “action” on PSPs in an attempt to hide the presence of these post-exploitation tools (if possible) or prevent the operator from taking actions that would trigger AV detections
In order to identify the PSPs configuration, the checkpsp.py script relies on several XML files to provide details on where the PSP stores its configuration information:
The screenshot above shows the information used by the checkpsp.py script to gather configuration information for the McAfee suite of AntiVirus products.
Additionally, the script attempts to bypass AV protections by using information contained in additional XML files which tell DanderSpritz which “actions” should be automatically performed to bypass the AV system or remain hidden by preventing the operator from taking actions that would trigger AV detections.
In the case of McAfee, the checkPSP script tells DanderSpritz to prevent the operator from registering services or adding autorun items in order to avoid detection.
The version of checkpsp.py script included in the Shadow Broker’s April 2017 leak (which includes information / tools from 2013) has logic to bypass the following AV engines:
It’s possible that there are no bypass actions for other AV suites because the DanderSpritz tools were not detected or because the bypass actions had not been written yet (again, this release is from 2013).
Security auditing checks & bypass (auditing.py)
The next check performed on a system is to identify the security auditing configuration enabled. This is done by executing the auditing.py python script. The script returns the types of events which are audited on the system and provides the ability for the operator to “dork” (temporarily disable) auditing:
In order to gather the systems security auditing configuration, the DanderSpritz framework first loads a DLL on the target machine called “Audit_Target_Vista.DLL” (depending on the Windows version). The PeddleCheap implant used to load the code has the ability to load the DLL directly into memory or via file as seen here:
DanderSpritz has 4 different DLLs which can potentially be loaded to provide this capability. A list of them are below with links to the VirusTotal analysis for each:
Once the DLL has been loaded, the script identifies which security audit policy settings are enabled by issuing a series of RPC queries provided by the DLL and parsing the data to identify security auditing policies and which parameters are used. A screenshot of the RPC data parsing script is below:
The script then attempts to “dork” (disable) auditing by issuing a series of RPC calls to disable all security auditing temporarily (this is automatically enabled again when the DanderSpritz session is disconnected)
Stealthily disabling security auditing via RPC (provided by the DLL) allows the operator to continue post-exploitation activities with little concern that his or her activities will be logged and reported.
Display and check installed drivers (driverlist.py)
The DanderSpritz survey continues by gathering a list of loaded and installed drivers, comparing them against known good or known bad driver names and hashes, and printing out a list of suspicious or unknown drivers installed. It does so by running the driverlist.py python script.
In order to gather driver data, DanderSpritz first loads a DLL onto the target machine called “Drivers_Target.dll”. Once again, this DLL can be loaded directly into memory or via a file on disk. There are 2 DLLs which could potentially be used for this task. Links to VirusTotal analysis of both of the DLLs is available below:
Once the DLL has been loaded, DanderSpritz once again uses RPC queries to gather driver information:
Below is the output of the “driverlist.py –verbose” command being run on my test machine:
As you can see above, the driverlist.py script performs the following actions:
- Gathers the list of loaded drivers
- Hashes all driver files
- Loads a list of known drivers (legitimate and malicious) and their hashes from a driver database
- Compares hashes and disregards known good drivers
- Begins checking unknown drivers against a series of regexes to identify their potential use
- Prints out a list of unknown or suspect drivers
The driverslist.py script checks the driver’s file name against 5 different regexes to identify their potential use:
As you can see in the output of the screenshot above, several drivers installed on my test system begin with the name “dump” (due to CrowdStrike being installed) and thus DanderSpritz highlighted them as potentially being used to dump system memory.
Persistence checks (persistence.py)
DanderSpritz attempts to identify if PeddleCheap or other Equation Group “implants” may be installed on the system persistently. It does so by running the persistence.py python script.
The script first loads a python list (which contains several python dictionaries) of known good registry keys and their expected values if the legitimate software were to be installed (instead of the Equation Group’s persistence mechanisms):
The script then iterates through these lists, which contain key:value pairs of potential registry locations and what their legitimate value should be:
If the script detects a key which could be used malicious for implant persistence, but has a value different than it’s “known good” it will display the results in “yellow” to warn the operator to verify the value:
In image above, the script highlighted “wship.dll” as a potential method of persistence. The script expected the legitimate DLL that is used for that registry key (which is wshtcpip.dll). In this scenario, as I had previously used other tools in the DanderSpritz framework to gain persistence on the machine (more on this in part two of this series) the “warning” is displayed and has indeed identified the driver I used to gain persistence on this machine.
More to follow!
As mentioned in the introduction, this is intended to be an in-depth series of blog posts that cover DanderSpritz’s post-exploitation capabilities and documents how they work from a technical perspective. In part two of the series I will be covering how the tools can be used to gain persistence, to install a keylogger, dump passwords, capture network traffic, edit Windows event logs, and more.
In the meantime, feel free to review more DanderSpritz code and contribute to the documentation project on my Github repository:
If you have any questions, corrections, or additional information please reach out: