Thursday, July 12, 2018

Understanding IP Fragmentation Overlapping with Scapy


The following alert was received from a Symantec Endpoint Protection (SEP) device

<179>Jul 10 09:25:14 sep-papw01 SymantecServer: XXX,SHA-256: ,MD-5: ,"Denial of Service 'IP Fragmentation Overlap' attack detected. Description: An IP Fragmentation Overlap attack exploits IP's packet reassembly feature by creating packet fragments with overlapping offset fields, making it impossible for your system to reassemble the packets properly.",Local: 0.0.0.0,Local: XXXX,Remote: ,Remote: XXXX,Remote: 000000000000,Inbound,ICMP,,Begin: 2018-07-10 06:26:10,End: 2018-07-10 06:26:11,Occurrences: 2,Application: ,Location: XXXX,User: XXXX,Domain: XXXX,XXXX Port 0,Remote Port 0,CIDS Signature ID: 0,CIDS Signature string: ,CIDS Signature SubID: 0,Intrusion URL: ,Intrusion Payload URL: 

Our main concern from the message above is "Denial of Service 'IP Fragmentation Overlap' attack detected".

If you are a new Analyst and see this message, you may wonder WTF is this? What does this mean?
Fortunately the above alert also provides a description, which is:
"An IP Fragmentation Overlap attack exploits IP's packet reassembly feature by creating packet fragments with overlapping offset fields, making it impossible for your system to reassemble the packets properly"

 If you are still thinking but Nik, WTF does this mean? Then let's get into solving this mystery.

Your network interface card has a maximum number of bytes it can carry at one time. This is called the MTU or the Maximum Transmission Unit. To see your interface's current MTU, on a Linux device type:

securitynik@securitynik.lab:~# ifconfig | grep --color=always --perl-regexp "mtu.*?$"
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536



Above you see, for eth0 interface I have an MTU of 1500 bytes, while on my loopback there is an MTU of 65536 bytes. While we will not be crafting packets as large as 1500 or 65536 bytes, the concept remains the same. If a packet is larger than the MTU then the packet needs to be fragmented or broken up into smaller pieces so that it can traverse your network. When the sending device or network device breaks this packet up, it needs to be reassembled by the receiving host. In order for this reassembly to work properly, data has to be placed at specific offset. If that data overlaps or there are missing fragments, it can impact the successful reassembly of the packets.

Let's craft a "normal" packet with scapy and the string "SecurityNik-IP-Fragmentation" to understand what "normal" should look like before we look at what fragment overlapping looks like.


>>> send(IP(src="1.1.1.1", dst="192.168.208.131")/"SecurityNik-IP-Fragmentation", count=1)

The above produces the following in tcpdump as shown below.

securitynik@securitynik.lab:~# tcpdump -nntvvi any host 1.1.1.1 -X
IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto Options (0), length 48)
    1.1.1.1 > 192.168.208.131:  ip-proto-0 28
 0x0000:  4500 0030 0001 0000 4000 e79f 0101 0101  E..0....@.......
 0x0010:  c0a8 d083 5365 6375 7269 7479 4e69 6b2d  ....SecurityNik-
 0x0020:  4950 2d46 7261 676d 656e 7461 7469 6f6e  IP-Fragmentation

The above represents a packet which is not fragmented. We can tell its not fragmented because among the most important items for fragmentation, is the fact that we see above "offset 0" and "flags none". Another critical component of fragmentation is the IP ID field. Above this is represented by "id 1". As we look above we also see "length 48" which implies this packet is 48 bytes long. Minus the 20 bytes of IP header and we have 28 bytes of data as seen by the "28" above after "ip-proto-0". This means that the string "SecurityNik-IP-Fragmentation" takes up 28 bytes. When counting the offset, we start from 0. Therefore 0-27 will result in 28 bytes.


S  e  c  u  r  i  t  y  N  i  k  -  I  P  -  F  r  a  g  m  e  n  t  a  t  i  o  n
0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 

