DFIR Breakdown: Impacket Remote Execution Activity – atexec

Impacket is a collection of python classes designed to provide low level access to numerous network protocols. In addition to the python classes, Impacket contains a folder of sample scripts that demonstrate how to use many of the python classes for various use cases such as: dumping passwords from memory, executing commands remotely, interacting with kerberos tickets, and much more. Unfortunately, many of these scripts are abused by threat actors. 

The sample folder contains several scripts that demonstrate how to perform remote command execution using various techniques and protocols. This blog post will focus on how to detect atexec.py remote execution activity from various DFIR artifacts. We will discuss the other remote execution scripts that Impacket offers (wmiexec.py, smbexec.py, psexec.py, and dcomexec.py) in following posts. 

We will cover the following topics:

  • Atexec basics
  • How threat actors use atexec
  • Atexec artifacts
  • Detecting atexec activity
  • How Cyber Triage helps

Atexec Basics

Atexec.py achieves remote execution through the use of remotely created scheduled tasks. For a refresher on scheduled tasks, check out our blog post on Windows Scheduled Tasks in DFIR Investigations.

Remote task creation/execution/deletion is possible through the use of RPC procedures such as SchRpcRegisterTask, SchRpcRun, and SchRpcDelete. The command provided to atexec is put into the task action and is then executed on the remote system. Command output is retrieved by redirecting output to a temp file that is then read via the ADMIN$ network share. 

Example usage of atexec running whoami on 10.1.12.193

Let’s breakdown the key actions that occur when running atexec without optional arguments:

  1. A scheduled task with a random 8 character name, containing only ascii letters, is created in the root of the Windows task folder by calling SchRpcRegisterTask.
  2. The scheduled task is run using the SYSTEM account by calling SchRpcRun. By default, atexec wraps the command provided to it into a cmd.exe command and redirects all output to a randomly named .tmp file. The name will match the task.
    • Ex: “cmd.exe” /C whoami > C:\Windows\Temp\BwBxpEDt.tmp 2>&1
  3. The schedule task is deleted by calling SchRpcDelete.
  4. Command output is displayed to the user by reading the .tmp file which is accessed via ADMIN$ share.
  5. The .tmp file is deleted.

There are two optional arguments that can impact what artifacts are left behind:

  1. -SilentCommand:  Runs the provided command directly instead of indirectly through cmd.exe. No output will be sent back to the user. As a result, the temporary file is not created and ADMIN$ share access is not attempted.
  2. -session-id [SESSION_NUMBER]: Similar to -SilentCommand, this argument will run commands directly instead of through cmd.exe, and no output is sent back. However, it additionally changes the user context that the action runs as. The action will run under the context of the user with the associated sessionID on the remote system instead of the SYSTEM account. 

Note that the user provided in the command, in the above case “qa”, is not the user the remote command will run as. That account is used for remote authentication, so atexec is able to create tasks remotely and access the ADMIN$ share to get output back. 

How Threat Actors Use Atexec

Atexec can be executed from an attacker’s system resulting in DFIR artifacts only on the targeted systems. However, there is nothing preventing an adversary from bringing atexec into a compromised environment and using it to access other machines. This can be noisy for an attacker as they would need to install python (if not already present) and bring the necessary Impacket python classes. To overcome this issue, threat actors will compile the python script into an executable that can be run without any dependencies.Two common tools that provide such ability are PyInstaller and Auto PY to EXE. This is how APT10 used atexec as documented in a report by PWC. Additionally, there are existing repos that have released executable versions of the Impacket python scripts as found here and here.

Red Canary reported Impacket, in both its 2023 and 2024 threat detection reports, as the second most common threat found among their customers. This does not directly say anything about atexecs usage; nonetheless, it’s important to understand Impackets popularity and the capabilities it provides. The DFIR Report reported an incident last year where the threat actor used atexec as one of the tools for remote execution. Additionally, a SOC-as-a-Service provider reported Lacefly APT using atexec.

Atexec artifacts 

There are numerous artifacts created by atexec activity on a targeted endpoint depending on the audit policy in place and the arguments passed to atexec. We will briefly touch on a few high-value artifacts so we can discuss detection rules that can be used to identify this activity. 

Event log activity will be the most interesting to us because of the transient nature of these scheduled tasks (task is created/ran/deleted within milliseconds for each command executed) unlike when tasks are used as persistence by attackers. As a result, we will look at the following event logs:

  • Security event log
  • Microsoft-Windows-TaskScheduler/Operational event log

