Stealthy Persistence While Using Windows Terminal.

By misusing the setting file

bob van der staak
InfoSec Write-ups

--

I stumbled upon an interesting write-up explaining a technique to create persistence on a windows machine using Windows Terminal profiles.

However while readying this writeup I noticed the terminal window would hang and this would be a clear indication of compromise.

Hanging cmd not that stealty persistent

So I investigated further to find a method to eliminate the hanging cmd window and make it a bit more stealthy.

The terminal documentation

As explained in the other writeup, windows terminal has a settings.json which gives the possibility to change the configuration of the terminal. This makes it possible to change the colours, but also other configurations like which terminals to start.

The settings file can be found under the following folder.

“%localappdata%\Packages\Microsoft.WindowsTerminal_<PackageID>\LocalState\”

I noticed on the Microsoft documentation that there was an method not used in the other writeup which is called startupActions.

startupAction property explained by microsoft documentation

With startupActions it is possible to define which terminal windows you want to start on start up.

This is an important feature because we want to start a “dirty” terminal, which will execute some actions and automatically destroys itself afterwards. To limit the amount of time that a victim may view the dirty tab.

But first we needed to define the dirty profile. I defined a profile for the terminal which on start up would start PowerShell and start a new process ( in this instance notepad). This command would create the same persistence, but without showing a hanging terminal.

{
"guid": "{d21dfa6e-2fd4-40ff-86fe-19ccdb2535f9}",
"name": "Proof Of Concept",
"hidden": true, "commandline":"%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe Start-Process %SystemRoot%\\System32\\notepad.exe",
},

After that we can add it in our startupActions.

startupActions property

With this line, when starting the terminal application all specified tabs will be opened automatically. For the best stealth it is wise to validate if there already is a default profile specified.

default profile explained by microsoft

If there is one specified and there is no startupAction yet. You can integrate that profile in the start up options which creates an almost seamless integration. In the event that there is no default profile defined, the terminal will fall back to the PowerShell GUID as the default so then add that one instead.

The code below makes use of the startupActions to start the default Powershell property and loads the Proof of concept profile.

"startupActions": "new-tab -p \"Windows PowerShell\" — title \"PowerShell\" ; new-tab -p \"Proof Of Concept\" — title \"cmd hanging\" ",

The interesting part with this technique is that the executed program is only part of the wt terminal for a few seconds. Afterwards because Powershell is terminated, the program is decoupled from the windows terminal.

Process monitor showing the killing of powershell under WindowsTerminal and the starting of Notepad.exe

Here PowerShell will be killed almost immediately.

Notepad.exe is no longer located under WindowsTerminal but has the same pid.

After the extra PowerShell is killed (which started the program notepad), it will have a non existing parent, but the pid is still the same!

After the killing of Powershell the program has a “non-existing process” as parent

For some extra stealth the hidden parameter can be set to true. This makes sure it isn’t an selectable item in the drop-down menu in the terminal interface

Hide profile explained by microsoft documentation

Now it isn’t visible anymore in the dropdown menu in the terminal. Making it less likely to be spotted when the user is trying to opening new terminals.

The Proof of concept option is not visable from the dropdown because of the hidden attribute.

As a second option you could at an icon. There is a small window where the cmd window can be shown to the user. With the standard hanging icon from windows it could give some extra dimension and make it more logical why it would error and close

Therefor the icon property could be set.
“icon”: “<icon location>”

icon option explained

The greate write-up that gave me the inspiration can be found here: https://nasbench.medium.com/persistence-using-windows-terminal-profiles-5035d3fc86fe. which is from Nasreddine Bencherchali

Conclusion

This trick gives some easy possibilities to force persistence on devices using the Microsoft terminal application. With in mind that of 18 october 2022 the Microsoft terminal is now the default terminal this is a valid and noticeable risk.

It was fun though to read more in dept on how the terminal functions worked and find a method which is almost seamless to create persistence with a tool I use almost daily.

I Haven’t seen it yet on the Mitre Att&ck framework, maybe it is a new sub technique for T1546?

For more information on the terminal you can visit:

And if you want to discuss anything related to infosec I’m on linkedin: https://www.linkedin.com/in/bobvanderstaak/

From Infosec Writeups: A lot is coming up in the Infosec every day that it’s hard to keep up with. Join our weekly newsletter to get all the latest Infosec trends in the form of 5 articles, 4 Threads, 3 videos, 2 GitHub Repos and tools, and 1 job alert for FREE!

--

--