<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on DFIR musings</title><link>https://tomchop.me/posts/</link><description>Recent content in Posts on DFIR musings</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>&lt;a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener"&gt;CC BY-NC 4.0&lt;/a&gt;</copyright><lastBuildDate>Mon, 21 Nov 2016 00:00:00 +0000</lastBuildDate><atom:link href="https://tomchop.me/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>Tutorial - Volatility plugins &amp; malware analysis</title><link>https://tomchop.me/posts/volatility-plugin-malware-analysis/</link><pubDate>Mon, 21 Nov 2016 00:00:00 +0000</pubDate><guid>https://tomchop.me/posts/volatility-plugin-malware-analysis/</guid><description>Finding persistence points is a recurring task of any investigation potentially involving malware. Here&amp;rsquo;s how to do it using Volatility.</description><content type="html"><![CDATA[<p>The benefits of analyzing malware in live memory are well known. What we&rsquo;ll see
here is how to leverage the power of the Volatility framework to automate the
task of extracting a malware&rsquo;s configuration file.</p>
<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li><strong>A working installation of Volatility 2.5, Yara 3.5.0, and python-yara</strong></li>
<li>Basic knowledge of Python and Volatility</li>
<li>Basic knowledge of how malware behaves in a system</li>
</ul>
<h3 id="useful-links">Useful links</h3>
<ul>
<li><a href="https://github.com/volatilityfoundation/volatility">Volatility</a> and its
<a href="https://github.com/volatilityfoundation/volatility/wiki">wiki</a> (very well
documented)</li>
<li><a href="http://virustotal.github.io/yara/">Yara</a> (on
<a href="https://github.com/VirusTotal/yara">GitHub</a>) and especially its
<a href="http://yara.readthedocs.io/en/v3.5.0/">documentation</a></li>
<li>Cisco Talos <a href="http://blog.talosintel.com/2016/10/lockydump.html">blogpost</a> on
Locky configuration files</li>
</ul>
<hr>
<h2 id="how-plugins-work">How plugins work</h2>
<h3 id="the-calculate-function">The Calculate function</h3>
<p>This is the main plugin core. The goal of the function is to perform all the
heavy lifting and to provide structured output to a <code>render</code> function (such as
<code>render_text</code>)</p>
<h3 id="the-render-function">The render function</h3>
<p>This takes the output provided by the calculate function and renders it
according to its type.</p>
<ul>
<li><code>render_text</code> will render it as text</li>
<li><code>render_table</code> will make a table</li>
<li><code>render_custom_format</code> will render the output using a custom output format</li>
</ul>
<p>output format can be called with <code>--output [text|table|custom_format]</code></p>
<h3 id="a-note-on-list-vs-scan-plugins">A note on &ldquo;list&rdquo; vs. &ldquo;scan&rdquo; plugins</h3>
<p>Volatility has two main approaches to plugins, which are sometimes reflected in
their names. &ldquo;list&rdquo; plugins will try to navigate through Windows Kernel
structures to retrieve information like processes (locate and walk the linked
list of <code>_EPROCESS</code> structures in memory), OS handles (locating and listing the
handle table, dereferencing any pointers found, etc). They more or less behave
like the Windows API would if requested to, for example, list processes.</p>
<p>That makes &ldquo;list&rdquo; plugins pretty fast, but just as vulnerable as the Windows API
to manipulation by malware. For instance, if malware uses DKOM to unlink a
process from the <code>_EPROCESS</code> linked list, it won&rsquo;t show up in the Task Manager
and neither will it in the pslist.</p>
<p>&ldquo;scan&rdquo; plugins, on the other hand, will take an approach similar to carving the
memory for things that might make sense when dereferenced as specific
structures. <code>psscan</code> for instance will read the memory and try to make out
<code>_EPROCESS</code> objects out of it (it uses pool-tag scanning, which is basically
searching for 4-byte strings that indicate the presence of a structure of
interest). The advantage is that it can dig up processes that have exited, and
even if malware tampers with the <code>_EPROCESS</code> linked list, the plugin will still
find the structure lying around in memory (since it still needs to exist for the
process to run). The downfall is that &ldquo;scan&rdquo; plugins are a bit slower than
&ldquo;list&rdquo; plugins, and can sometimes yield false-positives (a process that exited
too long ago and had parts of its structure overwritten by other operations).</p>
<h3 id="yara-signatures-ftw">Yara signatures FTW</h3>
<p>Scanning the memory for structures can take some time, especially now that
memory dumps can regularly be over 8 GB in size, especially when the structures
you&rsquo;re looking for are small or don&rsquo;t have lots of constraints. A good approach
for searching for specific patterns in memory are Yara rules, which can be
leveraged with the <code>yarascan</code> plugin. Besides being faster, it has the added
bonus of being able to be re-used as Yara rules outside Volatility!</p>
<hr>
<h2 id="hands-on-building-a-locky-configuration-extractor">Hands-on: Building a Locky configuration extractor</h2>
<h3 id="implementation-strategy">Implementation strategy</h3>
<p>Based on available information, the implementation strategy for your plugin may
change. Unfortunately, there is no silver bullet for locating interesting stuff
in memory. You&rsquo;ll need to have a basic understanding of how your sample works
and what it does in memory; depending on your reverse engineering skills this
might be more or less easy.</p>
<p>As most forensic investigations, it&rsquo;s important to have anchor or pivot points.
In the case of most plugins bundled with Volatility, these anchor points are the
Kernel. Since malware does not register its crown jewels in Kernel entries,
you&rsquo;ll have to work through the sample in order to find how it references
interesting data, and try to find the point where it references it in a way
where it is as generic as possible.</p>
<p>In the case of Locky, our analysis tells us that one of the places it accesses
its configuration looks like this:</p>

    <img src="/img/config_disasm.png"  alt="Interesting assemly code"  class="center"  style="border-radius: 8px;"  />