Let's now craft a fragmented packet which has 2 fragment trains to get an idea what fragmentation looks like. In this case, we will break up the string "SecurityNik-IP-Fragmentation". To be specific, the first fragment will contain "SecurityNik-IP-F" while the second fragment contains "ragmentation"

Here is scapy crafting of the packet.

>>> send(IP(src="1.1.1.1", dst="192.168.208.131", id=20, flags=0x1, frag=0)/"SecurityNik-IP-F", count=1)
>>> send(IP(src="1.1.1.1", dst="192.168.208.131", id=20, flags=0x0, frag=2)/"ragmentation", count=1)

Here is tcpdump output

securitynik@securitynik.lab:~# tcpdump -nntvvi any host 1.1.1.1 -X
IP (tos 0x0, ttl 64, id 20, offset 0, flags [+], proto Options (0), length 36)
    1.1.1.1 > 192.168.208.131:  ip-proto-0 16
 0x0000:  4500 0024 0014 2000 4000 c798 0101 0101  E..$....@.......
 0x0010:  c0a8 d083 5365 6375 7269 7479 4e69 6b2d  ....SecurityNik-
 0x0020:  4950 2d46                                IP-F
IP (tos 0x0, ttl 64, id 20, offset 16, flags [none], proto Options (0), length 32)
    1.1.1.1 > 192.168.208.131: ip-proto-0
 0x0000:  4500 0020 0014 0002 4000 e79a 0101 0101  E.......@.......
 0x0010:  c0a8 d083 7261 676d 656e 7461 7469 6f6e  ....ragmentation
 

From above, if we look at the first record, we see "offset 0" and "flags [+]". Notice the IP ID is also the same "id 20". Notice also the "length 36". Once again, minus the 20 byte IP header and there is "16" bytes of data. The second record (fragment) has "offset 16" and "flags [none]". This means the second record should be placed 16 bytes after the first record and there are no more fragments to follow. We know there are no more fragments because the "flags [none]".

From a more visual perspective

S  e  c  u  r  i  t  y  N  i  k  -  I  P  -  F  r  a  g  m  e  n  t  a  t  i  o  n
0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 


As you can see from above, there is no overlap. The string "SecurityNik-IP-Fragmentation" looks much the same as the "normal" packet we discussed above. The "S" starts at 0 and the "r" starts at offset 16.

Now that we have the basics out of the way, let's now look at the overlap. To help, let's craft the same packet again, this time modifying the offset to ensure they overlap. Whereas above "frag=2" was used, below "frag=1" will be used. To get a better understanding of these numbers, you have to multiply then by "8". Hence the "frag=2" is offset 16 and "frag=1" will be offset "8"

And the tcpdump output

securitynik@securitynik.lab:~# tcpdump -nntvvi any host 1.1.1.1 -X
IP (tos 0x0, ttl 64, id 20, offset 0, flags [+], proto Options (0), length 36)
    1.1.1.1 > 192.168.208.131:  ip-proto-0 16
 0x0000:  4500 0024 0014 2000 4000 c798 0101 0101  E..$....@.......
 0x0010:  c0a8 d083 5365 6375 7269 7479 4e69 6b2d  ....SecurityNik-
 0x0020:  4950 2d46                                IP-F
IP (tos 0x0, ttl 64, id 20, offset 8, flags [none], proto Options (0), length 32)
    1.1.1.1 > 192.168.208.131: ip-proto-0
 0x0000:  4500 0020 0014 0001 4000 e79b 0101 0101  E.......@.......
 0x0010:  c0a8 d083 7261 676d 656e 7461 7469 6f6e  ....ragmentation

From a more visual perspective

S  e  c  u  r  i  t  y  N  i  k  -  I  P  -  F  
0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 
                        r  a  g  m  e  n  t  a  t  i  o  n 
                        8  9  10 11 12 13 14 15 17 18 19 20

As we can see above, the two fragments begin to overlap at offset 8.

Why would a threat actor want to use this you may be asking? The reality is, this can be used to bypass security products such as IDS/IPS if not properly configured.

Ok. That's it for a Understanding IP Fragmentation Overlapping with Scapy

