{"id":1134,"date":"2018-04-09T00:05:25","date_gmt":"2018-04-08T22:05:25","guid":{"rendered":"https:\/\/hitco.at\/blog\/?p=1134"},"modified":"2025-11-27T08:06:53","modified_gmt":"2025-11-27T07:06:53","slug":"howto-prevent-bypassing-applocker-using-alternate-data-streams","status":"publish","type":"post","link":"https:\/\/hitco.at\/blog\/howto-prevent-bypassing-applocker-using-alternate-data-streams\/","title":{"rendered":"How to prevent bypassing AppLocker using Alternate Data Streams"},"content":{"rendered":"<p>I usually write my blog-posts in german. This one is in english, because&nbsp;<a href=\"http:\/\/blog.win-fu.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Sami Laiho<\/a> asked me to do a short write-up, to make this problem available to a broader audience.<\/p>\n<h1>Who is affected and what&#8217;s the problem?<\/h1>\n<p>If you are using <strong>AppLocker<\/strong> Application-Whitelisting using <strong>Path-Rules with Exceptions<\/strong>&nbsp;you are probably affected. See the following example to understand, what type of problem we have to fight against.<\/p>\n<h2>Short-Summary &#8211; Typical Situation: How to &#8222;Design&#8220; an AppLocker Path-Rule:<\/h2>\n<p>Your unsigned but business-critical application is located in following directory, and writes logs to a subfolder:<\/p>\n<blockquote>\n<pre>C:\\Program Files (x86)\\DemoApplication\\<\/pre>\n<pre>C:\\Program Files (x86)\\DemoApplication\\logs<\/pre>\n<\/blockquote>\n<p>As this application is not authenticode-signed, you create an AppLocker path-rule: Allow to execute everything in DemoApplication, but exclude the logs-directory (as this is user-writeable, so otherwise a user or a malicious process could put a binary there and execute it).<\/p>\n<figure id=\"attachment_1138\" aria-describedby=\"caption-attachment-1138\" style=\"width: 429px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1138\" src=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory.png\" alt=\"AppLocker Exception: Log Directory\" width=\"429\" height=\"430\" srcset=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory.png 429w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory-150x150.png 150w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory-300x300.png 300w\" sizes=\"auto, (max-width: 429px) 100vw, 429px\" \/><figcaption id=\"caption-attachment-1138\" class=\"wp-caption-text\">AppLocker Exception: Logs Directory<\/figcaption><\/figure>\n<h2>Testing the Rule<\/h2>\n<figure id=\"attachment_1139\" aria-describedby=\"caption-attachment-1139\" style=\"width: 819px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1139 size-full\" src=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-in-Logs-Dirctory-Denied.png\" alt=\"AppLocker: Execute Binary in Logs-Directory is denied\" width=\"819\" height=\"174\" srcset=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-in-Logs-Dirctory-Denied.png 819w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-in-Logs-Dirctory-Denied-300x64.png 300w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-in-Logs-Dirctory-Denied-768x163.png 768w\" sizes=\"auto, (max-width: 819px) 100vw, 819px\" \/><figcaption id=\"caption-attachment-1139\" class=\"wp-caption-text\">AppLocker: Execute Binary in Logs-Directory is denied<\/figcaption><\/figure>\n<p>The rule works as expected. A regular user can copy a binary (like for example SysInternals Tcpview.exe, which I use for demonstration purposes in this example) into the logs-directory, but cannot execute it. AppLocker-eventlog shows, that tcpview.exe (located in the logs-directory) was prevented from running &#8211; thats correct behavior:<\/p>\n<figure id=\"attachment_1140\" aria-describedby=\"caption-attachment-1140\" style=\"width: 625px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1140\" src=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Denied-Eventlog.png\" alt=\"AppLocker: Execution Denied - Eventlog\" width=\"625\" height=\"187\" srcset=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Denied-Eventlog.png 625w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Denied-Eventlog-300x90.png 300w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><figcaption id=\"caption-attachment-1140\" class=\"wp-caption-text\">AppLocker: Execution Denied &#8211; Eventlog<\/figcaption><\/figure>\n<h1>Bypassing AppLocker by using Alternate Data Streams<\/h1>\n<p>If you are not aware what Alternate Data Streams are, check out <a href=\"https:\/\/blogs.technet.microsoft.com\/askcore\/2013\/03\/24\/alternate-data-streams-in-ntfs\/\" target=\"_blank\" rel=\"noopener noreferrer\">this blog-post<\/a>. So, what&#8217;s the trick to bypass AppLocker: We copy the contents of an executable to an Alternate Data Stream of the logs-directory. To be clear: Not to a file in the logs-directory, but to an ADS of the logs-directory itself! The copy-job is done using the &#8222;type&#8220; command redirecting the output to an ADS. The <a href=\"https:\/\/gist.github.com\/api0cradle\/cdd2d0d0ec9abb686f0e89306e277b8f\" target=\"_blank\" rel=\"noopener noreferrer\">execution of an ADS can be done by various ways<\/a>, one way would be to use wmic to create a new process, but there are other ways too.<\/p>\n<figure id=\"attachment_1141\" aria-describedby=\"caption-attachment-1141\" style=\"width: 824px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Alternate-DataStream.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1141 size-full\" src=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Alternate-DataStream.png\" alt=\"AppLocker Bypass: Execute Alternate Data Stream\" width=\"824\" height=\"398\" srcset=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Alternate-DataStream.png 824w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Alternate-DataStream-300x145.png 300w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Alternate-DataStream-768x371.png 768w\" sizes=\"auto, (max-width: 824px) 100vw, 824px\" \/><\/a><figcaption id=\"caption-attachment-1141\" class=\"wp-caption-text\">AppLocker Bypass: Execute Alternate Data Stream<\/figcaption><\/figure>\n<p>Looking into eventlog reveals: Yes, that was a straight-forward AppLocker bypass. Applocker saw this execution operation but decided it is &#8222;allowed to run&#8220;:<\/p>\n<figure id=\"attachment_1142\" aria-describedby=\"caption-attachment-1142\" style=\"width: 626px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1142\" src=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Alternate-DataStream_Eventlog.png\" alt=\"AppLocker Bypass: Execute Alternate Data Stream - Eventlog\" width=\"626\" height=\"197\" srcset=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Alternate-DataStream_Eventlog.png 626w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Execute-Alternate-DataStream_Eventlog-300x94.png 300w\" sizes=\"auto, (max-width: 626px) 100vw, 626px\" \/><figcaption id=\"caption-attachment-1142\" class=\"wp-caption-text\">AppLocker Bypass: Execute Alternate Data Stream &#8211; Eventlog<\/figcaption><\/figure>\n<h1>How to prevent<\/h1>\n<p>So &#8211; bad situation. How to prevent this? Why did AppLocker allow the execution, even if we excluded the logs-directory?<\/p>\n<p>In fact: We did <strong>not<\/strong> exclude the logs-directory! We excluded everything below the logs-directory! We have to add a second exclude-rule &#8222;<strong>logs:*<\/strong>&#8220; to prevent this:<\/p>\n<figure id=\"attachment_1143\" aria-describedby=\"caption-attachment-1143\" style=\"width: 434px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1143\" src=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory-Alternate-Data-Streams.png\" alt=\"AppLocker Exception: log-directory, exclude Alternate Data Streams\" width=\"434\" height=\"436\" srcset=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory-Alternate-Data-Streams.png 434w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory-Alternate-Data-Streams-150x150.png 150w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory-Alternate-Data-Streams-300x300.png 300w\" sizes=\"auto, (max-width: 434px) 100vw, 434px\" \/><figcaption id=\"caption-attachment-1143\" class=\"wp-caption-text\">AppLocker Exception: log-directory, exclude Alternate Data Streams<\/figcaption><\/figure>\n<p>After inserting this second exception-rule, which excludes all Alternate Data Streams of the logs-Directory from executing, the start of the &#8222;Evil-ADS-Binary&#8220; is prevented by AppLocker:<\/p>\n<figure id=\"attachment_1144\" aria-describedby=\"caption-attachment-1144\" style=\"width: 625px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1144\" src=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory-Alternate-Data-Streams_prevented.png\" alt=\"AppLocker: Alternate Data Streams - Execution prevented\" width=\"625\" height=\"193\" srcset=\"https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory-Alternate-Data-Streams_prevented.png 625w, https:\/\/hitco.at\/blog\/wp-content\/uploads\/AppLocker_Exception-Log-Directory-Alternate-Data-Streams_prevented-300x93.png 300w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><figcaption id=\"caption-attachment-1144\" class=\"wp-caption-text\">AppLocker: Alternate Data Streams &#8211; Execution prevented<\/figcaption><\/figure>\n<h1>Which Versions of Windows are affected?<\/h1>\n<p>All versions I tested so far, at least I can say: Every Windows 10 Version &#8211; including the newest v1803 Release (final Insider preview, tested on 08. April 2018) are affected.<\/p>\n<h1>Why doesn&#8217;t Microsoft prevent this?<\/h1>\n<p>I don&#8217;t know. I reported this behaviour twice. I cannot see any useful or legit case, where executing an Alternate Data Stream is needed. In my opinion there should be a single checkbox &#8222;prevent all ADS from being executed&#8220; which should be on by default &#8211; but AppLocker doesn&#8217;t handle ADS this way I would like to see.<\/p>\n<p>Is this behaviour a problem? Yes &#8211; I really think it is. And I&#8217;m not the one who originally &#8222;found&#8220; this bug \/ bad behaviour. If you do a <a href=\"https:\/\/www.google.com\/search?q=applocker+bypass+alternate+data+stream\" target=\"_blank\" rel=\"noopener noreferrer\">google-search<\/a>, you can find <a href=\"https:\/\/github.com\/api0cradle\/UltimateAppLockerByPassList\/blob\/master\/README.md\" target=\"_blank\" rel=\"noopener noreferrer\">other sources explaining this problem<\/a> &#8211; not exactly in detail like I did here, but I&#8217;m quite sure this is a very well known and commonly used AppLocker-Bypass trick. I think almost nobody of the SysAdmins out there is aware of the fact, that you have to set ACLs on the writeable directories in a way you cannot add ADS, or have to configure two Exclude-Rules for every writeable path. As Microsoft seems not to change AppLocker behaviour, you should be aware of this and maybe double-check your Path-Exclusion-Rules soon!<\/p>\n<h1>Additional Notes<\/h1>\n<ul>\n<li><a href=\"http:\/\/www.darknessgate.com\/security-tutorials\/date-hiding\/ntfs-alternate-data-streams\/\" target=\"_blank\" rel=\"noopener noreferrer\">Check this blog post<\/a> for detailed Information about Alternate Data Streams, hiding Executables in ADS etc&#8230;<\/li>\n<li>Have a look at the <a href=\"https:\/\/github.com\/api0cradle\/UltimateAppLockerByPassList\" target=\"_blank\" rel=\"noopener noreferrer\">Ultimate AppLocker ByPass List<\/a>&nbsp;and follow <a href=\"https:\/\/twitter.com\/Oddvarmoe\" target=\"_blank\" rel=\"noopener noreferrer\">Oddvar Moe<\/a> on Twitter<\/li>\n<li>I informed Aaron Margosis, his <a href=\"https:\/\/blogs.msdn.microsoft.com\/aaron_margosis\/2018\/10\/11\/aaronlocker-update-v0-91-and-see-aaronlocker-in-action-on-channel-9\/\" target=\"_blank\" rel=\"noopener noreferrer\">popular script AaronLocker<\/a> can handle this correct now and provides mitigation too (released on 10th October 2018)<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>I usually write my blog-posts in german. This one is in english, because&nbsp;Sami Laiho asked me to do a short write-up, to make this problem available to a broader audience. Who is affected and what&#8217;s the problem? If you are using AppLocker Application-Whitelisting using Path-Rules with Exceptions&nbsp;you are probably affected. See the following example to understand, what type of problem&#8230; <\/p>\n","protected":false},"author":1,"featured_media":1143,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[3,4,23],"tags":[],"class_list":["post-1134","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-it","category-security","category-windows"],"_links":{"self":[{"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/posts\/1134","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/comments?post=1134"}],"version-history":[{"count":19,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/posts\/1134\/revisions"}],"predecessor-version":[{"id":1403,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/posts\/1134\/revisions\/1403"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/media\/1143"}],"wp:attachment":[{"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/media?parent=1134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/categories?post=1134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hitco.at\/blog\/wp-json\/wp\/v2\/tags?post=1134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}