Author Topic: hiv-wfw.trid.xml for Windows Firewall configuration; variant of Windows Registry  (Read 1160 times)

jenderek

  • Sr. Member
  • ****
  • Posts: 375
Hello trid users,

some months ago i send definitions to do sub classification of Windows NT
Registry Hive. In this session i will handle Windows Firewall configuration.

Such files have typically name suffix WFW (like Win10firewall.wfw
netsh-advfirewall.wfw).

Unfortunately as usual you do not find information about file format from
Microsoft. Either you get samples with accessing files via API or low level
information like click on foo to get bar. Luckily there exist an unofficial
page about Windows registry file format on GitHub. This describe some
technical aspects. So i use this as reference in one definition. That is
expressed by line like:
 <RefURL>
 https://github.com/msuhanov/regf/blob/master/
 Windows%20registry%20file%20format%20specification.md
 </RefURL>

Such samples can be exported and imported for example by command like:
      netsh advfirewall export "c:\firewall-rules.wfw"

So i run trid utility on such WFW examples. All samples are recognized and
are described in principal OK as "Windows NT Registry Hive (generic)" by
hiv.trid.xml. But file name suffix is wrong. It is not HIV/DAT (see appended
trid-v-old.txt in output).

For comparison reason i also run the file format identification utility
DROID (See https://sourceforge.net/projects/droid/). Here the samples are
not recognized.

For comparison reason i also run file command (version 5.45) on such
samples. Here such samples are recognized and described generic as "MS
Windows registry file, NT/2000 or above" (see appended file-5.45.txt in
output). The mime type is here generic application/octet-stream (see
appended file-i-5.45.txt in output). The file name suffix is also not
recognized (see appended file-ext-5.45.txt in output).

Instead of generic application/octet-stream mime type i choose the type used
for generic Windows NT Registry Hive. That is expressed by line like:
   <Mime>application/x-ms-registry</Mime>

Because of missing complete information i first create TrID definition
hiv-wfw.trid.xml by running tridscan on many (29) samples. After running
Windows system in Virtualbox and deleting firewall rules i get small enough
samples containing not so much content.

In global string sections i get 2 lines:
   <String>HBIN</String>
   <String>REGF</String>
According to documentation the first is triggered by 4 byte signature hbin
of Hive bins header. The second is triggered by 4 byte signature regf of
Base block, also known as a file header. All these lines are apparently
characteristics for Windows Registry Hive, but no is specif for WFW.

In Front Block section the first construct is characteristic for all
hive. That is expressed by XML construct like:
   <Pattern>
      <Bytes>72656766</Bytes>
      <ASCII> r e g f</ASCII>
      <Pos>0</Pos>
   </Pattern>

Then there are 3 non nil sequences. These look like:
   <Pattern>
      <Bytes>010000000500000000000000010000002000000000</Bytes>
      <Pos>20</Pos>
   </Pattern>
   <Pattern>
      <Bytes>0001000000</Bytes>
      <Pos>43</Pos>
   </Pattern>
   <Pattern>
      <Bytes>726D746D</Bytes>
      <ASCII> r m t m</ASCII>
      <Pos>164</Pos>
   </Pattern>
Apparently here are some fields constant, but none are specific for WFW.

So i looked in output of patched file command according to documentation
(see file.tmp in output). The content becomes visible when you load such
samples with Microsoft registry editor regedit.exe. Or you can use the
Forensic Registry EDitor (fred). The advantage of this program is that there
exist ports for Windows and Linux. The disadvantage is that is does not work
on all registry examples, because file format is not officially revealed. So
maybe the function of some fields are not known and lead to program
crashes. This tool can be found at
    https://www.pinguin.lu/fred .

After deleting all firewall rules i got not so much patterns in definition
(So no needle in haystack problem).
When i look inside Global Strings section i see only 22 lines like:
   <String>P'F'I'R'E'W'A'L'L'.'L'O'G</String>
   <String>%'S'Y'S'T'E'M'R'O'O'T'%</String>
   <String>DISABLENOTIFICATIONS</String>
   <String>DISABLESTATEFULPPTP</String>
   <String>DISABLESTATEFULFTP</String>
   <String>L'O'G'F'I'L'E'S</String>
   <String>S'Y'S'T'E'M'3'2</String>
   <String>STANDARDPROFILE</String>
   <String>ENABLEFIREWALL</String>
   <String>DOMAINPROFILE</String>
   <String>POLICYVERSION</String>
   <String>PUBLICPROFILE</String>
   <String>IPSECEXEMPT</String>
   <String>LOGFILEPATH</String>
   <String>LOGFILESIZE</String>
   <String>LOGGING</String>
   <String>CP-NO</String>
   <String>HBIN</String>
   <String>HCP-</String>
   <String>REGF</String>
   <String>RMTM</String>
   <String>TALL</String>