References:
https://wiki.wireshark.org/Ethernet
https://en.wikipedia.org/wiki/Ethernet_frame
https://wiki.wireshark.org/CaptureSetup/Ethernet
https://snort.org/faq/readme-frag3
https://www.plixer.com/blog/general/netflow-security-detecting-ip-fragmentation-exploits-scrutinizer/
http://pld.cs.luc.edu/courses/447/sum08/class3/novak.target_based_frag.pdf
https://www.cs.montana.edu/courses/fall2005/440/slides/slides_20051026_ip_2.pdf
http://www.tcpipguide.com/free/t_IPMessageReassemblyProcess.htm

Monday, July 9, 2018

Host based threat hunting with Australia's Cert DensityScout and Sysinternals's Sigcheck

In this post, I'm looking at using a two different tools to detect the known unknowns. Basically, I will be doing some host based threat hunting. The known in this case refers to files which are known to be malicious. This can be as a result of AntiMalware vendors, VirusTotal, etc.. classifying these files. However, the unknown refers to me not being aware of these being malicious files. Specifically, the tools we will review are Australia Cert DensityScout and Microsoft Sysinternal sigcheck. These tools will help us to identifies anomalies.

As always with any tool you use, you first should look at the help, man page or any other documentation to get an understanding of what the tool does. In our case, there is also good documentation online as shown in the reference section.

To get the help, you can run densityscout without any arguments. It is recommended if you are on a 64 bit windows system to use the x64 version of densityscout.

E:\Tools\densityscout_45\win64>densityscout.exe -pe -p 0.1 -l 0.1 -o c:\tmp\densityscout-results.txt -r c:\


From above, the options are as follows:
-pe -> focus on files that has the PE header. that is the "MZ" signature in its first 2 bytes.
-p 0.1 -> print on the screen files that have a density lower than 0.1
-l 0.1 -> only files that have a density lower than 0.1
-o c:\tmp\densityscout-results.txt -> The output file to which the results should be written
-r c:\ -> start at the root of the C drive and recurse through all sub-directories

After the tool finishes running, we see our file has been created.
E:\Tools\densityscout_45\win64>dir c:\tmp\densityscout-results.txt

 Volume in drive C has no label.
 Volume Serial Number is 080B-A369
 Directory of c:\tmp

2018-06-07  11:21 PM            14,046 densityscout-results.txt
               1 File(s)         14,046 bytes
               0 Dir(s)  44,528,136,192 bytes free


I then moved this file to my analysis machine to sort the value from lowest to highest.
$ sort densityscout-results.txt --reverse > densityscout-results-sorted.txt
$ cat densityscout-results-sorted.txt | more
(0.09947) | c:\Program Files\Microsoft Office\Office16\1033\MSOUC.HXS
(0.09709) | c:\Users\All Users\PCDr\6875\AddOnDownloaded\d1381de6-f6df-4c78-9412-f365e1907833.dll
(0.09709) | c:\ProgramData\PCDr\6875\AddOnDownloaded\d1381de6-f6df-4c78-9412-f365e1907833.dll
(0.09167) | c:\PortablApps\PortableApps\YUMIPortable\App\YUMI\YUMI.exe
(0.09061) | c:\Program Files\Microsoft Office\Office16\1033\GRAPH.HXS
(0.09008) | c:\Windows\SoftwareDistribution\Download\9f24bc49f22b4a2eda1267a5c08b0903\amd64_Microsoft-Windows-EditionP
ack-Enterprise-Package~~AMD64~~10.0.17134.1\amd64_windows-defender-am-sigs_31bf3856ad364e35_10.0.17134.1_none_a2054a63
84cba550\mpasdlta.vdm
(0.08639) | c:\Windows\WinSxS\amd64_microsoft-windows-p..urepassword-library_31bf3856ad364e35_10.0.16299.15_none_33fba
22d1a24c307\Windows.UI.PicturePassword.dll
(0.08639) | c:\Windows\System32\Windows.UI.PicturePassword.dll
(0.08273) | c:\Users\Security Nik\AppData\Roaming\PCDr\Repair\BundleApplicationRepairTool.exe
(0.08273) | c:\home\SecurityNik\AppData\Roaming\PCDr\Repair\BundleApplicationRepairTool.exe
(0.08245) | c:\Users\All Users\Comodo Downloader\cis\download\installs\5080\xml_binaries\ise\ise_installer.exe
(0.08245) | c:\ProgramData\Comodo Downloader\cis\download\installs\5080\xml_binaries\ise\ise_installer.exe
(0.08181) | c:\Users\All Users\Comodo\ISE\ise_installer.exe
(0.08181) | c:\Users\All Users\Comodo\Installer\ise_installer.exe
(0.08181) | c:\Users\All Users\Comodo Downloader\cis\download\installs\5140\xml_binaries\ise\ise_installer.exe
(0.08181) | c:\ProgramData\Comodo\ISE\ise_installer.exe
.................

