BOOL kuhl_m_kernel_addWorldToMimikatz(SC_HANDLE monHandle)
{
	BOOL status = FALSE;
	DWORD dwSizeNeeded;
	PSECURITY_DESCRIPTOR oldSd, newSd;
	SECURITY_DESCRIPTOR dummySdForXP;
	SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
	EXPLICIT_ACCESS ForEveryOne = {
		SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG | SERVICE_INTERROGATE | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_PAUSE_CONTINUE | SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL | READ_CONTROL,
		SET_ACCESS,
		NO_INHERITANCE,
		{NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_WELL_KNOWN_GROUP, NULL}
	};
	if(!QueryServiceObjectSecurity(monHandle, DACL_SECURITY_INFORMATION, &dummySdForXP, 0, &dwSizeNeeded) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
	{
		if(oldSd = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, dwSizeNeeded))
		{
			if(QueryServiceObjectSecurity(monHandle, DACL_SECURITY_INFORMATION, oldSd, dwSizeNeeded, &dwSizeNeeded))
			{
				if(AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, (PSID *)&ForEveryOne.Trustee.ptstrName))
				{
					if(BuildSecurityDescriptor(NULL, NULL, 1, &ForEveryOne, 0, NULL, oldSd, &dwSizeNeeded, &newSd) == ERROR_SUCCESS)
					{
						status = SetServiceObjectSecurity(monHandle, DACL_SECURITY_INFORMATION, newSd);
						LocalFree(newSd);
					}
					FreeSid(ForEveryOne.Trustee.ptstrName);
				}
			}
			LocalFree(oldSd);
		}
	}
	return status;
}
BOOL CNTScmService::QueryObjectSecurity(SECURITY_INFORMATION dwSecurityInformation,
                                        PSECURITY_DESCRIPTOR& lpSecurityDescriptor) const
{
  //Validate our parameters
  ATLASSUME(m_hService != NULL);
  ATLASSERT(lpSecurityDescriptor == NULL); //To prevent double overwrites, this function
                                        //asserts if you do not send in a NULL pointer

  DWORD dwBytesNeeded;
  BOOL bSuccess = QueryServiceObjectSecurity(m_hService, dwSecurityInformation, NULL, 0, &dwBytesNeeded);
  if (!bSuccess && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  {
    lpSecurityDescriptor = static_cast<PSECURITY_DESCRIPTOR>(new BYTE[dwBytesNeeded]);
    DWORD dwSize;
    bSuccess = QueryServiceObjectSecurity(m_hService, dwSecurityInformation, lpSecurityDescriptor, dwBytesNeeded, &dwSize);
  }

  return bSuccess;
}
Esempio n. 3
0
void changeServiceAccess(const char* szName)
{
	gcAssert(szName);

	SC_HANDLE scm = nullptr;
	SC_HANDLE Service = nullptr;

	BOOL                 bDaclPresent   = FALSE;
	BOOL                 bDaclDefaulted = FALSE;
	DWORD                dwSize         = 0;
	EXPLICIT_ACCESS      ea;
	PACL                 pacl           = nullptr;
	PACL                 pNewAcl        = nullptr;
	PSECURITY_DESCRIPTOR psd            = nullptr;
	SECURITY_DESCRIPTOR  sd;


	//open connection to SCM
	scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT);

	if (!scm)
		throw gcException(ERR_NULLSCMANAGER, GetLastError(), "Failed to open the Service Control Manager");

	gcWString wName(szName);

	try
	{
		//open service
		Service = OpenService(scm, wName.c_str(), READ_CONTROL|WRITE_DAC);
		if (!Service)
			throw gcException(ERR_NULLSERVICE, GetLastError(), gcString("Failed to open service: {0}", szName));


		// Get the current security descriptor.
		if (!QueryServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, psd, 0, &dwSize))
		{
			if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
			{
				psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);

				if (!psd)
					throw gcException(ERR_SERVICE, gcString("Failed heap allocation for service service: {0}", szName));

				//get securtty info
				if (!QueryServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, psd, dwSize, &dwSize))
					throw gcException(ERR_SERVICE, GetLastError(), gcString("QueryServiceObjectSecurity failed for service: {0}", szName));
			}
		}

		if (!psd)
			throw gcException(ERR_SERVICE, gcString("Failed heap allocation for service service: {0}", szName));

		// Get the DACL.
		if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted))		
			throw gcException(ERR_SERVICE, GetLastError(), gcString("GetSecurityDescriptorDacl failed for service: {0}", szName));


		DWORD SidSize;
		PSID TheSID;

		SidSize = SECURITY_MAX_SID_SIZE;
		// Allocate enough memory for the largest possible SID.
		if(!(TheSID = LocalAlloc(LMEM_FIXED, SidSize)))
		{    
			LocalFree(TheSID);
			throw gcException(ERR_SERVICE, GetLastError(), gcString("LocalAlloc failed for  service: {0}", szName));
		}

		if(!CreateWellKnownSid(WinWorldSid, nullptr, TheSID, &SidSize))
		{
			LocalFree(TheSID);
			throw gcException(ERR_SERVICE, GetLastError(), gcString("CreateWellKnownSid failed for  service: {0}", szName));
		}

		wchar_t everyone[255];
		wchar_t domain[255];
		DWORD eSize = 255;
		DWORD dSize = 255;
		SID_NAME_USE rSidNameUse;

		if (!LookupAccountSid(nullptr, TheSID, everyone, &eSize, domain, &dSize, &rSidNameUse))
		{
			LocalFree(TheSID);
			throw gcException(ERR_SERVICE, GetLastError(), gcString("LookupAccountSid failed for  service: {0}", szName));
		}

		LocalFree(TheSID);

		// Build the ACE.
		BuildExplicitAccessWithName(&ea, everyone, SERVICE_START|SERVICE_STOP|READ_CONTROL|SERVICE_QUERY_STATUS|PROCESS_QUERY_INFORMATION, SET_ACCESS, NO_INHERITANCE);

		if (SetEntriesInAcl(1, &ea, pacl, &pNewAcl) != ERROR_SUCCESS)
		{
			throw gcException(ERR_SERVICE, GetLastError(), gcString("SetEntriesInAcl failed for  service: {0}", szName));
		}

		// Initialize a NEW Security Descriptor.
		if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))			
			throw gcException(ERR_SERVICE, GetLastError(), gcString("InitializeSecurityDescriptor failed for  service: {0}", szName));

		// Set the new DACL in the Security Descriptor.
		if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))						
			throw gcException(ERR_SERVICE, GetLastError(), gcString("SetSecurityDescriptorDacl failed for  service: {0}", szName));

		// Set the new DACL for the service object.
		if (!SetServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, &sd))		
			throw gcException(ERR_SERVICE, GetLastError(), gcString("SetServiceObjectSecurity failed for  service: {0}", szName));

	}
	catch (gcException &e)
	{
		if (Service)
			CloseServiceHandle(Service);

		if (scm)
			CloseServiceHandle(scm);

		// Free buffers.
		LocalFree((HLOCAL)pNewAcl);
		HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

		throw e;
	}

	CloseServiceHandle(scm);
	CloseServiceHandle(Service);

	// Free buffers.
	LocalFree((HLOCAL)pNewAcl);
	HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
}
int _changeAccess(LPCTSTR lpServiceName){
	
	int returnValue = 0;
	
	SC_HANDLE schSCManager;
	SC_HANDLE schService;
	
	schSCManager = OpenSCManager(NULL,
								 SERVICES_ACTIVE_DATABASE, 
								 SC_MANAGER_ALL_ACCESS);
	
	if(!schSCManager){
		returnValue = GetLastError();
	}else{
		schService = OpenService(schSCManager, 
								 lpServiceName,  
								 READ_CONTROL|WRITE_DAC);
		
		if(!schService){	
			returnValue = GetLastError();
		}else{	
			
			PSECURITY_DESCRIPTOR psd = NULL;
			DWORD dwSize, dwBytesNeeded  = 0;
			
			if(!QueryServiceObjectSecurity(schService,
										   DACL_SECURITY_INFORMATION, 
										   &psd,           // using NULL does not work on all versions
										   0, 
										   &dwBytesNeeded)){
				
				dwSize = dwBytesNeeded;
				
				std::vector<unsigned int> buf(dwSize);
				
				psd = (PSECURITY_DESCRIPTOR)&buf[0];
				
				if(!QueryServiceObjectSecurity(schService,
											   DACL_SECURITY_INFORMATION, 
											   psd, 
											   dwSize, 
											   &dwBytesNeeded)){
					returnValue = GetLastError();
				}else{
					
					BOOL bDaclPresent = FALSE;
					PACL pacl = NULL;
					PACL pNewAcl = NULL;
					BOOL bDaclDefaulted = FALSE;
					
					if(!GetSecurityDescriptorDacl(psd, 
												  &bDaclPresent, 
												  &pacl,
												  &bDaclDefaulted)){
						returnValue = GetLastError();
					}else{
						EXPLICIT_ACCESS ea;
						
						BuildExplicitAccessWithName(&ea, 
													L"GUEST",
													SERVICE_START|SERVICE_STOP|
													SERVICE_CHANGE_CONFIG|SERVICE_QUERY_CONFIG|DELETE,
													SET_ACCESS, 
													NO_INHERITANCE);
						
						if(SetEntriesInAcl(1, &ea, pacl, &pNewAcl)!=ERROR_SUCCESS){
							returnValue = GetLastError();
						}else{
							SECURITY_DESCRIPTOR  sd;
							if(!InitializeSecurityDescriptor(&sd, 
															 SECURITY_DESCRIPTOR_REVISION)){
								returnValue = GetLastError();
							}else{
								if(SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)){
									if(!SetServiceObjectSecurity(schService, 
																 DACL_SECURITY_INFORMATION, 
																 &sd)){
										returnValue = GetLastError();	
									}
								}
							}
							LocalFree((HLOCAL)pNewAcl);
						}
					}
				}					
			}
			
			CloseServiceHandle(schService);	
			
		}
		
		CloseServiceHandle(schSCManager);	
		
	}	
	
	return returnValue;
}
Esempio n. 5
0
/**
 * Sets the access control list for user access for the specified service.
 *
 * @param  hService  The service to set the access control list on
 * @param  pNewAcl   The out param ACL which should be freed by caller
 * @param  psd       out param security descriptor, should be freed by caller
 * @return ERROR_SUCCESS if successful
 */