Security Event Log

Within the Security event log, there are three groups of artifacts we are interested in: scheduled tasks, processes, and network share access. 

The two relevant events for scheduled tasks are event 4698 (scheduled task created) and 4699 (scheduled task deleted). Note that these events require Audit other object access to be turned on for them to generate. Event 4698 will show the user that created the task, the XML task definition, and the time the task was created. Event 4699 will contain the time the task was deleted which is key for one of our detection rules that identifies tasks that are created and deleted within a small time window.

Next, we have event 4688 (process created) to record process execution history. This event will provide the user that the command executed as and the command itself. This is the next best event to have when trying to detect atexec activity if the previous task events are not available. However, like the previous events, process creation is not enabled by default and must have Audit process creation turned on as well as a group policy enabled for command line auditing to get the process arguments.

Lastly, we have network share access events. The most interesting event is 5145 (detailed share access) which requires Audit detailed file sharing to be enabled. This event can provide a few unique pieces of information. First, when the task is created, there will be an IPC$ share access with a relative target of “atsvc” this indicates a scheduled task is being interacted with remotely. 

5145 event showing 10.1.0.188 accessing atsvc endpoint to interact with scheduled tasks

The second is when the share is for ADMIN$ and the relative target is for a file matching the .tmp file pattern created by atexec.

5145 showing access to ADMIN$ for .tmp file to be deleted

In both scenarios, the source IP will be included which gets us the system that initiated the atexec activity. Aside from being less verbose than the previously mentioned events, this event is also extremely noisy as every file accessed on a network share is logged. 

Microsoft-Windows-TaskScheduler/OperationalEvent Log

The TaskScheduler event log records scheduled task related events. Its auditing is all or nothing and requires task history (from task scheduler UI) to be enabled. Unlike the task events from the security event log, we will not get the XML task definition; however, we will still get most of the important details needed for detection across multiple events. 

The events of most interest are 106 (task registered), 129 (created task process), 100 (task started), and 141 (task registration deleted). Event 106 provides the time the task was created as well as the task name (as do all of the events). Event 129 will give us the command that ran (without arguments) and the PID of the process the command ran with.  

Event 129 shows exe that ran, PID of process, and task name

The PID can be used to map back to a 4688 event to get arguments if proper auditing is enabled. 

Shows command args for process 41372 (0xa19C hex representation)

Event 100 will contain the user that the task action ran with, and 141 provides the time of task deletion. Combining multiple events together will allow for a stronger detection rule.

There are numerous other artifacts that can be left behind related to process execution, logon sessions, file creation/deletion, etc… but most if not all require correlation across multiple different events to build up enough information to detect atexec activity.  

Detecting Atexec Activity

There are several detection rules that we can use to detect atexec activity from the previously discussed artifacts. Some rules are more accurate at identifying atexe activity. Our recommendation is to combine multiple rules together when possible depending on the data available for the given artifacts. 

We should note that the rules below are based on the original atexec script. All of the detection rules we will discuss can be evaded by making modifications to the script. That is why it is best to apply multiple rules when possible to account for an attacker modifying one indicator but ignoring or missing others. Even with this risk, many threat actors still use the Impacket scripts as is. 

Rule 1: Flag Scheduled task with “<StartBoundary>2015-07-15T20:35:13.2757294</StartBoundary>”  in the XML definition. 

Rule 1 has a very high detection confidence as the task definition is hardcoded into atexec.py at line 128. We are looking for a scheduled task that has a uniquely defined calendar trigger. The high fidelity timestamp makes this a great detection opportunity as it represents the time the trigger was added to the original task definition and then copied into the atexec.py code. This rule requires task XML which will only be found in event 4698.

Event 4698 highlighting the unique calendar trigger created by atexec

Rule 2: Flag scheduled task with action with exe of “cmd.exe and arguments ending with ”&gt; %windir%\Temp\[a-zA-Z]{8}.tmp 2&gt;&amp;1”

Rule 2 has a high detection confidence as the action pattern is unique to atexec activity. This rule requires access to task XML which will only be found in event 4698. Note that > and & have been escaped in this rule.

Event 4698 showing newly created task with actions matching atexec pattern

It’s important to note that this rule will fail if the command pattern is altered in atexec.py (defined at line 121/122) or if using either of the optional atexec arguments we previously discussed.

