aalfaifi Aug 27, 2020 08:21 0 0

Certutil Artifacts Analysis

certutil is a build-in tool on windows systems that is used to manage certificates. However certutil could be used to base64 encode/decode, calculate file hashes and download files from the internet. In this blog we will take a look at the artifacts generated by certutil when downloading a file, specifically the metadata file, analyze it's structure and write a parser for it.


In this example we will download a file using certutil and observe the files written to the system. The following command will download mimkatz from github and save it to the current directory (C:\windows\temp):

certutil.exe -urlcache -split -f "https://github.com/gentilkiwi/mimikatz/releases/download/2.2.0-20200816/mimikatz_trunk.7z" m.7z

After executing the above command we can see in procmon that is writing to two files:

Both files have the same name but on different directories. The file name BC456035A9E2885290EDC953764CC761  is the MD5 hash for the URL UTF-16LE encode:

The file located on C:\Users\u0041\AppData\LocalLow\Microsoft\CryptnetUrlCache\Content\BC456035A9E2885290EDC953764CC761 contains the actual file:

However C:\Users\u0041\AppData\LocalLow\Microsoft\CryptnetUrlCache\MetaData\BC456035A9E2885290EDC953764CC761 contains UTF-16LE encode URL and MD5 hash for the downloaded file in addition to some binary data:

The URL and the MD5 hash can be extracted easily, But what about the header (116 bytes) ? the following summarize my findings:

Field NameOffsetSizeType


-x00x0CbyteUnknown. x70x00x00x00 might be the header length (112 bytes).
urlSizex0Cx04uint32The size for the UTF-16LE encoded URL
Timestampx10x08uint64The last time the file was downloaded in FILETIME format.


The file last modification time header from the reponse (Thanks to @mrAn61 on Twitter for pointing that out)

hashSizex64x04uint32The size for the UTF-16LE encode hash
fileSizex70x04uint32The downloaded file size in bytes
URLx74urlSizeUTF-16LE StringThe URL from where the file was downloaded
x74 + urlSizehashSizeUTF-16LE String

The hash for the downloaded file. The following are some of the hashing algorithms observed during analysis:

  • MD5
  • SHA1
  • SHA256
  • Unkown hash (ex. 57f3c9cf-1514ce) 

In some cases the hash value is empty.


This is the E-Tag header of the file from the HTTP response. E-Tag is used to identify a specific version of a file, If the file changes then the E-Tag changes.

As you can see the metadata file contains a lot of useful information, However there is a lot more data that is unknown (highlighted with red color). I am still researching what that data might be, If you want to help please leave a comment on this blog or send me a DM on twitter @A__ALFAIFI.


I wrote a parser that output the above data in readable format (CSV, JSON or JSONL). You can find it here for the Python version CryptnetURLCacheParser and here CryptnetURLCacheParser-rs for the Rust version. The following is the parser output in JSON format:

  1. {
  2. "Timestamp": "2020-09-11T16:53:07.297208",
  3. "URL": "https://github.com/gentilkiwi/mimikatz/releases/download/2.2.0-20200816/mimikatz_trunk.7z",
  4. "FileSize": 875252,
  5. "MetadataHash": "5abdd836d4458370a804f2974431c993",
  6. "FullPath": "C:\\Users\\u0041\\AppData\\LocalLow\\Microsoft\\CryptnetUrlCache\\MetaData\\BC456035A9E2885290EDC953764CC761",
  7. "MD5": "5abdd836d4458370a804f2974431c993"
  8. }

Edit 1

I have identified a couple of stuff in the metadata structure, the table above is updated to the latest findings. The following is the summery:

  • The MetadataHash field is actually the E-Tag header from the HTTP response.
  • Another timestamp is recorded which is the LastModificationTime header from the HTTP response (Thanks to @mrAn61 on Twitter for pointing that out).
  • Created another parser for this artifact bu in Rust! you can find it here CryptnetURLCacheParser-rs.



No Comments - Yet 😁

Write a comment

You need to login to write comments - you can login from HERE or register from HERE