Windows.Forensics.CertUtil
Windows.Forensics.CertUtil
Extracts download metadata from the Windows Certutil CryptnetUrlCache to reveal LOLBin downloads.
The Windows Certutil binary is capable of downloading arbitrary files. Attackers typically use it to fetch tools undetected when using “Living off the Land” (LOL) techniques.
Certutil maintains a cache of the downloaded files and this contains valuable metadata. The artifact parses this metadata to establish what was downloaded and when.
name: Windows.Forensics.CertUtil
description: |
Extracts download metadata from the Windows Certutil
CryptnetUrlCache to reveal LOLBin downloads.
The Windows Certutil binary is capable of downloading arbitrary
files. Attackers typically use it to fetch tools undetected when
using "Living off the Land" (LOL) techniques.
Certutil maintains a cache of the downloaded files and this contains
valuable metadata. The artifact parses this metadata to establish
what was downloaded and when.
reference:
- https://u0041.co/blog/post/3
- https://thinkdfir.com/2020/07/30/certutil-download-artefacts/
- https://lolbas-project.github.io/lolbas/Binaries/Certutil/
parameters:
- name: MinSize
type: int
description: Only show contents larger than this size.
- name: URLWhitelist
type: csv
default: |
URL
http://sf.symcd.com
http://oneocsp.microsoft.com
http://certificates.godaddy.com
http://ocsp.pki.goog
http://repository.certum.pl
http://www.microsoft.com
http://ocsp.verisign.com
http://ctldl.windowsupdate.com
http://ocsp.sectigo.com
http://ocsp.usertrust.com
http://ocsp.comodoca.com
http://cacerts.digicert.com
http://ocsp.digicert.com
- name: MetadataGlobUser
default: C:/Users/*/AppData/LocalLow/Microsoft/CryptnetUrlCache/MetaData/*
- name: MetadataGlobSystem
default: C:/Windows/*/config/systemprofile/AppData/LocalLow/Microsoft/CryptnetUrlCache/MetaData/*
- name: AlsoUpload
type: bool
- name: VSSAnalysisAge
type: int
default: 0
description: |
If larger than zero we analyze VSS within this many days
ago. (e.g 7 will analyze all VSS within the last week). Note
that when using VSS analysis we have to use the ntfs accessor
for everything which will be much slower.
- name: DISABLE_DANGEROUS_API_CALLS
type: bool
description: |
Enable this to disable potentially flakey APIs which may cause
crashes.
sources:
- query: |
LET VSS_MAX_AGE_DAYS <= VSSAnalysisAge
LET Accessor = if(condition=VSSAnalysisAge > 0, then="ntfs_vss", else="auto")
LET Profile = '[
["Header", 0, [
["UrlSize", 12, "uint32"],
["HashSize", 100, "uint32"],
["DownloadTime", 16, "uint64"],
["FileSize", 112, "uint32"],
["URL", 116, "String", {
"encoding": "utf16",
"length": "x=>x.UrlSize"
}],
["Hash", "x=>x.UrlSize + 116", "String", {
"encoding": "utf16",
"length": "x=>x.HashSize"
}]
]]
]'
-- Build a whitelist regex
LET URLRegex <= "^" + join(array=URLWhitelist.URL, sep="|")
LET Files = SELECT OSPath,
-- Parse each metadata file.
parse_binary(filename=OSPath, accessor=Accessor,
profile=Profile,
struct="Header") AS Header,
-- The content is kept in the Content directory.
OSPath.Dirname.Dirname + "Content" + OSPath.Basename AS _ContentPath,
read_file(length=4, accessor=Accessor,
filename=OSPath.Dirname.Dirname + "Content" + OSPath.Basename) AS ContentHeader
FROM glob(globs=[MetadataGlobUser, MetadataGlobSystem], accessor=Accessor)
WHERE Header.FileSize > MinSize
SELECT OSPath AS _MetadataFile, _ContentPath,
if(condition=AlsoUpload, then=upload(file=OSPath, accessor=Accessor)) AS _MetdataUpload,
if(condition=AlsoUpload, then=upload(file=_ContentPath, accessor=Accessor)) AS _Upload,
Header.URL AS URL,
url(parse=Header.URL).Host AS UrlTLD,
Header.FileSize AS FileSize,
regex_replace(re='"', replace="", source=Header.Hash) AS Hash,
timestamp(winfiletime=Header.DownloadTime) AS DownloadTime,
if(condition= ContentHeader=~ 'MZ',
then= parse_pe(file= _ContentPath, accessor=Accessor).VersionInformation,
else= 'N/A' ) as VersionInformation,
if(condition= ContentHeader=~ 'MZ',
then= authenticode(filename= _ContentPath, accessor=Accessor),
else= 'N/A' ) as Authenticode
FROM Files
WHERE NOT URL =~ URLRegex