Introduction Danderspritz, NSA post-exploitation tool, has some interesting reconnaissance scripts, which were used in covert operations. Basically, they gather as much information as possible about drivers, memory, network traffic ( ) or (Personal Security Product — AV software). DSky PSP Most of the scripts are in “ ” directory, inside “ ” catalog which deserve additional attention, you can find full list . Ops Windows here How to setup lab, run Fuzzbunch and Danderspritz . here Everything was said about this framework, so I will focus only on post-exploitation modules. At the end of article, I will show how to write your own plugin, so bear with me. Not every tool can be accessed in Danderspritz at the beginning, you have to add an alias to make it work, example with module. SimonTatham Adding alias in Danderspritz and after that it can be used with given alias. You can also execute it by typing “ ” python windows\SimonTatham.py module is responsible for getting session and credentials to WinSCP by looking in registry and storage. This module can be also accessed in Overseer. SimonTatham Reboot history In some cases persistent may be not necessary knowing that system is rebooted once per year. Moreover, together with other environmental data it may be used as sandbox detection. Script uses couple sources in order to determine history of reboot — , , , and . Also It checks for logs, which is error troubleshooting tool for old version of Windows, to gather even more information about OS. eventlogs dumps registry keys logfiles Dr. Watson Event logs File contains 12 functions responsible for retrieving and parsing information regarding reboot history. First one looks into event logs for following IDs: reboothistory.py — Event log startup 6005 — Event log service was stoppped 6006 — Last shutdown was unexpected 6008 — User restarted or shut down system 6009 — Application crashed or hung 1001 — System shut down or restarted by other task 1074 — Shutdown by kernel power manager 109 — System went into sleep mode 42 — Shutdown during sleep mode(?) 41 — Proper shutdown(?) 13 — System started 12 Reboot history Some of the IDs are weakly documented, but from what I found every one refer to restart, shutdown OS by user, other task or kernel. Also sleep mode wasn’t omitted during checks. In addition, boot log is created, which means it measures system’s boot, shutdown and up time based on specific event IDs. Code measuring boot time Registry, dumps and logs As previously mentioned script checks for presence of specific registry entries and files to examine reboot history. “ ” is key that include useful information about unexpected applications behavior like crashes or hangs, extracted values are “ ” and “ ”. HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\CrashControl Dumps Minidumps Checking crashcontrol When path is extracted from registry it calls function in order to retrieve metadata from dump. checkdumps Function ‘ ’ looks for files with extension . in directory and finally displays metadata of found files. Dump file keeps memory dump of Windows crashes but in this case content is not important, only metadata like ‘ ’, ‘ ’, ‘ ’ are gathered. checkdumps DMP %%SystemRoot%% Modified Accessed Created Retrieving metadata from dump files Windows Error Reporting ( ) functionality is also abused to retrieve errors and crashes information, from current user as well as from local machine, the information about can be found in and is in WER WER software\\microsoft\\windows\\windows error reporting ReportQueue Microsoft\\Windows\\WER\\ReportQueue ‘ ’ looks for registry key in “ ”, which tracks every shutdown. The most important keys here are and , . Checkdirtyshutdown software\microsoft\windows\currenversion\reliability DirtyShutdown DirtyShutdownTime more details about this keys Windows server logs every shutdown into “ ”, this location is also checked in function “ ”. Windows\system32\logfiles\shutdown checkshutdownlogfiles is a tool for Windows 98, Millennium and XP and can help you troubleshoot issues with application by creating system snapshot and then analyze it. Dr. Watson What is interesting here, script checks only “ ” directory, which is correct for Windows 2000. In XP and ME, paths are “ ” and “ ” adequately. It might indicate that script wasn’t regularly updated even at that time. %%allusersprofile%%\documents\DrWatson All Users\Application Data\Microsoft\Dr Watson C:\Windows\Drwatson Dr. Watson check You can find full script here https://github.com/francisck/DanderSpritz_docs/blob/master/Ops/PyScripts/windows/reboothistory.py User query This module tracks signs of activity of Windows Media Player, Internet Explorer, Remote Desktop Protocol and others. Check can be done for specific user or for every user in system. It achieves that by iterating through and picking Security Identifier Number ( ) between 42 and 49 characters. Additional, one function can convert SID to user name by using command. HKEY\USERS SID sidlookup Check for all users last files are accessed by querying key . It is simple way to hijack what user was watching recently and then inspect it in details. Windows Media Player Software\Microsoft\MediaPlayer\Player\RecentFileList Only is targeted in this reconnaissance script and last typed urls are gathered. It’s worth to note that Ripper, other script from collection, is responsible for retrieving credentials, storage and history of other browsers. The key which is used in this case is . Internet Explorer Software\Microsoft\Internet Explorer\TypedURLs Even last Windows popups are in interest of script. It queries to get list of files that were accessed in Windows dialog popups i.e. during download or save. Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSaveMRU Another interesting functionality is USB monitoring, in some cases it can proof that two separate people plugged this same USB stick or phone into his computer. Last connected devices can be found in and it’s only key checked, however also class keeps history of connected removable devices. Moreover, this way may allow to detect virtual environment. SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\{53f56307-b6bf-11d0–94f2–00a0c91efb8b {53f5630d-b6bf-11d0–94f2–00a0c91efb8b} USB devices It has something common with next, very precise function — “ ”. Registry keeps track of your last commands, or displayed hints in autocomplete box in Windows Run. The responsible key is . start_run Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU is next Windows functionality that collects detailed information about operating system and its usage. Precisely speaking, key keeps metadata like timestamp, number of execution or path to executed software on machine. Its structure requires couple words of introduction, in registry, key (path) is encoded and value is binary representation of information data. This value is different for various systems, for XP, ME it’s 16 bytes and for newer ones is 72 bytes. Script has no checks for Win 95 and 98, where the value is 8 bytes, as well as for focus time value. UserAssist SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\UserAssist ROT13 What you can dig from binary is number of execution (bytes 4–8 bytes), focus time (bytes 12–16) and timestamp (bytes from 60 to 68). To find this module, we need to dig little deeper to another project called ‘ ’, which then calls ‘history’ and ‘ ’ modules. (More about modules and structure later on). dsz User Assist https://github.com/francisck/DanderSpritz_docs/blob/master/Ops/PyScripts/windows/userquery.py#L45 This project required decompilation but after that, python code became easily readable. Below code clearly shows how described data are retrieved for Windows 7. Obtaining data from UserAssist Of course, script saves decoded path of executed file and other useful data as well, I strongly encourage you to read about User Assist possibility in forensics and general usage ROT13 here You can turn off this feature in your system by setting key named “ ” and creating with name “ ” and value . Settings DWORD NoLog 1 Last thing is history of connections, whole cache is RDP Software\Microsoft\Terminal Server Client\Default Full script — https://github.com/francisck/DanderSpritz_docs/blob/master/Ops/PyScripts/windows/userquery.py Persistence — Survey If you don’t know it already, each time when DanderSpritz connects to the target, survey takes place. It is bunch of python scripts trying to gather as much detailed information about environment, where implant is already installed. It has modular design, which means each script is in separate file in “ ” directory. Among others modules, persistence checking is present. The idea behind this module is simple, it investigates what software are running during startup. It’s kind of similar to ( ) which looks for indicator of compromise of known malware and other APT groups. Now, let’s try focus more on structure of the code itself, first executed file is from “ ”. The most important parameter it gets is “ — ”, which is obvious. lib/ops/survey TeritorialDispute TeDi launcher.py survey/launcher.py module After some basic arguments and path checks, method “ ” is called with given parameters. Worth to highlight is that parameter “ ” stands for “ ” and allows to execute script in background. plugin_launcher bg background launcher.py https://github.com/francisck/DanderSpritz_docs/blob/86bb7caca5a957147f120b18bb5c31f299914904/Ops/PyScripts/survey/launcher.py “ ” also parses flags and if everything is fine, it executes specific module with help of . plugin_launcher runpy plugin_launcher The actual script is in and takes only one parameter “ — ” which stands for “ ” and is 3600 by default. persistence.py lib/ops/survey maxage Maximum age of information to use before re-running commands for this module It contains dictionaries with registry keys, values to check and known good values. However, there is no checks for schedule task. In addition, paths to , and are generated but no used in script. %Program Files% %AllUsersProfile% %WINROOT% Following items were extracted from script: s_ystem\\currentcontrolset\\Services\\tcpip\\Parameters\\Winsock_ — Value to check — , known goods — ‘ ’, ‘ ’ HelperDllName wshtcpip.dll %%SystemRoot%%\\System32\\wshtcpip.dll — Value to check — Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows AppInit_Dlls — Values to check — , known goods — ‘ ’, ‘‘ Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon Shell, Userinit explorer.exe C:\\Windows\\system32\\userinit.exe’ — known goods — ’: ‘“ ”’, ‘ ’: ‘“ ” Software\\Microsoft\\Windows\\CurrentVersion\\Run[OnceEx] VMware Tools C:\\Program Files\\VMware\\VMware Tools\\VMwareTray.exe VMware User Process C:\\Program Files\\VMware\\VMware Tools\\VMwareUser.exe Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Custom %%SystemRoot%%\AppPatch\Custom What is interesting here, it executes ‘ ’ on . I found , however it was 1 year ago. First has occurred in 2016 but script is quite older than that — 2013 dir %%SystemRoot%%\AppPatch\Custom one case when this method was used for persistence Black Hat talk persistence.py So let’s jump into “ ” method in , as far as I’ve learned, each module is executed this same way. So situation looks identical with ‘ ’ command, which retrieves mentioned registry keys. get_dirlisting lib\ops\files\dirs.py registryquery This one is straightforward, it creates new instance of , which refers to command and then checks if results haven’t been cached. getDszCommand DanderSpritZ get_dirlisting function Structure of system commands like ‘ ’, ‘ ’ or ‘ ’ is organized this same way as plugins for survey but each module is in directory. “ ” method parses delivered commands and after that it imports specified plugin from . At the end it returns callable object, as it’s presented on below screenshot. dir registryquery processes lib\ops\cmd getDszCommand ops\cmd function getDSZCommand Returned object is checked against cache database in method “ ” (2 screenshots up) in . For each project local database is created and goal of ‘ ’ is to check db cache based on proper tags and target ID generic_cache_get ops\project generic_cache_get https://github.com/francisck/DanderSpritz_docs/blob/86bb7caca5a957147f120b18bb5c31f299914904/Ops/PyScripts/lib/ops/project/__init__.py#L274. I will omit this part, it’s subject for separate article. After all of checks, finally actual command is execute by calling method. Command object was given from ‘ ’ and include ‘ ’ method. command.execute() getDszCommand execute generic_cache_get function Finally, actual command is executed with help of ‘_actual_execute’ method, you can see that in called from , which refers to another project ‘ ’ and interact with DanderSpritz directly, you can find decompiled code of . RunEx dsz\cmd dsz dsz\cmd.py here Executing command At the end lets look at execution flow of persistence Survey. Flow of execution Writing own post exploitation Danderspritz modules Now, we are armored with all necessary information to build our own plugin. Scripts collection contains almost everything but I found no checks for virtual machines and last connected networks. To obtain information about first of them we need to go to directory. Details about connected networks are located in . [username]\Documents\Virtual Machines HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\ID Output of checking last connected network and virtual machines Retrieving network information This might be helpful to track victim travels based on his WIFI SSID in for example hotels. Network name, last connected time and category are the most interesting fields. Places that stores network profiles are , and . We can use second one to obtain profile ID and then pass it to retrieve more detailed information about each profile. At the end script shows nice output thanks to function. Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\ID SOFTWARE\Microsoft\Widows\CurrentVersion\HomeGroup\NetworkLocations\Home windows\system32\networkprofiles pprint Code for checking last connected networks Virtual machines It’s always good to know if trojanized machine is used for something more than regular mail checking. It may turn out that it belongs to researcher or contains top secret VM’s First script enumerates all users in and then checks if each one has directory “ ” in his Documents. This example includes interacting with Danderspritz in order to retrieve content of possible found directories. It’s possible to ask user about next decision, it can be achieved by “ ” method. c:\Users folder Virtual Machines dsz.ui.Prompt Virtual machines check Full script — https://github.com/woj-ciech/other/blob/master/example.py Conclusion As it was shown, the reconnaissance scripts are not rocket science, however there are lot of interesting tricks to gather intelligence from infected machine. Thanks to modular design, Danderspritz can be easily scalable and it’s very simple to write additional plugin and put it into Danderspritz. I’m not surprised of amount of the reconnaissance scripts, where every information can be priceless and possible save lives.