Rule 3: Flag scheduled task with name of \[a-zA-Z]{8} (8 ascii letters)

This rule has a medium detection confidence at detecting bad activity. False positives can arise from scheduled tasks created in the root task folder from users and organizations if the task names are 8 ascii letters. However, weeding out these false positives by eye is trivial as they will not look randomly generated. This rule can be applied to all of the task related events in both Security and TaskScheduler event logs. 

Event 106 showing the creation of a task following atexec naming convention

Detection can be avoided if the random name generation process is altered in atexec.py. The temporary name is defined on line 115 and the task is created on 171.

Rule 4: Flag scheduled task that is created and then deleted within 500 ms

This detection rule is not specific to atexec but to remote execution via temporary scheduled tasks. It should have little false positives as we have not run into any normal scenarios of tasks being created and then immediately being deleted. It can be combined with rule 3 to have higher confidence that the activity is related to atexec. Rule 4 can be applied to both event log scheduled task events for detection.

TaskScheduler event log depicts task created and deleted under 1s

Modification of the atexec.py script can result in evasion by simply adding a sleep timer before running and/or deleting the task.

Rule 5: Flag process with exe of “cmd.exe” and args ending with “\[a-zA-Z]{8}.tmp 2>&1”

This rule is similar to rule 2; however, note that > and & are no longer escaped as we are not looking in XML data. It can apply to event 4688 (process created) as well as any other sources of process information that contain arguments. Rule 5 faces the same evasion risk as outlined in rule 2.

Process creation event showing arguments matching atexec pattern

Rule 6: Flag network share access to windows\temp\[a-zA-Z]{8}.tmp (8 ascii letters) via ADMIN$

This rule is specific to event 5145 but could be expanded to any artifact by looking for random looking 8 ascii letter .tmp strings. However, that is more likely to have a higher false positive rate. Similar to rule 3, this can be evaded easily by modifying atexec.py to change how random file names are created. 

How Cyber Triage Can Help

It can be difficult to remember all of the locations where evidence can be found or the various detection rules that can be applied. This is where Cyber Triage shines, as one of our goals is to automate collection and scoring as much as possible so analysts do not need to worry about remembering all of the details.

One of the biggest differences between Cyber Triage and other tools is that we merge many artifacts together and group them under high level types like “Triggered Tasks.” This is where you’d find any sort of persistence on a system. You can filter down to see “Scheduled Tasks”. 

Cyber Triage trigger task view

From here, we aim to make a single entry for a given task even when it may be represented in multiple sources. For example, instead of having to go review task files on disk, tasks in the registry, and tasks in the events logs, we merge all of these sources together (when possible) and show a single unified entry. You can click on this entry and view the sources tab to see all of the locations that this data came from. This can make review much faster and easier as all of the data is in a single location merged together. 

The same concept applies to our adaptive collector. Instead of having to know all of the various scheduled task artifacts, you can simply collect triggered tasks or skip collecting triggered tasks depending on your need. 

Aside from the merging of multiple artifacts into a single entry, Cyber Triage will apply its automated scoring to bubble up items that may be relevant to your case. In the case of atexec, Cyber Triage will flag both the scheduled task and process related artifacts if they match atexec command line patterns. 

Process flagged as bad for having atexec command pattern
Scheduled task flagged as bad for having atexec command pattern

You can go to the analysis results tab to check out more information about the analysis applied. In this case, we can see that the threat detected links back to two MITRE IDs: one for the Impacket software (S0357) and another for Scheduled Task (T1053-005)

Analysis result tab showing more information about analysis via MITRE

Conclusion

In summary, atexec is a python based script that is abused by attackers for remote command execution. Although Impacket provides atexec as a python script, other repos have gone through the work to convert the popular Impacket scripts to executable binaries with no dependencies. 

Remote command execution is achieved through the use of scheduled tasks created/run/deleted via RPC. Numerous artifacts are generated on the targeted system due to this activity and depending on the systems audit settings detection can be easy. The two most valuable events are 4698 (task created) and 4688 (process created). The task created event provides both a unique piece of data in the XML task definition along with the unique action pattern used by atexec. The process started event will also contain the same unique command line pattern except it will not have > and & escaped like in the 4698 event. Other events and artifacts on the system can be used in combination to build up to the conclusion that atexec was used on a system.

If you are looking for a faster and more comprehensive way to analyze systems, then try Cyber Triage. You can download a free one week trial version here: https://www.cybertriage.com/download-eval/