<p>This looks like a good place to start.</p>
<ul>
<li>Based on the opcodes relevant to our code, use <code>yarascan</code> to find the
interesting process</li>
</ul>
<pre tabindex="0"><code>$ vol.py -f affid_3_dga_87233.mem --profile=Win7SP1x64 yarascan -Y &#34;{A1 ?? ?? ?? ?? 8B 40 08 85 C0}&#34;
Volatility Foundation Volatility Framework 2.5
Rule: r1
Owner: Process svchost.exe Pid 2308
[snip]
Rule: r1
Owner: Process svchost.exe Pid 2308
[snip]
Rule: r1
Owner: Process rundll32.exe Pid 1456
0x73e24eac  a1 70 23 e4 73 8b 40 08 85 c0 74 0d 69 c0 e8 03   .p#.s.@...t.i...
0x73e24ebc  00 00 50 ff 15 28 71 e3 73 8d 45 b4 50 e8 04 20   ..P..(q.s.E.P...
0x73e24ecc  00 00 59 50 bb 74 10 e4 73 8b c3 c6 45 fc 01 e8   ..YP.t..s...E...
0x73e24edc  f3 15 00 00 6a 01 33 ff 8d 75 b4 c6 45 fc 00 e8   ....j.3..u..E...
0x73e24eec  ec 1a 00 00 e8 51 fe ff ff 84 c0 0f 85 9b 04 00   .....Q..........
0x73e24efc  00 83 3d 88 10 e4 73 10 a1 74 10 e4 73 73 02 8b   ..=...s..t..ss..
[snip]
</code></pre><ul>
<li>Start <code>volshell</code> and get to the point where we&rsquo;re visualizing the assembly
code.</li>
</ul>
<pre tabindex="0"><code>In [1]: cc(pid=1456)
Current context: rundll32.exe @ 0xfffffa8003b55060, pid=1456, ppid=2220 DTB=0x74f39000

In [2]: db(0x73e24eac)
0x73e24eac  a1 70 23 e4 73 8b 40 08 85 c0 74 0d 69 c0 e8 03   .p#.s.@...t.i...
0x73e24ebc  00 00 50 ff 15 28 71 e3 73 8d 45 b4 50 e8 04 20   ..P..(q.s.E.P...
0x73e24ecc  00 00 59 50 bb 74 10 e4 73 8b c3 c6 45 fc 01 e8   ..YP.t..s...E...
0x73e24edc  f3 15 00 00 6a 01 33 ff 8d 75 b4 c6 45 fc 00 e8   ....j.3..u..E...
0x73e24eec  ec 1a 00 00 e8 51 fe ff ff 84 c0 0f 85 9b 04 00   .....Q..........
0x73e24efc  00 83 3d 88 10 e4 73 10 a1 74 10 e4 73 73 02 8b   ..=...s..t..ss..
0x73e24f0c  c3 50 ff 15 44 71 e3 73 66 85 c0 0f 85 7b 04 00   .P..Dq.sf....{..
0x73e24f1c  00 83 3d 88 10 e4 73 10 72 06 8b 1d 74 10 e4 73   ..=...s.r...t..s
</code></pre><h3 id="extracting-relevant-information-from-memory">Extracting relevant information from memory</h3>
<p>We found the instance of our code in memory. Time to access the relevant data!
We&rsquo;re going to need to read raw bytes from memory and also be able to
dereference pointers. The bytes we&rsquo;re after are the address of the pointer to
the configuration file, the ones which were left as wildcards in the Yara rule.</p>
<pre tabindex="0"><code>0x73e24eac  a1 [70 23 e4 73] 8b 40 08 85 c0 74 0d 69 c0 e8 03   .p#.s.@...t.i...
</code></pre><p>This is <code>0x73e42370</code> in little endian. What&rsquo;s the value of this variable?</p>
<pre tabindex="0"><code>In [4]: db(0x73e42370, 4)
0x73e42370  00 00 16 00                                       ....
</code></pre><p>In little endian again, this means that our configuration file is located at
<code>0x00160000</code>. This nice, round, and page-aligned number also happens to be it&rsquo;s
own memory segment. Check the output of <code>vaddump</code>, you&rsquo;ll see something like
<code>rundll32.exe.99155060.0x0000000000160000-0x0000000000166fff.dmp</code> which actually
contains all of our configuration file.</p>
<p>What&rsquo;s at address <code>0x00160000</code>?</p>
<pre tabindex="0"><code>In [5]: db(0x00160000)
0x00160000  01 00 00 00 c1 54 01 00 19 00 00 00 00 00 01 2f   .....T........./
0x00160010  61 70 61 63 68 65 5f 68 61 6e 64 6c 65 72 2e 70   apache_handler.p
0x00160020  68 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00   hp..............
0x00160030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 34   ...............4
0x00160040  36 2e 38 2e 34 34 2e 31 30 35 2c 39 31 2e 32 31   6.8.44.105,91.21
0x00160050  39 2e 32 38 2e 37 36 2c 31 38 38 2e 31 32 30 2e   9.28.76,188.120.
0x00160060  32 33 36 2e 32 31 2c 32 31 37 2e 31 32 2e 32 32   236.21,217.12.22
0x00160070  33 2e 37 38 2c 34 36 2e 31 38 33 2e 32 32 31 2e   3.78,46.183.221.
</code></pre><p>That&rsquo;s starting to look like something!</p>
<p>Since it can become quite tedious to copy and paste values from <code>vollshell</code>, so
we&rsquo;re going to use two simple functions to read bytes from memory and
dereference pointers. Copy and paste the following lines into the prompt:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>a <span style="color:#f92672">=</span> self<span style="color:#f92672">.</span>_proc<span style="color:#f92672">.</span>get_process_address_space()
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">read_bytes</span>(aspace, a, length<span style="color:#f92672">=</span><span style="color:#ae81ff">4</span>):
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> a<span style="color:#f92672">.</span>read(address, length)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">deref</span>(address, a, length<span style="color:#f92672">=</span><span style="color:#ae81ff">4</span>):
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> struct<span style="color:#f92672">.</span>unpack(<span style="color:#e6db74">&#34;&lt;I&#34;</span>, a<span style="color:#f92672">.</span>read(address, length))[<span style="color:#ae81ff">0</span>]
</span></span></code></pre></div><ul>
<li>
<p><code>a = self._proc.get_process_address_space()</code> sets an object to the process'
address space (so that we can reference memory using the processes virtual
memory addressing)</p>
</li>
<li>
<p><code>read_bytes</code> just reads bytes at a given address and returns it as a binary
buffer</p>
</li>
<li>
<p><code>deref</code> will read 4 bytes at a given address and return the pointer value at
that address</p>
</li>
</ul>
<p>See for yourself:</p>
<pre tabindex="0"><code>In [23]: config_ptr = deref(0x73e24eac + 1, a)

In [24]: hex(config_ptr)
Out[24]: &#39;0x73e42370&#39;

In [25]: conf_object = deref(config_ptr, a)

In [26]: db(conf_object)
0x00160000  01 00 00 00 c1 54 01 00 19 00 00 00 00 00 01 2f   .....T........./
0x00160010  61 70 61 63 68 65 5f 68 61 6e 64 6c 65 72 2e 70   apache_handler.p
0x00160020  68 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00   hp..............
0x00160030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 34   ...............4
0x00160040  36 2e 38 2e 34 34 2e 31 30 35 2c 39 31 2e 32 31   6.8.44.105,91.21
0x00160050  39 2e 32 38 2e 37 36 2c 31 38 38 2e 31 32 30 2e   9.28.76,188.120.
0x00160060  32 33 36 2e 32 31 2c 32 31 37 2e 31 32 2e 32 32   236.21,217.12.22
0x00160070  33 2e 37 38 2c 34 36 2e 31 38 33 2e 32 32 31 2e   3.78,46.183.221.
</code></pre><p>Thanks to Michael Ligh for pointing this out: there is a helper Volatility class
for dereferencing pointers as structures.</p>
<blockquote>
<p>For example, if you wanted to read an address and dereference it as a pointer
to a <code>_LockyConfig</code>, you could do this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>ptr <span style="color:#f92672">=</span> obj<span style="color:#f92672">.</span>Object(<span style="color:#e6db74">&#34;address&#34;</span>, offset <span style="color:#f92672">=</span> offset, vm <span style="color:#f92672">=</span> a)
</span></span><span style="display:flex;"><span>config <span style="color:#f92672">=</span> ptr<span style="color:#f92672">.</span>dereference_as(<span style="color:#e6db74">&#34;_LockyConfig&#34;</span>)
</span></span></code></pre></div><p>The size of an &ldquo;address&rdquo; will be automatically read from the profile (so 4
bytes on 32-bit and 8 bytes on 64-bit). You can also define pointers to values
in the structure definitions (<code>vtypes</code>).</p>
</blockquote>
<hr>
<h2 id="building-your-plugin">Building your plugin</h2>
<p>So now that we understand how to go from a raw memory dump to the interesting
data, let&rsquo;s try to automate it! Here&rsquo;s what our plugin will start looking like
the contents in
<a href="/files/tutorial-volatility-plugin/volatility-locky.py.00">volatility-locky.py.00</a></p>
<h3 id="baby-steps">Baby steps</h3>
<p>Make sure that volatility loads it:</p>
<pre tabindex="0"><code>$ vol.py --plugins=./plugin/ -f affid_3_dga_87233.mem -h | grep locky
Volatility Foundation Volatility Framework 2.5
  lockyconfig    	Searches for Locky configs in memory
</code></pre><p>Let&rsquo;s make it a little more useful. The idea is to:</p>
<ul>
<li>iterate though all processes - use the <code>tasks.pslist(addr_space)</code> generator
which yields <code>task</code> objects</li>
<li>for each process, iterate through its VADs - use <code>task.get_vads()</code> generator,
which yields <code>(vad, address_space)</code> tuples</li>
<li>reach each VAD&rsquo;s content and match it against our Yara rule - read the
address_space with <code>process_space.zread(vad.Start, vad.Length)</code></li>
</ul>
<p>Check out
<a href="/files/tutorial-volatility-plugin/volatility-locky.py.01_partial">volatility-locky.py.01_partial</a>
for hints and Yara-related commands, and
<a href="/files/tutorial-volatility-plugin/volatility-locky.py.01">volatility-locky.py.01</a>
for the final solution.</p>
<p>Notice we&rsquo;re not using <code>render_text</code> yet; we&rsquo;ll get back to this a little later.</p>
<h3 id="dereferencing-memory-inside-plugins">Dereferencing memory inside plugins</h3>
<p>Remember when we used volshell to derefence memory? Let&rsquo;s try to automate this
so we don&rsquo;t have to copy and paste the commands for each candidate (ie. match)
we find.</p>
<p>See
<a href="/files/tutorial-volatility-plugin/volatility-locky.py.02_partial">volatility-locky.py.02_partial</a>
for hints and
<a href="/files/tutorial-volatility-plugin/volatility-locky.py.02">volatility-locky.py.02</a>
for working code.</p>
<h3 id="using-vtypes-to-convert-objects">Using vtypes to convert objects</h3>
<p>Now that we have the address for our configuration file, we can easily parse it
and use the <code>render_output</code> function to give the user some feedback. Before
that, let&rsquo;s explore a cool feature of Volatiliy : <em>vtypes</em>. vtypes are
structures that can be &ldquo;applied&rdquo; to memory, yielding objects that can then be
easily manipulated. The advantage of using vtypes over standard string slicing
to parse structures is manyfold:</p>
<ul>
<li>It&rsquo;s auto-documenting</li>
<li>It&rsquo;s easier to maintain should the structure change in the future</li>
<li>It&rsquo;s easier for a third party to understand what&rsquo;s going on</li>
<li>No need for special code for strings, integers (unpacking), binary code, etc.</li>
</ul>
<p>vtypes look like C structures. The
<a href="http://blog.talosintel.com/2016/10/lockydump.html">Cisco Talos blog</a> has
conveniently translated Locky structures into C:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> _LockyConfigHeader {
</span></span><span style="display:flex;"><span>	DWORD affilID;
</span></span><span style="display:flex;"><span>	DWORD DGASeed;
</span></span><span style="display:flex;"><span>	DWORD Delay;
</span></span><span style="display:flex;"><span>	BYTE PersistSvchost;
</span></span><span style="display:flex;"><span>	BYTE PersistRegistry;
</span></span><span style="display:flex;"><span>	BYTE IgnoreRussian;
</span></span><span style="display:flex;"><span>} LOCKY_CONFIG_HEADER;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> _LockyConfig {
</span></span><span style="display:flex;"><span>	LOCKY_CONFIG_HEADER Header;
</span></span><span style="display:flex;"><span>	CHAR CallbackPath[<span style="color:#ae81ff">48</span>];
</span></span><span style="display:flex;"><span>	CHAR C2Servers[<span style="color:#ae81ff">4096</span>];
</span></span><span style="display:flex;"><span>	DWORD RsaKeyID;
</span></span><span style="display:flex;"><span>	DWORD RsaKeySizeBytes;
</span></span><span style="display:flex;"><span>	PUBLICKEYSTRUC RsaKeyStruct;
</span></span><span style="display:flex;"><span>	RSAPUBKEY RsaKeyHdr;
</span></span><span style="display:flex;"><span>	BYTE RsaKeyData[<span style="color:#ae81ff">1080</span>];
</span></span><span style="display:flex;"><span>	CHAR RansomNote[<span style="color:#ae81ff">0x1000</span>];
</span></span><span style="display:flex;"><span>	CHAR HtmlRansom[<span style="color:#ae81ff">0x3000</span>];
</span></span><span style="display:flex;"><span>} LOCKY_CONFIG;
</span></span></code></pre></div><p>The good news is that vtypes are pretty easy to build. To make things easier,
load the VAD dump corresponding to the configuration file in a hex editor
(you&rsquo;ll be playing around with offsets in that file, which correspond to the
offsets you will be defining in the vtype).</p>
<p>A volatility vtype looks like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>locky_config <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;_LOCKY_CONFIG&#34;</span>: [<span style="color:#f92672">&lt;</span>TOTAL_STRUCTURE_SIZE<span style="color:#f92672">&gt;</span>, {
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;&lt;MEMBER_NAME&gt;&#39;</span>: [<span style="color:#f92672">&lt;</span>MEMBER_OFFSET<span style="color:#f92672">&gt;</span>, <span style="color:#f92672">&lt;</span>MEMBER_TYPE<span style="color:#f92672">&gt;</span>],
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;&lt;MEMBER_NAME&gt;&#39;</span>: [<span style="color:#f92672">&lt;</span>MEMBER_OFFSET<span style="color:#f92672">&gt;</span>, <span style="color:#f92672">&lt;</span>MEMBER_TYPE<span style="color:#f92672">&gt;</span>],
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;&lt;MEMBER_NAME&gt;&#39;</span>: [<span style="color:#f92672">&lt;</span>MEMBER_OFFSET<span style="color:#f92672">&gt;</span>, <span style="color:#f92672">&lt;</span>MEMBER_TYPE<span style="color:#f92672">&gt;</span>],
</span></span><span style="display:flex;"><span>        [<span style="color:#f92672">...</span>],
</span></span><span style="display:flex;"><span>    }]
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li><strong>MEMBER_NAME</strong>: the name of the structure member; it will be accessed using
<code>&lt;object&gt;.&lt;member_name&gt;</code> in your code</li>
<li><strong>MEMBER_OFFSET</strong>: the offset from the start of the structure (ie. the
cumulative size of previous members)</li>
<li><strong>MEMBER_TYPE</strong>: how volatility should interpret this member: <code>['int']</code>,
<code>['char']</code>, <code>['String', dict(length=0x30)]</code>,&hellip;
<ul>
<li><code>['int']</code> - your typical integer (4 bytes long)</li>
<li><code>['char']</code> - a DWORD (4 bytes long)</li>
<li><code>['String', dict(length=0x30)]</code> - a string. The dict after it specifies the
length of the string (n bytes long, as defined)</li>
<li><code>['array', 1080, ['unsigned char']]</code> - an array of <code>unsigned chars</code>.</li>
</ul>
</li>
</ul>
<p>Check out
<a href="/files/tutorial-volatility-plugin/volatility-locky.py.03_partial">volatility-locky.py.03_partial</a>
for sample code, and fill in the vtype. Check out
<a href="/files/tutorial-volatility-plugin/volatility-locky.py.03">volatility-locky.py.03</a>
for a complete vtype.</p>
<h3 id="rendering-the-output">Rendering the output</h3>
<p>Time to use render text and take those nasty print statements out of the
<code>calculate</code> function! You need to make a minor adjustment to <code>calculate</code>: is has
to <code>yield</code> any data that will be passed on to the <code>render</code> function (thus
becoming a generator).</p>
<p>Check out files
<a href="/files/tutorial-volatility-plugin/volatility-locky.py.04_partial">volatility-locky.py.04_partial</a>
and
<a href="/files/tutorial-volatility-plugin/volatility-locky.py.04">volatility-locky.py.04</a>
for solutions.</p>
]]></content></item><item><title>Volatility autoruns plugin</title><link>https://tomchop.me/posts/volatility-autoruns-plugin/</link><pubDate>Thu, 18 Sep 2014 00:00:00 +0000</pubDate><guid>https://tomchop.me/posts/volatility-autoruns-plugin/</guid><description>Finding persistence points is a recurring task of any investigation potentially involving malware. Here&amp;rsquo;s how to do it using Volatility.</description><content type="html"><![CDATA[<p>Finding persistence points (also called <strong>Auto-Start Extensibility Points</strong>, or
ASEPs) is a recurring task of any investigation potentially involving malware.</p>
<p>Checking for persistence is relatively easy when you have a forensic copy of the
hard-drive: tools such as
<a href="http://technet.microsoft.com/en-us/en-en/sysinternals/bb963902.aspx">Sysinternal&rsquo;s Autoruns</a>
(and its lesser-known ability to analyze offline systems by manually selecting
registry hives) or
<a href="https://code.google.com/p/regripper/wiki/RegRipper">regripper</a> and its
<code>user_run</code> and <code>soft_run</code> plugins all do the job perfectly.</p>
<p>When all you have is a live memory dump and your trusty Volatility framework,
things get a little more tedious since you have to play around with <code>printkey</code>
to display every possible Run or Service key. The <code>svcscan</code> plugin can come in
handy but it won&rsquo;t tell you which DLL the service is hosting or when was the
service created.</p>
<h2 id="plugin-features">Plugin features</h2>
<p>To make an analyst&rsquo;s life a bit easier, I came up with the <code>autoruns</code> plugin.
<code>autoruns</code> basically automates most of the tasks you would need to run when
trying to find out where malware is persisting from. Once all the autostart
locations are found, they are matched with running processes in memory.</p>
<p>Today, the plugin goes through:</p>
<ul>
<li>Popular keys in the HKLM and HKCU hives (Run, RunOnce, etc.). This is the most
common place for malware to establish persistence in.</li>
<li>Winlogon parameters (such as <code>Shell</code> and <code>Userinit</code>) and Notify registrations</li>
<li>Services: It will go through all services that are set to automatically start
with Windows. If the service is invoked through <code>svchost.exe</code>, it will grab
the loaded DLL name.</li>
<li>AppInit DLLs: The DLLs specified here are loaded with every application that
is ran on the system.</li>
<li>Scheduled tasks in memory (tested on Windows 7 only)</li>
</ul>
<p>Besides listing all these persistence points and their corresponding values, the
plugin will match them with a running process. This is particularly useful to:</p>
<ul>
<li>Immediately identify the process that corresponds to the service that loaded a
suspicious-looking DLL.</li>
<li>Determine which binaries where set to load at system start and are no longer
running. Malware often injects itself into other processes before exiting, so
an entry with no associated PIDs may be an indicator of strange activity.</li>
</ul>
<h2 id="how-to">How-to</h2>
<p>The plugin is pretty straightforward to use. The folder where the plugin is
located should be passed on to Volatility using the <code>--plugins=</code> parameter.</p>
<p>Relevant options for the plugin are:</p>
<ul>
<li><code>-v</code> or <code>--verbose</code> - Shows extra information that would normally be filtered
(like Services from the <code>System32</code> folder)</li>
<li><code>-t</code> or <code>--asep-type</code> - Use it to focus on specific ASEPS. Options are:
<code>autoruns</code>, <code>services</code>, <code>appinit</code>, <code>winlogon</code>, and <code>tasks</code>. You can specify
any combination of them with a comma-separated list: <code>autoruns,services</code>.
Leave blank to get all ASEPs.</li>
<li><code>--output=[text|table]</code> - <code>table</code> will output the text in a table format (less
readable but somehow more consice; see screenshot below). The default output
mode is <code>text</code>, where more information is avialable.</li>
</ul>
<p>Sample plugin output:</p>

    <img src="/img/plugin-sample-output.png"  alt="Sample plugin output."  class="center"  style="border-radius: 8px;"  />


<h2 id="roadmap">Roadmap</h2>
<p>I plan on including some more ASEPs like Scheduled tasks <em>(done!)</em> and Startup
folders. If you see any other way than going through the MFT, please do let me
know!</p>
<p>I also plan on extending support to OS X and hopefully Linux.</p>
<p>Since the plugin needs to parse a lot of registry keys, it can take a while to
run (it took approximately 3 minutes to do all the checks on the memory sample I
tested it on).</p>
<h2 id="details-and-download">Details and download</h2>
<p>The plugin has its own
<a href="https://github.com/tomchop/volatility-autoruns">GitHub repo</a>. Check the
<a href="https://github.com/tomchop/volatility-autoruns/blob/master/README.md">README</a>
there for more details on the specific checks that are made.</p>
<p>It was tested with Volatility 2.4 on several of the memory samples available
<a href="https://github.com/volatilityfoundation/volatility/wiki/Memory-Samples">here</a>.</p>
]]></content></item><item><title>Speeding up Volatility with ramdisks</title><link>https://tomchop.me/posts/volatility-ramdisk/</link><pubDate>Mon, 01 Sep 2014 00:00:00 +0000</pubDate><guid>https://tomchop.me/posts/volatility-ramdisk/</guid><description>Use ramdisks to speed up analysis on large memory dumps</description><content type="html"><![CDATA[<p><a href="https://github.com/volatilityfoundation/volatility">Volatility</a> is one of the
greatest memory forensic tools available out there. It&rsquo;s got tons of plugins,
it&rsquo;s open source, it&rsquo;s written in python, what&rsquo;s not to like? Plus,
they&rsquo;ve just migrated to GitHub, which is awesome.</p>
<p>Volatility works on live memory (RAM) dumps. Most of the time, plugins such as
<code>pslist</code> can reveal interesting information just by scanning specific kernel
structures and walking lists. Plugins such as <code>psscan</code> take longer, since they
scan the whole memory dump looking for specific pool tags. There are other
read-intensive plugins such as <code>strings</code> that take even longer to run.</p>
<p>You can usually limit the time you spend running plugns by piping their output
to a text file (which is smart since the memory dump doesn&rsquo;t change in time
anyways). If you are developing - and therefore testing - your own plugins,
you&rsquo;ll have to run them every time, which can quickly become tedious if they
take ≈3 minutes to run.</p>
<h2 id="ramdisks-to-the-rescue">Ramdisks to the rescue</h2>
<p>Ramdisks are like any other mounted device, only they map a portion of your live
memory to a directory on disk. It works just like any other device, only faster.
<strong>Way faster</strong>. Because their content is in RAM, any changes will be lost if
unmounted or if the workstation they&rsquo;re mounted on restarts, so make sure you
save your progress on a physical disk.</p>
<h3 id="mac-os-x">Mac OS X</h3>
<p>Ramdisks are supported in Mac OS X natively. The following script was tested on
Mavericks 10.9.4:</p>
<pre tabindex="0"><code class="language-terminal" data-lang="terminal">diskutil erasevolume HFS+ &#39;[NAME]&#39; `hdiutil attach -nomount ram://[SIZE]`
</code></pre><p>Where <code>[SIZE]</code> is the number of sectors of your new filesystem, and <code>[NAME]</code> is
the name you want to give to the new volume. To check your sector size:</p>
<pre tabindex="0"><code class="language-terminal" data-lang="terminal">$ diskutil info / | grep &#34;Block Size&#34;
   Device Block Size:        512 Bytes
