PsExec and NTUSER data

TL;DR - Using PsExec to deploy & execute a file in the context of a user results in the specified user's NTUSER data profile being created despite never interactively logging onto the system itself.
Last week I was involved in the response to ransomware being deployed in an enterprise environment. I was able to trace PsExec events back to the original staging host, however on all of the encrypted servers I observed NTUSER data (NTUSER.dat and default folders - Desktop, Downloads, Documents, etc) being created immediately prior to ransomware notes being deployed.
I initially thought this indicated an interactive logon from a remote host, however I wasn't able to locate any network logon/authentication logs (that's a separate issue outside the scope of this particular page) or Desktop/Terminal Services events. I had a timeline of PsExec events, a timeline of events related to ransomware (files being renamed, ransomware note creation times etc) and a timeline of NTUSER data being created.
In this environment there was no SIEM, no EDR, no syslog, no verbose logging, only plain old antivirus. With access to Windows Event Logs and the system drive MFT, I needed to answer the following questions;
  1. 1.
    What occurred on the system which resulted in the creation of NTUSER data?
  2. 2.
    Was the logon an interactive, or non-interactive logon event?
My running theory was that NTUSER data was caused by PsExec execution, however I wasn't able to quantify this with the data available to me at the time (more data was later available which explained what happened, but this write up is in the context of limited data). I also hadn't been presented with this particular scenario, so instead of fumbling and guessing, I reached out to @randomaccess and started discussing plausible scenarios.
A special thank you to @randomaccess over at https://thisweekin4n6.com/about/ for helping me brainstorm a few ideas and for a little nudge to complete this write up
😉
🍺
In order to test my theory, I followed the following steps using my DF lab;
  1. 1.
    Create a Windows 10 and Windows Server 2019 virtual machine (standalone, no domain),
  2. 2.
    Create second privileged user (default Administrator account was created during setup),
  3. 3.
    Using the Administrator account, create a test file (test.txt) in a common, easily accessible location (C:\Windows\Temp),
  4. 4.
    Execute PsExec on 'attacker' host to open test file on the victim host; PsExec -i -u TARGETUSERNAME \\REMOTEHOST notepad C:\windows\test.txt
  5. 5.
    Shutdown VM
  6. 6.
    Acquire VMDK from ESXi VMFS volume
  7. 7.
    Extract Windows Event Logs & parse using EZ tools' EvtxECmd
  8. 8.
    Extract MFT & parse using EZ tools' MFTECmd
  9. 9.
    View timeline for both MFT and Windows Event Log.
Confirming the process was executed on the receiving host;
If you open Process Explorer on the receiving host, you'll see the following process tree (this would be useful if you're trying to identify a process/service/parent PID/PID from a memory dump)
winnit.exe > services.exe > PSEXESVC.exe > notepad.exe
Of course these are just the defaults. PsExec also provides a switch (-r) to rename the remote service to something else, so it may appear as something unfamiliar (randomservicename.exe) or something 'familiar' in an unfamiliar/strange location.
The following artefacts were generated in the MFT on the victim host.
C:\Windows\Temp\test.txt was created by me, then PsExec was used ~6 minutes later to open it using Notepad.
MFT from receiving host
MFT from receiving host (cont.)
What's interesting about the above events showing the target account logging on (it was only ever via PsExec, never directly from the terminal/login screen or over remote desktop) is that LogonType 2 (record 1578 above) traditionally indicates it was a hands-on-keyboard/interactive logon when it wasn't. This highlights the risk of interpreting single artefacts (such as an event record, MFT entry, etc) in isolation, as it doesn't provide any context and is (potentially) subject to misinterpretation. If an analyst was presented with the above records, it may cause them to conclude that a person logged onto the server (via a traditional interactive method, such as hands-on-keyboard etc) using the admin.ldap account which is clearly not what happened.
That being said, this testing shows (and what appears to have happened during the initial engagement) is that PsExec was used from a remote host, via the local network, using the -i flag which executes the specified command in the the context of the specified user. See the full list of PsExec switches here.
Flag
Explanation
-i
Run the program so that it interacts with the desktop of the specified session on the remote system. If no session is specified the process runs in the console session. This flag is required when attempting to run console applications interactively (with redirected standard IO).
To answer the original questions;
1. What occurred on the system which resulted in the creation of NTUSER data?
There were no authentication logs which suggest the destination account had ever logged onto to the system prior to the ransomware being deployed. The destination account's NTUSER data was created at the time of the incident due to lateral movement and subsequent authentication via PsExec, which was used to execute the ransomware executable.
2. Was the logon an interactive, or non-interactive logon event?
Based on system logs (including service logs), we were able to show that PsExec was executed from a remote host in the context of the specified user. The user account itself was never used to log onto the victim host in a traditional interactive/hands-on-keyboard sense.
As a side note, this is what Harlan Carvey often speaks about when he refers to opportunities to write detection rules, leverage insight via system/process/executable telemetry etc based on usage of native binaries. We know PsExec is a legitimate binary, but do you actually use it in your environment? If you know the 'usual' circumstances in which you use (or perhaps more importantly, you do not use!) native binaries then you can begin to build detection rules based on otherwise 'innocent' system behaviour.
If you have a central logging system such as Wazuh/Elastic/Graylog, your flow could be similar to this for alerts;
System logs > Wazuh/Elastic/Graylog platform > PsExec usage detected > trigger alert (email/PagerDuty/Slack/Teams/etc)
Logs (related to account activitity, not PsExec behaviour)
Event ID 4624 (Microsoft Windows Security Auditing) Successful Logon Event ID 4776 (Microsoft Windows Security Auditing) NTLM Authentication Request Event ID 4648 (Microsoft Windows Security Auditing) A logon was attempted using explicit credentials Event ID 5625 (Microsoft Windows Security Auditing) Failed Logon Event ID 62443 (Microsoft Windows Shell Core) AppDefaults Logon User Profile Created