{"id":9781,"date":"2024-12-31T00:20:44","date_gmt":"2024-12-31T00:20:44","guid":{"rendered":"https:\/\/www.hexacorn.com\/blog\/?p=9781"},"modified":"2024-12-31T00:25:20","modified_gmt":"2024-12-31T00:25:20","slug":"smuggling-payloads-and-tools-in-using-wim-images","status":"publish","type":"post","link":"https:\/\/www.hexacorn.com\/blog\/2024\/12\/31\/smuggling-payloads-and-tools-in-using-wim-images\/","title":{"rendered":"Smuggling payloads and tools in, using WIM images"},"content":{"rendered":"\n<p>We often hear of attackers bringing in their payloads via virtual drive images (f.ex. vhd,vhdx) in an attempt to bypass security solutions. The WIM files can be used to smuggle in tools and payloads to the target, too. In my <a href=\"https:\/\/www.hexacorn.com\/blog\/2024\/12\/28\/wimmountdata-ads\/\" data-type=\"post\" data-id=\"9767\">previous post<\/a> I discussed the $WIMMOUNTDATA Alternate Data Stream that is created by <em>dism.exe<\/em> when we use it to mount a WIM image. <\/p>\n\n\n\n<p>Now, the way the WIM images are mounted is interesting for many reasons: <\/p>\n\n\n\n<ul>\n<li>they are mounted read-only, so once mounted, can&#8217;t delete files they provide access to<\/li>\n\n\n\n<li>the files they expose to the OS are not &#8216;created&#8217; in any telemetry sense, so there are no &#8216;File Created&#8217; events for them &#8211; it&#8217;s just a file system tunnel<\/li>\n\n\n\n<li>they are tiny, and can even be easily encrypted\/decrypted using available lolbin tools, or powershell<\/li>\n\n\n\n<li>the .wim files themselves, once mounted, can&#8217;t be deleted<\/li>\n\n\n\n<li>interestingly, when you create .WIM files from sources that include <em>Zone.Identifier<\/em> ADS (typically after downloading the files from the internet), these ADS will make it to the WIM image as well; so, have to be mindful of it<\/li>\n<\/ul>\n\n\n\n<p>Here&#8217;s an example <a href=\"https:\/\/hexacorn.com\/d\/mimikatz.zip\">mimikatz.wim<\/a> (pass: mimi) WIM image (it actually has a decent detection rate on <a href=\"https:\/\/www.virustotal.com\/gui\/file\/99c786b6626ed0eb9d31ea8d140edc8ec03abadc54fd934b148d903d9bf1f7f7\">VT<\/a>). Its file list indicates it was created from a directory that included old mimikatz files downloaded directly from github (hence, ADS are present):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mimidrv.sys<br>mimidrv.sys:Zone.Identifier<br>mimikatz.exe<br>mimikatz.exe:Zone.Identifier<br>mimilib.dll<br>mimilib.dll:Zone.Identifier<br>mimispool.dll<br>mimispool.dll:Zone.Identifier<\/pre>\n\n\n\n<p>The 7z listing of the archive looks as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Listing archive: mimikatz.wim\n\n--\nPath = mimikatz.wim\nType = wim\nPhysical Size = 704059\nSize = 1440688\nPacked Size = 702019\nMethod = XPress:15\nCluster Size = 32768\nCreated = 2024-12-30 22:11:48.7166057\nModified = 2024-12-30 22:11:48.7385760\nComment = &lt;WIM&gt;&lt;TOTALBYTES&gt;703241&lt;\/TOTALBYTES&gt;&lt;IMAGE INDEX=\"1\"&gt;&lt;DIRCOUNT&gt;0&lt;\/DIRCOUNT&gt;&lt;FILECOUNT&gt;4&lt;\/FILECOUNT&gt;&lt;TOTALBYTES&gt;1440600&lt;\/TOTALBYTES&gt;&lt;HARDLINKBYTES&gt;0&lt;\/HARDLINKBYTES&gt;&lt;CREATIONTIME&gt;&lt;HIGHPART&gt;0x01DB5B07&lt;\/HIGHPART&gt;&lt;LOWPART&gt;0xD2354269&lt;\/LOWPART&gt;&lt;\/CREATIONTIME&gt;&lt;LASTMODIFICATIONTIME&gt;&lt;HIGHPART&gt;0x01DB5B07&lt;\/HIGHPART&gt;&lt;LOWPART&gt;0xD2389CA0&lt;\/LOWPART&gt;&lt;\/LASTMODIFICATIONTIME&gt;&lt;WIMBOOT&gt;0&lt;\/WIMBOOT&gt;&lt;NAME&gt;mimi&lt;\/NAME&gt;&lt;\/IMAGE&gt;&lt;\/WIM&gt;\nVersion = 1.13\nMultivolume = -\nVolume = 1\nVolumes = 1\nImages = 1\n\n   Date      Time    Attr         Size   Compressed  Name\n------------------- ----- ------------ ------------  ------------------------\n2013-01-22 16:50:12 ....A        37208        17078  mimidrv.sys\n2022-09-19 15:44:01 ....A        37376        19303  mimilib.dll\n2022-09-19 15:43:57 ....A        10752         4973  mimispool.dll\n2022-09-19 15:44:39 ....A      1355264       660577  mimikatz.exe\n------------------- ----- ------------ ------------  ------------------------\n2022-09-19 15:44:39            1440600       701931  4 files\n2022-09-19 15:44:39                352          352  4 alternate streams\n2022-09-19 15:44:39            1440952       702283  8 streams<\/pre>\n\n\n\n<p>There are plenty of forensic artefacts present in that file, including the <em>Comment<\/em> field that 7z extracts:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;WIM&gt;\n &lt;TOTALBYTES&gt;703241&lt;\/TOTALBYTES&gt;\n &lt;IMAGE INDEX=\"1\"&gt;\n  &lt;DIRCOUNT&gt;0&lt;\/DIRCOUNT&gt;\n  &lt;FILECOUNT&gt;4&lt;\/FILECOUNT&gt;\n  &lt;TOTALBYTES&gt;1440600&lt;\/TOTALBYTES&gt;\n  &lt;HARDLINKBYTES&gt;0&lt;\/HARDLINKBYTES&gt;\n  &lt;CREATIONTIME&gt;\n   &lt;HIGHPART&gt;0x01DB5B07&lt;\/HIGHPART&gt;\n   &lt;LOWPART&gt;0xD2354269&lt;\/LOWPART&gt;\n  &lt;\/CREATIONTIME&gt;\n  &lt;LASTMODIFICATIONTIME&gt;\n   &lt;HIGHPART&gt;0x01DB5B07&lt;\/HIGHPART&gt;\n   &lt;LOWPART&gt;0xD2389CA0&lt;\/LOWPART&gt;\n  &lt;\/LASTMODIFICATIONTIME&gt;\n  &lt;WIMBOOT&gt;0&lt;\/WIMBOOT&gt;\n  &lt;NAME&gt;mimi&lt;\/NAME&gt;\n &lt;\/IMAGE&gt;\n&lt;\/WIM&gt;<\/pre>\n\n\n\n<p>Combining the knowledge from this and previous post, one can start wondering&#8230;<\/p>\n\n\n\n<p>If we mount an innocent WIM image first, one that lists only good (or at the very least &#8211; dummy) files, and then, we export the mounted directory&#8217;s $WIMMOUNTDATA ADS, modify it to point to a different WIM file, the bad one, then we write it back to the directory&#8217;s ADS&#8230; what will the system see\/do?<\/p>\n\n\n\n<p>Turns out, that modifying the ADS alone is NOT ENOUGH to fool the OS to &#8216;redirect&#8217; the tunnel to a different image \ud83d\ude41<\/p>\n\n\n\n<p>Looking for other angles, we can search the Registry and we can discover that this whole WIM mounting business is nicely documented here:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/WIMMOUNTDATA_3.png\"><img decoding=\"async\" src=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/WIMMOUNTDATA_3.png\" alt=\"\" class=\"wp-image-9783\" width=\"520\" srcset=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/WIMMOUNTDATA_3.png 874w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/WIMMOUNTDATA_3-300x91.png 300w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/WIMMOUNTDATA_3-768x232.png 768w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/WIMMOUNTDATA_3-500x151.png 500w\" sizes=\"(max-width: 874px) 100vw, 874px\" \/><\/a><\/figure>\n\n\n\n<p>under the following key:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">HKLM\\SOFTWARE\\Microsoft\\WIMMount\\Mounted Images\\<\/pre>\n\n\n\n<p>So, what about we change the <em>WIM Path<\/em> value to point to the <em>bad <\/em> WIM image, and restart the system?<\/p>\n\n\n\n<p>Nothing.<\/p>\n\n\n\n<p>The &#8216;mounted&#8217; directory will still list the files from the original &#8216;neutral&#8217; WIM image only.<\/p>\n\n\n\n<p>Okay, so it&#8217;s time we explore the actual $MFT of the C: drive where we mounted our WIM image to. To our surprise, the $MFT does include FILE records for every single file from our neutral WIM image!<\/p>\n\n\n\n<p>Oops. Our original assumption that there are no &#8216;File Create&#8217; events in our telemetry was wrong!<\/p>\n\n\n\n<p>Literally, the <em>dism.exe<\/em> is reading the WIM image file and then it is recreating its codified directory structure by writing it to a destination folder, recursively; and for each directory or file, or even ADS, it is triggering the &#8220;File Create&#8221; events:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_subdirs.png\"><img decoding=\"async\" src=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_subdirs.png\" alt=\"\" class=\"wp-image-9784\" width=\"520\" srcset=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_subdirs.png 838w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_subdirs-300x180.png 300w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_subdirs-768x461.png 768w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_subdirs-500x300.png 500w\" sizes=\"(max-width: 838px) 100vw, 838px\" \/><\/a><\/figure>\n\n\n\n<p>And there is one more wrong assumption we need to address:<\/p>\n\n\n\n<ul>\n<li>the WIM images are mounted as read-only<\/li>\n<\/ul>\n\n\n\n<p>The <em>dism.exe<\/em> program tells us it is not true when we try to remount the WIM image that is already mounted:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_rw.png\"><img decoding=\"async\" src=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_rw.png\" alt=\"\" class=\"wp-image-9785\" width=\"520\" srcset=\"https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_rw.png 753w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_rw-300x71.png 300w, https:\/\/www.hexacorn.com\/blog\/wp-content\/uploads\/2024\/12\/dism_rw-500x118.png 500w\" sizes=\"(max-width: 753px) 100vw, 753px\" \/><\/a><\/figure>\n\n\n\n<p>Exploring the mounted directories, you can easily delete files and directories.<\/p>\n\n\n\n<p>Oops.<\/p>\n\n\n\n<p>At this stage, you probably realize that this post is written from a perspective of an unreliable narrator&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We often hear of attackers bringing in their payloads via virtual drive images (f.ex. vhd,vhdx) in an attempt to bypass security solutions. The WIM files can be used to smuggle in tools and payloads to the target, too. In my &hellip; <a href=\"https:\/\/www.hexacorn.com\/blog\/2024\/12\/31\/smuggling-payloads-and-tools-in-using-wim-images\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[53,19],"tags":[],"_links":{"self":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/9781"}],"collection":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/comments?post=9781"}],"version-history":[{"count":3,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/9781\/revisions"}],"predecessor-version":[{"id":9787,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/9781\/revisions\/9787"}],"wp:attachment":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/media?parent=9781"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/categories?post=9781"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/tags?post=9781"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}