Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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);
  }
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
QueryData genKernelInfo(QueryContext& context) {
  Row r;
  GetKernelVersion(r);
  GetBootArgs(r);
  GetSystemDriveGUID(r);

  r["path"] = SQL_TEXT(getSystemRoot().string() + "\\System32\\ntoskrnl.exe");

  return {r};
}
Пример #7
0
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"));
    }
  }
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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);
}
Пример #11
0
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();
}
Пример #12
0
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;
}
Пример #13
0
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();
}
Пример #14
0
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);
}