Intro
In a previous blog, I visited the topic of identifying internet-sourced files on a host system to help incident response teams quickly collect information to investigate a potential incident by utilizing Zone Identifiers. This information is crucial to gather as it could often answer the questions surrounding source attribution. So now that we found some suspicious MS Office files downloaded from the internet, how can we say they were enabled and executed?
Is it possible to prove that a user trusted and enabled the active content (i.e. – macro) of an MS Office document?
Absolutely!
Research
Windows maintains a list of trusted content through entries in the registry located at HKU\<SID>\Software\Microsoft\Office\<version>\<application>\Security\Trusted Documents\TrustRecords
.
Microsoft defines ‘Active Content’ as an “additional functionality in a file or program, such as macros, add-ins, or data connections.” Clicking on ‘Enable Content’ will ensure that document becomes trusted moving forward. Trusted documents in Windows will not display the security warning “Message” bar, indicating potential virus or malicious content, for active content embedded in the document.

Proof of Concept
In conducting this experiment, two Microsoft Word documents were transmitted via the internet, one containing a macro and the other without. Both documents were tested by enabling editing, which resulted in the “REG_BINARY” values in the registry being updated to end with byte sequences of “01 00 00 00”. Upon enabling content on the document containing the macro, the “REG_BINARY” value was observed to change byte sequences to end with “FF FF FF 7F”.
Using PowerShell, let’s inspect the relevant records to view this information:

The output is expected with the ‘REG_BINARY’ byte sequences being as they are. To streamline the process and eliminate the need for manual recall of these values and their significance, the script below can provide incident response teams with readily accessible information regarding the trusted documents of a user and the host system’s actions in response to user authorization.
Script
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# output file
$csvFile = 'C:\temp\documents_users_trusted_and_enabled.csv'
# Define the regular expression
$regex = '^(?<FileName>.+?)\s{2,}(?<REG_BINARY>REG_BINARY)\s{2,}(?<binary>.+)$'
# Initialize an array to hold the matches
$matches = @()
# Get the list of registry keys and loop through each one
$registryKeys = gci 'REGISTRY::HKU\*\Software\Microsoft\Office\*\*\Security\Trusted Documents\TrustRecords' -ea 0
foreach ($key in $registryKeys) {
# Query the properties of the key
$queryResult = reg query $key.Name
# Extract all matches in the query result using the Matches() method
$matchCollection = [regex]::Matches($queryResult, $regex)
# Loop through each match and add it to the array
foreach ($match in $matchCollection) {
$FileName = $match.Groups['FileName'].Value
$REG_BINARY = $match.Groups['REG_BINARY'].Value
$binary = $match.Groups['binary'].Value
$matches += "$FileName $REG_BINARY $binary"
}
}
# Concatenate the matches into a single string, separated by newline characters
$concatenated = $matches -join "`n"
# Replace every occurrence of white space characters with a newline character
$split = $concatenated -replace '(\s+)(?:\s+\s+){2}', "`n"
# Split the string into lines
$lines = $split -split "`n"
# Create an empty array to hold the CSV rows
$csvRows = @()
# Loop through each line
foreach ($line in $lines) {
# Extract the FileName and binary values
if ($line -match '^(?<FileName>.+?)\s{2,}REG_BINARY\s{2,}(?<binary>.+)$') {
$FileName = $Matches['FileName']
$binary = $Matches['binary']
# Check if the binary value has "01000000"
if ($binary -match '.+01000000.*') {
# Set EnabledEditing to "True"
$EnabledEditing = "True"
$EnabledContent = "False"
} elseif ($binary -match '.+FFFFFF7F.*') {
# Check if the binary value has "FFFFFF7F"
# Set to "True"
$EnabledContent = "True"
$EnabledEditing = "True"
} else {
# Set to "False"
$EnabledContent = "False"
$EnabledEditing = "False"
}
# Add a row to the CSV array
$csvRows += "$FileName,$EnabledEditing,$EnabledContent,$binary"
}
}
# Join the CSV rows into a single string, separated by newline characters
$csv = $csvRows -join "`n"
# Output the CSV to a file
Set-Content -Path $csvFile -Value $csv
# Convert the CSV rows to objects
$objects = $csvRows | ForEach-Object {
$row = $_ -split ','
[PSCustomObject]@{
FileName = $row[0]
EnabledEditing = $row[1]
EnabledContent = $row[2]
BinaryValue = $row[3]
}
}
# Output the objects to a CSV file
$objects | Export-Csv -Path $csvFile -NoTypeInformation
This will output a csv file at ‘C:\Temp\documents_users_trusted_and_enabled.csv’ containing the following information:
FileName | EnabledEditing | EnabledContent | BinaryValue |
%USERPROFILE%/Downloads/Searches.xlsx | TRUE | FALSE | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01000000 |
%USERPROFILE%/Downloads/asdfasdfasdf.docx | TRUE | FALSE | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01000000 |
%USERPROFILE%/Downloads/testing_macros.docm | TRUE | TRUE | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxFFFFFF7F |
Conclusion
By utilizing the Windows registry, it is possible to track changes made to trusted documents in the context of security. This information is critical in understanding the potential threats posed by malicious documents containing active content. Rapid detection of these malicious activities, as well as the ability to quickly gather relevant information post-compromise, is vital in protecting against these threats.