Now that we have the densityscout data, let's now transition to leveraging Sigcheck.

Running sigcheck:

E:\Tools\SysinternalsSuite>sigcheck -e -c -u -h -vr -s c:\ > c:\tmp\sigCheck.csv
-e -> Scan executable images only
-u -> show only unsigned files
-h -> generate file hshes
-i -> Show the catalog name and signing chain
-vr -> Submit to VirusTotal and open a report via the browser for hahses found to be a malware
-s c:\ -> while searchig the C drive, recurse through the subdirectories
> c:\tmp\sigCheck.csv -> Instead of putting the output on the screen, redirect it to a file named sigCheck.csv

Taking a snapshot of the output from Sigcheck, we get:
E:\Tools\SysinternalsSuite>type c:\tmp\sigCheck.csv | more
Path,Verified,Date,Publisher,Company,Description,Product,Product Version,File Version,Machine Type,MD5,SHA1,PESHA1,PESHA256,SHA256,IMP,VT detection,VT link
"c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\1031\TrackerUI.dll","Signed","11:30 PM 2017-10-19","Microsoft Corporation","Microsoft Corporation","TrackerUI","Microsoft« Build Tools«","15.0.27019.1","15.0.27019.1 built by: D15REL","32-bit","F29E0E408814D42D57DF21716CD639F5","EE068C956AA94D6D142671BE0587451A0B607F04","7C625DB9CC169B46DA3A2A5CEF7AE898B08912F9","317A7B6ED6BC09E428C40B32E93E28F8CC60EE9B4165FA615A4CEA02541066F2","9AB44675F42B0D6037495FAF00258CA560F7EAA7F19AD0087A8D96C6D4290F2A","n/a","1|66","https://www.virustotal.com/file/9ab44675f42b0d6037495faf00258ca560f7eaa7f19ad0087a8d96c6d4290f2a/analysis/"
"c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\amd64\de\MSBuildTaskHost.resources.dll","Signed","6:06 PM 2017-12-04","Microsoft Corporation","Microsoft Corporation","MSBuildTaskHost.exe","Microsoft« Build Tools«","15.5.180+ge4c819961e","15.5.180.51428","32-bit","493F30FA92F8A9328EB0FE7602D14967","6EDAA34EAC59C858A1B73D28064B182BD2CF020B","E14F7B38A666BE9E85E3C49B890C959952091E7C","80AA7F9B2E3537B481CAFC211A6E5D782F2447B3BF3BC4CE6B6501C1791AAEB7","B732893B0A3965E831F6B2B7A06A3216137CEBE1D3309F1653107DC564EA13C8","DAE02F32A21E03CE65412F6E56942DAA","1|65","https://www.virustotal.com/file/b732893b0a3965e831f6b2b7a06a3216137cebe1d3309f1653107dc564ea13c8/analysis/"
............


From the data returned from Sigcheck, the first thing I did in the interest of time, was to sort the data by the VirusTotal column, to understand VirusTotal ratings of the files starting from highest to lowest.


To achieve my objective, I started off by using the Linux sort utility on the 17th field as the key. However, for whatever strange reason I was not getting the results I expected. This is why we should always be aware of different ways of receiving the same results. As a result, I used "awk" to rewrite the fields so that the 17th column could move to the first and the first moved to the second.