</code></pre><p>To mount a 8 GB (<code>8 * 1024 * 1024 * 1024 / 512 = 16777216</code> sectors) volume named
<em>RAMDISK</em>, you&rsquo;d use:</p>
<pre tabindex="0"><code class="language-terminal" data-lang="terminal">diskutil erasevolume HFS+ &#39;RAMDISK&#39; `hdiutil attach -nomount ram://16777216`
</code></pre><p>To unmount, just eject the disk as you would with any USB key.</p>
<h3 id="linux">Linux</h3>
<p>The following was successfully tested on Ubuntu 14.04 LTS:</p>
<pre tabindex="0"><code class="language-terminal" data-lang="terminal">mkdir /mnt/ramdisk
mount -t [TYPE] -o size=[SIZE] [FSTYPE] [MOUNTPOINT]
</code></pre><p>Where:</p>
<ul>
<li><code>[TYPE]</code> is the type of RAM disk to use; either tmpfs or ramfs.</li>
<li><code>[SIZE]</code> is the size to use for the file system. This understands units. (e.g.
<code>1024m</code> for 1024 MB.)</li>
<li><code>[FSTYPE]</code> is the type filesystem you want to use; tmpfs, ramfs, ext4, etc.</li>
</ul>
<p>To mount a 512 MB filesystem on <code>/mnt/ramdisk</code> you would use:</p>
<pre tabindex="0"><code class="language-terminal" data-lang="terminal">mount -t tmpfs -o size=512m tmpfs /mnt/ramdisk
</code></pre><p>Unmount as any other device:</p>
<pre tabindex="0"><code class="language-terminal" data-lang="terminal">umount /mnt/ramdisk
</code></pre><h3 id="windows">Windows</h3>
<p>I haven&rsquo;t tested this, but a quick Google search gives the following utility:
<a href="http://www.tekrevue.com/tip/create-10-gbs-ram-disk-windows/">http://www.tekrevue.com/tip/create-10-gbs-ram-disk-windows/</a>.</p>
<h2 id="speed-gain">Speed gain</h2>
<p>The speed gain you might experience may vary according to your system
configuration. I&rsquo;ve had times when analysis carried out from a dump on a ramdisk
went up to <strong>4x</strong> as fast as on a typical hard-drive. The speed gain may also
vary according to which plugin you&rsquo;re using.</p>
<p>In my case, a <code>psscan</code> on a dump on the ramdisk took <strong>3.1 seconds</strong>, while the
same command on the same dump on a classical (non-SSD) hard-drive took <strong>13
seconds</strong>.</p>
<pre tabindex="0"><code class="language-terminal" data-lang="terminal">(env-forensics)tomchop:malware tomchop$ time vol.py -f /Volumes/ramdisk/Windows\ XP\ Professional-130bb3ad.vmem --profile=WinXPSP2x86 psscan
[...]
real  0m3.124s
user  0m2.072s
sys   0m0.898s
</code></pre><pre tabindex="0"><code class="language-terminal" data-lang="terminal">(env-forensics)tomchop:malware tomchop$ time vol.py -f Windows\ XP\ Professional-130bb3ad.vmem --profile=WinXPSP2x86 psscan
[...]
real  0m13.060s
user  0m2.102s
sys   0m0.964s
</code></pre><p>In this case the time gain was noticeable, but it may vary from setup to setup.
Seeing how RAM is cheaper than SSD drives, it&rsquo;s definitely worth trying.</p>
]]></content></item></channel></rss>