void genInterfaceDetail(const WmiResultItem& adapter, QueryData& results) { Row r; long lPlaceHolder; bool bPlaceHolder; std::vector<std::string> vPlaceHolder; unsigned __int64 ulPlaceHolder; r["interface"] = INTEGER(lPlaceHolder); adapter.GetString("MACAddress", r["mac"]); adapter.GetString("AdapterType", r["type"]); adapter.GetString("Description", r["description"]); adapter.GetLong("InterfaceIndex", lPlaceHolder); adapter.GetString("Manufacturer", r["manufacturer"]); adapter.GetString("NetConnectionID", r["connection_id"]); adapter.GetLong("NetConnectionStatus", lPlaceHolder); r["connection_status"] = INTEGER(lPlaceHolder); adapter.GetBool("NetEnabled", bPlaceHolder); r["enabled"] = INTEGER(bPlaceHolder); adapter.GetBool("PhysicalAdapter", bPlaceHolder); r["physical_adapter"] = INTEGER(bPlaceHolder); adapter.GetUnsignedLongLong("Speed", ulPlaceHolder); r["speed"] = INTEGER(ulPlaceHolder); std::string query = "SELECT * FROM win32_networkadapterconfiguration WHERE " "InterfaceIndex = " + r["interface"]; WmiRequest irequest(query); if (irequest.getStatus().ok()) { auto& iresults = irequest.results(); iresults[0].GetLong("MTU", lPlaceHolder); r["mtu"] = INTEGER(lPlaceHolder); iresults[0].GetBool("DHCPEnabled", bPlaceHolder); r["dhcp_enabled"] = INTEGER(bPlaceHolder); iresults[0].GetString("DHCPLeaseExpires", r["dhcp_lease_expires"]); iresults[0].GetString("DHCPLeaseObtained", r["dhcp_lease_obtained"]); iresults[0].GetString("DHCPServer", r["dhcp_server"]); iresults[0].GetString("DNSDomain", r["dns_domain"]); iresults[0].GetVectorOfStrings("DNSDomainSuffixSearchOrder", vPlaceHolder); r["dns_domain_suffix_search_order"] = SQL_TEXT(boost::algorithm::join(vPlaceHolder, ", ")); iresults[0].GetString("DNSHostName", r["dns_host_name"]); iresults[0].GetVectorOfStrings("DNSServerSearchOrder", vPlaceHolder); r["dns_server_search_order"] = SQL_TEXT(boost::algorithm::join(vPlaceHolder, ", ")); } results.push_back(r); }
void queryDrvInfo(const SC_HANDLE& schScManager, ENUM_SERVICE_STATUS_PROCESS& svc, std::map<std::string, std::string>& loadedDrivers, QueryData& results) { Row r; DWORD cbBufSize = 0; auto schService = OpenService(schScManager, svc.lpServiceName, SERVICE_QUERY_CONFIG); if (schService == nullptr) { TLOG << "OpenService failed (" << GetLastError() << ")"; return; } QueryServiceConfig(schService, nullptr, 0, &cbBufSize); auto lpsc = static_cast<LPQUERY_SERVICE_CONFIG>(malloc(cbBufSize)); if (QueryServiceConfig(schService, lpsc, cbBufSize, &cbBufSize) != 0) { TLOG << "QueryServiceConfig failed (" << GetLastError() << ")"; } r["name"] = SQL_TEXT(svc.lpServiceName); r["display_name"] = SQL_TEXT(svc.lpDisplayName); r["status"] = SQL_TEXT(kDrvStatus[svc.ServiceStatusProcess.dwCurrentState]); r["start_type"] = SQL_TEXT(kDrvStartType[lpsc->dwStartType]); // If SCM can't get 'path' of the driver then use the path // available in loadedDrivers list if (strlen(lpsc->lpBinaryPathName) <= 0) { r["path"] = loadedDrivers[svc.lpServiceName]; } else { r["path"] = SQL_TEXT(lpsc->lpBinaryPathName); } if (kDriverType.count(lpsc->dwServiceType) > 0) { r["type"] = SQL_TEXT(kDriverType.at(lpsc->dwServiceType)); } else { r["type"] = SQL_TEXT("UNKNOWN"); } QueryData regResults; queryKey("HKEY_LOCAL_MACHINE", "SYSTEM\\CurrentControlSet\\Services\\" + r["name"], regResults); for (const auto& aKey : regResults) { if (aKey.at("name") == "Owners") { r["inf"] = SQL_TEXT(aKey.at("data")); } } // Remove the driver from loadedDrivers list to avoid duplicates loadedDrivers.erase(svc.lpServiceName); results.push_back(r); free(lpsc); CloseServiceHandle(schService); }
void GetSystemDriveGUID(Row& r) { char buf[51] = {0}; auto sysRoot = getSystemRoot().root_name().string() + "\\"; if (GetVolumeNameForVolumeMountPoint( sysRoot.c_str(), static_cast<LPSTR>(buf), 50)) { r["device"] = SQL_TEXT(buf); } }
QueryData genDrivers(QueryContext& context) { DWORD bytesNeeded = 0; DWORD serviceCount = 0; std::map<std::string, std::string> loadedDrivers; QueryData results; // Get All Loaded Drivers including ones managed by SCM enumLoadedDrivers(loadedDrivers); auto schScManager = OpenSCManager(nullptr, nullptr, GENERIC_READ); if (schScManager == nullptr) { TLOG << "EnumServiceStatusEx failed (" << GetLastError() << ")"; return {}; } EnumServicesStatusEx(schScManager, SC_ENUM_PROCESS_INFO, SERVICE_DRIVER, SERVICE_STATE_ALL, nullptr, 0, &bytesNeeded, &serviceCount, nullptr, nullptr); auto buf = static_cast<PVOID>(malloc(bytesNeeded)); if (EnumServicesStatusEx(schScManager, SC_ENUM_PROCESS_INFO, SERVICE_DRIVER, SERVICE_STATE_ALL, (LPBYTE)buf, bytesNeeded, &bytesNeeded, &serviceCount, nullptr, nullptr) != 0) { auto services = static_cast<ENUM_SERVICE_STATUS_PROCESS*>(buf); for (DWORD i = 0; i < serviceCount; ++i) { queryDrvInfo(schScManager, services[i], loadedDrivers, results); } } else { TLOG << "EnumServiceStatusEx failed (" << GetLastError() << ")"; } free(buf); CloseServiceHandle(schScManager); for (const auto& element : loadedDrivers) { Row r; r["name"] = element.first; r["path"] = element.second; r["status"] = SQL_TEXT(kDrvStatus[4]); results.push_back(r); } return results; }
QueryData genIPv4ArpCache(QueryContext& context) { QueryData results; QueryData interfaces = genInterfaceDetails(context); WmiRequest wmiSystemReq("select * from MSFT_NetNeighbor", (BSTR)L"ROOT\\StandardCimv2"); std::vector<WmiResultItem>& wmiResults = wmiSystemReq.results(); std::map<long, std::string> mapOfInterfaces = { {1, ""}, // loopback }; unsigned short usiPlaceHolder; unsigned char cPlaceHolder; unsigned int uiPlaceHolder; std::string strPlaceHolder; for (const auto& iface : interfaces) { long interfaceIndex; if (iface.count("interface") > 0) { safeStrtol(iface.at("interface"), 10, interfaceIndex); std::string macAddress = iface.at("mac"); mapOfInterfaces.insert(std::make_pair(interfaceIndex, macAddress)); } } for (const auto& item : wmiResults) { Row r; item.GetUnsignedShort("AddressFamily", usiPlaceHolder); r["address_family"] = SQL_TEXT(kMapOfAddressFamily.at(usiPlaceHolder)); item.GetUChar("Store", cPlaceHolder); r["store"] = SQL_TEXT(kMapOfStore.at(cPlaceHolder)); item.GetUChar("State", cPlaceHolder); r["state"] = SQL_TEXT(kMapOfState.at(cPlaceHolder)); item.GetUnsignedInt32("InterfaceIndex", uiPlaceHolder); r["interface"] = SQL_TEXT(mapOfInterfaces.at(uiPlaceHolder)); item.GetString("IPAddress", r["ip_address"]); item.GetString("InterfaceAlias", r["interface_alias"]); item.GetString("LinkLayerAddress", strPlaceHolder); r["link_layer_address"] = SQL_TEXT(boost::replace_all_copy(strPlaceHolder, "-", ":")); results.push_back(r); } return results; }
QueryData genKernelInfo(QueryContext& context) { Row r; GetKernelVersion(r); GetBootArgs(r); GetSystemDriveGUID(r); r["path"] = SQL_TEXT(getSystemRoot().string() + "\\System32\\ntoskrnl.exe"); return {r}; }
void GetBootArgs(Row& r) { QueryData regResults; queryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control", regResults); for (const auto& aKey : regResults) { if (aKey.at("name") == "SystemStartOptions") { r["arguments"] = SQL_TEXT(aKey.at("data")); } } }
QueryData genInterfaceAddresses(QueryContext& context) { QueryData results; DWORD buffSize = kWorkingBufferSize; auto alloc_attempts = 0; size_t alloc_result = 0; const auto addrFamily = AF_UNSPEC; const auto addrFlags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST; std::unique_ptr<IP_ADAPTER_ADDRESSES> adapters(nullptr); // Buffer size can change between the query and malloc (if adapters are // added/removed), so shenanigans are required do { adapters.reset(static_cast<PIP_ADAPTER_ADDRESSES>(malloc(buffSize))); if (adapters == nullptr) { return results; } alloc_result = GetAdaptersAddresses( addrFamily, addrFlags, nullptr, adapters.get(), &buffSize); alloc_attempts++; } while (alloc_result == ERROR_BUFFER_OVERFLOW && alloc_attempts < kMaxBufferAllocRetries); if (alloc_result != NO_ERROR) { return results; } const IP_ADAPTER_ADDRESSES* currAdapter = adapters.get(); while (currAdapter != nullptr) { std::wstring wsAdapterName = std::wstring(currAdapter->FriendlyName); auto adapterName = std::string(wsAdapterName.begin(), wsAdapterName.end()); const IP_ADAPTER_UNICAST_ADDRESS* ipaddr = currAdapter->FirstUnicastAddress; while (ipaddr != nullptr) { Row r; r["interface"] = SQL_TEXT(currAdapter->IfIndex); r["friendly_name"] = adapterName; genInterfaceAddress(ipaddr, r); ipaddr = ipaddr->Next; results.push_back(r); } currAdapter = currAdapter->Next; } return results; }
QueryData genArpCache(QueryContext& context) { QueryData results; QueryData winArpCache = genIPv4ArpCache(context); for (const auto& item : winArpCache) { if (item.at("link_layer_address").empty() || item.at("link_layer_address") == "00:00:00:00:00:00") { continue; } if (item.at("address_family") == "IPv4") { Row r; r["address"] = item.at("ip_address"); r["mac"] = item.at("link_layer_address"); r["interface"] = item.at("interface"); r["permanent"] = SQL_TEXT(("Permanent" == item.at("state")) ? "1" : "0"); results.push_back(r); } } return results; }
void GetKernelVersion(Row& r) { unsigned int size = 0; auto verSize = GetFileVersionInfoSize(kNtKernelPath.c_str(), nullptr); if (verSize == 0) { TLOG << "GetFileVersionInfoSize failed (" << GetLastError() << ")"; return; } auto verData = static_cast<LPSTR>(malloc(verSize)); if (!GetFileVersionInfo(kNtKernelPath.c_str(), 0, verSize, verData)) { TLOG << "GetFileVersionInfo failed (" << GetLastError() << ")"; } void* vptrVersionInfo = nullptr; if (!VerQueryValue(verData, "\\", &vptrVersionInfo, &size)) { TLOG << "GetFileVersionInfo failed (" << GetLastError() << ")"; } auto lpVersionInfo = static_cast<VS_FIXEDFILEINFO*>(vptrVersionInfo); if (size > 0) { if (lpVersionInfo->dwSignature == 0xfeef04bd) { auto majorMS = HIWORD(lpVersionInfo->dwProductVersionMS); auto minorMS = LOWORD(lpVersionInfo->dwProductVersionMS); auto majorLS = HIWORD(lpVersionInfo->dwProductVersionLS); auto minorLS = LOWORD(lpVersionInfo->dwProductVersionLS); r["version"] = SQL_TEXT( std::to_string(majorMS) + "." + std::to_string(minorMS) + "." + std::to_string(majorLS) + "." + std::to_string(minorLS)); } else { TLOG << "Incorrect Version Signature (" << GetLastError() << ")"; } } else { TLOG << "No Version information (" << GetLastError() << ")"; } free(verData); }
void enumerateTasksForFolder(std::string path, QueryData& results) { void* vpService = nullptr; auto ret = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, &vpService); if (FAILED(ret)) { VLOG(1) << "Failed to create COM instance " << ret; return; } auto pService = static_cast<ITaskService*>(vpService); ret = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); if (FAILED(ret)) { VLOG(1) << "Failed to connect to TaskService " << ret; pService->Release(); return; } ITaskFolder* pRootFolder = nullptr; auto widePath = stringToWstring(path); ret = pService->GetFolder(BSTR(widePath.c_str()), &pRootFolder); pService->Release(); if (FAILED(ret)) { VLOG(1) << "Failed to get root task folder " << ret; return; } IRegisteredTaskCollection* pTaskCollection = nullptr; ret = pRootFolder->GetTasks(TASK_ENUM_HIDDEN, &pTaskCollection); pRootFolder->Release(); if (FAILED(ret)) { VLOG(1) << "Failed to get task collection for root folder " << ret; return; } long numTasks = 0; pTaskCollection->get_Count(&numTasks); for (size_t i = 0; i < numTasks; i++) { IRegisteredTask* pRegisteredTask = nullptr; // Collections are 1-based lists ret = pTaskCollection->get_Item(_variant_t(i + 1), &pRegisteredTask); if (FAILED(ret)) { VLOG(1) << "Failed to process task"; continue; } Row r; BSTR taskName; ret = pRegisteredTask->get_Name(&taskName); std::wstring wTaskName(taskName, SysStringLen(taskName)); r["name"] = ret == S_OK ? SQL_TEXT(wstringToString(wTaskName.c_str())) : ""; VARIANT_BOOL enabled = false; pRegisteredTask->get_Enabled(&enabled); r["enabled"] = enabled ? INTEGER(1) : INTEGER(0); TASK_STATE taskState; pRegisteredTask->get_State(&taskState); r["state"] = kStateMap.count(taskState) > 0 ? kStateMap.at(taskState) : kStateMap.at(TASK_STATE_UNKNOWN); BSTR taskPath; ret = pRegisteredTask->get_Path(&taskPath); std::wstring wTaskPath(taskPath, SysStringLen(taskPath)); r["path"] = ret == S_OK ? wstringToString(wTaskPath.c_str()) : ""; VARIANT_BOOL hidden = false; pRegisteredTask->get_Enabled(&hidden); r["hidden"] = hidden ? INTEGER(1) : INTEGER(0); HRESULT lastTaskRun = E_FAIL; pRegisteredTask->get_LastTaskResult(&lastTaskRun); _com_error err(lastTaskRun); r["last_run_message"] = err.ErrorMessage(); r["last_run_code"] = INTEGER(lastTaskRun); // We conver the COM Date type to a unix epoch timestamp DATE dRunTime; SYSTEMTIME st; FILETIME ft; FILETIME locFt; pRegisteredTask->get_LastRunTime(&dRunTime); VariantTimeToSystemTime(dRunTime, &st); SystemTimeToFileTime(&st, &ft); LocalFileTimeToFileTime(&ft, &locFt); r["last_run_time"] = INTEGER(filetimeToUnixtime(locFt)); pRegisteredTask->get_NextRunTime(&dRunTime); VariantTimeToSystemTime(dRunTime, &st); SystemTimeToFileTime(&st, &ft); LocalFileTimeToFileTime(&ft, &locFt); r["next_run_time"] = INTEGER(filetimeToUnixtime(locFt)); ITaskDefinition* taskDef = nullptr; IActionCollection* tActionCollection = nullptr; pRegisteredTask->get_Definition(&taskDef); if (taskDef != nullptr) { taskDef->get_Actions(&tActionCollection); } long actionCount = 0; if (tActionCollection != nullptr) { tActionCollection->get_Count(&actionCount); } std::vector<std::string> actions; // Task collections are 1-indexed for (auto j = 1; j <= actionCount; j++) { IAction* act = nullptr; IExecAction* execAction = nullptr; tActionCollection->get_Item(j, &act); if (act == nullptr) { continue; } act->QueryInterface(IID_IExecAction, reinterpret_cast<void**>(&execAction)); if (execAction == nullptr) { continue; } BSTR taskExecPath; execAction->get_Path(&taskExecPath); std::wstring wTaskExecPath(taskExecPath, SysStringLen(taskExecPath)); BSTR taskExecArgs; execAction->get_Arguments(&taskExecArgs); std::wstring wTaskExecArgs(taskExecArgs, SysStringLen(taskExecArgs)); BSTR taskExecRoot; execAction->get_WorkingDirectory(&taskExecRoot); std::wstring wTaskExecRoot(taskExecRoot, SysStringLen(taskExecRoot)); auto full = wTaskExecRoot + L" " + wTaskExecPath + L" " + wTaskExecArgs; actions.push_back(wstringToString(full.c_str())); act->Release(); } if (tActionCollection != nullptr) { tActionCollection->Release(); } if (taskDef != nullptr) { taskDef->Release(); } r["action"] = !actions.empty() ? osquery::join(actions, ",") : ""; results.push_back(r); pRegisteredTask->Release(); } pTaskCollection->Release(); }
QueryData genTime(QueryContext& context) { Row r; // Request UNIX time (a wrapper around std::time). auto local_time = std::time(nullptr); auto osquery_time = getUnixTime(); auto osquery_timestamp = getAsciiTime(); // The concept of 'now' is configurable. struct tm gmt; gmtime_r(&local_time, &gmt); struct tm now; if (FLAGS_utc) { now = gmt; } else { localtime_r(&local_time, &now); } struct tm local; localtime_r(&local_time, &local); char weekday[10] = {0}; strftime(weekday, sizeof(weekday), "%A", &now); char timezone[5] = {0}; strftime(timezone, sizeof(timezone), "%Z", &now); char local_timezone[5] = {0}; strftime(local_timezone, sizeof(local_timezone), "%Z", &local); char iso_8601[21] = {0}; strftime(iso_8601, sizeof(iso_8601), "%FT%TZ", &gmt); r["weekday"] = SQL_TEXT(weekday); r["year"] = INTEGER(now.tm_year + 1900); r["month"] = INTEGER(now.tm_mon + 1); r["day"] = INTEGER(now.tm_mday); r["hour"] = INTEGER(now.tm_hour); r["minutes"] = INTEGER(now.tm_min); r["seconds"] = INTEGER(now.tm_sec); r["timezone"] = SQL_TEXT(timezone); if (r["timezone"].empty()) { r["timezone"] = "UTC"; } r["local_time"] = INTEGER(local_time); r["local_timezone"] = SQL_TEXT(local_timezone); if (r["local_timezone"].empty()) { r["local_timezone"] = "UTC"; } r["unix_time"] = INTEGER(osquery_time); r["timestamp"] = SQL_TEXT(osquery_timestamp); // Date time is provided in ISO 8601 format, then duplicated in iso_8601. r["datetime"] = SQL_TEXT(iso_8601); r["iso_8601"] = SQL_TEXT(iso_8601); QueryData results; results.push_back(r); return results; }
void enumerateTasksForFolder(std::string path, QueryData& results) { void* vpService = nullptr; auto ret = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, &vpService); if (FAILED(ret)) { VLOG(1) << "Failed to create COM instance " << ret; return; } auto pService = static_cast<ITaskService*>(vpService); ret = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); if (FAILED(ret)) { VLOG(1) << "Failed to connect to TaskService " << ret; pService->Release(); return; } ITaskFolder* pRootFolder = nullptr; auto widePath = stringToWstring(path.c_str()); ret = pService->GetFolder(BSTR(widePath.c_str()), &pRootFolder); pService->Release(); if (FAILED(ret)) { VLOG(1) << "Failed to get root task folder " << ret; return; } IRegisteredTaskCollection* pTaskCollection = nullptr; ret = pRootFolder->GetTasks(TASK_ENUM_HIDDEN, &pTaskCollection); pRootFolder->Release(); if (FAILED(ret)) { VLOG(1) << "Failed to get task collection for root folder " << ret; return; } long numTasks = 0; pTaskCollection->get_Count(&numTasks); for (size_t i = 0; i < numTasks; i++) { IRegisteredTask* pRegisteredTask = nullptr; // Collections are 1-based lists ret = pTaskCollection->get_Item(_variant_t(i + 1), &pRegisteredTask); if (FAILED(ret)) { VLOG(1) << "Failed to process task"; continue; } Row r; BSTR taskName; ret = pRegisteredTask->get_Name(&taskName); std::wstring wTaskName(taskName, SysStringLen(taskName)); r["name"] = ret == S_OK ? SQL_TEXT(wstringToString(wTaskName.c_str())) : ""; VARIANT_BOOL enabled = false; pRegisteredTask->get_Enabled(&enabled); r["enabled"] = enabled ? INTEGER(1) : INTEGER(0); TASK_STATE taskState; pRegisteredTask->get_State(&taskState); r["state"] = kStateMap.count(taskState) > 0 ? kStateMap.at(taskState) : kStateMap.at(TASK_STATE_UNKNOWN); BSTR taskPath; ret = pRegisteredTask->get_Path(&taskPath); std::wstring wTaskPath(taskPath, SysStringLen(taskPath)); r["path"] = ret == S_OK ? SQL_TEXT(wstringToString(wTaskPath.c_str())) : ""; VARIANT_BOOL hidden = false; pRegisteredTask->get_Enabled(&hidden); r["hidden"] = hidden ? INTEGER(1) : INTEGER(0); HRESULT lastTaskRun = E_FAIL; pRegisteredTask->get_LastTaskResult(&lastTaskRun); _com_error err(lastTaskRun); r["last_run_message"] = err.ErrorMessage(); r["last_run_code"] = INTEGER(lastTaskRun); // We conver the COM Date type to a unix epoch timestamp DATE dRunTime; SYSTEMTIME st; FILETIME ft; FILETIME locFt; pRegisteredTask->get_LastRunTime(&dRunTime); VariantTimeToSystemTime(dRunTime, &st); SystemTimeToFileTime(&st, &ft); LocalFileTimeToFileTime(&ft, &locFt); r["last_run_time"] = INTEGER(filetimeToUnixtime(locFt)); pRegisteredTask->get_NextRunTime(&dRunTime); VariantTimeToSystemTime(dRunTime, &st); SystemTimeToFileTime(&st, &ft); LocalFileTimeToFileTime(&ft, &locFt); r["next_run_time"] = INTEGER(filetimeToUnixtime(locFt)); results.push_back(r); pRegisteredTask->Release(); } pTaskCollection->Release(); }
void genProcess(const WmiResultItem& result, QueryData& results_data) { Row r; Status s; long pid; long lPlaceHolder; std::string sPlaceHolder; /// Store current process pid for more efficient API use. auto currentPid = GetCurrentProcessId(); s = result.GetLong("ProcessId", pid); r["pid"] = s.ok() ? BIGINT(pid) : BIGINT(-1); long uid = -1; long gid = -1; HANDLE hProcess = nullptr; if (pid == currentPid) { hProcess = GetCurrentProcess(); } else { hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid); } if (GetLastError() == ERROR_ACCESS_DENIED) { uid = 0; gid = 0; } result.GetString("Name", r["name"]); result.GetString("ExecutablePath", r["path"]); result.GetString("CommandLine", r["cmdline"]); result.GetString("ExecutionState", r["state"]); result.GetLong("ParentProcessId", lPlaceHolder); r["parent"] = BIGINT(lPlaceHolder); result.GetLong("Priority", lPlaceHolder); r["nice"] = INTEGER(lPlaceHolder); r["on_disk"] = osquery::pathExists(r["path"]).toString(); result.GetLong("ThreadCount", lPlaceHolder); r["threads"] = INTEGER(lPlaceHolder); std::vector<char> fileName(MAX_PATH); fileName.assign(MAX_PATH + 1, '\0'); if (pid == currentPid) { GetModuleFileName(nullptr, fileName.data(), MAX_PATH); } else { GetModuleFileNameEx(hProcess, nullptr, fileName.data(), MAX_PATH); } r["cwd"] = SQL_TEXT(fileName.data()); r["root"] = r["cwd"]; r["pgroup"] = "-1"; r["euid"] = "-1"; r["suid"] = "-1"; r["egid"] = "-1"; r["sgid"] = "-1"; FILETIME createTime; FILETIME exitTime; FILETIME kernelTime; FILETIME userTime; auto procRet = GetProcessTimes(hProcess, &createTime, &exitTime, &kernelTime, &userTime); if (procRet == FALSE) { r["user_time"] = BIGINT(-1); r["system_time"] = BIGINT(-1); r["start_time"] = BIGINT(-1); } else { // Windows stores proc times in 100 nanosecond ticks ULARGE_INTEGER utime; utime.HighPart = userTime.dwHighDateTime; utime.LowPart = userTime.dwLowDateTime; r["user_time"] = BIGINT(utime.QuadPart / 10000000); utime.HighPart = kernelTime.dwHighDateTime; utime.LowPart = kernelTime.dwLowDateTime; r["system_time"] = BIGINT(utime.QuadPart / 10000000); r["start_time"] = BIGINT(osquery::filetimeToUnixtime(createTime)); } result.GetString("PrivatePageCount", sPlaceHolder); r["wired_size"] = BIGINT(sPlaceHolder); result.GetString("WorkingSetSize", sPlaceHolder); r["resident_size"] = sPlaceHolder; result.GetString("VirtualSize", sPlaceHolder); r["total_size"] = BIGINT(sPlaceHolder); /// Get the process UID and GID from its SID HANDLE tok = nullptr; std::vector<char> tokOwner(sizeof(TOKEN_OWNER), 0x0); auto ret = OpenProcessToken(hProcess, TOKEN_READ, &tok); if (ret != 0 && tok != nullptr) { unsigned long tokOwnerBuffLen; ret = GetTokenInformation(tok, TokenUser, nullptr, 0, &tokOwnerBuffLen); if (ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { tokOwner.resize(tokOwnerBuffLen); ret = GetTokenInformation( tok, TokenUser, tokOwner.data(), tokOwnerBuffLen, &tokOwnerBuffLen); } // Check if the process is using an elevated token auto elevated = FALSE; TOKEN_ELEVATION Elevation; DWORD cbSize = sizeof(TOKEN_ELEVATION); if (GetTokenInformation( tok, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) { elevated = Elevation.TokenIsElevated; } r["is_elevated_token"] = elevated ? INTEGER(1) : INTEGER(0); } if (uid != 0 && ret != 0 && !tokOwner.empty()) { auto sid = PTOKEN_OWNER(tokOwner.data())->Owner; r["uid"] = INTEGER(getUidFromSid(sid)); r["gid"] = INTEGER(getGidFromSid(sid)); } else { r["uid"] = INTEGER(uid); r["gid"] = INTEGER(gid); } if (hProcess != nullptr) { CloseHandle(hProcess); } if (tok != nullptr) { CloseHandle(tok); tok = nullptr; } results_data.push_back(r); }