{"id":1142,"date":"2015-07-10T05:04:06","date_gmt":"2015-07-10T05:04:06","guid":{"rendered":"http:\/\/www.gironsec.com\/blog\/?p=1142"},"modified":"2015-07-10T05:04:06","modified_gmt":"2015-07-10T05:04:06","slug":"sandworm-detection","status":"publish","type":"post","link":"https:\/\/www.gironsec.com\/blog\/2015\/07\/sandworm-detection\/","title":{"rendered":"Sandworm detection"},"content":{"rendered":"<p>Hello loyal readers!<\/p>\n<p>Sorry for the delay in posts, I&#8217;ve just been busy with life. Anywho, I got some code to share. A lil script I put together for scanning office documents for the <a href=\"http:\/\/www.rapid7.com\/db\/modules\/exploit\/windows\/fileformat\/ms14_060_sandworm\" target=\"_blank\">Sandworm exploit<\/a>. aka Microsoft Security Bulletin MS14-060.<\/p>\n<p>For those of you who don&#8217;t know \/ live under a rock, its a recent vulnerability in PowerPoint that can be used to run code and it DOESN&#8217;T require shellcode making it highly favorable \/ reliable for malware people.<\/p>\n<p>The way it works is a specially crafted PPT document allows a malicious user to load an INF file. INF files are quite powerful in what they allow you to do &#8211; load files, mess with the registry, etc. Here&#8217;s what one such INF file looks like:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%\">; 61883.INF\r\n\r\n[Version]\r\nSignature = &quot;$CHICAGO$&quot;\r\nclass=61883\r\nClasGuid=%Msft%\r\nDriverVer=0\/21\/2006,61.7600.16385\r\n\r\n[DestinationDirs]\r\nDefaultDestDir = 1\r\n\r\n[DefaultInstall]\r\nRenFiles = RxRename\r\nAddReg = RxStart\r\n\r\n[RxRename]\r\npenguin.exe, cedt370r(3).exe\r\n[RxStart]\r\nHKLM,Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce,Install,,%1%\\penguin.exe\r\n<\/pre>\n<\/div>\n<p>In the above sample, the INF file would add a certain exe to auto-run the next time the computer is rebooted.<\/p>\n<p>So how do we detect such an attack in a PPT document? Easily. Search for INF file artifacts!<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #fb660a; font-weight: bold\">import<\/span> <span style=\"color: #ffffff\">struct<\/span>\r\n<span style=\"color: #fb660a; font-weight: bold\">import<\/span> <span style=\"color: #ffffff\">sys<\/span>\r\n<span style=\"color: #fb660a; font-weight: bold\">import<\/span> <span style=\"color: #ffffff\">zlib<\/span>\r\n\r\n<span style=\"color: #ffffff\">ole_object_header<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #0086d2\">&quot;\\x10\\x00\\x11\\x10&quot;<\/span>\r\n<span style=\"color: #ffffff\">gzip_header<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #0086d2\">&#39;\\x1f\\x8b\\x08&#39;<\/span> <span style=\"color: #ffffff\">+<\/span> <span style=\"color: #0086d2\">&#39;\\x00&#39;<\/span> <span style=\"color: #ffffff\">*<\/span> <span style=\"color: #0086f7; font-weight: bold\">7<\/span>\r\n\r\n<span style=\"color: #fb660a; font-weight: bold\">with<\/span> <span style=\"color: #ffffff\">open(sys.argv[<\/span><span style=\"color: #0086f7; font-weight: bold\">1<\/span><span style=\"color: #ffffff\">],<\/span> <span style=\"color: #0086d2\">&quot;rb&quot;<\/span><span style=\"color: #ffffff\">)<\/span> <span style=\"color: #fb660a; font-weight: bold\">as<\/span> <span style=\"color: #ffffff\">f:<\/span>\r\n    <span style=\"color: #ffffff\">data<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">f.read()<\/span>\r\n\r\n    <span style=\"color: #ffffff\">n_objs<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">data.count(ole_object_header)<\/span>\r\n\r\n    <span style=\"color: #fb660a; font-weight: bold\">print<\/span> <span style=\"color: #0086d2\">&quot;%d objs found&quot;<\/span> <span style=\"color: #ffffff\">%<\/span> <span style=\"color: #ffffff\">n_objs<\/span>\r\n\r\n    <span style=\"color: #ffffff\">pos<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">-<\/span><span style=\"color: #0086f7; font-weight: bold\">1<\/span>\r\n    <span style=\"color: #fb660a; font-weight: bold\">for<\/span> <span style=\"color: #ffffff\">i<\/span> <span style=\"color: #ffffff\">in<\/span> <span style=\"color: #ffffff\">range(n_objs):<\/span>\r\n        <span style=\"color: #ffffff\">d<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">zlib.decompressobj(zlib.MAX_WBITS<\/span> <span style=\"color: #ffffff\">|<\/span> <span style=\"color: #0086f7; font-weight: bold\">32<\/span><span style=\"color: #ffffff\">)<\/span>\r\n        <span style=\"color: #ffffff\">pos<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">pos+<\/span><span style=\"color: #0086f7; font-weight: bold\">1<\/span> <span style=\"color: #ffffff\">+<\/span> <span style=\"color: #ffffff\">data[pos+<\/span><span style=\"color: #0086f7; font-weight: bold\">1<\/span><span style=\"color: #ffffff\">:].find(ole_object_header)<\/span>\r\n        <span style=\"color: #ffffff\">compressed_len<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">struct.unpack(<\/span><span style=\"color: #0086d2\">&quot;I&quot;<\/span><span style=\"color: #ffffff\">,<\/span> <span style=\"color: #ffffff\">data[pos+<\/span><span style=\"color: #0086f7; font-weight: bold\">4<\/span><span style=\"color: #ffffff\">:pos+<\/span><span style=\"color: #0086f7; font-weight: bold\">8<\/span><span style=\"color: #ffffff\">])[<\/span><span style=\"color: #0086f7; font-weight: bold\">0<\/span><span style=\"color: #ffffff\">]<\/span>\r\n        <span style=\"color: #fb660a; font-weight: bold\">try<\/span><span style=\"color: #ffffff\">:<\/span>\r\n            <span style=\"color: #ffffff\">obj<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #ffffff\">d.decompress(gzip_header<\/span> <span style=\"color: #ffffff\">+<\/span> <span style=\"color: #ffffff\">data[pos+<\/span><span style=\"color: #0086f7; font-weight: bold\">12<\/span><span style=\"color: #ffffff\">:pos+<\/span><span style=\"color: #0086f7; font-weight: bold\">12<\/span><span style=\"color: #ffffff\">+compressed_len-<\/span><span style=\"color: #0086f7; font-weight: bold\">4<\/span><span style=\"color: #ffffff\">])<\/span>\r\n        <span style=\"color: #fb660a; font-weight: bold\">except<\/span> <span style=\"color: #ffffff\">zlib.error:<\/span>\r\n            <span style=\"color: #ffffff\">obj<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #0086d2\">&#39;(zlib error)&#39;<\/span>\r\n        <span style=\"color: #008800; font-style: italic; background-color: #0f140f\"># find INF file artifacts within ole_objects<\/span>\r\n        <span style=\"color: #ffffff\">look1<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #0086d2\">&quot;\\[Version\\]&quot;<\/span>\r\n        <span style=\"color: #ffffff\">look2<\/span> <span style=\"color: #ffffff\">=<\/span> <span style=\"color: #0086d2\">&quot;DriverVer&quot;<\/span>\r\n        <span style=\"color: #fb660a; font-weight: bold\">if<\/span> <span style=\"color: #ffffff\">look1<\/span> <span style=\"color: #ffffff\">and<\/span> <span style=\"color: #ffffff\">look2<\/span> <span style=\"color: #ffffff\">in<\/span> <span style=\"color: #ffffff\">obj:<\/span>\r\n            <span style=\"color: #fb660a; font-weight: bold\">print<\/span> <span style=\"color: #0086d2\">&quot;found inf file in stream # &quot;<\/span><span style=\"color: #ffffff\">,<\/span>  <span style=\"color: #ffffff\">i<\/span>\r\n        <span style=\"color: #fb660a; font-weight: bold\">else<\/span><span style=\"color: #ffffff\">:<\/span>\r\n            <span style=\"color: #fb660a; font-weight: bold\">print<\/span> <span style=\"color: #0086d2\">&quot;Found no inf in stream # &quot;<\/span><span style=\"color: #ffffff\">,<\/span>  <span style=\"color: #ffffff\">i<\/span>\r\n<\/pre>\n<\/div>\n<p>Code in action:<\/p>\n<p><a href=\"http:\/\/www.gironsec.com\/blog\/wp-content\/uploads\/2015\/07\/dddk.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-1144\" src=\"http:\/\/www.gironsec.com\/blog\/wp-content\/uploads\/2015\/07\/dddk.png\" alt=\"dddk\" width=\"557\" height=\"251\" srcset=\"https:\/\/www.gironsec.com\/blog\/wp-content\/uploads\/2015\/07\/dddk.png 557w, https:\/\/www.gironsec.com\/blog\/wp-content\/uploads\/2015\/07\/dddk-300x135.png 300w\" sizes=\"(max-width: 557px) 100vw, 557px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>All my code does is search a binary stream for an OLE header, then searches for the gzip header, then extracts the data, then looks for the artifacts. Simplicity is golden.<\/p>\n<p>Stay safe out there!<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"http:\/\/www.gironsec.com\/blog\/wp-content\/uploads\/2015\/07\/1433860762983.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-1143\" src=\"http:\/\/www.gironsec.com\/blog\/wp-content\/uploads\/2015\/07\/1433860762983.jpg\" alt=\"1433860762983\" width=\"306\" height=\"640\" srcset=\"https:\/\/www.gironsec.com\/blog\/wp-content\/uploads\/2015\/07\/1433860762983.jpg 306w, https:\/\/www.gironsec.com\/blog\/wp-content\/uploads\/2015\/07\/1433860762983-143x300.jpg 143w\" sizes=\"(max-width: 306px) 100vw, 306px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello loyal readers! Sorry for the delay in posts, I&#8217;ve just been busy with life. Anywho, I got some code to share. A lil script I put together for scanning office documents for the Sandworm exploit. aka Microsoft Security Bulletin MS14-060. For those of you who don&#8217;t know \/ live under a rock, its a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,7],"tags":[],"_links":{"self":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts\/1142"}],"collection":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/comments?post=1142"}],"version-history":[{"count":2,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts\/1142\/revisions"}],"predecessor-version":[{"id":1146,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts\/1142\/revisions\/1146"}],"wp:attachment":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/media?parent=1142"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/categories?post=1142"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/tags?post=1142"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}