The command below starts by first reading the file Sigcheck.csv. Next a grep was made for the string "Unsigned". This allows us to focus only on the returned results which are unsigned. This was then followed by the awk command to print the 17th and 1st field. Finally, the 12th field is moved to field 3. From the results returned, this was then followed by a grep using perl regular expresion looking for the first column that does not start with the number 1. From the results returned, it was then sorted to keep VirusTotal highes match rate at the top.


$ cat Sigcheck.csv | grep "Unsigned" | awk --field-separator=, '{ print $17","$1","$12 }' | grep --perl-regexp "^[^1]*\|\d+" | sort --uniq --reverse
"4|67","c:\VTRoot\HarddiskVolume2\Portable Apps\PortableApps\HDHackerPortable\App\HDHacker\HDHacker.exe","5C2D22AAC32335E5F29898473EAEF9D21B38EDD7"
"3|66","c:\Windows\assembly\NativeImages_v4.0.30319_32\Microsoft.Vde5ed89a#\457b4a4c20bed2246e03f1f9e5eaa1a5\Microsoft.VisualStudio.Utilities.Internal.ni.dll","D4B3C929D755B7AD9AAE5D6C64081DE5BD5E4060"
"2|68","c:\VTRoot\HarddiskVolume2\Portable Apps\PortableApps\IObitUnlockerPortable\App\IObitUnlocker\SysLegacy32\IObitUnlocker.sys","2446597BD4FD1F67657425310BEC5DB5614A8616"
"2|68","c:\VTRoot\HarddiskVolume2\Portable Apps\PortableApps\FreeUPXPortable\App\FreeUPX\upx394.exe","747159A347C12D394E9576167C234D7DB3D9AB0A"
"2|66","c:\VTRoot\HarddiskVolume2\Portable Apps\PortableApps\ConverberPortable\App\Converber\Converber.exe","38EF4F2313BF0670B845907F089D5B2873A65F32"
"2|65","c:\VTRoot\HarddiskVolume2\Portable Apps\PortableApps\FreeUPXPortable\App\FreeUPX\upx393.exe","73AC17C4301274342E69A32E25C2CA2FB84D985B"

Now that we have the results from Sigcheck analysis, let's now see if any of these results also show up in the densityscout report. Leveraging our analysis machine again, we have.


$ cat densityscout-results-sorted.txt | grep --perl-regexp --ignore-case "(HDHacker|IObitUnlocker|upx394|upx393|Converber)"
(0.07310) | c:\VTRoot\HarddiskVolume2\Portable Apps\PortableApps\HDHackerPortable\App\HDHacker\HDHacker.exe
(0.07310) | c:\PortablApps\PortableApps\HDHackerPortable\App\HDHacker\HDHacker.exe
(0.03109) | c:\VTRoot\HarddiskVolume2\Portable Apps\PortableApps\FreeUPXPortable\App\FreeUPX\upx393.exe
(0.03109) | c:\PortablApps\PortableApps\FreeUPXPortable\App\FreeUPX\upx393.exe
(0.02833) | c:\VTRoot\HarddiskVolume2\Portable Apps\PortableApps\FreeUPXPortable\App\FreeUPX\upx394.exe
(0.02833) | c:\PortablApps\PortableApps\FreeUPXPortable\App\FreeUPX\upx394.exe

Since we have matches across the two files, we can start with now putting the hashes in VirusTotal or another other site that does this type of analysis and start getting a better understanding of what the file does.

Obviously at this point if there are concerns about these files, they should be removed from your system. Alternatively, you may want to update your own Antimalware solutions and perform a scan to see if it detects these files as malicious. Additionally, you may choose to run it in a confined environment to perform your own analysis.

Ok. That's it for this post. Hope you enjoyed it.


References:
https://www.cert.at/downloads/software/densityscout_en.html
https://docs.microsoft.com/en-us/sysinternals/downloads/sigcheck
https://stackoverflow.com/questions/4105956/regex-does-not-contain-certain-characters
https://www.gnu.org/software/gawk/manual/gawk.html
https://regexone.com/lesson/excluding_characters