Analysing NSRL data set for fun and because… curious

Last year I took a very quick look at NSRL hash set. Being de facto golden standard of good hashes I was curious what sort of data is actually included in it. There is no better way of looking at it than actually looking at it so I downloaded the files and started some basic analysis.

The NSRLFile.txt.zip stores 26G file NSRLFile.txt that includes the following number of entries:

192677750 NSRLFile.txt

Yay, that’s a lot!

Now that we know how many entries we have in it, let’s try to see what sort of file extensions we can find inside the file. After parsing the data set I came up with the following results (top 30):

class 44776614
<no ext> 36040752
png 8968329
manifest 6258021
js 4846976
foliage 4513590
py 3938119
dll 3658422
java 3263630
nasl 3256040
html 3068834
h 2671295
xml 2582138
cat 2355352
htm 2197584
mum 2164820
txt 1906815
uasset 1859095
dat 1779063
o 1749951
c 1697767
gz 1691747
mui 1377019
svg 1018434
properties 1004380
mo 1000680
gif 973653
ogg 842367
dds 822591
upk 772181

This is a very interesting statistic — it tells us that a substantial number of records relate to .class files – compiled Java files. This is most likely a result of an automated processing where every single .JAR file is being unzipped and every embedded .class files is accounted for. There are tones of non-executables as well (media files, source code, etc.). It’s a majority of them, really.

Looking specifically for executable / installer files we quickly realize that these are indeed quite scarce:

dll    3658422
o    1749951
bin    557524
so    504442
exe    346292
sys    98390
msi    24763
bat    31482
ps1    13433
cmd    10931
scr    8567
drv    5350

File extensions tell us roughly what file types we deal with, but another great way to look at the NSRL set is statistical analysis of its file names. A quick & dirty histogram I came up with looks like this (top 30):

1221091 ".text"
744897 "1"
719540 "text" 
641856 ".reloc" 
630123 "__bitcode" 
579898 "version.txt" 
530652 ".data" 
457126 "__compact_unwind" 
393021 "__gcc_except_tab" 
387403 "__eh_frame" 
312569 ".rodata" 
312238 "CERTIFICATE" 
265511 "__init.py"
235670 ".rdata"
230514 "Makefile"
214357 ".dynamic"
212477 ".dynsym"
208787 "pathname"
208787 "asset.meta"
208594 ".dynstr"
201074 ".eh_frame"
198758 ".symtab"
194931 ".init"
194760 ".note.gnu.build-id"
194215 ".strtab"
185339 "__const"
184099 "English.dat"
182945 ".gnu.version"
176370 "Master.js"
175495 ".gnu.version_r"

This is yet another interesting statistic that tells us that what we believed to be just large file hashset is actually a mix of files hashes and hashes of sections of executable files. These are useful in malware analysis, but not so much in forensic time-saving exercise that relies on excluding files with known hashes. In other words, if you blindly use NSRL hashset on your forensic images, you are wasting time testing correlations that by the sole nature of NSRL data set will be a waste of CPU cycles. The only set applied to the file system should be hashes of actual files, not their chunks.

The third lesson is pretty obvious — if you plan on using NSRL hashset it’s best to have different sets for different operating systems and for that, we can leverage OpSystemCode field (use a OS-specific subset for the target image). Oh, but not so fast. There are 1300+ OS versions listed inside NSRLOS.txt file. The file includes Amstrad, MSDOS, Novell Netware, NextStep, AIX and many other kinda derelict platforms. If you plan on using NSRL it’s probably good to simply exclude files belonging to these ancient systems first.

Let’s be honest – there is a lot of value in NSRL hashset, but there is always more than just one “but” and I have listed a few. This is not to discourage using it, but be a bit more choosy how we use it and selectively cherry-pick subsets of its data for the time-sensitive analysis.

Putting .inf files and NSRL database to a better use

When you look at a large repository of clean files there is always an opportunity to find something interesting. For instance, list of precursors to forensic artifacts that one can find in legitimate software installation packages. Both pre- and post- install.

Why these may come handy?

Well, while this will never be a 100%-reliable solution these may help to automate at least some of the digital forensic triage processdx. And by that, I mean f.ex. exclusions via file names or their clusters (as opposed to hashes).

I wrote about it long time ago in a context of filelighting, but there are perhaps other, simpler avenues to pursue as well. Filelighting idea focuses on looking for file names referenced by files residing in the installed program folder. We can as well expand it to pre-install directories — be it temporary created folders, manually unpacked drivers or software package installation folders, etc.. And while some of this is no longer that important — after all more and more updates and installations happen in a background, often w/o user’s knowledge, via App stores, etc. and frankly, people probably download less and less software directly today than say 10 years ago, well… it still does happen a lot, and if we can help with some automation… why not?

One of the most interesting sources of information about software packages are good old fashioned .inf files. The other is the good ol’ NSRL database. Yes, the latter focuses primarily on post-install, but we should use whatever is available.

The .inf files reference everything that is there to be installed, often in many configurations, and they provide a list of created / modified files, directories, but also – Registry keys, service names – you name it. It’s a gold mine of information of how a ‘good’ Windows software looks like. It’s a gold mine of forensic artifact precursors. The NSRL database is kinda similar, is a superset of everything good really, but it’s also obviously limited to data available in a dump.

Let’s have a look.

The top of the .inf file usually includes [Version] section. You can find description of the .inf files elsewhere, here, we are focused on stats only. I must note here that parsing .inf files is not as easy as it may seem as they heavily rely on self-referencing, multiple .inf files can be merged together, and there is also a mechanism of string substitution (tokens) in play. Lots of quirks to take care of.

The top occurrences of fields within this section are as follows:

  • Class
  • DriverVer
  • Provider
  • CatalogFile
  • Signature
  • ClassGuid

Combing .inf files for say… CatalogFile field can give us a list of all legitimate .cat files out there (with an obvious caveat that the list is as good, as our ‘good files’ repo). Still, this may come handy for filename-based exclusions. There is a double-edged sword lying somewhere there of course — if you are a bad guy, knowing what good file names are available in legit software packs will very well serve your nefarious purposes as you may surely pick up a file name for your payload from the list…. Oh well…

The NSRL database is well known, so doesn’t need any introduction. What is interesting about the set is an often-forgotten ProductCode field. This is an indicator of where the file/hash/tuple comes from. If you cluster the set by ProductCode you may end up with clusters of file names that belong to a specific product. For example, if we look at say product code 196184 we get this result. As a side note, some of the file names seem to be section names of executables, so the drill-down NSRL guys use seems to be going really deep.

So… there you have it… parse your good .inf files, enrich it by clusters of file names extracted from NSRL set and you may generate a nice cluster-based exclusion list! Happy filelighting!

Bonus:

Okay, not everything is rosy. Here’s a list of .cat file names I have collected during this exercise. Lots of them. I think they can only make sense in a context of either a software installation package (hint: the one with .inf file), or ProductCode in NSRL.