std::set<std::string> getGlobalCommands() { std::set<std::string> handlersSet; size_t keys = 0; HKEY hTestKey = NULL; if (RegOpenKeyEx(HKEY_CLASSES_ROOT, 0, 0, KEY_READ, &hTestKey) != ERROR_SUCCESS) { return handlersSet; } std::vector<std::string> subkeys = get_subkeys(hTestKey); RegCloseKey(hTestKey); std::vector<std::string>::iterator itr; for (itr = subkeys.begin(); itr != subkeys.end(); itr++) { if (itr->at(0) != '.') { continue; } //extension found! HKEY innerKey1; if (RegOpenKeyExA(HKEY_CLASSES_ROOT, itr->c_str(), 0, KEY_READ, &innerKey1) != ERROR_SUCCESS) { continue; } std::string ext = *itr; std::string handlerName = getValueString(HKEY_CLASSES_ROOT, ext); if (handlerName.length() == 0) continue; std::string path = getValueString(HKEY_CLASSES_ROOT, handlerName + "\\shell\\open\\command"); if (path.length() == 0) continue; handlersSet.insert(handlerName); } return handlersSet; }
std::string getLocalClasses() { HKEY hTestKey = NULL; if (RegOpenKeyEx(HKEY_USERS, 0, 0, KEY_READ, &hTestKey) != ERROR_SUCCESS) { return 0; } std::vector<std::string> subkeys = get_subkeys(hTestKey); RegCloseKey(hTestKey); hTestKey = NULL; std::vector<std::string>::iterator itr; for (itr = subkeys.begin(); itr != subkeys.end(); itr++) { if (itr->find("_Classes") == std::string::npos) { continue; } HKEY innerKey1; if (RegOpenKeyExA(HKEY_USERS, itr->c_str(), 0, KEY_READ | KEY_WRITE, &innerKey1) != ERROR_SUCCESS) { continue; } RegCloseKey(innerKey1); return *itr; } return ""; }
size_t hijackHandlers(std::string proxy_path) { HKEY hTestKey = NULL; if (RegOpenKeyEx(HKEY_USERS, 0, 0, KEY_READ, &hTestKey) != ERROR_SUCCESS) { return 0; } std::vector<std::string> subkeys = get_subkeys(hTestKey); RegCloseKey(hTestKey); hTestKey = NULL; size_t changed = 0; size_t hijacked = 0; std::vector<std::string>::iterator itr; for (itr = subkeys.begin(); itr != subkeys.end(); itr++) { HKEY innerKey1; if (RegOpenKeyExA(HKEY_USERS, itr->c_str(), 0, KEY_READ | KEY_WRITE, &innerKey1) != ERROR_SUCCESS) { continue; } std::string subKey = *itr; printf("[W] %s\n", subKey.c_str()); std::vector<std::string> subkeys2 = get_subkeys(innerKey1); for (std::vector<std::string>::iterator itr2 = subkeys2.begin(); itr2 != subkeys2.end(); itr2++) { std::string subKey2 = subKey + "\\" + *itr2; printf("> %s\n", subKey2.c_str()); if (hijack_key(subKey2, proxy_path)) { hijacked++; } } RegCloseKey(innerKey1); } printf("Hijacked keys: %d\n", hijacked); return hijacked; }
/// Get subkeys /// \param key /// \param nlevels: 1=only return immediate children; 2=children and grandchildren; (unsigned int) -1: all children /// \return All subkeys, recursively void FilesystemKVS::get_subkeys(const std::string &key, std::vector<std::string> &keys, unsigned int nlevels, bool (*subdir_filter)(const char *subdirname)) const { std::string path = directory_key_to_path(key); std::string prefix = (key == "") ? "" : key+"."; DIR *dir = opendir(path.c_str()); if (!dir) return; while (1) { struct dirent *ent = readdir(dir); if (!ent) break; if (!strcmp(ent->d_name, ".")) continue; if (!strcmp(ent->d_name, "..")) continue; if (filename_suffix(ent->d_name) == "val") { keys.push_back(prefix+filename_sans_suffix(ent->d_name)); } else if (nlevels > 1 && (!subdir_filter || (*subdir_filter)(ent->d_name))) { // If it's a directory, recurse, honoring symlinks bool is_directory = false; std::string fullpath = path+"/"+ent->d_name; switch (ent->d_type) { case DT_DIR: is_directory = true; break; case DT_UNKNOWN: case DT_LNK: { struct stat statbuf; int ret = stat(fullpath.c_str(), &statbuf); if (ret != 0) { perror(("stat " + fullpath).c_str()); } else { is_directory = S_ISDIR(statbuf.st_mode); } } } if (is_directory) get_subkeys(prefix+ent->d_name, keys, nlevels-1); } } closedir(dir); }
std::wstring c_tun_device_windows::get_device_guid() { const std::wstring adapterKey = L"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"; _fact("Looking for device guid" << to_string(adapterKey)); LONG status = 1; HKEY key = nullptr; status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, adapterKey.c_str(), 0, KEY_READ, &key); if (status != ERROR_SUCCESS) throw std::runtime_error("RegOpenKeyEx error, error code " + std::to_string(status)); hkey_wrapper key_wrapped(key); std::vector<std::wstring> subkeys_vector; try { subkeys_vector = get_subkeys(key_wrapped.get()); } catch (const std::exception &e) { key_wrapped.close(); throw e; } _dbg1("found " << subkeys_vector.size() << " reg keys"); key_wrapped.close(); for (const auto & subkey : subkeys_vector) { // foreach sub key if (subkey == L"Properties") continue; std::wstring subkey_reg_path = adapterKey + L"\\" + subkey; _fact(to_string(subkey_reg_path)); status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, subkey_reg_path.c_str(), 0, KEY_QUERY_VALUE, &key); if (status != ERROR_SUCCESS) throw std::runtime_error("RegOpenKeyEx error, error code " + std::to_string(status)); // get ComponentId field DWORD size = 256; std::wstring componentId(size, '\0'); // this reinterpret_cast is not UB(3.10.10) because LPBYTE == unsigned char * // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx status = RegQueryValueExW(key, L"ComponentId", nullptr, nullptr, reinterpret_cast<LPBYTE>(&componentId[0]), &size); if (status != ERROR_SUCCESS) { RegCloseKey(key); continue; } key_wrapped.set(key); std::wstring netCfgInstanceId; try { if (componentId.substr(0, 8) == L"root\\tap" || componentId.substr(0, 3) == L"tap") { // found TAP _note(to_string(subkey_reg_path)); size = 256; netCfgInstanceId.resize(size, '\0'); // this reinterpret_cast is not UB(3.10.10) because LPBYTE == unsigned char * // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx status = RegQueryValueExW(key_wrapped.get(), L"NetCfgInstanceId", nullptr, nullptr, reinterpret_cast<LPBYTE>(&netCfgInstanceId[0]), &size); if (status != ERROR_SUCCESS) throw std::runtime_error("RegQueryValueEx error, error code " + std::to_string(GetLastError())); netCfgInstanceId.erase(size / sizeof(wchar_t) - 1); // remove '\0' _note(to_string(netCfgInstanceId)); key_wrapped.close(); HANDLE handle = open_tun_device(netCfgInstanceId); if (handle == INVALID_HANDLE_VALUE) continue; else { BOOL ret = CloseHandle(handle); if (ret == 0) throw std::runtime_error("CloseHandle error, " + std::to_string(GetLastError())); } return netCfgInstanceId; } } catch (const std::out_of_range &e) { _warn(std::string("register value processing error ") + e.what()); _note("componentId = " + to_string(componentId)); _note("netCfgInstanceId " + to_string(netCfgInstanceId)); } key_wrapped.close(); } _erro("Can not find device in windows registry"); throw std::runtime_error("Device not found"); }