Shadow Wizard Registry Gang: Structured Registry Querying

Why Do We Need New Tooling for Registry Collection?

The Windows registry, an intricate database storing settings for both the operating system and the applications that run on it, is a treasure trove of valuable information. It is known. For this reason, countless offensive security tools have emerged to query the Windows registry, especially for post-exploitation activity. In this space, most tooling falls into two broad categories: specific registry querying with post-processing and arbitrary key querying. One of these tools, PowerUp, is designed to probe for misconfigurations such as unquoted service paths in services and although it brilliantly executes its purpose; PowerUp primarily focuses on fetching a select set of registry keys and relaying the presence of any misconfigurations. This is in contrast to arbitrary querying tools like Cobalt Strike’s reg command, which offers a more generalized utility.

Yet, amidst this vast arsenal, why introduce another tool into the mix?

The reason is straightforward: automated post-processing engines. The uniqueness of our newest registry query tool, developed as a Beacon Object File (BOF), isn’t its ability to collect data but rather its seamless connection to the Nemesis post-processing engine. Instead of two categories of registry querying tools, we now have one and post-processing is performed on every arbitrary registry key queried.

With the release of Nemesis, modern-day security practices emphasize not only the “collection” but also on the “interpretation” of data. It’s no longer enough to merely fetch the data; how the data is structured, processed, and relayed for further analysis holds equal significance. Tools that offer structured and machine-parsable outputs can bridge the gap between raw data collection and actionable insights. As Will aptly highlighted in his blog post titled “On (Structured) Data,” there’s a need for such tooling. This registry query tool, bof_reg_collect, performs a query of a registry path, serializes the data into a binary format, and then sends it back to the C2 as a file. A second tool running on the teamserver captures file downloads with a particular name, deserializes the data, and returns a JSON file that can be used for offensive data analysis.

Harnessing BOFs for Stealthy Data Collection

A quick tangent about Beacon Object Files (BOF): for those unfamiliar, BOFs are common object file format (COFF) libraries that, when tasked by the C2 agent, execute within the agent process and aren’t linked to a C standard library during runtime. The structure of a BOF is very simple. A developer defines a function named go that contains the code to be executed when the BOF is run. The BOF loader built into a compatible C2 agent will find the go function, link the desired functions, and call the go function when tasked. This makes BOFs great for calling a few Win32 API functions and sending the results back to the user. Although BOFs have some downsides such as not having the flexibility of a standard C library, they are still a good option because of their small size. In the Cobalt Strike documentation, there’s an interesting example: “A UAC bypass privilege escalation Reflective DLL implementation may weigh in at 100KB+. The same exploit, built as a BOF, is < 3KB.” (source).

Performing host data collection in any language on Windows typically follows the process of calling one or more Win32 API functions, performing some processing, and then sending that data back to the user in some format like stdout. Because BOFs have a small form factor and relatively operationally secure execution mechanism, they’re a great form factor for writing post-exploitation data collection tooling. To solve the issue of returning structured data for registry collection, the Nemesis team developed a BOF that serializes the data returned from the registry into a standardized format so that it can be converted to JSON for Nemesis to parse.

Step-by-Step Breakdown of bof_reg_collect

To collect registry keys, the registry collection BOF utilizes a series of Win32 APIs, puts that data into a C structure, and serializes the data after all the data has been collected.

Using Win32 API Functions to Query Registries

The process kicks off by querying the registry using the Win32 API functions, specifically utilizing the wide string (-W postfix) versions of those functions. This ensures that registry paths with non-ASCII characters, with the exception of the null character, can be collected. A registry path is first opened with RegOpenKeyExW to get a handle to the registry key. This handle is used as the input for RegQueryInfoKeyW, which returns details about the key like the number of subkeys and values associated with the target path. Next, we iterate on the number of subkeys and call RegEnumKeyExW for each subkey present in the path. If the recursive option is enabled, the tool uses the base path and the new target key name to create a new target key and then performs the registry query function — this time with the new target key. Next, we iterate on the number of values and call RegEnumValueW for each value present in the path. We save the path name, key, value type, and value in a C structure which is pushed to a linked list living on the stack. Finally, we’ll call RegCloseKey to clean up the open handle.

Client-Side Serialization

Now, we have a linked list of C structures that represent the data we want to send back to the C2. Instead of using a text-based serialization format like JSON or YAML, we chose a binary serialization format. The rationale behind this decision is straightforward: with binary serialization, we can achieve a more compact data representation, leading to more efficient storage and potentially faster transmission times. However, we are using a BOF to implement this collector, which presents a unique challenge. Given the nature of BOFs — not being linked to libc — it’s hard to find binary serialization libraries specifically tailored for BOFs. While the ideal would be a BOF-dedicated serialization library (

05 September 2023


>>More