According to documentation the second last is triggered by 4 byte signature
rmtm of GUID. According to documentation this field exist in Windows 10. So
maybe if other users have samples from older Windows version like Vista this
line will vanish. My samples are from Windows 11, 10, 8 and 7, but such
samples are maybe "reorganized" by newer Windows version. So i keep this
line at the moment.

In my samples the GUID signature appears as expected at fixed offset. This
is expressed inside front block section by XML construct like:
   <Pattern>
      <Bytes>726D746D</Bytes>
      <ASCII> r m t m</ASCII>
      <Pos>164</Pos>
   </Pattern>

According to documentation before that 16 byte GUID is stored.  After the
signature 8 byte last reorganized timestamp is stored. So in my samples
value zero obviously means not reorganized.

The pattern before looks like:
   <Pattern>
      <Bytes>11</Bytes>
      <Pos>155</Pos>
   </Pattern>
According to documentation at offset 148 16 byte GUID TmId is stored. So
apparently by lucky circumstances 1 byte is the same.  Assuming that other
GUID values can occur this construct vanish.

The pattern before looks like:
   <Pattern>
      <Bytes>00000000</Bytes>
      <Pos>144</Pos>
   </Pattern>
The same thoughts must be applied here. According to documentation at offset
144 4 byte flags are stored. So i keep it and mention fact in remark line.

The pattern before looks like:
   <Pattern>
      <Bytes>11</Bytes>
      <Pos>135</Pos>
   </Pattern>
According to documentation at 128 16 byte GUID LogId is stored.  So
apparently by luckily circumstances 1 byte of LogId in my samples is the
same. Assuming that other GUID values can occur this construct vanish and
can be deleted.

The pattern before look like:
   <Pattern>
      <Bytes>11</Bytes>
      <Pos>119</Pos>
   </Pattern>
The same thoughts must be applied here. According to documentation at offset
112 16 byte GUID RmId is stored. Here in my samples one middle byte of that
GUID is the same. Assuming that other GUID values can occur this construct
vanish and can be deleted.

The first 3 XML constructs look like:
   <Pattern>
      <Bytes>72656766</Bytes>
      <ASCII> r e g f</ASCII>
      <Pos>0</Pos>
   </Pattern>
   <Pattern>
      <Bytes>000000</Bytes>
      <Pos>5</Pos>
   </Pattern>
   <Pattern>
      <Bytes>000000</Bytes>
      <Pos>9</Pos>
   </Pattern>
According to documentation after regf signature 4 byte primary sequence
number is stored followed by secondary sequence number.  The first number is
incremented by 1 in the beginning of a write operation on the primary
file. And the second is incremented by 1 at the end of a write operation on
the primary file and numbers should be equal after a successful write
operation. So apparently for such samples the sequence numbers are always be
1 at the beginning. In my examples i get beside 1 low sequence number 5. So
the 3 upper bytes of sequence numbers are nil.  When reaching 32-bit limit
the last 2 construct will vanish. So i delete these.

So next XML construct must be inspected. This looks like:
 <Bytes>010000000500000000000000010000002000000000</Bytes>
 <Pos>20</Pos>

According to documentation at offset 20 major version is stored. The value
in all NT Windows is 1. At offset 24 minor version is stored. In my examples
i get value 5. This is the values mostly found in my other registry
samples. Value 0 means "pre" version, 1 means NT 3.1, 2 means NT 3.5 and
higher values 3,4,5,6 means NT 4 til Windows 11. At offset 28 file type is
stored. 0 means primary file and other values are used for transaction
variants (*.LOG*). So this is always true here. At offset 32 file format is
stored. 1 means direct memory load; This is what i also found in my other
registry samples. At offset 36 root cell offset is stored. In all my
registry samples i get value 20h. At offset 40 Hive bins data size is
stored. Here i get lowest value 1000h. That is apparently the minimal
possible value. I do not know if other values occur here. So i keep this
construct and mention facts in remark line.

The next construct looks like:
   <Pattern>
      <Bytes>0001000000</Bytes>
      <Pos>43</Pos>
   </Pattern>