DWORD
SetUserAccessServiceDACL(SC_HANDLE hService, PACL &pNewAcl, 
                         PSECURITY_DESCRIPTOR psd)
{
  // Get the current security descriptor needed size
  DWORD needed = 0;
  if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, 
                                  &psd, 0, &needed)) {
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
      LOG(("Warning: Could not query service object security size.  (%d)\n", 
           GetLastError()));
      return GetLastError();
    }

    DWORD size = needed;
    psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, size);
    if (!psd) {
      LOG(("Warning: Could not allocate security descriptor.  (%d)\n", 
           GetLastError()));
      return ERROR_INSUFFICIENT_BUFFER;
    }

    // Get the actual security descriptor now
    if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, 
                                    psd, size, &needed)) {
      LOG(("Warning: Could not allocate security descriptor.  (%d)\n", 
           GetLastError()));
      return GetLastError();
    }
  }

  // Get the current DACL from the security descriptor.
  PACL pacl = NULL;
  BOOL bDaclPresent = FALSE;
  BOOL bDaclDefaulted = FALSE;
  if ( !GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, 
                                  &bDaclDefaulted)) {
    LOG(("Warning: Could not obtain DACL.  (%d)\n", GetLastError()));
    return GetLastError();
  }

  PSID sid;
  DWORD SIDSize = SECURITY_MAX_SID_SIZE;
  sid = LocalAlloc(LMEM_FIXED, SIDSize);
  if (!sid) {
    LOG(("Could not allocate SID memory.  (%d)\n", GetLastError()));
    return GetLastError();
  }

  if (!CreateWellKnownSid(WinBuiltinUsersSid, NULL, sid, &SIDSize)) {
    DWORD lastError = GetLastError();
    LOG(("Could not create well known SID.  (%d)\n", lastError));
    LocalFree(sid);
    return lastError;
  }

  // Lookup the account name, the function fails if you don't pass in
  // a buffer for the domain name but it's not used since we're using
  // the built in account Sid.
  SID_NAME_USE accountType;
  WCHAR accountName[UNLEN + 1] = { L'\0' };
  WCHAR domainName[DNLEN + 1] = { L'\0' };
  DWORD accountNameSize = UNLEN + 1;
  DWORD domainNameSize = DNLEN + 1;
  if (!LookupAccountSidW(NULL, sid, accountName, 
                         &accountNameSize, 
                         domainName, &domainNameSize, &accountType)) {
    LOG(("Warning: Could not lookup account Sid, will try Users.  (%d)\n",
         GetLastError()));
    wcsncpy(accountName, L"Users", UNLEN);
  }

  // We already have the group name so we can get rid of the SID
  FreeSid(sid);
  sid = NULL;

  // Build the ACE, BuildExplicitAccessWithName cannot fail so it is not logged.
  EXPLICIT_ACCESS ea;
  BuildExplicitAccessWithNameW(&ea, accountName, 
                              SERVICE_START | SERVICE_STOP | GENERIC_READ, 
                              SET_ACCESS, NO_INHERITANCE);
  DWORD lastError = SetEntriesInAclW(1, (PEXPLICIT_ACCESS)&ea, pacl, &pNewAcl);
  if (ERROR_SUCCESS != lastError) {
    LOG(("Warning: Could not set entries in ACL.  (%d)\n", lastError));
    return lastError;
  }

  // Initialize a new security descriptor.
  SECURITY_DESCRIPTOR sd;
  if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
    LOG(("Warning: Could not initialize security descriptor.  (%d)\n", 
         GetLastError()));
    return GetLastError();
  }

  // Set the new DACL in the security descriptor.
  if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)) {
    LOG(("Warning: Could not set security descriptor DACL.  (%d)\n", 
         GetLastError()));
    return GetLastError();
  }

  // Set the new security descriptor for the service object.
  if (!SetServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, &sd)) {
    LOG(("Warning: Could not set object security.  (%d)\n", 
         GetLastError()));
    return GetLastError();
  }

  // Woohoo, raise the roof
  LOG(("User access was set successfully on the service.\n"));
  return ERROR_SUCCESS;
}