Skip to content

Commit

Permalink
Fixes crash with non-null-terminated values in registry enumeration (o…
Browse files Browse the repository at this point in the history
…squery#8421)

Co-authored-by: seph <[email protected]>
  • Loading branch information
sinclairjw and directionless authored Oct 18, 2024
1 parent b2230ac commit f1a2136
Showing 1 changed file with 28 additions and 19 deletions.
47 changes: 28 additions & 19 deletions osquery/tables/system/windows/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ Status queryKey(const std::string& keyPath, QueryData& results) {
DWORD cSubKeys;
DWORD cValues;
DWORD cchMaxValueName;
DWORD cbMaxValueData;
DWORD retCode;
FILETIME ftLastWriteTime;
retCode = RegQueryInfoKeyW(hRegistryHandle.get(),
Expand All @@ -254,7 +253,7 @@ Status queryKey(const std::string& keyPath, QueryData& results) {
nullptr,
&cValues,
&cchMaxValueName,
&cbMaxValueData,
nullptr,
nullptr,
&ftLastWriteTime);
if (retCode != ERROR_SUCCESS) {
Expand Down Expand Up @@ -296,7 +295,6 @@ Status queryKey(const std::string& keyPath, QueryData& results) {

DWORD cchValue = maxKeyLength;
auto achValue = std::make_unique<WCHAR[]>(maxValueName);
auto bpDataBuff = std::make_unique<BYTE[]>(cbMaxValueData);

// Process registry values
for (size_t i = 0; i < cValues; i++) {
Expand All @@ -315,24 +313,36 @@ Status queryKey(const std::string& keyPath, QueryData& results) {
return Status(retCode, "Failed to enumerate registry values");
}

DWORD lpData = cbMaxValueData;
DWORD lpData = 0;
DWORD lpType;

retCode = RegQueryValueExW(hRegistryHandle.get(),
achValue.get(),
nullptr,
&lpType,
bpDataBuff.get(),
&lpData);
if (retCode != ERROR_SUCCESS) {
return Status(retCode, "Failed to query registry value");
// Get the required size
retCode = RegGetValueW(hRegistryHandle.get(),
nullptr,
achValue.get(),
RRF_RT_ANY,
&lpType,
nullptr,
&lpData);

if ((retCode != ERROR_SUCCESS) || (lpData == 0)) {
return Status(retCode, "Failed to query registry value size");
}

// It's possible for registry entries to have been inserted incorrectly
// resulting in non-null-terminated strings
if (bpDataBuff != nullptr && lpData != 0 &&
kRegistryStringTypes.find(lpType) != kRegistryStringTypes.end()) {
bpDataBuff[lpData - 1] = 0x00;
std::unique_ptr<BYTE[]> bpDataBuff = std::make_unique<BYTE[]>(lpData);

// Read the registry value data ensuring correct handling of non-terminated
// strings
retCode = RegGetValueW(hRegistryHandle.get(),
nullptr,
achValue.get(),
RRF_RT_ANY,
&lpType,
bpDataBuff.get(),
&lpData);

if (retCode != ERROR_SUCCESS) {
return Status(retCode, "Failed to query registry value");
}

Row r;
Expand Down Expand Up @@ -365,7 +375,7 @@ Status queryKey(const std::string& keyPath, QueryData& results) {
case REG_FULL_RESOURCE_DESCRIPTOR:
case REG_RESOURCE_LIST:
case REG_BINARY:
for (size_t j = 0; j < cbMaxValueData; j++) {
for (size_t j = 0; j < lpData; j++) {
regBinary.push_back((char)bpDataBuff[j]);
}
boost::algorithm::hex(
Expand Down Expand Up @@ -406,7 +416,6 @@ Status queryKey(const std::string& keyPath, QueryData& results) {
default:
break;
}
ZeroMemory(bpDataBuff.get(), cbMaxValueData);
}
results.push_back(r);
}
Expand Down

0 comments on commit f1a2136

Please sign in to comment.