At offset 44 the clustering factor is stored. In all my registry samples i
get here value 1. That means 512 block size. Before data size is stored. So
in my samples i get "low" values. So the upper byte is nil.  Assuming that
this size can reach 32-bit limit this now becomes like:
   <Pattern>
      <Bytes>01000000</Bytes>
      <Pos>44</Pos>
   </Pattern>

At offset 48 the partial file path is stored. These 64 bytes contain UTF-16
LE encoded name. In the samples with sequence number 1 this string is not
used. So it is filled there with nil bytes. But these names parts can look
like:
   ry\netsh-advfirewall-export.wfw
Because name part are ASCII like stored as UTF16-LE on odd offsets i get a
nil byte. That is expressed by XML constructs like:
   <Pattern>
      <Bytes>00</Bytes>
      <Pos>49</Pos>
   </Pattern>
   <Pattern>
      <Bytes>00</Bytes>
      <Pos>51</Pos>
   </Pattern>
   ...
   <Pattern>
      <Bytes>00</Bytes>
      <Pos>107</Pos>
   </Pattern>
   <Pattern>
      <Bytes>000000</Bytes>
      <Pos>109</Pos>
   </Pattern>
I do not know if it possible to create WFW on file system with directory
names with exotic languages like Chinese. When this is true then the nil
bytes will vanish and only the terminating nil character for UTF-16 will
survive. So the above mentioned patterns vanish and the last one becomes
like:
   <Pattern>
      <Bytes>0000</Bytes>
      <Pos>110</Pos>
   </Pattern>

The last XML construct is like in other definition. At offset 200h (=512)
comes 600h (=1536) padding nil bytes. This is expressed by XML construct
like:
   <Bytes>0000000000000000000000000000000000000000000000000000000
   <Pos>512</Pos>

In other definition after rmtm signature comes Last reorganized
timestamp. After that at offset 176 i get nil byte sequence til about 512
limit. So this looks like:
   <Pattern>
      <Bytes>0000000000000000000000000000000000000000000000
      <Pos>176</Pos>
   </Pattern>

In global strings section i get 4 lines triggered by UTF-16 strings.  The
lines look like:
   <String>P'F'I'R'E'W'A'L'L'.'L'O'G</String>
   <String>%'S'Y'S'T'E'M'R'O'O'T'%</String>
   <String>L'O'G'F'I'L'E'S</String>
   <String>S'Y'S'T'E'M'3'2</String>
Apparently these seem to be characteristic for all WFW samples. When you
look in exported output of regedit you see that this is the file name of
log. That looks like:
   %systemroot%\\system32\\LogFiles\\Firewall\\pfirewall.log

I do not know if it is possible to change this path, but i see no GUI option
to do this. So i assume that this always true. This name is stored inside
variable LogFilePath together with LogFileSize in Logging section. So these
facts are expressed by lines like:
   <String>LOGFILEPATH</String>
   <String>LOGFILESIZE</String>
   <String>LOGGING</String>

One section up i get 3 profiles sections. These are expressed by lines like:
   <String>STANDARDPROFILE</String>
   <String>DOMAINPROFILE</String>
   <String>PUBLICPROFILE</String>

Then some are apparently triggered by behaviour of firewall. These are
expressed by lines like:
   <String>DISABLENOTIFICATIONS</String>
   <String>DISABLESTATEFULPPTP</String>
   <String>DISABLESTATEFULFTP</String>
   <String>ENABLEFIREWALL</String>
   <String>POLICYVERSION</String>
   <String>IPSECEXEMPT</String>
But i do not know if these conditions are always apply. So i keep lines.

Then there are lines that look like garbage:
   <String>CP-NO</String>
   <String>HCP-</String>
   <String>TALL</String>
The last obviously is triggered by keys like DoNotAllowExceptions
CertificateInstall-TCP-Out. The first is triggered by keys that contains
phrases like -RTSP-NoScope or -TCP-NoScope.  The second is triggered by keys
contains phrases like DHCP-In DHCP-Out So i delete these 3 lines.

With this new trid definition now all my WFW samples are described in detail
(correct suffix) beside generic. TrID definition, some samples and output
are stored in archive wfw_.zip. I hope that my definition can be used in
future version of triddefs.

With best wishes
Jörg Jenderek

Mark0

  • Administrator
  • Hero Member
  • *****
  • Posts: 2743
    • Mark0's Home Page
Thanks!