<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="https://n1ght-w0lf.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://n1ght-w0lf.github.io/" rel="alternate" type="text/html" /><updated>2024-02-04T23:23:40+00:00</updated><id>https://n1ght-w0lf.github.io/feed.xml</id><title type="html">n1ghtw0lf</title><subtitle>Malware Analysis - Reverse Engineering - Exploit Development</subtitle><author><name>Abdallah Elshinbary</name></author><entry><title type="html">Deep Analysis of GCleaner</title><link href="https://n1ght-w0lf.github.io/malware%20analysis/gcleaner-loader/" rel="alternate" type="text/html" title="Deep Analysis of GCleaner" /><published>2023-07-15T00:00:00+00:00</published><updated>2023-07-15T00:00:00+00:00</updated><id>https://n1ght-w0lf.github.io/malware%20analysis/gcleaner-loader</id><content type="html" xml:base="https://n1ght-w0lf.github.io/malware%20analysis/gcleaner-loader/">&lt;p&gt;Howdy! I’m finally back with another malware deep dive report. This time we are digging into GCleaner.&lt;/p&gt;

&lt;p&gt;GCleaner is a Pay-Per-Install (PPI) loader &lt;a href=&quot;https://medium.com/csis-techblog/gcleaner-garbage-provider-since-2019-2708e7c87a8a&quot;&gt;first discovered&lt;/a&gt; in early 2019, it has been used to deploy other malicious families like Smokeloader, Amadey, Redline and Raccoon.&lt;/p&gt;

&lt;p&gt;We will be working on this sample:&lt;/p&gt;

&lt;p&gt;(SHA256: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;020d370b51711b0814901d7cc32d8251affcc3506b9b4c15db659f3dbb6a2e6b&lt;/code&gt;)&lt;/p&gt;

&lt;h1 id=&quot;initial-triage&quot;&gt;Initial Triage&lt;/h1&gt;

&lt;p&gt;Let’s start by running the sample in &lt;a href=&quot;https://tria.ge/230711-rx3c1saf31&quot;&gt;Triage sandbox&lt;/a&gt; to get an overview of what it does.&lt;/p&gt;

&lt;p&gt;We can see from the process tree that it drops and runs another binary out of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;%APPDATA%&quot;&lt;/code&gt; folder with a seemingly random name then it kills itself using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;taskkill&quot;&lt;/code&gt; and deletes the sample binary from disk.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/1.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/1.png&quot; alt=&quot;1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The network tab shows communications to different IP addresses which are considered as C2 servers in Triage’s malware config tab. Each C2 has a different URL path, we will dig deeper to find out what each of them is responsible for.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/2.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/2.png&quot; alt=&quot;2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right when we open the sample in IDA we don’t have much to look at, there are some interesting strings and API imports but not very helpful to start with.&lt;/p&gt;

&lt;p&gt;We can see a repeated pattern across the code where some values are pushed into the stack then xored with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2E&lt;/code&gt;, so we first need to decrypt these values.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/3.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/3.png&quot; alt=&quot;3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;string-decryption&quot;&gt;String Decryption&lt;/h1&gt;

&lt;p&gt;Automating the decryption for stack strings in this sample can be a bit tricky, luckily I noticed a specific instruction that occurs after loading the encrypted strings into stack (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmp      eax, [reg+4]&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/4.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/4.png&quot; alt=&quot;4&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we can find all occurrences of this instruction then walk back to find the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mov&lt;/code&gt; instructions and get the encrypted values. Let’s apply this to an IDA python script.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Lowest address used in the program
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_inf_attr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INF_MIN_EA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Search for &quot;cmp eax, [reg+4]&quot;
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ida_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BADADDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;3B ?? 04 00 00 00&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ida_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEARCH_NEXT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ida_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEARCH_DOWN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BADADDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;enc_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;''&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Search for possible stack strings in the previous 12 instructions
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prev_head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_insn_mnem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;mov&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_operand_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o_displ&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_operand_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o_imm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# Get the value of the second operand
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;operand_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_operand_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The returned operand value is an integer but we need to store it as a byte array, so we first need to figure out the size of that operand to store it correctly.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;            &lt;span class=&quot;c1&quot;&gt;# Get the size of the second operand
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;insn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ida_ua&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insn_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;ida_ua&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode_insn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;operand_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ida_ua&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_dtype_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Op2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;c1&quot;&gt;# Specify the correct data type
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operand_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;operand_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;I&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operand_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operand_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;operand_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;H&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operand_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;operand_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;B&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operand_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                
            &lt;span class=&quot;n&quot;&gt;enc_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operand_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enc_bytes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One more thing I noticed is that some strings use a combination of stack values and other values stored in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;.rdata&quot;&lt;/code&gt; section (retrieved using the XMM instruction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;movaps&quot;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/5.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/5.png&quot; alt=&quot;5&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we can search for this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;movaps&quot;&lt;/code&gt; instruction after the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;cmp&quot;&lt;/code&gt; instruction, if found we can read the values stored at its operand address and append it to the encrypted bytes.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;c1&quot;&gt;# Find possible xmmword movaps
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;xmmword_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ida_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pattern2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ida_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEARCH_NEXT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ida_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEARCH_DOWN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmmword_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BADADDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# Read the xmmword value
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;xmmword_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_operand_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xmmword_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;enc_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xmmword_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enc_bytes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally we can xor the encrypted values with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x2E&lt;/code&gt; (this key has been the same for all GCleaner samples I looked at).&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;c1&quot;&gt;# Decrypt and strip encrypted bytes
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;dec_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x2E&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enc_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dec_str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dec_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x00&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'utf-8'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dec_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; --&amp;gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dec_str&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Set a comment with the decrypted string
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dec_str&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;comment_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BADADDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set_comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;comment_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dec_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here is the list of decrypted strings:&lt;/p&gt;

&lt;details style=&quot;color: #EEFFFF; font-family: monospace !default; font-size: 0.85em; background: #263238; border: 1px solid #263238; border-radius: 3px; padding: 10px; line-height: 1.8&quot;&gt;
    &lt;summary style=&quot;outline: none; cursor: pointer&quot;&gt;
        &lt;span style=&quot;color: darkgray&quot;&gt;
            Expand to see more
        &lt;/span&gt;&lt;br /&gt;
&amp;emsp; 45.12.253.56&lt;br /&gt;
&amp;emsp; 45.12.253.72&lt;br /&gt;
&amp;emsp; 45.12.253.98&lt;br /&gt;
&amp;emsp; 45.12.253.75/dll.php&lt;br /&gt;
&amp;emsp; mixinte&lt;br /&gt;
&amp;emsp; mixtwo&lt;br /&gt;
&lt;/summary&gt;
&amp;emsp; B&lt;br /&gt;
&amp;emsp; USERPROFILE&lt;br /&gt;
&amp;emsp; CCleaner&lt;br /&gt;
&amp;emsp; VLC media player&lt;br /&gt;
&amp;emsp; Acrobat Reader DC&lt;br /&gt;
&amp;emsp; Russian&lt;br /&gt;
&amp;emsp; admin&lt;br /&gt;
&amp;emsp; Shah&lt;br /&gt;
&amp;emsp; testBench&lt;br /&gt;
&amp;emsp; taskmgr&lt;br /&gt;
&amp;emsp; Taskmgr&lt;br /&gt;
&amp;emsp; wireshark&lt;br /&gt;
&amp;emsp; Process Hacker&lt;br /&gt;
&amp;emsp; Wireshark&lt;br /&gt;
&amp;emsp; C:\Program Files&lt;br /&gt;
&amp;emsp; C:\ProgramData&lt;br /&gt;
&amp;emsp; C:\Temp&lt;br /&gt;
&amp;emsp; C:\Program Files&lt;br /&gt;
&amp;emsp; C:\ProgramData&lt;br /&gt;
&amp;emsp; C:\Temp&lt;br /&gt;
&amp;emsp; /advertisting/plus.php?s=&lt;br /&gt;
&amp;emsp; &amp;amp;str=mixtwo&lt;br /&gt;
&amp;emsp; &amp;amp;substr=&lt;br /&gt;
&amp;emsp; /default/stuk.php&lt;br /&gt;
&amp;emsp; /default/puk.php&lt;br /&gt;
&amp;emsp; NOSUB&lt;br /&gt;
&amp;emsp; chk&lt;br /&gt;
&amp;emsp; /chk&lt;br /&gt;
&amp;emsp; test&lt;br /&gt;
&lt;/details&gt;
&lt;p&gt;We can now see the C2 IPs, URL paths and some other interesting strings. Let’s keep going.&lt;/p&gt;

&lt;h1 id=&quot;anti-checks-or-is-it&quot;&gt;Anti Checks (or is it..?)&lt;/h1&gt;

&lt;p&gt;GCleaner is filled with host checks but weirdly enough it doesn’t do anything them, maybe they were like test features? copy-paste code? not really sure but let’s quickly go though them.&lt;/p&gt;

&lt;h2 id=&quot;checking-username&quot;&gt;Checking username&lt;/h2&gt;

&lt;p&gt;Get the current username using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;GetUserNameA()&quot;&lt;/code&gt; and compare it to hardcoded names (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;admin&quot;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;Shah&quot;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;testBench&quot;&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;checking-foreground-window&quot;&gt;Checking foreground window&lt;/h2&gt;

&lt;p&gt;Get the title of the foreground window using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;GetWindowTextA()&quot;&lt;/code&gt; and compare it to hardcoded strings.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/6.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/6.png&quot; alt=&quot;6&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;checking-desktop-files&quot;&gt;Checking desktop files&lt;/h2&gt;

&lt;p&gt;Search for Desktop files with specific strings in their name (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;CCleaner&quot;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;VLC media player&quot;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;Acrobat Reader DC&quot;&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;checking-locale-and-keyboard-layout&quot;&gt;Checking locale and keyboard layout&lt;/h2&gt;

&lt;p&gt;Check if the computer locale is Russian and compare the keyboard layout against specific values (CIS countries).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/7.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/7.png&quot; alt=&quot;7&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;dropped-binary&quot;&gt;Dropped Binary&lt;/h1&gt;

&lt;p&gt;Looking back at the process tree we need to figure out where does that child binary with random name comes from.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;%APPDATA%\{846ee340-7039-11de-9d20-806e6f6e6963}\34LMAylZs6FixF.exe&quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can see below that the sample reads the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;%APPDATA%&quot;&lt;/code&gt; path using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;getenv()&quot;&lt;/code&gt; then creates a random directory using the GUID of the current hardware profile, if retrieving the hardware profile failed it will fall back to generating a random folder name. Other possible locations for creating the random directory are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;C:\Program Files&quot;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;C:\Temp&quot;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;C:\ProgramData&quot;&lt;/code&gt; (fallback locations).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/8.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/8.png&quot; alt=&quot;8&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next it generates a random file name, appends &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;.exe&quot;&lt;/code&gt; extension to it then drops it to the newly created directory and runs it from there.&lt;/p&gt;

&lt;p&gt;The binary file is hardcoded into the parent sample.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/9.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/9.png&quot; alt=&quot;9&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All that binary child does is…well…sleep for 10 seconds, that’s it :|&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/10.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/10.png&quot; alt=&quot;10&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;c2-communications&quot;&gt;C2 Communications&lt;/h1&gt;

&lt;p&gt;The actors behind GCleaner have been known to use &lt;a href=&quot;https://medium.com/csis-techblog/inside-view-of-brazzzersff-infrastructure-89b9188fd145&quot;&gt;BraZZZers fast flux&lt;/a&gt; service to hide their infrastructure, it works more like a proxy system between the victims and the real C2 server.&lt;/p&gt;

&lt;p&gt;Before reaching out to the C2 servers, GCleaner adds hardcoded HTTP headers (could be used for a network sig) an a custom user-agent to each C2 request.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/11.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/11.png&quot; alt=&quot;11&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now to figure out what each C2 request is responsible for.&lt;/p&gt;

&lt;h2 id=&quot;first-c2&quot;&gt;First C2&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;IP: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;45[.]12.253.56&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;UA: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OK&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;PCAP:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/12.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/12.png&quot; alt=&quot;12&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This C2 is likely responsible for bot registration. The sample will only continue execution if the server response is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;0&quot;&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;1&quot;&lt;/code&gt;, otherwise it goes to sleep and tries again.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/13.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/13.png&quot; alt=&quot;13&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;str&quot;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;substr&quot;&lt;/code&gt; parameters in the C2 request above are possibly referring to the campaign ID, GCleaner has been known to use similar values in the past like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;usone&quot;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;ustwo&quot;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;euthree&quot;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;cafive&quot;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;mixshop&quot;&lt;/code&gt;, …&lt;/p&gt;

&lt;h2 id=&quot;second-c2&quot;&gt;Second C2&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;IP: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;45[.]12.253.72&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;UA: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OK&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;PCAP:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/14.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/14.png&quot; alt=&quot;14&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first request to this C2 is responsible for getting an AES key.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/15.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/15.png&quot; alt=&quot;15&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key length must be between 10 and 100 bytes, otherwise it breaks the execution.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/16.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/16.png&quot; alt=&quot;16&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second request is responsible for getting an AES encrypted PE file (notice the filename in the response headers!), That PE file is decrypted using the key from the previous request.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/17.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/17.png&quot; alt=&quot;17&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The decryption routine is pretty trivial, the sample first calculates the SHA256 hash of the server key then derives the session key used for decryption (AES_128).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/18.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/18.png&quot; alt=&quot;18&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that it loads the decrypted PE file into memory (without touching disk) to get the address of an export function called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;GetLicInfo&quot;&lt;/code&gt; which is used in the next stage.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/19.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/19.png&quot; alt=&quot;19&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;downloaded-dll&quot;&gt;Downloaded DLL&lt;/h3&gt;

&lt;p&gt;Before going further we first need to take a look at the downloaded PE file. To be able to analyze it we can either use the debugger to dump the decrypted file or get the encrypted response from the PCAP and decrypt it manually.&lt;/p&gt;

&lt;p&gt;We can easily implement the decryption code in Python as follow:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;hashlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Crypto.Cipher&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AES&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;enc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;puk.php.bin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;kvQoRqtcCyMtHmQyQXOUu&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf-16le&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Important to encode!!
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha256_hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hashlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;aes_key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sha256_hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;digest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cipher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aes_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MODE_CBC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x00&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cipher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decrypt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;out.bin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;wb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now let’s see what this export function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;GetLicInfo&quot;&lt;/code&gt; does.&lt;/p&gt;

&lt;p&gt;Basically it sends an http request to the supplied C2 server then checks the response length, if the length is greater than 2048 bytes it creates a a new directory with a random name under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;%APPDATA%&quot;&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;%TEMP%&quot;&lt;/code&gt; folder then generates a random filename and appends &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;.exe&quot;&lt;/code&gt; extension to it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/20.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/20.png&quot; alt=&quot;20&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally it writes the server response to a disk file with the generated random filename and executes that file.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/21.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/21.png&quot; alt=&quot;21&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;third-c2&quot;&gt;Third C2&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;IP: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;45[.]12.253.75&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;UA: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;PCAP:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/22.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/22.png&quot; alt=&quot;22&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This C2 is responsible for downloading further payloads, notice the user-agent used here is the one from the decrypted strings list unlike the previous 2 C2s.&lt;/p&gt;

&lt;p&gt;The address is supplied to the external function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;GetLicInfo&quot;&lt;/code&gt; which downloads and executes the payload as we stated above. GCleaner tries to get a payload from the server for 10 iterations with a sleep period of 2 seconds between every try.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/23.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/23.png&quot; alt=&quot;23&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If no further payload is received from the server the samples kills its process and deletes the parent file from disk.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/24.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/24.png&quot; alt=&quot;24&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;forth-c2&quot;&gt;Forth C2&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;IP: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;45[.]12.253.98&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This C2 wasn’t used in the sample we are looking at.&lt;/p&gt;

&lt;h1 id=&quot;config-extraction&quot;&gt;Config Extraction&lt;/h1&gt;

&lt;p&gt;We can use the IDA python script we used for string decryption to build a standalone config extractor as most of the interesting stuff are in the decrypted strings list.&lt;/p&gt;

&lt;p&gt;Here’s the output of the code after extracting the useful information:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/25.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/25.png&quot; alt=&quot;25&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code can be found &lt;a href=&quot;https://github.com/n1ght-w0lf/MalwareAnalysis/tree/master/GCleaner&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;(this script is not optimized for production, it’s just for research purposes)&lt;/p&gt;

&lt;h1 id=&quot;hunting&quot;&gt;Hunting&lt;/h1&gt;

&lt;h2 id=&quot;urlscan&quot;&gt;Urlscan&lt;/h2&gt;

&lt;p&gt;The URL path of the first C2 request can be a good candidate to hunt for more C2s on urlscan.&lt;/p&gt;

&lt;p&gt;I looked at more samples and found these two URL patterns:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s=NOSUB&amp;amp;str=...&amp;amp;substr=...&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sub=NOSUB&amp;amp;stream=...&amp;amp;substream=...&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;page.url&quot;&lt;/code&gt; field to &lt;a href=&quot;https://urlscan.io/search/#page.url%3A%22sub%3DNOSUB%26stream%3D%22%20%7C%7C%20page.url%3A%22s%3DNOSUB%26str%3D%22&quot;&gt;search&lt;/a&gt; for the first part of these patterns.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/gcleaner/26.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/gcleaner/26.png&quot; alt=&quot;26&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;yara&quot;&gt;Yara&lt;/h2&gt;

&lt;p&gt;We saw that many strings were encrypted but we can use some of the hardcoded ones to create a simple yara rule for hunting more samples.&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;GCleaner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;py&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;Detects GCleaner payload&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;Abdallah Elshinbary (@_n1ghtw0lf)&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hash1&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;020d370b51711b0814901d7cc32d8251affcc3506b9b4c15db659f3dbb6a2e6b&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hash2&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;73ed1926e850a9a076a8078932e76e1ac5f109581996dd007f00681ae4024baa&quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Kill&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;\&quot; &amp;amp; exit&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;\&quot; /f &amp;amp; erase &quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;/c taskkill /im \&quot;&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Anti&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;checks&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s4&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot; Far &quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s5&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;roxifier&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s6&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;HTTP Analyzer&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s7&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;Wireshark&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s8&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;NetworkMiner&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HTTP&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s9&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;Accept-Language: ru-RU,ru;q=0.9,en;q=0.8&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s10&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s11&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s12&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullword&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;uint16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x5a4d&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;and&lt;/span&gt;
        &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;them&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://medium.com/csis-techblog/gcleaner-garbage-provider-since-2019-2708e7c87a8a&quot;&gt;https://medium.com/csis-techblog/gcleaner-garbage-provider-since-2019-2708e7c87a8a&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://medium.com/csis-techblog/inside-view-of-brazzzersff-infrastructure-89b9188fd145&quot;&gt;https://medium.com/csis-techblog/inside-view-of-brazzzersff-infrastructure-89b9188fd145&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Abdallah Elshinbary</name></author><category term="Malware Analysis" /><summary type="html">Howdy! I’m finally back with another malware deep dive report. This time we are digging into GCleaner. GCleaner is a Pay-Per-Install (PPI) loader first discovered in early 2019, it has been used to deploy other malicious families like Smokeloader, Amadey, Redline and Raccoon. We will be working on this sample: (SHA256: 020d370b51711b0814901d7cc32d8251affcc3506b9b4c15db659f3dbb6a2e6b) Initial Triage Let’s start by running the sample in Triage sandbox to get an overview of what it does. We can see from the process tree that it drops and runs another binary out of &quot;%APPDATA%&quot; folder with a seemingly random name then it kills itself using &quot;taskkill&quot; and deletes the sample binary from disk. The network tab shows communications to different IP addresses which are considered as C2 servers in Triage’s malware config tab. Each C2 has a different URL path, we will dig deeper to find out what each of them is responsible for. Right when we open the sample in IDA we don’t have much to look at, there are some interesting strings and API imports but not very helpful to start with. We can see a repeated pattern across the code where some values are pushed into the stack then xored with 0x2E, so we first need to decrypt these values. String Decryption Automating the decryption for stack strings in this sample can be a bit tricky, luckily I noticed a specific instruction that occurs after loading the encrypted strings into stack (cmp eax, [reg+4]). So we can find all occurrences of this instruction then walk back to find the mov instructions and get the encrypted values. Let’s apply this to an IDA python script. # Lowest address used in the program addr = idc.get_inf_attr(INF_MIN_EA) while True: # Search for &quot;cmp eax, [reg+4]&quot; addr = ida_search.find_binary(addr, idc.BADADDR, &quot;3B ?? 04 00 00 00&quot;, 16, ida_search.SEARCH_NEXT | ida_search.SEARCH_DOWN) if addr == idc.BADADDR: break enc_bytes = b'' # Search for possible stack strings in the previous 12 instructions for i in range(12): ea = idc.prev_head(ea) if (idc.print_insn_mnem(ea) == &quot;mov&quot; and idc.get_operand_type(ea, 0) == idc.o_displ and idc.get_operand_type(ea, 1) == idc.o_imm): # Get the value of the second operand operand_value = idc.get_operand_value(ea, 1) The returned operand value is an integer but we need to store it as a byte array, so we first need to figure out the size of that operand to store it correctly. # Get the size of the second operand insn = ida_ua.insn_t() ida_ua.decode_insn(insn, ea) operand_size = ida_ua.get_dtype_size(insn.Op2.dtype) # Specify the correct data type if operand_size == 4: operand_bytes = struct.pack(&quot;&amp;lt;I&quot;, operand_value) elif operand_size == 2: operand_bytes = struct.pack(&quot;&amp;lt;H&quot;, operand_value) else: operand_bytes = struct.pack(&quot;&amp;lt;B&quot;, operand_value) enc_bytes = operand_bytes + enc_bytes One more thing I noticed is that some strings use a combination of stack values and other values stored in the &quot;.rdata&quot; section (retrieved using the XMM instruction &quot;movaps&quot;). So we can search for this &quot;movaps&quot; instruction after the &quot;cmp&quot; instruction, if found we can read the values stored at its operand address and append it to the encrypted bytes. # Find possible xmmword movaps xmmword_addr = ida_search.find_binary(addr, addr+50, pattern2, 16, ida_search.SEARCH_NEXT | ida_search.SEARCH_DOWN) if xmmword_addr != idc.BADADDR: # Read the xmmword value xmmword_value = idc.get_bytes(get_operand_value(xmmword_addr, 1), 16) enc_bytes = xmmword_value + enc_bytes Finally we can xor the encrypted values with 0x2E (this key has been the same for all GCleaner samples I looked at). # Decrypt and strip encrypted bytes dec_bytes = bytes(c ^ 0x2E for c in enc_bytes) dec_str = dec_bytes.strip(b'\x00').decode('utf-8') if len(dec_str) != 0: print(f&quot;{hex(addr)} --&amp;gt; {dec_str}&quot;) # Set a comment with the decrypted string if dec_str and comment_addr != idc.BADADDR: set_comment(comment_addr, dec_str) Here is the list of decrypted strings: Expand to see more &amp;emsp; 45.12.253.56 &amp;emsp; 45.12.253.72 &amp;emsp; 45.12.253.98 &amp;emsp; 45.12.253.75/dll.php &amp;emsp; mixinte &amp;emsp; mixtwo &amp;emsp; B &amp;emsp; USERPROFILE &amp;emsp; CCleaner &amp;emsp; VLC media player &amp;emsp; Acrobat Reader DC &amp;emsp; Russian &amp;emsp; admin &amp;emsp; Shah &amp;emsp; testBench &amp;emsp; taskmgr &amp;emsp; Taskmgr &amp;emsp; wireshark &amp;emsp; Process Hacker &amp;emsp; Wireshark &amp;emsp; C:\Program Files &amp;emsp; C:\ProgramData &amp;emsp; C:\Temp &amp;emsp; C:\Program Files &amp;emsp; C:\ProgramData &amp;emsp; C:\Temp &amp;emsp; /advertisting/plus.php?s= &amp;emsp; &amp;amp;str=mixtwo &amp;emsp; &amp;amp;substr= &amp;emsp; /default/stuk.php &amp;emsp; /default/puk.php &amp;emsp; NOSUB &amp;emsp; chk &amp;emsp; /chk &amp;emsp; test We can now see the C2 IPs, URL paths and some other interesting strings. Let’s keep going. Anti Checks (or is it..?) GCleaner is filled with host checks but weirdly enough it doesn’t do anything them, maybe they were like test features? copy-paste code? not really sure but let’s quickly go though them. Checking username Get the current username using &quot;GetUserNameA()&quot; and compare it to hardcoded names (&quot;admin&quot;, &quot;Shah&quot;, &quot;testBench&quot;). Checking foreground window Get the title of the foreground window using &quot;GetWindowTextA()&quot; and compare it to hardcoded strings. Checking desktop files Search for Desktop files with specific strings in their name (&quot;CCleaner&quot;, &quot;VLC media player&quot;, &quot;Acrobat Reader DC&quot;). Checking locale and keyboard layout Check if the computer locale is Russian and compare the keyboard layout against specific values (CIS countries). Dropped Binary Looking back at the process tree we need to figure out where does that child binary with random name comes from. &quot;%APPDATA%\{846ee340-7039-11de-9d20-806e6f6e6963}\34LMAylZs6FixF.exe&quot; We can see below that the sample reads the &quot;%APPDATA%&quot; path using &quot;getenv()&quot; then creates a random directory using the GUID of the current hardware profile, if retrieving the hardware profile failed it will fall back to generating a random folder name. Other possible locations for creating the random directory are &quot;C:\Program Files&quot;, &quot;C:\Temp&quot;, &quot;C:\ProgramData&quot; (fallback locations). Next it generates a random file name, appends &quot;.exe&quot; extension to it then drops it to the newly created directory and runs it from there. The binary file is hardcoded into the parent sample. All that binary child does is…well…sleep for 10 seconds, that’s it :| C2 Communications The actors behind GCleaner have been known to use BraZZZers fast flux service to hide their infrastructure, it works more like a proxy system between the victims and the real C2 server. Before reaching out to the C2 servers, GCleaner adds hardcoded HTTP headers (could be used for a network sig) an a custom user-agent to each C2 request. Now to figure out what each C2 request is responsible for. First C2 IP: 45[.]12.253.56 UA: OK PCAP: This C2 is likely responsible for bot registration. The sample will only continue execution if the server response is &quot;0&quot; or &quot;1&quot;, otherwise it goes to sleep and tries again. The &quot;str&quot; and &quot;substr&quot; parameters in the C2 request above are possibly referring to the campaign ID, GCleaner has been known to use similar values in the past like &quot;usone&quot;, &quot;ustwo&quot;, &quot;euthree&quot;, &quot;cafive&quot;, &quot;mixshop&quot;, … Second C2 IP: 45[.]12.253.72 UA: OK PCAP: The first request to this C2 is responsible for getting an AES key. The key length must be between 10 and 100 bytes, otherwise it breaks the execution. The second request is responsible for getting an AES encrypted PE file (notice the filename in the response headers!), That PE file is decrypted using the key from the previous request. The decryption routine is pretty trivial, the sample first calculates the SHA256 hash of the server key then derives the session key used for decryption (AES_128). After that it loads the decrypted PE file into memory (without touching disk) to get the address of an export function called &quot;GetLicInfo&quot; which is used in the next stage. Downloaded DLL Before going further we first need to take a look at the downloaded PE file. To be able to analyze it we can either use the debugger to dump the decrypted file or get the encrypted response from the PCAP and decrypt it manually. We can easily implement the decryption code in Python as follow: import hashlib from Crypto.Cipher import AES enc = open(&quot;puk.php.bin&quot;, &quot;rb&quot;).read() key = &quot;kvQoRqtcCyMtHmQyQXOUu&quot;.encode(&quot;utf-16le&quot;) # Important to encode!! sha256_hash = hashlib.sha256(key) aes_key = sha256_hash.digest()[:16] cipher = AES.new(aes_key, mode=AES.MODE_CBC, IV=b&quot;\x00&quot;*16) dec = cipher.decrypt(enc) open(&quot;out.bin&quot;, &quot;wb&quot;).write(dec) Now let’s see what this export function &quot;GetLicInfo&quot; does. Basically it sends an http request to the supplied C2 server then checks the response length, if the length is greater than 2048 bytes it creates a a new directory with a random name under &quot;%APPDATA%&quot; or &quot;%TEMP%&quot; folder then generates a random filename and appends &quot;.exe&quot; extension to it. Finally it writes the server response to a disk file with the generated random filename and executes that file. Third C2 IP: 45[.]12.253.75 UA: B PCAP: This C2 is responsible for downloading further payloads, notice the user-agent used here is the one from the decrypted strings list unlike the previous 2 C2s. The address is supplied to the external function &quot;GetLicInfo&quot; which downloads and executes the payload as we stated above. GCleaner tries to get a payload from the server for 10 iterations with a sleep period of 2 seconds between every try. If no further payload is received from the server the samples kills its process and deletes the parent file from disk. Forth C2 IP: 45[.]12.253.98 This C2 wasn’t used in the sample we are looking at. Config Extraction We can use the IDA python script we used for string decryption to build a standalone config extractor as most of the interesting stuff are in the decrypted strings list. Here’s the output of the code after extracting the useful information: The code can be found here. (this script is not optimized for production, it’s just for research purposes) Hunting Urlscan The URL path of the first C2 request can be a good candidate to hunt for more C2s on urlscan. I looked at more samples and found these two URL patterns: s=NOSUB&amp;amp;str=...&amp;amp;substr=... sub=NOSUB&amp;amp;stream=...&amp;amp;substream=... So we can use the &quot;page.url&quot; field to search for the first part of these patterns. Yara We saw that many strings were encrypted but we can use some of the hardcoded ones to create a simple yara rule for hunting more samples. rule GCleaner { meta: description = &quot;Detects GCleaner payload&quot; author = &quot;Abdallah Elshinbary (@_n1ghtw0lf)&quot; hash1 = &quot;020d370b51711b0814901d7cc32d8251affcc3506b9b4c15db659f3dbb6a2e6b&quot; hash2 = &quot;73ed1926e850a9a076a8078932e76e1ac5f109581996dd007f00681ae4024baa&quot; strings: // Kill self $s1 = &quot;\&quot; &amp;amp; exit&quot; ascii fullword $s2 = &quot;\&quot; /f &amp;amp; erase &quot; ascii fullword $s3 = &quot;/c taskkill /im \&quot;&quot; ascii fullword // Anti checks $s4 = &quot; Far &quot; ascii fullword $s5 = &quot;roxifier&quot; ascii fullword $s6 = &quot;HTTP Analyzer&quot; ascii fullword $s7 = &quot;Wireshark&quot; ascii fullword $s8 = &quot;NetworkMiner&quot; ascii fullword // HTTP headers $s9 = &quot;Accept-Language: ru-RU,ru;q=0.9,en;q=0.8&quot; ascii fullword $s10 = &quot;Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1&quot; ascii fullword $s11 = &quot;Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0&quot; ascii fullword $s12 = &quot;Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1&quot; ascii fullword condition: uint16(0) == 0x5a4d and 10 of them } References https://medium.com/csis-techblog/gcleaner-garbage-provider-since-2019-2708e7c87a8a https://medium.com/csis-techblog/inside-view-of-brazzzersff-infrastructure-89b9188fd145</summary></entry><entry><title type="html">Dotnet String Decryptor</title><link href="https://n1ght-w0lf.github.io/tutorials/dotnet-string-decryptor/" rel="alternate" type="text/html" title="Dotnet String Decryptor" /><published>2023-06-15T00:00:00+00:00</published><updated>2023-06-15T00:00:00+00:00</updated><id>https://n1ght-w0lf.github.io/tutorials/dotnet-string-decryptor</id><content type="html" xml:base="https://n1ght-w0lf.github.io/tutorials/dotnet-string-decryptor/">&lt;p&gt;Welcome back! This is a short blog post about reverse engineering dotnet malware.&lt;/p&gt;

&lt;p&gt;When working with dotnet malware samples I always come around samples with obfuscated strings which makes analysis harder.&lt;/p&gt;

&lt;p&gt;My go to way to handle this situation was to identify the string decryption routine (through static/dynamic analysis) then use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;de4dot&lt;/code&gt; to decrypt the strings.&lt;/p&gt;

&lt;p&gt;But sometimes you don’t want to go through every sample and find the decryption routine or you need to automate this process for a collection of different samples.&lt;/p&gt;

&lt;p&gt;While looking around for a solution I found this cool &lt;a href=&quot;http://rhotav.com/stringDecryptionWithPythonen/&quot;&gt;blog&lt;/a&gt;, so I will be building on it to write a generic dotnet string decryptor which will hopefully make life a bit easier.&lt;/p&gt;

&lt;p&gt;We will be working on an obfuscated sample of &lt;a href=&quot;https://malpedia.caad.fkie.fraunhofer.de/details/win.dcrat&quot;&gt;DCRat&lt;/a&gt; to test our script.
&lt;a href=&quot;https://bazaar.abuse.ch/sample/c6244c8e4e4cdecd641017d52d344b1db6a23d05fd6a8ad338c8f4f77481f483/&quot;&gt;c6244c8e4e4cdecd641017d52d344b1db6a23d05fd6a8ad338c8f4f77481f483&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;writing-the-deobfuscation-script&quot;&gt;Writing the deobfuscation script&lt;/h1&gt;

&lt;h2 id=&quot;step-1--importing-libs-and-loading-the-net-file&quot;&gt;Step 1 : Importing libs and loading the .NET file&lt;/h2&gt;

&lt;p&gt;We first need to install &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pythonnet&lt;/code&gt; which allows CLR namespaces to be treated essentially as python packages.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip install pythonnet
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then we can import the required reflection modules which we will use later to get and invoke decryption methods.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;clr&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Reflection&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Assembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BindingFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MethodInfo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We also need to add a reference to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dnlib.dll&lt;/code&gt; which we will use to parse the .NET assemblies and modules.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;clr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;./dnlib&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;dnlib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;dnlib.DotNet&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModuleDef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModuleDefMD&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;dnlib.DotNet.Emit&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OpCodes&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;dnlib.DotNet.Writer&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModuleWriterOptions&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we can load our .NET file.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;file_module&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModuleDefMD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;file_assembly&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Assembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LoadFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-2--finding-suspected-decryption-methods&quot;&gt;Step 2 : Finding suspected decryption methods&lt;/h2&gt;

&lt;p&gt;Before we get any further we need to define the signatures of the suspected methods that are used for string decryption.&lt;/p&gt;

&lt;p&gt;A method signature consists of the type of its parameters and its return type.&lt;/p&gt;

&lt;p&gt;Below is the string decryption method in the sample we are working on:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/dotnet/1.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/dotnet/1.png&quot; alt=&quot;1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also found some wrapper methods that call the decryption method and they had a different signature.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/dotnet/2.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/dotnet/2.png&quot; alt=&quot;2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we can define our suspected method signatures as follows:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;DECRYPTION_METHOD_SIGNATURES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Parameters&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;System.Int32&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;ReturnType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;System.String&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Parameters&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;System.Int32&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;ReturnType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;System.Object&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Of course there could be other methods with similar signatures which are not related to string decryption, but invoking them shouldn’t affect the end result (&lt;strong&gt;and you better run the script in a sandboxed environment&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Next we use the reflection modules to loop through the methods of each Type (classes, interfaces, …) and find suspected methods based on the list of signatures we defined above.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Search for static, public and non public members
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eFlags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BindingFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Static&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BindingFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BindingFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NonPublic&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module_type&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_assembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetMethods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we find a suspected method we need to store its corresponding signature and &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.reflection.methodinfo&quot;&gt;MethodInfo&lt;/a&gt; object which we will use later to invoke that method.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        &lt;span class=&quot;c1&quot;&gt;# Check if the current method has a suspected signature
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StringDecryptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DECRYPTION_METHOD_SIGNATURES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# Check number of parameters and return type
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;parameters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Parameters&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReturnType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FullName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ReturnType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])):&lt;/span&gt;
               
                &lt;span class=&quot;c1&quot;&gt;# Check parameters types
&lt;/span&gt;                &lt;span class=&quot;n&quot;&gt;param_types_match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ParameterType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FullName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Parameters&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;param_types_match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;

                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_types_match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;# Store the signature and MethodInfo object of the current method
&lt;/span&gt;                    &lt;span class=&quot;n&quot;&gt;method_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DeclaringType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FullName&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;suspected_methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-3--finding-references-to-suspected-methods&quot;&gt;Step 3 : Finding references to suspected methods&lt;/h2&gt;

&lt;p&gt;The next step is to find references to the suspected methods so we can get the required parameters.&lt;/p&gt;

&lt;p&gt;To do this we can use dnlib modules to loop through the CIL instructions of each method and find calls to these methods.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module_type&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Types&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HasMethods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HasBody&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Loop through method instructions
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insnIdx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insn&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Instructions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# Find Call instructions
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OpCode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OpCodes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s_method_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_method_sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s_method_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;suspected_methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
                    &lt;span class=&quot;c1&quot;&gt;# Check if the callee is one of the suspected methods
&lt;/span&gt;                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_method_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Operand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we find a reference call, we need to get the required parameters (note that they are pushed to the stack in reverse order).&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                                &lt;span class=&quot;c1&quot;&gt;# Get method parameters in reverse order
&lt;/span&gt;                                &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_method_sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Parameters&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])):&lt;/span&gt;
                                    &lt;span class=&quot;n&quot;&gt;operand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetOperandValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Instructions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insnIdx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;s_method_sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Parameters&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
                                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operand&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

                                &lt;span class=&quot;c1&quot;&gt;# Check if we got all the parameters
&lt;/span&gt;                                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_method_sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Parameters&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next we can invoke suspected methods to get the decrypted strings&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                                    &lt;span class=&quot;c1&quot;&gt;# Invoke suspected method
&lt;/span&gt;                                    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_method_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
                                    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                                        &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-4--patching&quot;&gt;Step 4 : Patching&lt;/h2&gt;

&lt;p&gt;If the method invoke succeeded we can safely patch the method parameters with NOPs and patch the method call itself with the decrypted string.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                                    &lt;span class=&quot;c1&quot;&gt;# Patch suspected method parameters with NOPs
&lt;/span&gt;                                    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_method_sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Parameters&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])):&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Instructions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insnIdx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OpCode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OpCodes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Nop&lt;/span&gt;

                                    &lt;span class=&quot;c1&quot;&gt;# Patch suspected method call with the result string
&lt;/span&gt;                                    &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Instructions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insnIdx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OpCode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OpCodes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Ldstr&lt;/span&gt;
                                    &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Instructions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insnIdx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Operand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
                                    &lt;span class=&quot;n&quot;&gt;decrypted_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-5--saving&quot;&gt;Step 5 : Saving&lt;/h2&gt;

&lt;p&gt;Finally we can save the deobfuscated file to disk.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Add writer options to ignore dnlib errors
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModuleWriterOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dnlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DotNet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DummyLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NoThrowInstance&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Write cleaned module content
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;out.bin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;testing-and-final-notes&quot;&gt;Testing and final notes&lt;/h1&gt;

&lt;p&gt;Let’s run the script on the sample we have and see the results.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/tutorials/dotnet/3.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/dotnet/3.png&quot; alt=&quot;3&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/tutorials/dotnet/4.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/dotnet/4.png&quot; alt=&quot;4&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Perfect, now it’s much easier to work on the sample and analyze its functionalities.&lt;/p&gt;

&lt;p&gt;A little something before we wrap up, you can check if a PE is a dotnet file by checking the existence of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR&lt;/code&gt; data directory (at index 14).&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;dotnet_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pefile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DIRECTORY_ENTRY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# COM descriptor table index
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OPTIONAL_HEADER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DATA_DIRECTORY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dotnet_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VirtualAddress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[-] File is not .NET&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The full code can be found &lt;a href=&quot;https://github.com/n1ght-w0lf/dotnet-string-decryptor&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Until next time, cheers!&lt;/p&gt;</content><author><name>Abdallah Elshinbary</name></author><category term="Tutorials" /><summary type="html">Welcome back! This is a short blog post about reverse engineering dotnet malware. When working with dotnet malware samples I always come around samples with obfuscated strings which makes analysis harder. My go to way to handle this situation was to identify the string decryption routine (through static/dynamic analysis) then use de4dot to decrypt the strings. But sometimes you don’t want to go through every sample and find the decryption routine or you need to automate this process for a collection of different samples. While looking around for a solution I found this cool blog, so I will be building on it to write a generic dotnet string decryptor which will hopefully make life a bit easier. We will be working on an obfuscated sample of DCRat to test our script. c6244c8e4e4cdecd641017d52d344b1db6a23d05fd6a8ad338c8f4f77481f483 Writing the deobfuscation script Step 1 : Importing libs and loading the .NET file We first need to install pythonnet which allows CLR namespaces to be treated essentially as python packages. pip install pythonnet Then we can import the required reflection modules which we will use later to get and invoke decryption methods. import clr from System.Reflection import Assembly, BindingFlags, MethodInfo We also need to add a reference to dnlib.dll which we will use to parse the .NET assemblies and modules. clr.AddReference(&quot;./dnlib&quot;) import dnlib from dnlib.DotNet import ModuleDef, ModuleDefMD from dnlib.DotNet.Emit import OpCodes from dnlib.DotNet.Writer import ModuleWriterOptions Now we can load our .NET file. file_module = ModuleDefMD.Load(file_path) file_assembly = Assembly.LoadFile(file_path) Step 2 : Finding suspected decryption methods Before we get any further we need to define the signatures of the suspected methods that are used for string decryption. A method signature consists of the type of its parameters and its return type. Below is the string decryption method in the sample we are working on: I also found some wrapper methods that call the decryption method and they had a different signature. So we can define our suspected method signatures as follows: DECRYPTION_METHOD_SIGNATURES = [ { &quot;Parameters&quot;: [&quot;System.Int32&quot;], &quot;ReturnType&quot;: &quot;System.String&quot; }, { &quot;Parameters&quot;: [&quot;System.Int32&quot;], &quot;ReturnType&quot;: &quot;System.Object&quot; }, ] Of course there could be other methods with similar signatures which are not related to string decryption, but invoking them shouldn’t affect the end result (and you better run the script in a sandboxed environment). Next we use the reflection modules to loop through the methods of each Type (classes, interfaces, …) and find suspected methods based on the list of signatures we defined above. # Search for static, public and non public members eFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic for module_type in file_assembly.GetTypes(): for method in module_type.GetMethods(eFlags): If we find a suspected method we need to store its corresponding signature and MethodInfo object which we will use later to invoke that method. # Check if the current method has a suspected signature for sig in StringDecryptor.DECRYPTION_METHOD_SIGNATURES: # Check number of parameters and return type parameters = method.GetParameters() if ((len(parameters) == len(sig[&quot;Parameters&quot;])) and (method.ReturnType.FullName == sig[&quot;ReturnType&quot;])): # Check parameters types param_types_match = True for i in range(len(parameters)): if parameters[i].ParameterType.FullName != sig[&quot;Parameters&quot;][i]: param_types_match = False break if param_types_match: # Store the signature and MethodInfo object of the current method method_name = f&quot;{method.DeclaringType.FullName}::{method.Name}&quot; suspected_methods[method_name] = (sig, method) Step 3 : Finding references to suspected methods The next step is to find references to the suspected methods so we can get the required parameters. To do this we can use dnlib modules to loop through the CIL instructions of each method and find calls to these methods. for module_type in file_module.Types: if not module_type.HasMethods: continue for method in module_type.Methods: if not method.HasBody: continue # Loop through method instructions for insnIdx, insn in enumerate(method.Body.Instructions): # Find Call instructions if insn.OpCode == OpCodes.Call: for s_method_name, (s_method_sig, s_method_info) in suspected_methods.items(): # Check if the callee is one of the suspected methods if str(s_method_name) in str(insn.Operand): If we find a reference call, we need to get the required parameters (note that they are pushed to the stack in reverse order). # Get method parameters in reverse order params = [] for i in range(len(s_method_sig[&quot;Parameters&quot;])): operand = GetOperandValue( method.Body.Instructions[insnIdx - i - 1], s_method_sig[&quot;Parameters&quot;][-i - 1]) if operand is not None: params.append(operand) # Check if we got all the parameters if len(params) == len(s_method_sig[&quot;Parameters&quot;]): Next we can invoke suspected methods to get the decrypted strings # Invoke suspected method try: result = str(s_method_info.Invoke(None, params[::-1])) except Exception as e: continue Step 4 : Patching If the method invoke succeeded we can safely patch the method parameters with NOPs and patch the method call itself with the decrypted string. # Patch suspected method parameters with NOPs for i in range(len(s_method_sig[&quot;Parameters&quot;])): method.Body.Instructions[insnIdx - i - 1].OpCode = OpCodes.Nop # Patch suspected method call with the result string method.Body.Instructions[insnIdx].OpCode = OpCodes.Ldstr method.Body.Instructions[insnIdx].Operand = result decrypted_strings.append(result) Step 5 : Saving Finally we can save the deobfuscated file to disk. # Add writer options to ignore dnlib errors options = ModuleWriterOptions(file_module) options.Logger = dnlib.DotNet.DummyLogger.NoThrowInstance # Write cleaned module content file_module.Write(&quot;out.bin&quot;, options) Testing and final notes Let’s run the script on the sample we have and see the results. Perfect, now it’s much easier to work on the sample and analyze its functionalities. A little something before we wrap up, you can check if a PE is a dotnet file by checking the existence of the IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR data directory (at index 14). dotnet_dir = pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR'] # COM descriptor table index if pe.OPTIONAL_HEADER.DATA_DIRECTORY[dotnet_dir].VirtualAddress == 0: sys.exit(&quot;[-] File is not .NET&quot;) The full code can be found here. Until next time, cheers!</summary></entry><entry><title type="html">Writing x64dbg plugins</title><link href="https://n1ght-w0lf.github.io/tutorials/writing-x64dbg-plugins/" rel="alternate" type="text/html" title="Writing x64dbg plugins" /><published>2022-12-17T00:00:00+00:00</published><updated>2022-12-17T00:00:00+00:00</updated><id>https://n1ght-w0lf.github.io/tutorials/writing-x64dbg-plugins</id><content type="html" xml:base="https://n1ght-w0lf.github.io/tutorials/writing-x64dbg-plugins/">&lt;p&gt;In the &lt;a href=&quot;https://n1ght-w0lf.github.io/tutorials/writing-x64dbg-scripts&quot;&gt;previous post&lt;/a&gt; we talked about writing x64dbg scripts, now let’s dive deeper and write our own plugin to do the same job (automatically dumping unpacked PE payloads in memory).&lt;/p&gt;

&lt;p&gt;x64dbg comes with an integrated plugin SDK for creating plugins using C++.&lt;/p&gt;

&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;

&lt;p&gt;The easiest way to create a plugin is to use the &lt;a href=&quot;https://github.com/x64dbg/PluginTemplate&quot;&gt;PluginTemplate&lt;/a&gt; to create a new repository for your plugin.&lt;/p&gt;

&lt;p&gt;Next you can edit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmake.toml&lt;/code&gt; which contains the project configuration, for this tutorial we will only change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target&lt;/code&gt; values to our plugin name.&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;name = &lt;span class=&quot;s2&quot;&gt;&quot;EasyDump&quot;&lt;/span&gt;
....
[target.EasyDump]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To build the project for 64-bit –&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build64\ProjectName.sln&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cmake -B build64 -A x64
cmake --build build64 --config Release
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To build the project for 32-bit –&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build32\ProjectName.sln&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cmake -B build32 -A Win32
cmake --build build32 --config Release
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;plugin-structure&quot;&gt;Plugin structure&lt;/h2&gt;

&lt;p&gt;A plugin must have an exported function called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pluginit&lt;/code&gt;, this is the first function that gets called when the plugin is loaded and where the plugin data is initialized.&lt;/p&gt;

&lt;p&gt;Other optional exports are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plugstop&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;called when the plugin is about to be unloaded and where the plugin data cleanup occurs.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plugsetup&lt;/code&gt;:&lt;/p&gt;

    &lt;p&gt;called when the plugin initialization was successful, here you can register menus and other GUI-related things.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;sdk-functions&quot;&gt;SDK functions&lt;/h2&gt;

&lt;p&gt;Before we go any further we need to know what functions exported by the plugin SDK we can use, you can find some of these functions in the official &lt;a href=&quot;https://help.x64dbg.com/en/latest/developers/functions/index.html&quot;&gt;docs&lt;/a&gt; but many of them are not documented.&lt;/p&gt;

&lt;p&gt;To view the full list you can explore the SDK header files.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/x64dbg/plugins/1.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/x64dbg/plugins/1.png&quot; alt=&quot;1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For me plugin SDK functions are divided into 4 main categories:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;_plugin_ functions @&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_plugins.h&lt;/code&gt;:&lt;/p&gt;

    &lt;p&gt;Helper functions for plugin setup, initialization and logging.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;bridge functions @&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bridgemain.h&lt;/code&gt;:&lt;/p&gt;

    &lt;p&gt;Bridge is the communication library for the DBG and GUI part of x64dbg.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;scriptapi functions @&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_scriptapi_*.h&lt;/code&gt;:&lt;/p&gt;

    &lt;p&gt;It is intended to be used by plugins. It provides easy scripting experience for developers.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;TitanEngine functions @&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TitanEngine.h&lt;/code&gt;:&lt;/p&gt;

    &lt;p&gt;Titan is the debugging engine for x64dbg.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most functions are self explanatory or documented in the official docs, for TitanEngine functions you can find its docs &lt;a href=&quot;https://github.com/x64dbg/x64dbg/blob/development/src/dbg/TitanEngine/TitanEngine.txt&quot;&gt;here&lt;/a&gt; or you can check the markdown version for better readability I uploaded &lt;a href=&quot;https://gist.github.com/N1ght-W0lf/49c4141b52acf45434679602acb32f88&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ok enough talk let’s get our hands dirty.&lt;/p&gt;

&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;/h2&gt;

&lt;p&gt;Your code should go into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plugin.cpp&lt;/code&gt; file, let’s start with the plugin main components.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Initialize your plugin data here.&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pluginInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PLUG_INITSTRUCT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_plugin_logputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGIN_NAME&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;] Loaded successfully!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_plugin_registercommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pluginHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;EasyDump&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cbEasyDump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Failed to register command&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Return false to cancel loading the plugin.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Deinitialize your plugin data here.&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pluginStop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_plugin_unregistercommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pluginHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;EasyDump&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First we need to register a command that we can use in the command prompt using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_plugin_registercommand&lt;/code&gt; function, The definition for this function is:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_plugin_registercommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pluginHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// Plugin handle&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// Command name&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;CBPLUGINCOMMAND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cbCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Callback function&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debugonly&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;// Restrict the command to debug-only&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And of course don’t forget to unregister this command inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pluginStop&lt;/code&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_plugin_unregistercommand&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now let’s implement the callback function.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cbEasyDump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Delete All BPs&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DbgCmdExec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bpc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Set BP on VirtualAlloc ret&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SetAPIBreakPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;kernelbase.dll&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;VirtualAlloc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UE_BREAKPOINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UE_APIEND&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cbVirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Failed to set a Breakpoint on VirtualAlloc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Set BP on VirtualProtect start&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SetAPIBreakPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;kernelbase.dll&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;VirtualProtect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UE_BREAKPOINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UE_APISTART&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cbVirtualProtect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Failed to set a Breakpoint on VirtualProtect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;_plugin_logprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGIN_NAME&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;] Starting the program...&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DbgCmdExec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;run&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Callback arguments are passed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;argv&lt;/code&gt; starting at index 1, but our command doesn’t need any arguments.&lt;/p&gt;

&lt;p&gt;We will start with deleting all breakpoints to let the plugin run without interruption using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DbgCmdExec&lt;/code&gt; to execute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bpc&lt;/code&gt; command (breakpoint clear).&lt;/p&gt;

&lt;p&gt;Next we set our breakpoints using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetAPIBreakPoint&lt;/code&gt; function which is defined as:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;__stdcall&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SetAPIBreakPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;szDLLName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// DLL name&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;szAPIName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// API name&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bpxType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// UE_BREAKPOINT or UE_SINGLESHOOT&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bpxPlace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// UE_APISTART or UE_APIEND&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;LPVOID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bpxCallBack&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Callback function&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc&lt;/code&gt; we need to set the breakpoint at return so we will use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UE_APIEND&lt;/code&gt; as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bpxPlace&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;Next we do some logging and run the program.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// VirtualAlloc BP callback&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cbVirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetCAX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// auto x = GetFunctionParameter(DbgGetProcessHandle(), UE_FUNCTION_STDCALL_RET, 2, UE_PARAMETER_DWORD);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbgEval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;arg.get(1)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;_plugin_logprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGIN_NAME&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;] VirtualAlloc addr: %x&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_plugin_logprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGIN_NAME&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;] VirtualAlloc size: %x&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When reach the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc&lt;/code&gt; callback the allocated memory address would be stored at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EAX/RAX&lt;/code&gt;, we can use the scriptapi register function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetCAX&lt;/code&gt; to read this value (remember x64dbg provides special registers for architecture-independent code).&lt;/p&gt;

&lt;p&gt;To get the memory size stored at the second argument we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DbgEval&lt;/code&gt; to evaluate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arg.get(1)&lt;/code&gt; command and get its result.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// VirtualProtect BP callback&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cbVirtualProtect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Memory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReadWord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Check for MZ header&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x5a4d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_plugin_logprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGIN_NAME&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;] Found a PE file at addr: %x&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Build dumping path&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MAX_PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetMainModulePath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;memdump_%X_%zx_%zx.bin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getParentPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbgGetProcessId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Dump payload to disk&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DumpMemory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DbgGetProcessHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LPVOID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_plugin_logprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGIN_NAME&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;] Dumped payload at %s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;fail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Failed to dump the payload&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When we hit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualProtect&lt;/code&gt; we can read the first 2 bytes from the allocated memory address to check for the MZ header.&lt;/p&gt;

&lt;p&gt;To build a dumping path similar to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:memdump:&lt;/code&gt; from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;savedata&lt;/code&gt; command we need to get the current module path using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetMainModulePath&lt;/code&gt;, get the current process ID using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DbgGetProcessId&lt;/code&gt; and append the memory address and size to them.&lt;/p&gt;

&lt;p&gt;Finally to dump the payload to disk we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DumpMemory&lt;/code&gt; passing it the current process handle using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DbgGetProcessHandle&lt;/code&gt;, memory address, memory size and file path.&lt;/p&gt;

&lt;h2 id=&quot;trying-our-plugin&quot;&gt;Trying our plugin&lt;/h2&gt;

&lt;p&gt;After building the plugin we need to move the plugin files which end with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.dp32&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.dp64&lt;/code&gt; depending on the build configuration to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x64dbg\release\(x32|x64)\plugins&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To load the the plugin we can restart x64dbg and it will be loaded automatically or just use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loadplugin&lt;/code&gt; command passing it the plugin name like this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loadplugin EasyDump&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally we can run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EasyDump&lt;/code&gt; (the command we registered in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pluginInit&lt;/code&gt;) and watch the magic happen…again.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/x64dbg/plugins/2.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/x64dbg/plugins/2.png&quot; alt=&quot;2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;source code: &lt;a href=&quot;https://github.com/N1ght-W0lf/EasyDump&quot;&gt;https://github.com/N1ght-W0lf/EasyDump&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;updates&quot;&gt;Updates&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Some notes from &lt;a href=&quot;https://twitter.com/mrexodia&quot;&gt;Duncan Ogilvie @mrexodia&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

  &lt;p&gt;As a general rule I’d avoid using the TitanEngine APIs directly. They can cause some weird scenarios where x64dbg doesn’t know about a breakpoint for example. Unfortunately the plugin API isn’t very strong on this front though, so it’s a lot more work to do the same…&lt;/p&gt;

  &lt;p&gt;Also something worth exploring is the C# scripting plugin: &lt;a href=&quot;https://github.com/x64dbg/DotX64Dbg&quot;&gt;https://github.com/x64dbg/DotX64Dbg&lt;/a&gt;&lt;/p&gt;

  &lt;p&gt;And confusingly &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DbgCmdExec&lt;/code&gt; (queues a command asynchronously) causes a race condition in your example. Likely you want &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DbgCmdExecDirect&lt;/code&gt; instead (executed the implementation of the command directly)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;final-words&quot;&gt;Final words&lt;/h2&gt;

&lt;p&gt;The goal of this tutorial was to learn more about x64dbg not write the best dumping plugin :)&lt;/p&gt;

&lt;p&gt;This tutorial wouldn’t be possible without the help of the official x64dbg &lt;a href=&quot;https://help.x64dbg.com/&quot;&gt;docs&lt;/a&gt; and &lt;a href=&quot;https://x64dbg.com/blog/&quot;&gt;blog&lt;/a&gt;, you can check them out for more in depth info.&lt;/p&gt;

&lt;p&gt;You can also find many cool x64dbg plugins &lt;a href=&quot;https://github.com/x64dbg/x64dbg/wiki/Plugins&quot;&gt;here&lt;/a&gt; that can make your life easier.&lt;/p&gt;

&lt;p&gt;Special thanks to &lt;a href=&quot;https://twitter.com/mrexodia&quot;&gt;@mrexodia&lt;/a&gt; (creator of x64dbg and many other projects) for his awesome work, you can support him &lt;a href=&quot;https://github.com/sponsors/mrexodia&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hope you learned something new, until next time.&lt;/p&gt;</content><author><name>Abdallah Elshinbary</name></author><category term="Tutorials" /><summary type="html">In the previous post we talked about writing x64dbg scripts, now let’s dive deeper and write our own plugin to do the same job (automatically dumping unpacked PE payloads in memory). x64dbg comes with an integrated plugin SDK for creating plugins using C++. Setup The easiest way to create a plugin is to use the PluginTemplate to create a new repository for your plugin. Next you can edit cmake.toml which contains the project configuration, for this tutorial we will only change the name and target values to our plugin name. name = &quot;EasyDump&quot; .... [target.EasyDump] To build the project for 64-bit –&amp;gt; build64\ProjectName.sln cmake -B build64 -A x64 cmake --build build64 --config Release To build the project for 32-bit –&amp;gt; build32\ProjectName.sln cmake -B build32 -A Win32 cmake --build build32 --config Release Plugin structure A plugin must have an exported function called pluginit, this is the first function that gets called when the plugin is loaded and where the plugin data is initialized. Other optional exports are: plugstop: called when the plugin is about to be unloaded and where the plugin data cleanup occurs. plugsetup: called when the plugin initialization was successful, here you can register menus and other GUI-related things. SDK functions Before we go any further we need to know what functions exported by the plugin SDK we can use, you can find some of these functions in the official docs but many of them are not documented. To view the full list you can explore the SDK header files. For me plugin SDK functions are divided into 4 main categories: _plugin_ functions @_plugins.h: Helper functions for plugin setup, initialization and logging. bridge functions @bridgemain.h: Bridge is the communication library for the DBG and GUI part of x64dbg. scriptapi functions @_scriptapi_*.h: It is intended to be used by plugins. It provides easy scripting experience for developers. TitanEngine functions @TitanEngine.h: Titan is the debugging engine for x64dbg. Most functions are self explanatory or documented in the official docs, for TitanEngine functions you can find its docs here or you can check the markdown version for better readability I uploaded here. Ok enough talk let’s get our hands dirty. Implementation Your code should go into plugin.cpp file, let’s start with the plugin main components. // Initialize your plugin data here. bool pluginInit(PLUG_INITSTRUCT* initStruct) { _plugin_logputs(&quot;[&quot; PLUGIN_NAME &quot;] Loaded successfully!&quot;); if (!_plugin_registercommand(pluginHandle, &quot;EasyDump&quot;, cbEasyDump, true)) return fail(&quot;Failed to register command&quot;); return true; // Return false to cancel loading the plugin. } // Deinitialize your plugin data here. void pluginStop() { _plugin_unregistercommand(pluginHandle, &quot;EasyDump&quot;); } First we need to register a command that we can use in the command prompt using _plugin_registercommand function, The definition for this function is: bool _plugin_registercommand( int pluginHandle, // Plugin handle const char* command, // Command name CBPLUGINCOMMAND cbCommand, // Callback function bool debugonly // Restrict the command to debug-only ); And of course don’t forget to unregister this command inside pluginStop using _plugin_unregistercommand. Now let’s implement the callback function. static bool cbEasyDump(int argc, char* argv[]) { // Delete All BPs DbgCmdExec(&quot;bpc&quot;); // Set BP on VirtualAlloc ret if (!SetAPIBreakPoint(&quot;kernelbase.dll&quot;, &quot;VirtualAlloc&quot;, UE_BREAKPOINT, UE_APIEND, cbVirtualAlloc)) fail(&quot;Failed to set a Breakpoint on VirtualAlloc&quot;); // Set BP on VirtualProtect start if (!SetAPIBreakPoint(&quot;kernelbase.dll&quot;, &quot;VirtualProtect&quot;, UE_BREAKPOINT, UE_APISTART, cbVirtualProtect)) fail(&quot;Failed to set a Breakpoint on VirtualProtect&quot;); _plugin_logprint(&quot;[&quot; PLUGIN_NAME &quot;] Starting the program...\n&quot;); DbgCmdExec(&quot;run&quot;); return true; } Callback arguments are passed in argv starting at index 1, but our command doesn’t need any arguments. We will start with deleting all breakpoints to let the plugin run without interruption using DbgCmdExec to execute bpc command (breakpoint clear). Next we set our breakpoints using SetAPIBreakPoint function which is defined as: bool __stdcall SetAPIBreakPoint( char* szDLLName, // DLL name char* szAPIName, // API name DWORD bpxType, // UE_BREAKPOINT or UE_SINGLESHOOT DWORD bpxPlace, // UE_APISTART or UE_APIEND LPVOID bpxCallBack // Callback function ); For VirtualAlloc we need to set the breakpoint at return so we will use UE_APIEND as the bpxPlace value. Next we do some logging and run the program. // VirtualAlloc BP callback static void cbVirtualAlloc() { mem_addr = Script::Register::GetCAX(); // auto x = GetFunctionParameter(DbgGetProcessHandle(), UE_FUNCTION_STDCALL_RET, 2, UE_PARAMETER_DWORD); mem_size = DbgEval(&quot;arg.get(1)&quot;); _plugin_logprintf(&quot;[&quot; PLUGIN_NAME &quot;] VirtualAlloc addr: %x\n&quot;, mem_addr); _plugin_logprintf(&quot;[&quot; PLUGIN_NAME &quot;] VirtualAlloc size: %x\n&quot;, mem_size); } When reach the VirtualAlloc callback the allocated memory address would be stored at EAX/RAX, we can use the scriptapi register function GetCAX to read this value (remember x64dbg provides special registers for architecture-independent code). To get the memory size stored at the second argument we can use DbgEval to evaluate arg.get(1) command and get its result. // VirtualProtect BP callback static void cbVirtualProtect() { auto header = Script::Memory::ReadWord(mem_addr); // Check for MZ header if (header == 0x5a4d) { _plugin_logprintf(&quot;[&quot; PLUGIN_NAME &quot;] Found a PE file at addr: %x\n&quot;, mem_addr); // Build dumping path char path[MAX_PATH]; Script::Module::GetMainModulePath(path); sprintf(path, &quot;%s\\memdump_%X_%zx_%zx.bin&quot;, getParentPath(path), DbgGetProcessId(), mem_addr, mem_size); // Dump payload to disk if (DumpMemory(DbgGetProcessHandle(), (LPVOID)mem_addr, mem_size, path)) _plugin_logprintf(&quot;[&quot; PLUGIN_NAME &quot;] Dumped payload at %s\n&quot;, path); else fail(&quot;Failed to dump the payload&quot;); } } When we hit VirtualProtect we can read the first 2 bytes from the allocated memory address to check for the MZ header. To build a dumping path similar to :memdump: from savedata command we need to get the current module path using GetMainModulePath, get the current process ID using DbgGetProcessId and append the memory address and size to them. Finally to dump the payload to disk we can use DumpMemory passing it the current process handle using DbgGetProcessHandle, memory address, memory size and file path. Trying our plugin After building the plugin we need to move the plugin files which end with .dp32 or .dp64 depending on the build configuration to x64dbg\release\(x32|x64)\plugins. To load the the plugin we can restart x64dbg and it will be loaded automatically or just use loadplugin command passing it the plugin name like this loadplugin EasyDump. Finally we can run EasyDump (the command we registered in pluginInit) and watch the magic happen…again. source code: https://github.com/N1ght-W0lf/EasyDump Updates Some notes from Duncan Ogilvie @mrexodia As a general rule I’d avoid using the TitanEngine APIs directly. They can cause some weird scenarios where x64dbg doesn’t know about a breakpoint for example. Unfortunately the plugin API isn’t very strong on this front though, so it’s a lot more work to do the same… Also something worth exploring is the C# scripting plugin: https://github.com/x64dbg/DotX64Dbg And confusingly DbgCmdExec (queues a command asynchronously) causes a race condition in your example. Likely you want DbgCmdExecDirect instead (executed the implementation of the command directly) Final words The goal of this tutorial was to learn more about x64dbg not write the best dumping plugin :) This tutorial wouldn’t be possible without the help of the official x64dbg docs and blog, you can check them out for more in depth info. You can also find many cool x64dbg plugins here that can make your life easier. Special thanks to @mrexodia (creator of x64dbg and many other projects) for his awesome work, you can support him here. I hope you learned something new, until next time.</summary></entry><entry><title type="html">Writing x64dbg scripts</title><link href="https://n1ght-w0lf.github.io/tutorials/writing-x64dbg-scripts/" rel="alternate" type="text/html" title="Writing x64dbg scripts" /><published>2022-12-16T00:00:00+00:00</published><updated>2022-12-16T00:00:00+00:00</updated><id>https://n1ght-w0lf.github.io/tutorials/writing-x64dbg-scripts</id><content type="html" xml:base="https://n1ght-w0lf.github.io/tutorials/writing-x64dbg-scripts/">&lt;p&gt;x64dbg is an open-source x64/x32 debugger for windows, it has dozens of features that make the life of reverse engineers and malware analysts easier.&lt;/p&gt;

&lt;p&gt;One of the coolest features of x64dbg is that it’s extendable, it comes with a debuggable scripting language and a software development kit for writing your own plugins.&lt;/p&gt;

&lt;p&gt;In this post we will talk about x64dbg scripting and in the &lt;a href=&quot;https://n1ght-w0lf.github.io/tutorials/writing-x64dbg-plugins&quot;&gt;next one&lt;/a&gt; we will talk about plugins.&lt;/p&gt;

&lt;p&gt;Scripts are just a sequence of commands, you can see all the available commands &lt;a href=&quot;https://help.x64dbg.com/en/latest/commands/index.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To execute a command you can simply type it in the command prompt and check the result in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Log&lt;/code&gt; window.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/x64dbg/scripting/1.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/x64dbg/scripting/1.png&quot; alt=&quot;1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this tutorial we will write a simple script to automatically dump unpacked PE payloads in memory.&lt;/p&gt;

&lt;p&gt;The unpacking workflow (how I usually do it) is to set a breakpoint at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualProtect&lt;/code&gt;, run the program and follow the memory allocations in dump waiting for the MZ header to appear then dump that memory region. Let’s use the power of scripting to automate this process.&lt;/p&gt;

&lt;p&gt;First we will define two variables to hold the address and size of allocated memory regions using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;var&lt;/code&gt; command.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next we can set our breakpoints.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;bp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualAlloc&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SetBreakpointCommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;scriptcmd call cb_virtual_alloc&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;bp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualProtect&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SetBreakpointCommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualProtect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;scriptcmd call cb_virtual_protect&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetBreakpointCommand&lt;/code&gt; to set a command to execute when the breakpoint is hit.&lt;/p&gt;

&lt;p&gt;The command we need here is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt; which will jump to a callback function defined by a label, we also have to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scriptcmd&lt;/code&gt; to execute the call in the context of a running script (not in the context of the debugging loop).&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nl&quot;&gt;cb_virtual_alloc:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rtr&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cax&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Allocated memory address: {x:mem_addr}&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Allocated memory size: {x:mem_size}&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When we reach this callback we first need to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rtr&lt;/code&gt; command (run till return) to let &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc&lt;/code&gt; does the memory allocation.&lt;/p&gt;

&lt;p&gt;Next we can get the returned memory address stored at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eax/rax&lt;/code&gt; and store that value in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem_addr&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;x64dbg provides the following registers: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cax&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cbx&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ccx&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cdx&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;csp&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cbp&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;csi&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cdi&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cip&lt;/code&gt; which are mapped to 32-bit registers on a 32-bit platform, and to 64-bit registers on a 64-bit platform. This gives you the ability to write architecture-independent code, so we will use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cax&lt;/code&gt; to get the return value.&lt;/p&gt;

&lt;p&gt;As all good developers know the best debugging technique is print-based debugging :)&lt;/p&gt;

&lt;p&gt;So we can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;log&lt;/code&gt; command to print some logging messages.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;log&lt;/code&gt; command takes one argument which is a format string, you can read about the string formatter &lt;a href=&quot;https://help.x64dbg.com/en/latest/introduction/Formatting.html&quot;&gt;here&lt;/a&gt;. We only need the basic syntax which is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{?:expression}&lt;/code&gt; where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;?&lt;/code&gt; is the optional type of the expression (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; for hex value).&lt;/p&gt;

&lt;p&gt;Next we need to get the size of the allocated memory which is passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc&lt;/code&gt; as the second argument.&lt;/p&gt;

&lt;p&gt;To get an argument at a given index we can use the expression function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arg.get(index)&lt;/code&gt; which gets the argument at a given index (zero-based). Note that you should be inside the function boundaries to get the correct value.&lt;/p&gt;

&lt;p&gt;With that done let’s define the next callback.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nl&quot;&gt;cb_virtual_protect:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;New protection: {x:arg.get(2)}&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a4d&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;jne&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;savedata&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;memdump&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First we log the third argument of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualProtect&lt;/code&gt; which is the new memory protection, this can be used to check for protection changes which might indicate unpacking but we won’t use it here.&lt;/p&gt;

&lt;p&gt;Next we use another expression function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;word&lt;/code&gt; to read the first 2 bytes from the previously allocated memory address and compare them to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x5a4d&lt;/code&gt; (the MZ header). Note that all numbers are interpreted as hex by default.&lt;/p&gt;

&lt;p&gt;If the check is false we jump to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; label and continue execution, if not we save that memory region to disk.&lt;/p&gt;

&lt;p&gt;The first argument of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;savedata&lt;/code&gt; command is the filename, if we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:memdump:&lt;/code&gt; as a name it will save the file as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memdump_pid_addr_size.bin&lt;/code&gt; in the x64dbg directory.&lt;/p&gt;

&lt;p&gt;Finally we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run&lt;/code&gt; command to run the program and watch the magic happen. you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tab&lt;/code&gt; to step into the script or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Space&lt;/code&gt; to run the script.&lt;/p&gt;

&lt;video src=&quot;https://user-images.githubusercontent.com/58216643/208249322-502985c8-fb2a-4571-af57-a39b0b44eca8.mp4&quot; controls=&quot;controls&quot; style=&quot;max-width: 730px;&quot;&gt;&lt;/video&gt;

&lt;p&gt;Simple as that.&lt;/p&gt;

&lt;p&gt;Full script:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// define a variable to hold allocated mem address&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// define a variable to hold allocated mem size&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// set breakpoint on VirtualAlloc&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualAlloc&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// set callback on breakpoint hit&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SetBreakpointCommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualAlloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;scriptcmd call cb_virtual_alloc&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// set breakpoint on VirtualProtect&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualProtect&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// set callback on breakpoint hit&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SetBreakpointCommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualProtect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;scriptcmd call cb_virtual_protect&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// go to main label&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// define VirtualAlloc callback label&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cb_virtual_alloc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// run until return (stepout)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rtr&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// set mem_addr value to cax value (return value)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cax&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// log memory address&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Allocated memory address: {x:mem_addr}&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// set mem_size value to VirtualAlloc's second arg value (region size)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// log memory size&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Allocated memory size: {x:mem_size}&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// go to main label&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// define VirtualProtect callback label&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cb_virtual_protect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// log VirtualProtect's second arg value (new protection)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;New protection: {x:arg.get(2)}&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// compare the first 2 bytes at mem_addr address to &quot;MZ&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a4d&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// if not equal, jump to main label&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;jne&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// dump data at mem_addr address to disk&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;savedata&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;memdump&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// define main label&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// run the program&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// end the script&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Abdallah Elshinbary</name></author><category term="Tutorials" /><summary type="html">x64dbg is an open-source x64/x32 debugger for windows, it has dozens of features that make the life of reverse engineers and malware analysts easier. One of the coolest features of x64dbg is that it’s extendable, it comes with a debuggable scripting language and a software development kit for writing your own plugins. In this post we will talk about x64dbg scripting and in the next one we will talk about plugins. Scripts are just a sequence of commands, you can see all the available commands here. To execute a command you can simply type it in the command prompt and check the result in the Log window. For this tutorial we will write a simple script to automatically dump unpacked PE payloads in memory. The unpacking workflow (how I usually do it) is to set a breakpoint at VirtualAlloc and VirtualProtect, run the program and follow the memory allocations in dump waiting for the MZ header to appear then dump that memory region. Let’s use the power of scripting to automate this process. First we will define two variables to hold the address and size of allocated memory regions using var command. var mem_addr var mem_size Next we can set our breakpoints. bp VirtualAlloc SetBreakpointCommand VirtualAlloc, &quot;scriptcmd call cb_virtual_alloc&quot; bp VirtualProtect SetBreakpointCommand VirtualProtect, &quot;scriptcmd call cb_virtual_protect&quot; We can use SetBreakpointCommand to set a command to execute when the breakpoint is hit. The command we need here is call which will jump to a callback function defined by a label, we also have to use scriptcmd to execute the call in the context of a running script (not in the context of the debugging loop). cb_virtual_alloc: rtr set mem_addr, cax log &quot;Allocated memory address: {x:mem_addr}&quot; set mem_size, arg.get(1) log &quot;Allocated memory size: {x:mem_size}&quot; When we reach this callback we first need to use rtr command (run till return) to let VirtualAlloc does the memory allocation. Next we can get the returned memory address stored at eax/rax and store that value in mem_addr variable. x64dbg provides the following registers: cax , cbx , ccx , cdx , csp , cbp , csi , cdi , cip which are mapped to 32-bit registers on a 32-bit platform, and to 64-bit registers on a 64-bit platform. This gives you the ability to write architecture-independent code, so we will use cax to get the return value. As all good developers know the best debugging technique is print-based debugging :) So we can use the log command to print some logging messages. The log command takes one argument which is a format string, you can read about the string formatter here. We only need the basic syntax which is {?:expression} where ? is the optional type of the expression (x for hex value). Next we need to get the size of the allocated memory which is passed to VirtualAlloc as the second argument. To get an argument at a given index we can use the expression function arg.get(index) which gets the argument at a given index (zero-based). Note that you should be inside the function boundaries to get the correct value. With that done let’s define the next callback. cb_virtual_protect: log &quot;New protection: {x:arg.get(2)}&quot; cmp word(mem_addr), 5a4d jne main savedata :memdump:, mem_addr, mem_size First we log the third argument of VirtualProtect which is the new memory protection, this can be used to check for protection changes which might indicate unpacking but we won’t use it here. Next we use another expression function word to read the first 2 bytes from the previously allocated memory address and compare them to 0x5a4d (the MZ header). Note that all numbers are interpreted as hex by default. If the check is false we jump to the main label and continue execution, if not we save that memory region to disk. The first argument of savedata command is the filename, if we use :memdump: as a name it will save the file as memdump_pid_addr_size.bin in the x64dbg directory. Finally we use run command to run the program and watch the magic happen. you can use Tab to step into the script or Space to run the script. Simple as that. Full script: // define a variable to hold allocated mem address var mem_addr // define a variable to hold allocated mem size var mem_size // set breakpoint on VirtualAlloc bp VirtualAlloc // set callback on breakpoint hit SetBreakpointCommand VirtualAlloc, &quot;scriptcmd call cb_virtual_alloc&quot; // set breakpoint on VirtualProtect bp VirtualProtect // set callback on breakpoint hit SetBreakpointCommand VirtualProtect, &quot;scriptcmd call cb_virtual_protect&quot; // go to main label goto main // define VirtualAlloc callback label cb_virtual_alloc: // run until return (stepout) rtr // set mem_addr value to cax value (return value) set mem_addr, cax // log memory address log &quot;Allocated memory address: {x:mem_addr}&quot; // set mem_size value to VirtualAlloc's second arg value (region size) set mem_size, arg.get(1) // log memory size log &quot;Allocated memory size: {x:mem_size}&quot; // go to main label goto main // define VirtualProtect callback label cb_virtual_protect: // log VirtualProtect's second arg value (new protection) log &quot;New protection: {x:arg.get(2)}&quot; // compare the first 2 bytes at mem_addr address to &quot;MZ&quot; cmp word(mem_addr), 5a4d // if not equal, jump to main label jne main // dump data at mem_addr address to disk savedata :memdump:, mem_addr, mem_size // define main label main: // run the program run // end the script ret</summary></entry><entry><title type="html">YARA for config extraction</title><link href="https://n1ght-w0lf.github.io/tutorials/yara-for-config-extraction/" rel="alternate" type="text/html" title="YARA for config extraction" /><published>2022-08-08T00:00:00+00:00</published><updated>2022-08-08T00:00:00+00:00</updated><id>https://n1ght-w0lf.github.io/tutorials/yara-for-config-extraction</id><content type="html" xml:base="https://n1ght-w0lf.github.io/tutorials/yara-for-config-extraction/">&lt;p&gt;YARA is a tool aimed at helping malware researchers to identify and classify malware samples. It’s considered to be the pattern matching swiss knife for malware researchers.&lt;/p&gt;

&lt;p&gt;If you are not familiar with writing YARA rules, the &lt;a href=&quot;https://yara.readthedocs.io/en/stable/index.html&quot;&gt;official docs&lt;/a&gt; would be a great start.&lt;/p&gt;

&lt;p&gt;In this blog I will go through how YARA rules can be used for malware config extraction.&lt;/p&gt;

&lt;p&gt;YARA has come a long way since its original release and it now has some awesome modules for writing better and more complex rules.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-yara-module&quot;&gt;What is a YARA module&lt;/h2&gt;

&lt;p&gt;A YARA module is like a plugin for extending YARA features, it allows you to define data structures and functions which can be used in your rules.&lt;/p&gt;

&lt;p&gt;To use a YARA module you simply import it using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import &quot;module_name&quot;&lt;/code&gt;, you can refer to the docs to learn about the available functions of each module.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;pe&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;pe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number_of_sections&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With that said let’s now jump into malware land, I will demonstrate on two variants of &lt;a href=&quot;https://malpedia.caad.fkie.fraunhofer.de/details/win.redline_stealer&quot;&gt;RedLine Stealer&lt;/a&gt; which is a very popular dotnet stealer.&lt;/p&gt;

&lt;h2 id=&quot;redline-stealer-variant1&quot;&gt;RedLine Stealer Variant1&lt;/h2&gt;

&lt;p&gt;The first variant stores the config in plaintext, we are only interested in two fields (C2 and BotnetID).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/1.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/1.png&quot; alt=&quot;1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To read these fields we need to understand how &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldstr?view=net-6.0&quot;&gt;ldstr&lt;/a&gt; instruction works. The instruction’s opcode is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x72&lt;/code&gt; followed by 4 bytes which represent the string token.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A token is a DWORD value that represents a table and an index into that table. For example, the EntryPointToken 0x0600002C, references table 0x06 (MethodDef) and its row 0x2C. The table index is 1 byte and the row index is 3 bytes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the following instruction for example, the string token is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x7000067B&lt;/code&gt; (little-endian) and the row index is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x67B&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;727B060070   // ldstr &quot;87.251.71.4:80&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet&lt;/code&gt; module already has the functionality to retrieve all user strings from a dotnet sample.&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Test&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number_of_user_strings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/2.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/2.png&quot; alt=&quot;2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Notice that I used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt; to remove null characters because dotnet user strings are stored as an array of unicode strings.&lt;/p&gt;

&lt;/blockquote&gt;

&lt;p&gt;This is cool but we need to get the user strings using the row index from the string token.&lt;/p&gt;

&lt;p&gt;To achieve this we need to make a couple of changes to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet&lt;/code&gt; module source file at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libyara/modules/dotnet/dotnet.c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/3.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/3.png&quot; alt=&quot;3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/4.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/4.png&quot; alt=&quot;4&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will index the user strings array by row index (offset from the start of the strings table).&lt;/p&gt;

&lt;p&gt;To compile and install yara you need to run these two scripts for the first time only:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ./bootstrap.sh
$ ./configure
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then you build YARA with your changes:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ make
$ sudo make install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can now write a simple rule to read the config fields.&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Redline&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;$get_conf_v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0000: ldstr     &quot;87.251.71.4:80&quot;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0005: stsfld    &amp;lt;IP&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_000A: ldstr     &quot;lyla&quot;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_000F: stsfld    &amp;lt;ID&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0014: ldstr     &quot;&quot;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0019: call      set_Message(string)&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;A&lt;/span&gt;                  &lt;span class=&quot;c1&quot;&gt;// IL_001E: ret&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nl&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;$get_conf_v1&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[+] C2: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;get_conf_v1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xffffff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[+] Botnet: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;get_conf_v1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xffffff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@get_conf_v1&lt;/code&gt;: address of the first match of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$get_conf_v1&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int32&lt;/code&gt;: reads 4 bytes (string token) from an offset, I used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xffffff&lt;/code&gt; bit mask to only get the row index.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/5.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/5.png&quot; alt=&quot;5&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool, Let’s move to the second variant.&lt;/p&gt;

&lt;h2 id=&quot;redline-stealer-variant2&quot;&gt;RedLine Stealer Variant2&lt;/h2&gt;

&lt;p&gt;This variant stores the config in an encrypted form.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/6.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/6.png&quot; alt=&quot;6&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The decryption algorithm looks as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/7.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/7.png&quot; alt=&quot;7&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Currently YARA doesn’t have a module to do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base64&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xor&lt;/code&gt; operations in conditions, so why not write our own module :)&lt;/p&gt;

&lt;h2 id=&quot;writing-our-own-yara-module&quot;&gt;Writing our own YARA module&lt;/h2&gt;

&lt;p&gt;Modules are written in C and built into YARA as part of the compiling process.&lt;/p&gt;

&lt;p&gt;I will explain briefly how to write a YARA module, for more details refer to the &lt;a href=&quot;https://yara.readthedocs.io/en/stable/writingmodules.html&quot;&gt;official docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;YARA modules reside in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libyara/modules&lt;/code&gt;, it’s recommended to use the module name as the file name for the source file. Here I created a new module directory named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malutils&lt;/code&gt; and inside it is the source file named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malutils.c&lt;/code&gt;, now let’s go through the source code.&lt;/p&gt;

&lt;p&gt;First we need to include the required headers to be able to use YARA’s module API.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/8.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/8.png&quot; alt=&quot;8&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next we define the required functions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Xor decryption function which takes a buffer and a key and returns the decrypted string buffer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/9.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/9.png&quot; alt=&quot;9&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Base64 decoding function which takes a base64 encoded string and returns the decoded value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/10.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/10.png&quot; alt=&quot;10&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Helper function to convert dotnet user strings from wide to ascii.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/11.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/11.png&quot; alt=&quot;11&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then comes the declaration section where we declare the functions and data structures that will be available for our YARA rules.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/12.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/12.png&quot; alt=&quot;12&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that we have 2 pairs of functions, the first pair is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;module_initialize&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;module_finalize&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These functions allow you to initialize and finalize any global data structure you may need to use in your module, and both functions are invoked whether or not the module is being imported by some rule.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/13.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/13.png&quot; alt=&quot;13&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second pair is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;module_load&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;module_unload&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;module_load&lt;/code&gt; function is invoked once for each scanned file (only if the module is imported in your rule). It’s is where your module can inspect the file being scanned, parse or analyze it in the way preferred, and then populate the data structures defined in the declarations section.&lt;/p&gt;

&lt;p&gt;For each call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;module_load&lt;/code&gt; there is a corresponding call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;module_unload&lt;/code&gt;. This function allows your module to free any resource allocated during &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;module_load&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/14.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/14.png&quot; alt=&quot;14&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;final-touches&quot;&gt;Final Touches&lt;/h2&gt;

&lt;p&gt;Before we test our module there’s a nasty bug we need to take care of.&lt;/p&gt;

&lt;p&gt;When writing a YARA module, instead of using the C &lt;em&gt;return&lt;/em&gt; statement in your declared functions you must use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return_string(x)&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return_integer(x)&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return_float(x)&lt;/code&gt; to return from a function.&lt;/p&gt;

&lt;p&gt;The problem occurs when we return from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base64d&lt;/code&gt; function, the decoded string might contain null bytes so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return_string&lt;/code&gt; won’t return the full buffer.&lt;/p&gt;

&lt;p&gt;As you can see below, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return_string&lt;/code&gt; uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strlen&lt;/code&gt; to determine the length of the returned string so it will stop at the first null byte.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/15.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/15.png&quot; alt=&quot;15&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a workaround, I defined a new return macro called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return_sized_string&lt;/code&gt; which enables us to set the length of the returned string rather than relying on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strlen&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/16.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/16.png&quot; alt=&quot;16&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;building-our-module&quot;&gt;Building our module&lt;/h2&gt;

&lt;p&gt;To include our module in the compiling process of YARA we must follow two further steps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add our module name to the module_list at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libyara/modules/module_list&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;MODULE(malutils)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Add our module source file to the must compiled modules at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libyara/Makefile.am&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;MODULES += modules/malutils/malutils.c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally we build YARA with our module:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ make
$ sudo make install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With everything in place, let’s now test our module.&lt;/p&gt;

&lt;h2 id=&quot;testing-our-module&quot;&gt;Testing our module&lt;/h2&gt;

&lt;p&gt;Below is the final YARA rule that handles both RedLine variants.&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Redline&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;2022-08-08&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Abdallah 'n1ghtw0lf' Elshinbary&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Extracts Redline config (educational)&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;$get_conf_v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0000: ldstr     &quot;87.251.71.4:80&quot;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0005: stsfld    &amp;lt;IP&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_000A: ldstr     &quot;lyla&quot;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_000F: stsfld    &amp;lt;ID&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0014: ldstr     &quot;&quot;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0019: call      set_Message(string)&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;A&lt;/span&gt;                  &lt;span class=&quot;c1&quot;&gt;// IL_001E: ret&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;$get_conf_v2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0000: ldstr     &quot;CyYOXysPAwUnB1NQCxtdWioxKUInBC5QCDNUUw==&quot;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0005: stsfld    &amp;lt;IP&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_000A: ldstr     &quot;FzcNJDEOEDw7O1Y/FEM/IQ==&quot;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_000F: stsfld    &amp;lt;ID&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0014: ldstr     &quot;&quot;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0019: stsfld    &amp;lt;Message&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_001E: ldstr     &quot;Baying&quot;&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// IL_0023: stsfld    &amp;lt;Key&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nl&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is_dotnet&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;and&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;$get_conf_v1&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[+] C2: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wtoa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;get_conf_v1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xffffff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[+] Botnet: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wtoa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;get_conf_v1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xffffff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;or&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;$get_conf_v2&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[+] C2: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;base64d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;xord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                  &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;base64d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wtoa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;get_conf_v2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xffffff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// enc c2&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wtoa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;get_conf_v2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xffffff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// xor key&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[+] Botnet: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;base64d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;xord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                  &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;base64d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wtoa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;get_conf_v2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xffffff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// enc botnet&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wtoa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;get_conf_v2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xffffff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// xor key&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[+] Key: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;malutils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wtoa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(@&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;get_conf_v2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xffffff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Running the rule on a list of samples produces the following output:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/yara/17.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/yara/17.png&quot; alt=&quot;17&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Beautiful right!&lt;/p&gt;

&lt;p&gt;You can pull the code and try it yourself at 
&lt;a href=&quot;https://github.com/N1ght-W0lf/yara/tree/malutils&quot;&gt;https://github.com/N1ght-W0lf/yara/tree/malutils&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It was just for learning purposes so not the best code :)&lt;/p&gt;

&lt;h2 id=&quot;samples&quot;&gt;Samples&lt;/h2&gt;

&lt;p&gt;fed976b2d134008fd6daec8edc00099935df756beb721034f71db33e4d675a6e
e4f7246b103d9bda3a7604bea12dc5ac1064764c0f3691617c9829c4e5d469b5
2d3503d8540e319851a67e55f06ed9e5ba060e821eec6dbc83960a5947ad1310
a8c498f5129af0229081edf1e535ac9dab6ad568befcbcecbfc7cc4c61e0a8eb
c19938f0b9648dc1f6b95d0e767164da832b9a92f8128ab47dcb81c5e1ceb31a
e94d48e09cace8937941fbf81d1a466fa2b2b6acfd0d6142fc3443c70e067294
f343005539a589ec5512559e0bdc824c1069196ae39d519e5b1f3257f4a6660b&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://yara.readthedocs.io/en/stable/index.html&quot;&gt;https://yara.readthedocs.io/en/stable/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.ntcore.com/files/dotnetformat.htm&quot;&gt;https://www.ntcore.com/files/dotnetformat.htm&lt;/a&gt;&lt;/p&gt;</content><author><name>Abdallah Elshinbary</name></author><category term="Tutorials" /><summary type="html">YARA is a tool aimed at helping malware researchers to identify and classify malware samples. It’s considered to be the pattern matching swiss knife for malware researchers. If you are not familiar with writing YARA rules, the official docs would be a great start. In this blog I will go through how YARA rules can be used for malware config extraction. YARA has come a long way since its original release and it now has some awesome modules for writing better and more complex rules. What is a YARA module A YARA module is like a plugin for extending YARA features, it allows you to define data structures and functions which can be used in your rules. To use a YARA module you simply import it using import &quot;module_name&quot;, you can refer to the docs to learn about the available functions of each module. Example: import &quot;pe&quot; rule test { condition: pe.number_of_sections == 1 } With that said let’s now jump into malware land, I will demonstrate on two variants of RedLine Stealer which is a very popular dotnet stealer. RedLine Stealer Variant1 The first variant stores the config in plaintext, we are only interested in two fields (C2 and BotnetID). To read these fields we need to understand how ldstr instruction works. The instruction’s opcode is 0x72 followed by 4 bytes which represent the string token. A token is a DWORD value that represents a table and an index into that table. For example, the EntryPointToken 0x0600002C, references table 0x06 (MethodDef) and its row 0x2C. The table index is 1 byte and the row index is 3 bytes. In the following instruction for example, the string token is 0x7000067B (little-endian) and the row index is 0x67B. 727B060070 // ldstr &quot;87.251.71.4:80&quot; The dotnet module already has the functionality to retrieve all user strings from a dotnet sample. import &quot;dotnet&quot; import &quot;console&quot; rule Test { condition: for all i in (0..dotnet.number_of_user_strings-1): ( console.log(dotnet.user_strings[i]) ) } Notice that I used sed to remove null characters because dotnet user strings are stored as an array of unicode strings. This is cool but we need to get the user strings using the row index from the string token. To achieve this we need to make a couple of changes to the dotnet module source file at libyara/modules/dotnet/dotnet.c. This will index the user strings array by row index (offset from the start of the strings table). To compile and install yara you need to run these two scripts for the first time only: $ ./bootstrap.sh $ ./configure Then you build YARA with your changes: $ make $ sudo make install We can now write a simple rule to read the config fields. import &quot;dotnet&quot; import &quot;console&quot; rule Redline { strings: $get_conf_v1 = { 72 ?? ?? ?? 70 // IL_0000: ldstr &quot;87.251.71.4:80&quot; 80 ?? ?? ?? 04 // IL_0005: stsfld &amp;lt;IP&amp;gt; 72 ?? ?? ?? 70 // IL_000A: ldstr &quot;lyla&quot; 80 ?? ?? ?? 04 // IL_000F: stsfld &amp;lt;ID&amp;gt; 72 ?? ?? ?? 70 // IL_0014: ldstr &quot;&quot; 28 ?? ?? ?? ?? // IL_0019: call set_Message(string) 2A // IL_001E: ret } condition: $get_conf_v1 and console.log(&quot;[+] C2: &quot;, dotnet.user_strings[int32(@get_conf_v1+1) &amp;amp; 0xffffff] ) and console.log(&quot;[+] Botnet: &quot;, dotnet.user_strings[int32(@get_conf_v1+11) &amp;amp; 0xffffff] ) } @get_conf_v1: address of the first match of $get_conf_v1 int32: reads 4 bytes (string token) from an offset, I used 0xffffff bit mask to only get the row index. Cool, Let’s move to the second variant. RedLine Stealer Variant2 This variant stores the config in an encrypted form. The decryption algorithm looks as follows: Currently YARA doesn’t have a module to do base64 and xor operations in conditions, so why not write our own module :) Writing our own YARA module Modules are written in C and built into YARA as part of the compiling process. I will explain briefly how to write a YARA module, for more details refer to the official docs. YARA modules reside in libyara/modules, it’s recommended to use the module name as the file name for the source file. Here I created a new module directory named malutils and inside it is the source file named malutils.c, now let’s go through the source code. First we need to include the required headers to be able to use YARA’s module API. Next we define the required functions: Xor decryption function which takes a buffer and a key and returns the decrypted string buffer. Base64 decoding function which takes a base64 encoded string and returns the decoded value. Helper function to convert dotnet user strings from wide to ascii. Then comes the declaration section where we declare the functions and data structures that will be available for our YARA rules. After that we have 2 pairs of functions, the first pair is module_initialize &amp;amp; module_finalize. These functions allow you to initialize and finalize any global data structure you may need to use in your module, and both functions are invoked whether or not the module is being imported by some rule. The second pair is module_load &amp;amp; module_unload. The module_load function is invoked once for each scanned file (only if the module is imported in your rule). It’s is where your module can inspect the file being scanned, parse or analyze it in the way preferred, and then populate the data structures defined in the declarations section. For each call to module_load there is a corresponding call to module_unload. This function allows your module to free any resource allocated during module_load. Final Touches Before we test our module there’s a nasty bug we need to take care of. When writing a YARA module, instead of using the C return statement in your declared functions you must use return_string(x), return_integer(x) or return_float(x) to return from a function. The problem occurs when we return from base64d function, the decoded string might contain null bytes so return_string won’t return the full buffer. As you can see below, return_string uses strlen to determine the length of the returned string so it will stop at the first null byte. As a workaround, I defined a new return macro called return_sized_string which enables us to set the length of the returned string rather than relying on strlen. Building our module To include our module in the compiling process of YARA we must follow two further steps: Add our module name to the module_list at libyara/modules/module_list MODULE(malutils) Add our module source file to the must compiled modules at libyara/Makefile.am MODULES += modules/malutils/malutils.c Finally we build YARA with our module: $ make $ sudo make install With everything in place, let’s now test our module. Testing our module Below is the final YARA rule that handles both RedLine variants. import &quot;dotnet&quot; import &quot;console&quot; import &quot;malutils&quot; rule Redline { meta: date = &quot;2022-08-08&quot; author = &quot;Abdallah 'n1ghtw0lf' Elshinbary&quot; description = &quot;Extracts Redline config (educational)&quot; strings: $get_conf_v1 = { 72 ?? ?? ?? 70 // IL_0000: ldstr &quot;87.251.71.4:80&quot; 80 ?? ?? ?? 04 // IL_0005: stsfld &amp;lt;IP&amp;gt; 72 ?? ?? ?? 70 // IL_000A: ldstr &quot;lyla&quot; 80 ?? ?? ?? 04 // IL_000F: stsfld &amp;lt;ID&amp;gt; 72 ?? ?? ?? 70 // IL_0014: ldstr &quot;&quot; 28 ?? ?? ?? ?? // IL_0019: call set_Message(string) 2A // IL_001E: ret } $get_conf_v2 = { 72 ?? ?? ?? 70 // IL_0000: ldstr &quot;CyYOXysPAwUnB1NQCxtdWioxKUInBC5QCDNUUw==&quot; 80 ?? ?? ?? 04 // IL_0005: stsfld &amp;lt;IP&amp;gt; 72 ?? ?? ?? 70 // IL_000A: ldstr &quot;FzcNJDEOEDw7O1Y/FEM/IQ==&quot; 80 ?? ?? ?? 04 // IL_000F: stsfld &amp;lt;ID&amp;gt; 72 ?? ?? ?? 70 // IL_0014: ldstr &quot;&quot; 80 ?? ?? ?? 04 // IL_0019: stsfld &amp;lt;Message&amp;gt; 72 ?? ?? ?? 70 // IL_001E: ldstr &quot;Baying&quot; 80 ?? ?? ?? 04 // IL_0023: stsfld &amp;lt;Key&amp;gt; } condition: dotnet.is_dotnet and ( ( $get_conf_v1 and console.log(&quot;[+] C2: &quot;, malutils.wtoa(dotnet.user_strings[int32(@get_conf_v1+1) &amp;amp; 0xffffff]) ) and console.log(&quot;[+] Botnet: &quot;, malutils.wtoa(dotnet.user_strings[int32(@get_conf_v1+11) &amp;amp; 0xffffff]) ) ) or ( $get_conf_v2 and console.log(&quot;[+] C2: &quot;, malutils.base64d( malutils.xord( malutils.base64d( malutils.wtoa(dotnet.user_strings[int32(@get_conf_v2+1) &amp;amp; 0xffffff]) // enc c2 ), malutils.wtoa(dotnet.user_strings[int32(@get_conf_v2+31) &amp;amp; 0xffffff]) // xor key ) ) ) and console.log(&quot;[+] Botnet: &quot;, malutils.base64d( malutils.xord( malutils.base64d( malutils.wtoa(dotnet.user_strings[int32(@get_conf_v2+11) &amp;amp; 0xffffff]) // enc botnet ), malutils.wtoa(dotnet.user_strings[int32(@get_conf_v2+31) &amp;amp; 0xffffff]) // xor key ) ) ) and console.log(&quot;[+] Key: &quot;, malutils.wtoa(dotnet.user_strings[int32(@get_conf_v2+31) &amp;amp; 0xffffff]) ) ) ) } Running the rule on a list of samples produces the following output: Beautiful right! You can pull the code and try it yourself at https://github.com/N1ght-W0lf/yara/tree/malutils. It was just for learning purposes so not the best code :) Samples fed976b2d134008fd6daec8edc00099935df756beb721034f71db33e4d675a6e e4f7246b103d9bda3a7604bea12dc5ac1064764c0f3691617c9829c4e5d469b5 2d3503d8540e319851a67e55f06ed9e5ba060e821eec6dbc83960a5947ad1310 a8c498f5129af0229081edf1e535ac9dab6ad568befcbcecbfc7cc4c61e0a8eb c19938f0b9648dc1f6b95d0e767164da832b9a92f8128ab47dcb81c5e1ceb31a e94d48e09cace8937941fbf81d1a466fa2b2b6acfd0d6142fc3443c70e067294 f343005539a589ec5512559e0bdc824c1069196ae39d519e5b1f3257f4a6660b References https://yara.readthedocs.io/en/stable/index.html https://www.ntcore.com/files/dotnetformat.htm</summary></entry><entry><title type="html">Qiling For Malware Analysis: Part 1</title><link href="https://n1ght-w0lf.github.io/tutorials/qiling-for-malware-analysis-part-1/" rel="alternate" type="text/html" title="Qiling For Malware Analysis: Part 1" /><published>2020-07-25T00:00:00+00:00</published><updated>2020-07-25T00:00:00+00:00</updated><id>https://n1ght-w0lf.github.io/tutorials/qiling-for-malware-analysis-part-1</id><content type="html" xml:base="https://n1ght-w0lf.github.io/tutorials/qiling-for-malware-analysis-part-1/">&lt;h1 id=&quot;background&quot;&gt;Background&lt;/h1&gt;

&lt;p&gt;Qiling is an advanced binary emulation framework written in python and based on Unicorn engine.&lt;/p&gt;

&lt;p&gt;It supports multiple platform (Windows, MacOS, Linux, BSD, UEFI) and multiple architectures (X86, X86_64, Arm, Arm64, MIPS).&lt;/p&gt;

&lt;p&gt;Qiling is designed as a higher level framework, that leverages Unicorn  to emulate CPU instructions, but Qiling understands OS as it has executable format loaders (for PE, MachO &amp;amp; ELF at the moment), dynamic linkers (so we can load &amp;amp; relocate shared libraries), syscall &amp;amp; IO handlers. For this reason, Qiling can run executable binaries that normally runs in native OS.&lt;/p&gt;

&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;/h1&gt;

&lt;p&gt;Due to distribution restrictions, Qiling doesn’t bundle Microsoft Windows DLL files and registry.&lt;/p&gt;

&lt;p&gt;So for smooth installation, jump to a 64-bit windows machine and execute the following:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clone&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;https&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qilingframework&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qiling&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qiling&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;examples&lt;/span&gt;\&lt;span class=&quot;n&quot;&gt;scripts&lt;/span&gt;\&lt;span class=&quot;n&quot;&gt;dllscollector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bat&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# DLLs collector (requires admin privileges)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Sometimes the emulated program requires additional DLLs, you can copy them manually to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;qiling/examples/rootfs/x8664_windows/Windows/System32&quot;&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;qiling/examples/rootfs/x86_windows/Windows/SysWOW64/&quot;&lt;/code&gt; depending on the program architecture.&lt;/p&gt;

&lt;p&gt;Now you can copy &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;qiling&quot;&lt;/code&gt; folder to any machine you want (Windows, Linux, …) and complete the installation.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;pip3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requirements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txt&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# sudo for Linux
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;python3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# sudo for Linux
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;emulating-a-file&quot;&gt;Emulating a File&lt;/h1&gt;

&lt;p&gt;Emulating a binary file is as simple as that:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# initialize emulator (x86-64 linux)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qiling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;qiling/examples/rootfs/x8664_linux/bin/x8664_hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;rootfs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;qiling/examples/rootfs/x8664_linux&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# start emulation
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Qiling initialization &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constructor&lt;/code&gt; can take multiple arguments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filename&lt;/code&gt;&lt;/strong&gt;: binary file and its arguments, example: filename=[“test”,”-argv1”,”argv2”]&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rootfs&lt;/code&gt;&lt;/strong&gt;: virtual “/” folder, this is a “jail” file system when executing Qiling (target architecture)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env&lt;/code&gt;&lt;/strong&gt;: environment variables, example: env={“SHELL”:”/bin/bash”,”HOME”:”/tmp”}&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;output&lt;/code&gt;&lt;/strong&gt;: “default”, “debug”, “disasm”, “dump” where dump=(disam + debug)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run()&lt;/code&gt; function can also take multiple arguments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;begin&lt;/code&gt;&lt;/strong&gt;: start address of emulated code&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;end&lt;/code&gt;&lt;/strong&gt;: end address of emulated code&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;timeout&lt;/code&gt;&lt;/strong&gt;: emulation timeout (in microseconds)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;count&lt;/code&gt;&lt;/strong&gt;: maximum instruction count to be emulated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let’s run our first script:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;........
brk(0x0)
brk(0x555555779000)
write(1,555555758260,14) = 0
Hello, World!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, Qiling outputs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strace&lt;/code&gt; logs by default. You can disable them using filters.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# disable strace logs
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# display only &quot;open&quot; logs
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;open&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;emulating-a-shellcode&quot;&gt;Emulating a Shellcode&lt;/h1&gt;

&lt;p&gt;To keep things simple, we will use this tiny shellcode:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;shellcode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x41\x4a&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# inc ecx; dec edx
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, let’s initialize Qiling.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# initialize emulator (x86 linux)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qiling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shellcoder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shellcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;rootfs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;qiling/examples/rootfs/x86_linux/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;ostype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;linux&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;archtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x86&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;disasm&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Emulating shellcode is a little different than binary files, the initialization &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constructor&lt;/code&gt; takes additional arguments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shellcoder&lt;/code&gt;&lt;/strong&gt;: shellcode in binary format&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rootfs&lt;/code&gt;&lt;/strong&gt;: explained above&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env&lt;/code&gt;&lt;/strong&gt;: explained above&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ostype&lt;/code&gt;&lt;/strong&gt;: “linux”, “macos”, “windows”, “uefi”, “freebsd”&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;archtype&lt;/code&gt;&lt;/strong&gt;: “x8664”, “x86”, “arm”, “arm64”, “mips”&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;output&lt;/code&gt;&lt;/strong&gt;: explained above&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here we set the output to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;disasm&quot;&lt;/code&gt; to see the executed instructions.&lt;/p&gt;

&lt;p&gt;The shellcode modifies the values of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ECX&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EDX&lt;/code&gt; registers, so let’s write some values to them before emulating.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# set machine registers
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ecx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x3&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;edx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x7&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# start emulation
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# read machine registers
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ecx = 0x{:x}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ecx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;edx = 0x{:x}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;edx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s see the results:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[+] 0x11ff000      41          inc ecx
[+] 0x11ff001      4a          dec edx
ecx = 0x4
edx = 0x6
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;hooking&quot;&gt;Hooking&lt;/h1&gt;

&lt;p&gt;Qiling supports a wide range of hooks such as hooking specific instructions and hooking memory read/write actions.&lt;/p&gt;

&lt;p&gt;Let’s implement a basic disassembler with the help of Capstone and Qiling hooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capstone&lt;/strong&gt; is a multi-architecture disassembly framework, we can setup a code hook using Qiling to hook every instruction then use Capstone to disassemble the instructions.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;capstone&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# initialize emulator (x86 ARM)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qiling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;qiling/examples/rootfs/arm_linux/bin/arm_hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
             &lt;span class=&quot;s&quot;&gt;&quot;qiling/examples/rootfs/arm_linux&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# hook every instruction
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# start emulation (timeout in microseconds)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can add a code hook by simply calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hook_code()&lt;/code&gt; with a callback function.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hook_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# read current instruction bytes
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# initialize Capstone
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;md&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CS_ARCH_ARM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CS_MODE_ARM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# disassemble current instruction
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;md&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disasm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[*] 0x{:08x}: {} {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mnemonic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;op_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The callback function takes three arguments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ql&lt;/code&gt;: our emulator object&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;address&lt;/code&gt;: the address of the current instruction&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size&lt;/code&gt;: the size of the instruction in bytes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can disassemble the current instruction using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;disasm()&lt;/code&gt; which takes two arguments (data to disassemble and a base address), here we are printing the instruction address, instruction mnemonic and instruction operands.&lt;/p&gt;

&lt;p&gt;Let’s see the results:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[*] 0x047ba9e0: ldr sl, [pc, #0x94]
[*] 0x047ba9e4: ldr r4, [pc, #0x94]
[*] 0x047ba9e8: mov r0, sp
[*] 0x047ba9ec: bl #0x47bb154
[*] 0x0001030c: mov fp, #0
[*] 0x00010310: mov lr, #0
[*] 0x00010314: pop {r1}
..........
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;In this part we learned the basics of Qiling and how to emulate code for different architectures.&lt;/p&gt;

&lt;p&gt;I really encourage you to read through Qiling &lt;a href=&quot;https://docs.qiling.io/en/latest/&quot;&gt;Documentation&lt;/a&gt; to learn more about it’s amazing capabilities.&lt;/p&gt;

&lt;p&gt;Code snippets can be found on my &lt;a href=&quot;https://github.com/N1ght-W0lf/QilingForMalwareAnalysis/tree/master/Part%201&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;</content><author><name>Abdallah Elshinbary</name></author><category term="Tutorials" /><summary type="html">Background</summary></entry><entry><title type="html">Qiling For Malware Analysis: Part 2</title><link href="https://n1ght-w0lf.github.io/tutorials/qiling-for-malware-analysis-part-2/" rel="alternate" type="text/html" title="Qiling For Malware Analysis: Part 2" /><published>2020-07-25T00:00:00+00:00</published><updated>2020-07-25T00:00:00+00:00</updated><id>https://n1ght-w0lf.github.io/tutorials/qiling-for-malware-analysis-part-2</id><content type="html" xml:base="https://n1ght-w0lf.github.io/tutorials/qiling-for-malware-analysis-part-2/">&lt;p&gt;In the first part we talked about the basics of Qiling, you can find it &lt;a href=&quot;https://n1ght-w0lf.github.io/tutorials/qiling-for-malware-analysis-part-1&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now it’s time for some real world stuff, we will go through two scenarios where Qiling shines.&lt;/p&gt;

&lt;h1 id=&quot;fetching-ksløt-dynamic-imports&quot;&gt;Fetching KSLØT Dynamic Imports&lt;/h1&gt;

&lt;p&gt;Dynamic Imports or Dynamic API resolving is a common technique used by many malware samples to make static analysis harder. Instead of importing all needed APIs, the malware can store the APIs names or hashes then import them dynamically at runtime.&lt;/p&gt;

&lt;p&gt;The most common way to do this is by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadLibrary()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetProcAddress()&lt;/code&gt;, and that’s what we are KSLØT uses.&lt;/p&gt;

&lt;p&gt;According to &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress&quot;&gt;MSDN&lt;/a&gt;, the second argument to&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetProcAddress()&lt;/code&gt; is the function name (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;lpProcName&quot;&lt;/code&gt;). So we can hook &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetProcAddress()&lt;/code&gt; and dump the second argument each time it’s called.&lt;/p&gt;

&lt;p&gt;Now you might be thinking, why don’t we just use a debugger and trace the execution flow of the malware ?&lt;/p&gt;

&lt;p&gt;I can think of three problems about that approach:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The malware might be implementing Anti-Debugging/Anti-Analysis tricks to waste your time&lt;/li&gt;
  &lt;li&gt;The malware might run on a different architecture that you don’t have access to.&lt;/li&gt;
  &lt;li&gt;You might want to automate the whole process (Scalability)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s start writing the script.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qiling.const&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# initialize emulator (x86_64 windows)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qiling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;kSLØT_Keylogger.dll&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;qiling/examples/rootfs/x8664_windows&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The malware sample used here is distributed as a DLL file.&lt;/p&gt;

&lt;p&gt;Similar to the main function in typical executables, DLLs have their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DllMain&lt;/code&gt; function that is executed automatically when they are loaded into memory.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;BOOL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WINAPI&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DllMain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;HINSTANCE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hinstDLL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// handle to DLL module&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fdwReason&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// reason for calling function&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;LPVOID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lpReserved&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// reserved&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As we can see, the function takes 3 arguments. The first one (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hinstDLL&lt;/code&gt;) is a handle to the memory area where the DLL has been loaded. The second one stores a value that indicates the reason why the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DllMain&lt;/code&gt; has been triggered. Read more &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So to emulate the DLL properly, we need to set these arguments first (for x64 calling convention, paramerts are passed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RCX&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RDX&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R8&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R9&lt;/code&gt;).&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;DLL_MAIN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1800019a0&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# Adress of DLLMain function
# hinstDLL
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rcx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x180000000&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Address where Qiling loads the DLL
# fdwReason
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;# DLL_PROCESS_DETACH
# lpvReserved
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_api()&lt;/code&gt; function to hook &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetProcAddress()&lt;/code&gt; on exit.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#FARPROC GetProcAddress(
#  HMODULE hModule,
#  LPCSTR  lpProcName
#)
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hook_GetProcAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[*] Import: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;lpProcName&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# hook GetProcAddress() on exit
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_api&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;GetProcAddress&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hook_GetProcAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QL_INTERCEPT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EXIT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# disable logging
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# start emulation
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DLL_MAIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s see the results:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[+] Initiate stack address at 0x7ffffffde000 
[+] Loading kSLØT_Keylogger.dll to 0x180000000
[+] PE entry point at 0x180006118
[+] TEB addr is 0x6030
[+] PEB addr is 0x60b8
[+] Loading qiling/examples/rootfs/x8664_windows/Windows/System32/ntdll.dll to 0x7ffff0000000
[+] Done with loading qiling/examples/rootfs/x8664_windows/Windows/System32/ntdll.dll
[+] Loading qiling/examples/rootfs/x8664_windows/Windows/System32/kernel32.dll to 0x7ffff01e1000
[+] Done with loading qiling/examples/rootfs/x8664_windows/Windows/System32/kernel32.dll
[*] Import: GetProcAddress
[*] Import: LoadLibraryA
[*] Import: GetProcessImageFileNameW
[*] Import: GetForegroundWindow
[*] Import: GetWindowThreadProcessId
[*] Import: GetWindowTextW
[*] Import: GetKeyboardState
...........
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Perfect! Knowing the imports of a malware sample can help in profiling it, BTW this malware is a keylogger.&lt;/p&gt;

&lt;h1 id=&quot;decrypting-qbot-strings&quot;&gt;Decrypting QBot Strings&lt;/h1&gt;

&lt;p&gt;It’s common to see malware encrypting its strings to make the analysis process more challenging.&lt;/p&gt;

&lt;p&gt;Recently I was analyzing QBot which implements this same technique and it only decrypts required strings on demand.&lt;/p&gt;

&lt;p&gt;In my analysis, I reverse engineered the decryption routine as it was simple. But imagine if it was a complicated algorithm with lots of mathematical operations and obfuscated instructions, that’s where Qiling comes in handy.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/qiling/1.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/qiling/1.png&quot; alt=&quot;1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the decryption function takes one argument in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EAX&lt;/code&gt; which is an index and the returns the required string decrypted.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/qiling/2.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/qiling/2.png&quot; alt=&quot;2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can combine the power of Qiling and IDAPython to decrypt the strings and add them as IDA comments.&lt;/p&gt;

&lt;p&gt;First we need to get all cross references to the decryption function and then extract the index (second operand) from the previous instruction (as shown above).&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# start/end of the decryption function
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DEC_START&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x4065B7&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DEC_END&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x406655&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# xrefs to the decryption function
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xrefs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idautils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeRefsTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DEC_START&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# indexes of requested strings to decrypt
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;indexes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xrefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# address of previous instruction where &quot;eax&quot; is set
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prev_head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# type of the second operand of &quot;mov&quot;
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_operand_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# check if the second operand is an immediate (not dynamic value)
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o_imm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# get the index value (second operand)
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_operand_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;indexes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next we initialize Qiling emulator object and loop through collected indexes. At each iteration we set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EAX&lt;/code&gt; to the index value and run the decryption function.&lt;/p&gt;

&lt;p&gt;Finally we read the decrypted string from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EAX&lt;/code&gt; (return value) and set it as IDA comment.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# initialize emulator (x86 windows)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qiling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;qbot.exe&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rootfs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;qiling/examples/rootfs/x86_windows&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# loop through collected indexes
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# set function parameter @eax
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# run decryption function
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x4065B7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x406654&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# set decrypted string as ida comment
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_cmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;readString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Reading a string from memory address is simply reading bytes one by one until we reach a null byte.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# read string from memory address
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;readString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# read one byte at a time
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x00&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s see the results:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/tutorials/qiling/3.png&quot;&gt;&lt;img src=&quot;/assets/images/tutorials/qiling/3.png&quot; alt=&quot;3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Viola! we managed to decrypt most of the strings without reversing the decryption function.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Qiling is a great project for malware analysis and binary emulation. Although it’s still new but it has lots of capabilities and a lot more to come.&lt;/p&gt;

&lt;p&gt;Code snippets can be found on my &lt;a href=&quot;https://github.com/N1ght-W0lf/QilingForMalwareAnalysis/tree/master/Part%202&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Don’t forget to star the &lt;a href=&quot;https://github.com/qilingframework/qiling&quot;&gt;Project&lt;/a&gt; to support the devs :)&lt;/p&gt;</content><author><name>Abdallah Elshinbary</name></author><category term="Tutorials" /><summary type="html">In the first part we talked about the basics of Qiling, you can find it here.</summary></entry><entry><title type="html">Deep Analysis of QBot Banking Trojan</title><link href="https://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/" rel="alternate" type="text/html" title="Deep Analysis of QBot Banking Trojan" /><published>2020-07-15T00:00:00+00:00</published><updated>2020-07-15T00:00:00+00:00</updated><id>https://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan</id><content type="html" xml:base="https://n1ght-w0lf.github.io/malware%20analysis/qbot-banking-trojan/">&lt;p&gt;QBot is a modular information stealer also known as Qakbot or Pinkslipbot. It has been active for years since 2007. It has historically been known as a banking Trojan, meaning that it steals financial data from infected systems.&lt;/p&gt;

&lt;h1 id=&quot;infection-flow&quot;&gt;Infection Flow&lt;/h1&gt;

&lt;p&gt;QBot can be delivered in various different ways including Malspam (Malicious Spam) or dropped by other malware families like Emotet.&lt;/p&gt;

&lt;p&gt;The infection flow for this campaign is as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/1.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/1.png&quot; alt=&quot;1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, the victim receives a phishing email with a link to a malicious zip file.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/2.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/2.png&quot; alt=&quot;2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The zip file contains a very obfuscated VBS file which downloads and launches Qbot executable.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/3.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/3.png&quot; alt=&quot;3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The VBS file tries to download Qbot from different places:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;http://st29[.]ru/tbzirttmcnmb/88888888.png&lt;/li&gt;
  &lt;li&gt;http://restaurantbrighton[.]ru/uyqcb/88888888.png&lt;/li&gt;
  &lt;li&gt;http://royalapartments[.]pl/vtjwwoqxaix/88888888.png&lt;/li&gt;
  &lt;li&gt;http://alergeny.dietapacjenta[.]pl/pgaakzs/88888888.png&lt;/li&gt;
  &lt;li&gt;http://egyorg[.]com/vxvipjfembb/88888888.png&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice the misleading URL, it looks like it’s downloading a PNG image but the raw data says something else.&lt;/p&gt;

&lt;h1 id=&quot;unpacking&quot;&gt;Unpacking&lt;/h1&gt;

&lt;p&gt;QBot is packed with a custom packer, but the unpacking process is really simple. It allocates memory for the unpacked code using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc()&lt;/code&gt; and changes memory protection using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualProtect()&lt;/code&gt;. So we just need 2 breakpoints at  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAlloc()&lt;/code&gt;  and  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualProtect()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/4.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/4.png&quot; alt=&quot;4&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;encrypted-strings&quot;&gt;Encrypted Strings&lt;/h1&gt;

&lt;p&gt;Most of QBot strings are encrypted (stored in a continuous blob) and they are decrypted on demand. The decryption routine accepts one argument which is the  index to the string then it XORs it with a hardcoded bytes array until it encounters a null byte.&lt;/p&gt;

&lt;p&gt;We can use IDAPython to decrypt the strings and add them as comments.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;idc&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;idautils&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;dec_routine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x4065B7&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;enc_strings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x40B930&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bytes_arr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x410120&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decrypt_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x36F4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# out of bounds
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_wide_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enc_strings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_wide_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes_arr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x3F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;xrefs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idautils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeRefsTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dec_routine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xrefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prev_head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_operand_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o_imm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_operand_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decrypt_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_cmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And here is the result, that’s much easier to work with.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/5.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/5.png&quot; alt=&quot;5&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This should take care of most of the strings, the rest of strings indexes are calculated dynamically at runtime.&lt;/p&gt;

&lt;p&gt;We decrypt all strings by looping through the encrypted blob and decrypt strings one by one.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x36F4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decrypt_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;anti-analysis&quot;&gt;Anti-Analysis&lt;/h1&gt;

&lt;p&gt;QBot spawns a new process of itself with the  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;/C&quot;&lt;/code&gt; parameter, this process is responsible for doing Anti-Analysis checks.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/6.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/6.png&quot; alt=&quot;6&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The parent process checks the exit code of this spawned process. If the exit code is not 0, it means that QBot is being analyzed (and so it exits).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/7.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/7.png&quot; alt=&quot;7&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let’s go over the anti-analysis techniques.&lt;/p&gt;

&lt;h2 id=&quot;checking-vm&quot;&gt;Checking VM&lt;/h2&gt;

&lt;p&gt;In VMWare, communication with the host is done through a specific I/O  port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(0x5658)&lt;/code&gt;, so QBot uses the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;in&lt;/code&gt; assembly instruction to detect VMWare by reading from this port and checking the return value in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ebx&lt;/code&gt; if it’s equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VMXh&lt;/code&gt; (VMware magic value).&lt;/p&gt;

&lt;p&gt;If we are outside VMWare, a privilege error occurs and this code will return 0.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/8.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/8.png&quot; alt=&quot;8&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another Anti-VM trick is to check hardware devices against known devices names used by VMs and Sandboxes.&lt;/p&gt;

&lt;p&gt;Here is the list of devices names.&lt;/p&gt;

&lt;details style=&quot;color: #EEFFFF; font-family: monospace !default; font-size: 0.85em; background: #263238; border: 1px solid #263238; border-radius: 3px; padding: 10px; line-height: 2.2; overflow-x: scroll;&quot;&gt;
    &lt;summary style=&quot;outline: none; cursor: pointer&quot;&gt;
        &lt;span style=&quot;color: darkgray&quot;&gt;
            Expand to see more
        &lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;height: 1px&quot;&gt;&lt;/div&gt;
&amp;emsp; VMware Pointing&lt;br /&gt;
&amp;emsp; VMware Accelerated&lt;br /&gt;
&amp;emsp; VMware SCSI&lt;br /&gt;
&amp;emsp; VMware SVGA&lt;br /&gt;
&amp;emsp; VMware Replay&lt;br /&gt;
&amp;emsp; VMware server memory&lt;br /&gt;
&lt;/summary&gt;
&amp;emsp; CWSandbox&lt;br /&gt;
&amp;emsp; Virtual HD&lt;br /&gt;
&amp;emsp; QEMU&lt;br /&gt;
&amp;emsp; Red Hat VirtIO&lt;br /&gt;
&amp;emsp; srootkit&lt;br /&gt;
&amp;emsp; VMware VMaudio&lt;br /&gt;
&amp;emsp; VMware Vista&lt;br /&gt;
&amp;emsp; VBoxVideo&lt;br /&gt;
&amp;emsp; VBoxGuest&lt;br /&gt;
&amp;emsp; vmxnet&lt;br /&gt;
&amp;emsp; vmscsi&lt;br /&gt;
&amp;emsp; VMAUDIO&lt;br /&gt;
&amp;emsp; vmdebug&lt;br /&gt;
&amp;emsp; vm3dmp&lt;br /&gt;
&amp;emsp; vmrawdsk&lt;br /&gt;
&amp;emsp; vmx_svga&lt;br /&gt;
&amp;emsp; ansfltr&lt;br /&gt;
&amp;emsp; sbtisht&lt;br /&gt;
&lt;/details&gt;

&lt;h2 id=&quot;checking-processes&quot;&gt;Checking Processes&lt;/h2&gt;

&lt;p&gt;QBot loops through running processes and compares their executable names against known analysis tools.&lt;/p&gt;

&lt;details style=&quot;color: #EEFFFF; font-family: monospace !default; font-size: 0.85em; background: #263238; border: 1px solid #263238; border-radius: 3px; padding: 10px; line-height: 2.2; overflow-x: scroll;&quot;&gt;
    &lt;summary style=&quot;outline: none; cursor: pointer&quot;&gt;
        &lt;span style=&quot;color: darkgray&quot;&gt;
            Expand to see more
        &lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;height: 1px&quot;&gt;&lt;/div&gt;
&amp;emsp; Fiddler.exe&lt;br /&gt;
&amp;emsp; samp1e.exe&lt;br /&gt;
&amp;emsp; sample.exe&lt;br /&gt;
&amp;emsp; runsample.exe&lt;br /&gt;
&amp;emsp; lordpe.exe&lt;br /&gt;
&amp;emsp; regshot.exe&lt;br /&gt;
&lt;/summary&gt;
&amp;emsp; Autoruns.exe&lt;br /&gt;
&amp;emsp; dsniff.exe&lt;br /&gt;
&amp;emsp; VBoxTray.exe&lt;br /&gt;
&amp;emsp; HashMyFiles.exe&lt;br /&gt;
&amp;emsp; ProcessHacker.exe&lt;br /&gt;
&amp;emsp; Procmon.exe&lt;br /&gt;
&amp;emsp; Procmon64.exe&lt;br /&gt;
&amp;emsp; netmon.exe&lt;br /&gt;
&amp;emsp; vmtoolsd.exe&lt;br /&gt;
&amp;emsp; vm3dservice.exe&lt;br /&gt;
&amp;emsp; VGAuthService.exe&lt;br /&gt;
&amp;emsp; pr0c3xp.exe&lt;br /&gt;
&amp;emsp; CFF Explorer.exe&lt;br /&gt;
&amp;emsp; dumpcap.exe&lt;br /&gt;
&amp;emsp; Wireshark.exe&lt;br /&gt;
&amp;emsp; idaq.exe&lt;br /&gt;
&amp;emsp; idaq64.exe&lt;br /&gt;
&amp;emsp; TPAutoConnect.exe&lt;br /&gt;
&amp;emsp; ResourceHacker.exe&lt;br /&gt;
&amp;emsp; vmacthlp.exe&lt;br /&gt;
&amp;emsp; OLLYDBG.EXE&lt;br /&gt;
&amp;emsp; windbg.exe&lt;br /&gt;
&amp;emsp; bds-vision-agent-nai.exe&lt;br /&gt;
&amp;emsp; bds-vision-apis.exe&lt;br /&gt;
&amp;emsp; bds-vision-agent-app.exe&lt;br /&gt;
&amp;emsp; MultiAnalysis_v1.0.294.exe&lt;br /&gt;
&amp;emsp; x32dbg.exe&lt;br /&gt;
&amp;emsp; VBoxService.exe&lt;br /&gt;
&amp;emsp; Tcpview.exe&lt;br /&gt;
&lt;/details&gt;

&lt;h2 id=&quot;checking-dlls&quot;&gt;Checking DLLs&lt;/h2&gt;

&lt;p&gt;Sandbox detection can be done by enumerating loaded DLLs and comparing them against known DLLs used by sandboxes. Here it’s just using 2 of them.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ivm-inject.dll     # Buster Sandbox Analyzer
SbieDll.dll        # SandBoxie
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;checking-filename&quot;&gt;Checking Filename&lt;/h2&gt;

&lt;p&gt;Some sandboxes may change the sample file name. So QBot checks if its process name contains one of these strings.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sample
mlwr_smpl
artifact.exe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;checking-cpu&quot;&gt;Checking CPU&lt;/h2&gt;

&lt;p&gt;The last check is done using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CPUID&lt;/code&gt; instruction. First it is executed with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EAX=0&lt;/code&gt; to get the CPU vendor and compares it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenuineIntel&lt;/code&gt; (Intel processor).&lt;/p&gt;

&lt;p&gt;Then it is executed with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EAX=1&lt;/code&gt; to get the processors features.&lt;/p&gt;

&lt;p&gt;On a physical machine the last bit will be equal to 0. On a guest VM it will equal to 1.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/9.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/9.png&quot; alt=&quot;9&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;back-to-parent&quot;&gt;Back To Parent&lt;/h1&gt;

&lt;p&gt;After the Anti-Analysis checks, QBot drops a copy of itself along with a configuration file at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;%APPDATA%\Microsoft\&amp;lt;random_folder_name&amp;gt;&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/10.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/10.png&quot; alt=&quot;10&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, QBot starts the dropped copy in a new process and overwrites itself with a legitimate executable, here it’s  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;calc.exe&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/11.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/11.png&quot; alt=&quot;11&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;configuration-file&quot;&gt;Configuration File&lt;/h1&gt;

&lt;p&gt;The dropped configuration file is accessed frequently by Qbot, this file is RC4 encrypted. By setting a breakpoint before the contents of the file gets encrypted I got the following data:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Field&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;10=spx143&lt;/td&gt;
      &lt;td&gt;Campaign ID&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;11=2&lt;/td&gt;
      &lt;td&gt;Number of hardcoded C2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1=13.59.00-24/06/2020&lt;/td&gt;
      &lt;td&gt;Date of Qbot install in HH:MM:ss-dd/mm/yyyy&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2=1592996340&lt;/td&gt;
      &lt;td&gt;Victim Qbot install&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;50=1&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5=VgBCAE8AWABTAFYAUgA7ADIA&lt;/td&gt;
      &lt;td&gt;Victim network shares&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;38=1593047244&lt;/td&gt;
      &lt;td&gt;Last victim call to C2 (Unix time)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;45=187.163.101.137&lt;/td&gt;
      &lt;td&gt;C2 IP&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;46=995&lt;/td&gt;
      &lt;td&gt;C2 port&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;39=45.242.76.104&lt;/td&gt;
      &lt;td&gt;Victim external IP&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;43=1593006172&lt;/td&gt;
      &lt;td&gt;Time of record (Unix time)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;49=1&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h1 id=&quot;persistence&quot;&gt;Persistence&lt;/h1&gt;

&lt;p&gt;QBot achieves persistence by creating a new registry value under the key &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run&quot;&lt;/code&gt;. It also registers a scheduled task that runs every 5 hours.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/12.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/12.png&quot; alt=&quot;12&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;process-injection&quot;&gt;Process Injection&lt;/h1&gt;

&lt;p&gt;QBot tries to inject its unpacked code in one of these processes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(&quot;explorer.exe&quot;, &quot;mobsync.exe&quot;, &quot;iexplorer.exe&quot;)&lt;/code&gt; and it uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Process Hollowing&lt;/code&gt; technique to achieve that.&lt;/p&gt;

&lt;p&gt;It first starts a new suspended process with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CreateProcessW()&lt;/code&gt; then it writes the injected code into the target process using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ZwCreateSection()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ZwMapViewOfSection()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ZwWriteVirtualMemory()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally it sets the thread context to jump to the injected code and resume execution with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResumeThread()&lt;/code&gt;.&lt;/p&gt;

&lt;h1 id=&quot;core-module&quot;&gt;Core Module&lt;/h1&gt;

&lt;p&gt;The injected code loads and decrypts one of its resources  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;307&quot;&lt;/code&gt; . After dumping it, I found out that it’s a DLL (this is the core module).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/13.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/13.png&quot; alt=&quot;13&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From now on, we will be analyzing the core DLL of QBot.&lt;/p&gt;

&lt;p&gt;The core module has 2 resources both RC4 encrypted.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/14.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/14.png&quot; alt=&quot;14&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first resource gets loaded into memory then RC4 decrypted.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/15.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/15.png&quot; alt=&quot;15&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The contents of the decrypted resource are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;10=spx143 (Campaign ID)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;3=1592482956 (Timestamp)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After some digging, I found out how the resources are decrypted. The first &lt;strong&gt;20&lt;/strong&gt; bytes of each resource are the RC4 key of this resource, and the rest are the actual encrypted data.&lt;/p&gt;

&lt;p&gt;So by using this find, we can decrypt the other resource &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;311&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/16.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/16.png&quot; alt=&quot;16&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great!!! Now we have the list of C2 servers (150 servers!).&lt;/p&gt;

&lt;p&gt;The reason there is many controllers is that these are actually just proxies of infected bots acting as intermediate nodes between the victim and the real C2 and thus hiding the backend infrastructure of the attacker.&lt;/p&gt;

&lt;p&gt;So it works like this:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/17.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/17.png&quot; alt=&quot;17&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;c2-communication&quot;&gt;C2 Communication&lt;/h1&gt;

&lt;p&gt;QBot obfuscates its communication with the C2 server by encrypting the payloads using RC4 and encoding the result using Base64.&lt;/p&gt;

&lt;p&gt;The communication is also done over SSL, you can notice that the traffic has unusual certificate issuer data.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/18.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/18.png&quot; alt=&quot;18&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fiddler&lt;/code&gt; to intercept and decrypt the HTTPS traffic.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/19.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/19.png&quot; alt=&quot;19&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The RC4 key for encrypting the payload is the SHA1 hash of the first 16 bytes of the Base64-decoded payload + a hardcoded salt (The salt is stored as an encrypted string).&lt;/p&gt;

&lt;p&gt;Here is an implementation of the decryption algorithm:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;HARDCODED_SALT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;jHxastDcds)oMc=jvh7wdUhxcsdt2&quot;&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# decrypted string
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decrypt_payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encrypted_blob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b64_decoded&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encrypted_blob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;decryption_key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b64_decoded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HARDCODED_SALT&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sha1hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hashlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sha1hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decryption_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;decryption_key_hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sha1hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;digest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rc4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ARC4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decryption_key_hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rc4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decrypt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64_decoded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The decrypted payload is in JSON form.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Decrypted C2 Request: {“8”:9,”1”:17,”2”:”pnmfcq111232”}&lt;/li&gt;
  &lt;li&gt;Decrypted C2 Response: {“8”:5,”16”:770897804,”39”:”V4UnoDQSEblewhh63UfUqAns”,”38”:1}&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;commands-list&quot;&gt;Commands List&lt;/h1&gt;

&lt;p&gt;After establishing communication, the C2 server will send commands indexes to be executed.&lt;/p&gt;

&lt;p&gt;Here is the list of commands and their corresponding indexes (I have renamed the important commands).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/20.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/20.png&quot; alt=&quot;20&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s worth mentioning that dynamic imports of the core DLL are stored in the same format as commands &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;&amp;lt;address, API_index, DLL_index&amp;gt;&quot;&lt;/code&gt;, the API and DLL indexes are passed to the string decryption routine which returns their corresponding names then it uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadLibrary&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetProcAddress&lt;/code&gt; to resolve the imports.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/21.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/21.png&quot; alt=&quot;21&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s go through some of the interesting commands.&lt;/p&gt;

&lt;h2 id=&quot;command-13-lateral-movement&quot;&gt;Command 13: Lateral Movement&lt;/h2&gt;

&lt;p&gt;QBot can spread through the network by enumerating network shares using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WNetOpenEnumW()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WNetEnumResourceW&lt;/code&gt;() then it drops a copy of Qbot into the shared folders.&lt;/p&gt;

&lt;p&gt;Then the dropped executable is registered as an auto-start service on the target machine. The names for the service and the dropped file are randomly generated strings.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/22.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/22.png&quot; alt=&quot;22&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, Qbot deletes the created service and dropped file from the target machine (as it’s successfully infected).&lt;/p&gt;

&lt;h2 id=&quot;command-21-collecting-installed-applications&quot;&gt;Command 21: Collecting Installed Applications&lt;/h2&gt;

&lt;p&gt;QBot can collect installed applications by enumeration subkeys of the registry key &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/23.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/23.png&quot; alt=&quot;23&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The collected data is appended to the end of a string containing additional information about the victim’s machine and time of collection.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t=i1 time=[&amp;lt;time_of_collect&amp;gt;] ext_ip=[&amp;lt;external_IP&amp;gt;] dnsname=[?] hostname=[&amp;lt;computer_name&amp;gt;] user=[] domain=[] is_admin=[&amp;lt;YES/NO&amp;gt;] os=[&amp;lt;windows_ver&amp;gt;] qbot_version=[&amp;lt;qbot_ver&amp;gt;] install_time=[&amp;lt;qbot_install_time&amp;gt;] exe=[&amp;lt;injected_process&amp;gt;] prod_id=[NULL] iface_n=[&amp;lt;interface_IP&amp;gt;/&amp;lt;interface_IP&amp;gt;] UP] soft=[&amp;lt;app1;ver&amp;gt;|&amp;lt;app2;ver&amp;gt;|...]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example of collected data:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/24.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/24.png&quot; alt=&quot;24&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then the data is RC4 encrypted and written to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;wdqlxw32.dll&quot;&lt;/code&gt; at the same directory of QBot.&lt;/p&gt;

&lt;p&gt;Finally, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;wdqlxw32.dll&quot;&lt;/code&gt; is Zlib compressed and RC4 encrypted again then it’s saved to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;cwdqlxw32.dll&quot;&lt;/code&gt; and the original &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;wdqlxw32.dll&quot;&lt;/code&gt; is deleted.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/25.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/25.png&quot; alt=&quot;25&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The compressed file is then transfered to the C2 server (RC4 encrypted and Base64 encoded) in the key &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;36&quot;&lt;/code&gt; and the compressed file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;cwdqlxw32.dll&quot;&lt;/code&gt; is also deleted.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/26.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/26.png&quot; alt=&quot;26&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;command-31-fetching-plugins&quot;&gt;Command 31: Fetching Plugins&lt;/h2&gt;

&lt;p&gt;As we said before, QBot is known to be a modular malware. It can load additional plugins received from the C2 server (plugins are RC4 encrypted and Base64 encoded).&lt;/p&gt;

&lt;p&gt;QBot tries to inject the received plugin in 3 different processes depending on the machine architecture.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/27.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/27.png&quot; alt=&quot;27&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It creates a new suspended process then writes the plugin to the process memory using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WriteProcessMemory()&lt;/code&gt; and then resumes the injected process.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/qbot-banking-trojan/28.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/qbot-banking-trojan/28.png&quot; alt=&quot;28&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the time of writing this, Qbot has 3 different plugins (“Password grabber”, “Cookie grabber”, “UPnP module”).&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;QBot is considered to be a sophisticated malware, it’s receiving regular updates from time to time and it’s not likely to go away anytime soon.&lt;/p&gt;

&lt;p&gt;There is still more features that I didn’t cover such as WebInjects so maybe I will come back to Qbot later I guess :)&lt;/p&gt;

&lt;h1 id=&quot;iocs&quot;&gt;IOCs&lt;/h1&gt;

&lt;h4 id=&quot;hashes&quot;&gt;&lt;u&gt;Hashes&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;VBS File: b734caf792c968ca1870c3ec7dda68ad5dc47fef548751afb8509752c185a756&lt;/p&gt;

&lt;p&gt;QBot: 112a64190b9a0f356880eebf05e195f4c16407032bf89fa843fd136da6f5d515&lt;/p&gt;

&lt;h4 id=&quot;urls&quot;&gt;&lt;u&gt;URLs&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;http://st29[.]ru/tbzirttmcnmb/88888888.png&lt;/p&gt;

&lt;p&gt;http://restaurantbrighton[.]ru/uyqcb/88888888.png&lt;/p&gt;

&lt;p&gt;http://royalapartments[.]pl/vtjwwoqxaix/88888888.png&lt;/p&gt;

&lt;p&gt;http://alergeny.dietapacjenta[.]pl/pgaakzs/88888888.png&lt;/p&gt;

&lt;p&gt;http://egyorg[.]com/vxvipjfembb/88888888.png&lt;/p&gt;

&lt;h4 id=&quot;c2-domains&quot;&gt;&lt;u&gt;C2 Domains&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;39.36.254.179:995&lt;/p&gt;

&lt;p&gt;24.139.132.70:443&lt;/p&gt;

&lt;p&gt;24.202.42.48:2222&lt;/p&gt;

&lt;p&gt;72.204.242.138:443&lt;/p&gt;

&lt;p&gt;172.242.156.50:995&lt;/p&gt;

&lt;p&gt;72.204.242.138:20&lt;/p&gt;

&lt;p&gt;68.174.15.223:443&lt;/p&gt;

&lt;p&gt;74.193.197.246:443&lt;/p&gt;

&lt;p&gt;96.56.237.174:990&lt;/p&gt;

&lt;p&gt;64.19.74.29:995&lt;/p&gt;

&lt;p&gt;70.168.130.172:443&lt;/p&gt;

&lt;p&gt;189.236.166.167:443&lt;/p&gt;

&lt;p&gt;68.4.137.211:443&lt;/p&gt;

&lt;p&gt;76.187.8.160:443&lt;/p&gt;

&lt;p&gt;76.86.57.179:2222&lt;/p&gt;

&lt;p&gt;73.226.220.56:443&lt;/p&gt;

&lt;p&gt;67.250.184.157:443&lt;/p&gt;

&lt;p&gt;75.183.171.155:3389&lt;/p&gt;

&lt;p&gt;173.172.205.216:443&lt;/p&gt;

&lt;p&gt;173.3.132.17:995&lt;/p&gt;

&lt;p&gt;172.78.30.215:443&lt;/p&gt;

&lt;p&gt;207.255.161.8:32103&lt;/p&gt;

&lt;p&gt;75.137.239.211:443&lt;/p&gt;

&lt;p&gt;68.49.120.179:443&lt;/p&gt;

&lt;p&gt;206.51.202.106:50003&lt;/p&gt;

&lt;p&gt;82.127.193.151:2222&lt;/p&gt;

&lt;p&gt;207.255.161.8:2222&lt;/p&gt;

&lt;p&gt;207.255.161.8:2087&lt;/p&gt;

&lt;p&gt;24.152.219.253:995&lt;/p&gt;

&lt;p&gt;187.19.151.218:995&lt;/p&gt;

&lt;p&gt;197.37.48.37:993&lt;/p&gt;

&lt;p&gt;188.241.243.175:443&lt;/p&gt;

&lt;p&gt;72.88.119.131:443&lt;/p&gt;

&lt;p&gt;89.137.211.239:443&lt;/p&gt;

&lt;p&gt;108.30.125.94:443&lt;/p&gt;

&lt;p&gt;187.163.101.137:995&lt;/p&gt;

&lt;p&gt;100.19.7.242:443&lt;/p&gt;

&lt;p&gt;45.77.164.175:443&lt;/p&gt;

&lt;p&gt;80.240.26.178:443&lt;/p&gt;

&lt;p&gt;66.208.105.6:443&lt;/p&gt;

&lt;p&gt;207.246.75.201:443&lt;/p&gt;

&lt;p&gt;199.247.22.145:443&lt;/p&gt;

&lt;p&gt;199.247.16.80:443&lt;/p&gt;

&lt;p&gt;95.77.223.148:443&lt;/p&gt;

&lt;p&gt;68.60.221.169:465&lt;/p&gt;

&lt;p&gt;5.107.220.84:2222&lt;/p&gt;

&lt;p&gt;41.228.212.22:443&lt;/p&gt;

&lt;p&gt;86.233.4.153:2222&lt;/p&gt;

&lt;p&gt;68.200.23.189:443&lt;/p&gt;

&lt;p&gt;201.146.127.158:443&lt;/p&gt;

&lt;p&gt;79.114.199.39:443&lt;/p&gt;

&lt;p&gt;87.65.204.240:995&lt;/p&gt;

&lt;p&gt;71.74.12.34:443&lt;/p&gt;

&lt;p&gt;217.162.149.212:443&lt;/p&gt;

&lt;p&gt;195.162.106.93:2222&lt;/p&gt;

&lt;p&gt;75.165.112.82:50002&lt;/p&gt;

&lt;p&gt;201.248.102.4:2078&lt;/p&gt;

&lt;p&gt;96.41.93.96:443&lt;/p&gt;

&lt;p&gt;89.247.216.127:443&lt;/p&gt;

&lt;p&gt;84.232.238.30:443&lt;/p&gt;

&lt;p&gt;103.238.231.40:443&lt;/p&gt;

&lt;p&gt;174.34.67.106:2222&lt;/p&gt;

&lt;p&gt;98.115.138.61:443&lt;/p&gt;

&lt;p&gt;91.125.21.16:2222&lt;/p&gt;

&lt;p&gt;84.247.55.190:443&lt;/p&gt;

&lt;p&gt;193.248.44.2:2222&lt;/p&gt;

&lt;p&gt;74.135.37.79:443&lt;/p&gt;

&lt;p&gt;78.96.190.54:443&lt;/p&gt;

&lt;p&gt;86.126.97.183:2222&lt;/p&gt;

&lt;p&gt;2.50.47.97:2222&lt;/p&gt;

&lt;p&gt;68.39.160.40:443&lt;/p&gt;

&lt;p&gt;96.232.203.15:443&lt;/p&gt;

&lt;p&gt;86.144.150.29:2222&lt;/p&gt;

&lt;p&gt;71.220.191.200:443&lt;/p&gt;

&lt;p&gt;24.231.54.185:2222&lt;/p&gt;

&lt;p&gt;80.14.209.42:2222&lt;/p&gt;

&lt;p&gt;24.164.79.147:443&lt;/p&gt;

&lt;p&gt;70.183.127.6:995&lt;/p&gt;

&lt;p&gt;47.153.115.154:993&lt;/p&gt;

&lt;p&gt;184.180.157.203:2222&lt;/p&gt;

&lt;p&gt;50.104.68.223:443&lt;/p&gt;

&lt;p&gt;67.165.206.193:995&lt;/p&gt;

&lt;p&gt;200.113.201.83:993&lt;/p&gt;

&lt;p&gt;47.153.115.154:465&lt;/p&gt;

&lt;p&gt;24.42.14.241:995&lt;/p&gt;

&lt;p&gt;189.160.203.110:443&lt;/p&gt;

&lt;p&gt;188.27.76.139:443&lt;/p&gt;

&lt;p&gt;207.255.161.8:32102&lt;/p&gt;

&lt;p&gt;49.207.105.25:443&lt;/p&gt;

&lt;p&gt;71.210.177.4:443&lt;/p&gt;

&lt;p&gt;117.242.253.163:443&lt;/p&gt;

&lt;p&gt;50.244.112.106:443&lt;/p&gt;

&lt;p&gt;69.92.54.95:995&lt;/p&gt;

&lt;p&gt;41.34.91.90:995&lt;/p&gt;

&lt;p&gt;72.204.242.138:53&lt;/p&gt;

&lt;p&gt;41.97.138.74:443&lt;/p&gt;

&lt;p&gt;72.29.181.77:2078&lt;/p&gt;

&lt;p&gt;71.88.168.176:443&lt;/p&gt;

&lt;p&gt;2.50.171.142:443&lt;/p&gt;

&lt;p&gt;67.83.54.76:2222&lt;/p&gt;

&lt;p&gt;86.125.145.90:2222&lt;/p&gt;

&lt;p&gt;47.153.115.154:995&lt;/p&gt;

&lt;p&gt;24.122.157.93:443&lt;/p&gt;

&lt;p&gt;47.146.169.85:443&lt;/p&gt;

&lt;p&gt;72.181.9.163:443&lt;/p&gt;

&lt;p&gt;187.155.74.5:443&lt;/p&gt;

&lt;p&gt;71.209.187.4:443&lt;/p&gt;

&lt;p&gt;74.75.216.202:443&lt;/p&gt;

&lt;p&gt;24.44.180.236:2222&lt;/p&gt;

&lt;p&gt;24.43.22.220:993&lt;/p&gt;

&lt;p&gt;108.188.116.179:443&lt;/p&gt;

&lt;p&gt;100.4.173.223:443&lt;/p&gt;

&lt;p&gt;76.170.77.99:443&lt;/p&gt;

&lt;p&gt;70.95.118.217:443&lt;/p&gt;

&lt;p&gt;134.0.196.46:995&lt;/p&gt;

&lt;p&gt;68.225.56.31:443&lt;/p&gt;

&lt;p&gt;72.204.242.138:32102&lt;/p&gt;

&lt;p&gt;72.204.242.138:50001&lt;/p&gt;

&lt;p&gt;108.190.151.108:2222&lt;/p&gt;

&lt;p&gt;72.204.242.138:465&lt;/p&gt;

&lt;p&gt;50.244.112.10:443&lt;/p&gt;

&lt;p&gt;173.22.120.11:2222&lt;/p&gt;

&lt;p&gt;24.43.22.220:995&lt;/p&gt;

&lt;p&gt;24.43.22.220:443&lt;/p&gt;

&lt;p&gt;92.17.167.87:2222&lt;/p&gt;

&lt;p&gt;72.209.191.27:443&lt;/p&gt;

&lt;p&gt;72.204.242.138:80&lt;/p&gt;

&lt;p&gt;72.204.242.138:443&lt;/p&gt;

&lt;p&gt;71.187.170.235:443&lt;/p&gt;

&lt;p&gt;96.56.237.174:32103&lt;/p&gt;

&lt;p&gt;71.187.7.239:443&lt;/p&gt;

&lt;p&gt;184.98.104.7:995&lt;/p&gt;

&lt;p&gt;70.124.29.226:443&lt;/p&gt;

&lt;p&gt;137.99.224.198:443&lt;/p&gt;

&lt;p&gt;73.23.194.75:443&lt;/p&gt;

&lt;p&gt;151.205.102.42:443&lt;/p&gt;

&lt;p&gt;64.224.76.152:443&lt;/p&gt;

&lt;p&gt;72.204.242.138:32100&lt;/p&gt;

&lt;p&gt;173.187.101.221:443&lt;/p&gt;

&lt;p&gt;72.179.13.59:443&lt;/p&gt;

&lt;p&gt;208.93.202.49:443&lt;/p&gt;

&lt;p&gt;70.174.3.241:443&lt;/p&gt;

&lt;p&gt;96.37.137.42:443&lt;/p&gt;

&lt;p&gt;76.111.128.194:443&lt;/p&gt;

&lt;p&gt;67.209.195.198:3389&lt;/p&gt;

&lt;p&gt;61.3.184.27:443&lt;/p&gt;

&lt;p&gt;24.42.14.241:443&lt;/p&gt;

&lt;p&gt;74.56.167.31:443&lt;/p&gt;

&lt;p&gt;5.193.61.212:2222&lt;/p&gt;

&lt;p&gt;117.216.177.171:443&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=iB1psRMtlqg&quot;&gt;Demystifying QBot Banking Trojan - BSides Belfast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.virusbulletin.com/virusbulletin/2017/06/vb2016-paper-diving-pinkslipbots-latest-campaign&quot;&gt;https://www.virusbulletin.com/virusbulletin/2017/06/vb2016-paper-diving-pinkslipbots-latest-campaign&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.fortinet.com/blog/threat-research/deep-analysis-qbot-campaign&quot;&gt;https://www.fortinet.com/blog/threat-research/deep-analysis-qbot-campaign&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.vkremez.com/2018/07/lets-learn-in-depth-reversing-of-qakbot.html&quot;&gt;https://www.vkremez.com/2018/07/lets-learn-in-depth-reversing-of-qakbot.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.hexacorn.com/blog/2016/07/01/enter-sandbox-part-12-the-library-of-naughty-libraries/&quot;&gt;https://www.hexacorn.com/blog/2016/07/01/enter-sandbox-part-12-the-library-of-naughty-libraries/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.cyberbit.com/blog/endpoint-security/anti-vm-and-anti-sandbox-explained/&quot;&gt;https://www.cyberbit.com/blog/endpoint-security/anti-vm-and-anti-sandbox-explained/&lt;/a&gt;&lt;/p&gt;</content><author><name>Abdallah Elshinbary</name></author><category term="Malware Analysis" /><summary type="html">QBot is a modular information stealer also known as Qakbot or Pinkslipbot. It has been active for years since 2007. It has historically been known as a banking Trojan, meaning that it steals financial data from infected systems.</summary></entry><entry><title type="html">Deep Analysis of Anubis Banking Malware</title><link href="https://n1ght-w0lf.github.io/malware%20analysis/anubis-banking-malware/" rel="alternate" type="text/html" title="Deep Analysis of Anubis Banking Malware" /><published>2020-07-04T00:00:00+00:00</published><updated>2020-07-04T00:00:00+00:00</updated><id>https://n1ght-w0lf.github.io/malware%20analysis/anubis-banking-malware</id><content type="html" xml:base="https://n1ght-w0lf.github.io/malware%20analysis/anubis-banking-malware/">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;

&lt;p&gt;Anubis is a well known android banking malware. Although it hasn’t been around for long (since 2017), it had a higher impact than many older banking malwares due to its large set of capabilities.&lt;/p&gt;

&lt;p&gt;As most malware families these days, this sample of Anubis is riding on the “COVID-19” pandemic to trick victims into installing it. This campaign seems to be targeting Turkey and the app can be downloaded from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;http://sosyalkampanya2[.]ml/pandemi/Pandemi-Destek.apk&quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/0.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/0.png&quot; alt=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anubis can spread in two different ways, either by malicious websites (like this one) where it downloads the malicious app directly or it can spread over google play store (where it appears as a legitimate app) then download and install the next stage payload (the malicious app).&lt;/p&gt;

&lt;h1 id=&quot;behavioral-analysis&quot;&gt;Behavioral Analysis&lt;/h1&gt;

&lt;p&gt;After installation, Anubis forces the user to grant it &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Accessibility&lt;/code&gt; permissions so it can run in the background and receive callbacks by the system when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AccessibilityEvents&lt;/code&gt; are fired (such as window change and input focus).&lt;/p&gt;

&lt;p&gt;Anubis also hides its icon from the app launcher to make it more difficult to remove.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/1.gif&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/1.gif&quot; alt=&quot;1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;going-inside&quot;&gt;Going inside&lt;/h1&gt;

&lt;p&gt;After decompiling the APK, we can see that it’s asking for lots of permissions, which means lots of capabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/2.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/2.png&quot; alt=&quot;2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;capabilities&quot;&gt;Capabilities&lt;/h1&gt;

&lt;p&gt;Anubis has a large set of capabilities such as (Keylogging, Sound Recording, SMS Spam, VNC, File Encryption, …).&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/4.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/4.png&quot; alt=&quot;4&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/5.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/5.png&quot; alt=&quot;5&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h1 id=&quot;c2-servers&quot;&gt;C2 servers&lt;/h1&gt;

&lt;p&gt;A quick search for “http/https” reveals some interesting things.
First, Anubis has a hardcoded C2 server &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;http://sosyalkampanya2[.]tk/dedebus/&quot;&lt;/code&gt;, it’s also used as a VNC client.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/6.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/6.png&quot; alt=&quot;6&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get new C2 servers, Anubis uses a twitter account for this purpose.&lt;/p&gt;

&lt;p&gt;Interestingly enough, the twitter account used here was registered back in 2007.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/7.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/7.png&quot; alt=&quot;7&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The way this technique works is that it queries the twitter page (containing Chinese tweets) and searches for the text in between those two tags ( “ 苏尔的开始” ,  “ 苏尔苏尔完” ).&lt;/p&gt;

&lt;p&gt;Next it replaces each Chinese character with a corresponding English character.&lt;/p&gt;

&lt;p&gt;Finally, the result is Base64-decoded then it’s decrypted using RC4.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/8.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/8.png&quot; alt=&quot;8&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the RC4 implementation:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/9.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/9.png&quot; alt=&quot;9&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The RC4 key is not dynamically generated, instead it’s using a hardcoded one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;zanubis&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/10.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/10.png&quot; alt=&quot;10&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;data-exfiltration&quot;&gt;Data Exfiltration&lt;/h1&gt;

&lt;p&gt;Anubis has a list of php endpoints to exfiltrate collected data, each endpoint corresponds to a different log type (keystrokes, running processes, …).&lt;/p&gt;

&lt;p&gt;It sends a POST request to the C2 server containing the data in an encrypted form.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/11.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/11.png&quot; alt=&quot;11&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The data is encrypted using RC4 with the same key mentioned before then it’s Base64-encoded before it’s exfiltrated.&lt;/p&gt;

&lt;h1 id=&quot;receiving-commands&quot;&gt;Receiving Commands&lt;/h1&gt;

&lt;p&gt;Anubis can receive RAT commands (encrypted):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;opendir&lt;/li&gt;
  &lt;li&gt;downloadfile&lt;/li&gt;
  &lt;li&gt;deletefilefolder&lt;/li&gt;
  &lt;li&gt;startscreenVNC&lt;/li&gt;
  &lt;li&gt;stopscreenVNC&lt;/li&gt;
  &lt;li&gt;startsound&lt;/li&gt;
  &lt;li&gt;startforegroundsound&lt;/li&gt;
  &lt;li&gt;stopsound&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/12.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/12.png&quot; alt=&quot;12&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, it can receive a long string of commands separated by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;::&quot;&lt;/code&gt; to enable/disable certain functionalities, edit configs or send logs.&lt;/p&gt;

&lt;details style=&quot;color: #EEFFFF; font-family: monospace !default; font-size: 0.85em; background: #263238; border: 1px solid #263238; border-radius: 3px; padding: 10px; line-height: 1.8&quot;&gt;
    &lt;summary style=&quot;outline: none; cursor: pointer&quot;&gt;
        &lt;span style=&quot;color: darkgray&quot;&gt;
            Expand to see more
        &lt;/span&gt;&lt;br /&gt;
&amp;emsp; startinj&lt;br /&gt;
&amp;emsp; Send_GO_SMS&lt;br /&gt;
&amp;emsp; nymBePsG0&lt;br /&gt;
&amp;emsp; GetSWSGO&lt;br /&gt;
&amp;emsp; telbookgotext&lt;br /&gt;
&amp;emsp; getapps&lt;br /&gt;
&amp;emsp; getpermissions&lt;br /&gt;
&lt;/summary&gt;
&amp;emsp; startaccessibility&lt;br /&gt;
&amp;emsp; startpermission&lt;br /&gt;
&amp;emsp; ALERT&lt;br /&gt;
&amp;emsp; PUSH&lt;br /&gt;
&amp;emsp; startAutoPush&lt;br /&gt;
&amp;emsp; RequestPermissionInj&lt;br /&gt;
&amp;emsp; RequestPermissionGPS&lt;br /&gt;
&amp;emsp; ussd&lt;br /&gt;
&amp;emsp; sockshost&lt;br /&gt;
&amp;emsp; stopsocks5&lt;br /&gt;
&amp;emsp; spam&lt;br /&gt;
&amp;emsp; recordsound&lt;br /&gt;
&amp;emsp; replaceurl&lt;br /&gt;
&amp;emsp; startapplication&lt;br /&gt;
&amp;emsp; killBot&lt;br /&gt;
&amp;emsp; getkeylogger&lt;br /&gt;
&amp;emsp; startrat&lt;br /&gt;
&amp;emsp; startforward&lt;br /&gt;
&amp;emsp; stopforward&lt;br /&gt;
&amp;emsp; openbrowser&lt;br /&gt;
&amp;emsp; openactivity&lt;br /&gt;
&amp;emsp; cryptokey&lt;br /&gt;
&amp;emsp; decryptokey&lt;br /&gt;
&amp;emsp; getIP&lt;br /&gt;
&lt;/details&gt;

&lt;h1 id=&quot;keylogging&quot;&gt;Keylogging&lt;/h1&gt;

&lt;p&gt;Anubis is listening for accessibility events in the background, if the event is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;TYPE_VIEW_TEXT_CHANGED&quot;&lt;/code&gt;, this means that the user is typing something so it gets records.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/13.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/13.png&quot; alt=&quot;13&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The keystrokes are written to a file called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;keys.log&quot;&lt;/code&gt;, this file is sent to the attacker on demand along with the victim’s device info. The file’s contents can be erased if the C2 response contains the word &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;clear&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/14.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/14.png&quot; alt=&quot;14&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;file-encryption&quot;&gt;File Encryption&lt;/h1&gt;

&lt;p&gt;Anubis can also behave like a ransomware and encrypt files at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mnt, /mount, /sdcard, /storage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/15.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/15.png&quot; alt=&quot;15&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The encryption/decryption key is received from the C2 server along with the required amount to decrypt the files.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/16.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/16.png&quot; alt=&quot;16&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/17.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/17.png&quot; alt=&quot;17&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The encryption process itself is just RC4 using the received key. Then it writes the encrypted data to a new file with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.AnubisCrypt&lt;/code&gt; extension and deletes the original file.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/18.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/18.png&quot; alt=&quot;18&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;screen-vnc&quot;&gt;Screen VNC&lt;/h1&gt;

&lt;p&gt;This feature was recently added to Anubis (according to underground forums), it can start a VNC server using &lt;a href=&quot;http://developer.android.com/reference/android/media/projection/MediaProjection.html&quot;&gt;MediaProjection&lt;/a&gt; APIs available from Android 5.&lt;/p&gt;

&lt;p&gt;Due to Android API restrictions, the attacker can only see the screen of an Android 5+ device but cannot control it.&lt;/p&gt;

&lt;p&gt;As mentioned before, Anubis uses the hardcoded C2 server &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;http://sosyalkampanya2[.]tk/dedebus/&quot;&lt;/code&gt; as a VNC client.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/19.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/19.png&quot; alt=&quot;19&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;intercepting-calls-and-sms&quot;&gt;Intercepting Calls and SMS&lt;/h1&gt;

&lt;p&gt;Anubis can intercept and forward phone calls to the attacker (which can be used for bank verification for example), it also tries to mute the phone for android 6.0 and lower.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/20.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/20.png&quot; alt=&quot;20&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/21.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/21.png&quot; alt=&quot;21&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;SMS messages are intercepting using a broadcast receiver that listens for incoming SMS and sends it to the C2 server in clear text.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/22.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/22.png&quot; alt=&quot;22&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;targeted-apps&quot;&gt;Targeted Apps&lt;/h1&gt;

&lt;p&gt;Anubis loops through installed applications and compares them against hardcoded packages names (mostly banking apps). Once it determines that one of these apps is being used, it can carry out an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;overlay&lt;/code&gt; attack.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/3.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/3.png&quot; alt=&quot;3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Overlay attack works by loading a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WebView&lt;/code&gt; on top of the legitimate app that looks very similar to the original one. It can be used to steal payment data or used as an attack vector for phishing.&lt;/p&gt;

&lt;p&gt;The loading of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WebView&lt;/code&gt; is almost instant so that the victim doesn’t get suspicious.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/23.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/23.png&quot; alt=&quot;23&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;attempting-to-remove-anubis&quot;&gt;Attempting to Remove Anubis&lt;/h1&gt;

&lt;p&gt;Anubis can utilize accessibility events to prevent the victim from uninstalling it.&lt;/p&gt;

&lt;p&gt;It checks if the current open view contains these strings:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;current app name (malware app)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;com.android.settings&quot;&lt;/code&gt; which is the settings app&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;uninstall&quot;&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;to remove&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If that’s the case, the victim is sent back to the home screen.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/25.gif&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/25.gif&quot; alt=&quot;25&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/anubis-banking-malware/24.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/anubis-banking-malware/24.png&quot; alt=&quot;24&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Anubis is a very rich banking malware with lots of features and capabilities. Although there are rumors that Maza-In (the actor behind Anubis) had been arrested by the Russian authorities, we can see that it’s getting new updates (currently 2.5) and it’s still a common choice of criminals when it comes to Android banking malware.&lt;/p&gt;

&lt;p&gt;I have also written a small script for fetching new C2 domains + decrypting sent/received data:
&lt;a href=&quot;https://github.com/N1ght-W0lf/MalwareAnalysis/blob/master/Anubis/c2_emulator.py&quot;&gt;https://github.com/N1ght-W0lf/MalwareAnalysis/blob/master/Anubis/c2_emulator.py&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;iocs&quot;&gt;IOCs&lt;/h1&gt;

&lt;h4 id=&quot;apks&quot;&gt;&lt;u&gt;APKs&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;Pandemi-Destek.apk: 8cb941658ed8340b67a38a47162ab8850b89a14eee2899f0761fadd4f648fd5e&lt;/p&gt;

&lt;h4 id=&quot;c2-related&quot;&gt;&lt;u&gt;C2 Related&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;http://sosyalkampanya2[.]tk/dedebus/&lt;/p&gt;

&lt;p&gt;https://twitter[.]com/qweqweqwe/&lt;/p&gt;

&lt;h4 id=&quot;targeted-apps-1&quot;&gt;&lt;u&gt;Targeted Apps&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;at.spardat.bcrmobile&lt;/p&gt;

&lt;p&gt;at.spardat.netbanking&lt;/p&gt;

&lt;p&gt;com.bankaustria.android.olb&lt;/p&gt;

&lt;p&gt;com.bmo.mobile&lt;/p&gt;

&lt;p&gt;com.cibc.android.mobi&lt;/p&gt;

&lt;p&gt;com.rbc.mobile.android&lt;/p&gt;

&lt;p&gt;com.scotiabank.mobile&lt;/p&gt;

&lt;p&gt;com.td&lt;/p&gt;

&lt;p&gt;cz.airbank.android&lt;/p&gt;

&lt;p&gt;eu.inmite.prj.kb.mobilbank&lt;/p&gt;

&lt;p&gt;com.bankinter.launcher&lt;/p&gt;

&lt;p&gt;com.kutxabank.android&lt;/p&gt;

&lt;p&gt;com.rsi&lt;/p&gt;

&lt;p&gt;com.tecnocom.cajalaboral&lt;/p&gt;

&lt;p&gt;es.bancopopular.nbmpopular&lt;/p&gt;

&lt;p&gt;es.evobanco.bancamovil&lt;/p&gt;

&lt;p&gt;es.lacaixa.mobile.android.newwapicon&lt;/p&gt;

&lt;p&gt;com.dbs.hk.dbsmbanking&lt;/p&gt;

&lt;p&gt;com.FubonMobileClient&lt;/p&gt;

&lt;p&gt;com.hangseng.rbmobile&lt;/p&gt;

&lt;p&gt;com.MobileTreeApp&lt;/p&gt;

&lt;p&gt;com.mtel.androidbea&lt;/p&gt;

&lt;p&gt;com.scb.breezebanking.hk&lt;/p&gt;

&lt;p&gt;hk.com.hsbc.hsbchkmobilebanking&lt;/p&gt;

&lt;p&gt;com.aff.otpdirekt&lt;/p&gt;

&lt;p&gt;com.ideomobile.hapoalim&lt;/p&gt;

&lt;p&gt;com.infrasofttech.indianBank&lt;/p&gt;

&lt;p&gt;com.mobikwik_new&lt;/p&gt;

&lt;p&gt;com.oxigen.oxigenwallet&lt;/p&gt;

&lt;p&gt;jp.co.aeonbank.android.passbook&lt;/p&gt;

&lt;p&gt;jp.co.netbk&lt;/p&gt;

&lt;p&gt;jp.co.rakuten_bank.rakutenbank&lt;/p&gt;

&lt;p&gt;jp.co.sevenbank.AppPassbook&lt;/p&gt;

&lt;p&gt;jp.co.smbc.direct&lt;/p&gt;

&lt;p&gt;jp.mufg.bk.applisp.app&lt;/p&gt;

&lt;p&gt;com.barclays.ke.mobile.android.ui&lt;/p&gt;

&lt;p&gt;nz.co.anz.android.mobilebanking&lt;/p&gt;

&lt;p&gt;nz.co.asb.asbmobile&lt;/p&gt;

&lt;p&gt;nz.co.bnz.droidbanking&lt;/p&gt;

&lt;p&gt;nz.co.kiwibank.mobile&lt;/p&gt;

&lt;p&gt;com.getingroup.mobilebanking&lt;/p&gt;

&lt;p&gt;eu.eleader.mobilebanking.pekao.firm&lt;/p&gt;

&lt;p&gt;eu.eleader.mobilebanking.pekao&lt;/p&gt;

&lt;p&gt;eu.eleader.mobilebanking.raiffeisen&lt;/p&gt;

&lt;p&gt;pl.bzwbk.bzwbk24&lt;/p&gt;

&lt;p&gt;pl.ipko.mobile&lt;/p&gt;

&lt;p&gt;pl.mbank&lt;/p&gt;

&lt;p&gt;alior.bankingapp.android&lt;/p&gt;

&lt;p&gt;com.comarch.mobile.banking.bgzbnpparibas.biznes&lt;/p&gt;

&lt;p&gt;com.comarch.security.mobilebanking&lt;/p&gt;

&lt;p&gt;com.empik.empikapp&lt;/p&gt;

&lt;p&gt;com.empik.empikfoto&lt;/p&gt;

&lt;p&gt;com.finanteq.finance.ca&lt;/p&gt;

&lt;p&gt;com.orangefinansek&lt;/p&gt;

&lt;p&gt;com.orangefinanse&lt;/p&gt;

&lt;p&gt;eu.eleader.mobilebanking.invest&lt;/p&gt;

&lt;p&gt;pl.aliorbank.aib&lt;/p&gt;

&lt;p&gt;pl.allegro&lt;/p&gt;

&lt;p&gt;pl.bosbank.mobile&lt;/p&gt;

&lt;p&gt;pl.bph&lt;/p&gt;

&lt;p&gt;pl.bps.bankowoscmobilna&lt;/p&gt;

&lt;p&gt;pl.bzwbk.ibiznes24&lt;/p&gt;

&lt;p&gt;pl.bzwbk.mobile.tab.bzwbk24&lt;/p&gt;

&lt;p&gt;pl.ceneo&lt;/p&gt;

&lt;p&gt;pl_pl.ceneo&lt;/p&gt;

&lt;p&gt;pl.com.rossmann.centauros&lt;/p&gt;

&lt;p&gt;pl.fmbank.smart&lt;/p&gt;

&lt;p&gt;pl.ideabank.mobilebanking&lt;/p&gt;

&lt;p&gt;pl.ing.mojeing&lt;/p&gt;

&lt;p&gt;pl.millennium.corpApp&lt;/p&gt;

&lt;p&gt;pl.orange.mojeorange&lt;/p&gt;

&lt;p&gt;pl.pkobp.iko&lt;/p&gt;

&lt;p&gt;pl.pkobp.ipkobiznes&lt;/p&gt;

&lt;p&gt;com.kuveytturk.mobil&lt;/p&gt;

&lt;p&gt;com.magiclick.odeabank&lt;/p&gt;

&lt;p&gt;com.mobillium.papara&lt;/p&gt;

&lt;p&gt;com.pozitron.albarakaturk&lt;/p&gt;

&lt;p&gt;com.teb&lt;/p&gt;

&lt;p&gt;ccom.tmob.denizbank&lt;/p&gt;

&lt;p&gt;com.tmob.denizbank&lt;/p&gt;

&lt;p&gt;com.tmob.tabletdeniz&lt;/p&gt;

&lt;p&gt;com.vakifbank.mobilel&lt;/p&gt;

&lt;p&gt;com.vakifbank.mobile&lt;/p&gt;

&lt;p&gt;tr.com.sekerbilisim.mbank&lt;/p&gt;

&lt;p&gt;wit.android.bcpBankingApp.millenniumPL&lt;/p&gt;

&lt;p&gt;com.advantage.RaiffeisenBank&lt;/p&gt;

&lt;p&gt;hr.asseco.android.jimba.mUCI.ro&lt;/p&gt;

&lt;p&gt;may.maybank.android&lt;/p&gt;

&lt;p&gt;ro.btrl.mobile&lt;/p&gt;

&lt;p&gt;com.amazon.mShop.android.shopping&lt;/p&gt;

&lt;p&gt;com.amazon.windowshop&lt;/p&gt;

&lt;p&gt;com.ebay.mobile&lt;/p&gt;

&lt;p&gt;ru.sberbankmobile&lt;/p&gt;

&lt;p&gt;ru.sberbank.spasibo&lt;/p&gt;

&lt;p&gt;ru.sberbank_sbbol&lt;/p&gt;

&lt;p&gt;ru.sberbank.mobileoffice&lt;/p&gt;

&lt;p&gt;ru.sberbank.sberbankir&lt;/p&gt;

&lt;p&gt;ru.alfabank.mobile.android&lt;/p&gt;

&lt;p&gt;ru.alfabank.oavdo.amc&lt;/p&gt;

&lt;p&gt;by.st.alfa&lt;/p&gt;

&lt;p&gt;ru.alfabank.sense&lt;/p&gt;

&lt;p&gt;ru.alfadirect.app&lt;/p&gt;

&lt;p&gt;ru.mw&lt;/p&gt;

&lt;p&gt;com.idamob.tinkoff.android&lt;/p&gt;

&lt;p&gt;ru.tcsbank.c2c&lt;/p&gt;

&lt;p&gt;ru.tinkoff.mgp&lt;/p&gt;

&lt;p&gt;ru.tinkoff.sme&lt;/p&gt;

&lt;p&gt;ru.tinkoff.goabroad&lt;/p&gt;

&lt;p&gt;ru.vtb24.mobilebanking.android&lt;/p&gt;

&lt;p&gt;ru.bm.mbm&lt;/p&gt;

&lt;p&gt;com.vtb.mobilebank&lt;/p&gt;

&lt;p&gt;com.bssys.VTBClient&lt;/p&gt;

&lt;p&gt;com.bssys.vtb.mobileclient&lt;/p&gt;

&lt;p&gt;com.akbank.android.apps.akbank_direkt&lt;/p&gt;

&lt;p&gt;com.akbank.android.apps.akbank_direkt_tablet&lt;/p&gt;

&lt;p&gt;com.akbank.softotp&lt;/p&gt;

&lt;p&gt;com.akbank.android.apps.akbank_direkt_tablet_20&lt;/p&gt;

&lt;p&gt;com.fragment.akbank&lt;/p&gt;

&lt;p&gt;com.ykb.android&lt;/p&gt;

&lt;p&gt;com.ykb.android.mobilonay&lt;/p&gt;

&lt;p&gt;com.ykb.avm&lt;/p&gt;

&lt;p&gt;com.ykb.androidtablet&lt;/p&gt;

&lt;p&gt;com.veripark.ykbaz&lt;/p&gt;

&lt;p&gt;com.softtech.iscek&lt;/p&gt;

&lt;p&gt;com.yurtdisi.iscep&lt;/p&gt;

&lt;p&gt;com.softtech.isbankasi&lt;/p&gt;

&lt;p&gt;com.monitise.isbankmoscow&lt;/p&gt;

&lt;p&gt;com.finansbank.mobile.cepsube&lt;/p&gt;

&lt;p&gt;finansbank.enpara&lt;/p&gt;

&lt;p&gt;com.magiclick.FinansPOS&lt;/p&gt;

&lt;p&gt;com.matriksdata.finansyatirim&lt;/p&gt;

&lt;p&gt;finansbank.enpara.sirketim&lt;/p&gt;

&lt;p&gt;com.vipera.ts.starter.QNB&lt;/p&gt;

&lt;p&gt;com.redrockdigimark&lt;/p&gt;

&lt;p&gt;com.garanti.cepsubesi&lt;/p&gt;

&lt;p&gt;com.garanti.cepbank&lt;/p&gt;

&lt;p&gt;com.garantibank.cepsubesiro&lt;/p&gt;

&lt;p&gt;biz.mobinex.android.apps.cep_sifrematik&lt;/p&gt;

&lt;p&gt;com.garantiyatirim.fx&lt;/p&gt;

&lt;p&gt;com.tmobtech.halkbank&lt;/p&gt;

&lt;p&gt;com.SifrebazCep&lt;/p&gt;

&lt;p&gt;eu.newfrontier.iBanking.mobile.Halk.Retail&lt;/p&gt;

&lt;p&gt;tr.com.tradesoft.tradingsystem.gtpmobile.halk&lt;/p&gt;

&lt;p&gt;com.DijitalSahne.EnYakinHalkbank&lt;/p&gt;

&lt;p&gt;com.ziraat.ziraatmobil&lt;/p&gt;

&lt;p&gt;com.ziraat.ziraattablet&lt;/p&gt;

&lt;p&gt;com.matriksmobile.android.ziraatTrader&lt;/p&gt;

&lt;p&gt;com.matriksdata.ziraatyatirim.pad&lt;/p&gt;

&lt;p&gt;de.comdirect.android&lt;/p&gt;

&lt;p&gt;de.commerzbanking.mobil&lt;/p&gt;

&lt;p&gt;de.consorsbank&lt;/p&gt;

&lt;p&gt;com.db.mm.deutschebank&lt;/p&gt;

&lt;p&gt;de.dkb.portalapp&lt;/p&gt;

&lt;p&gt;com.de.dkb.portalapp&lt;/p&gt;

&lt;p&gt;com.ing.diba.mbbr2&lt;/p&gt;

&lt;p&gt;de.postbank.finanzassistent&lt;/p&gt;

&lt;p&gt;mobile.santander.de&lt;/p&gt;

&lt;p&gt;de.fiducia.smartphone.android.banking.vr&lt;/p&gt;

&lt;p&gt;fr.creditagricole.androidapp&lt;/p&gt;

&lt;p&gt;fr.axa.monaxa&lt;/p&gt;

&lt;p&gt;fr.banquepopulaire.cyberplus&lt;/p&gt;

&lt;p&gt;net.bnpparibas.mescomptes&lt;/p&gt;

&lt;p&gt;com.boursorama.android.clients&lt;/p&gt;

&lt;p&gt;com.caisseepargne.android.mobilebanking&lt;/p&gt;

&lt;p&gt;fr.lcl.android.customerarea&lt;/p&gt;

&lt;p&gt;com.paypal.android.p2pmobile&lt;/p&gt;

&lt;p&gt;com.wf.wellsfargomobile&lt;/p&gt;

&lt;p&gt;com.wf.wellsfargomobile.tablet&lt;/p&gt;

&lt;p&gt;com.wellsFargo.ceomobile&lt;/p&gt;

&lt;p&gt;com.usbank.mobilebanking&lt;/p&gt;

&lt;p&gt;com.usaa.mobile.android.usaa&lt;/p&gt;

&lt;p&gt;com.suntrust.mobilebanking&lt;/p&gt;

&lt;p&gt;com.moneybookers.skrillpayments.neteller&lt;/p&gt;

&lt;p&gt;com.moneybookers.skrillpayments&lt;/p&gt;

&lt;p&gt;com.clairmail.fth&lt;/p&gt;

&lt;p&gt;com.konylabs.capitalone&lt;/p&gt;

&lt;p&gt;com.yinzcam.facilities.verizon&lt;/p&gt;

&lt;p&gt;com.chase.sig.android&lt;/p&gt;

&lt;p&gt;com.infonow.bofa&lt;/p&gt;

&lt;p&gt;com.bankofamerica.cashpromobile&lt;/p&gt;

&lt;p&gt;uk.co.bankofscotland.businessbank&lt;/p&gt;

&lt;p&gt;com.grppl.android.shell.BOS&lt;/p&gt;

&lt;p&gt;com.rbs.mobile.android.natwestoffshore&lt;/p&gt;

&lt;p&gt;com.rbs.mobile.android.natwest&lt;/p&gt;

&lt;p&gt;com.rbs.mobile.android.natwestbandc&lt;/p&gt;

&lt;p&gt;com.rbs.mobile.investisir&lt;/p&gt;

&lt;p&gt;com.phyder.engage&lt;/p&gt;

&lt;p&gt;com.rbs.mobile.android.rbs&lt;/p&gt;

&lt;p&gt;com.rbs.mobile.android.rbsbandc&lt;/p&gt;

&lt;p&gt;uk.co.santander.santanderUK&lt;/p&gt;

&lt;p&gt;uk.co.santander.businessUK.bb&lt;/p&gt;

&lt;p&gt;com.sovereign.santander&lt;/p&gt;

&lt;p&gt;com.ifs.banking.fiid4202&lt;/p&gt;

&lt;p&gt;com.fi6122.godough&lt;/p&gt;

&lt;p&gt;com.rbs.mobile.android.ubr&lt;/p&gt;

&lt;p&gt;com.htsu.hsbcpersonalbanking&lt;/p&gt;

&lt;p&gt;com.grppl.android.shell.halifax&lt;/p&gt;

&lt;p&gt;com.grppl.android.shell.CMBlloydsTSB73&lt;/p&gt;

&lt;p&gt;com.barclays.android.barclaysmobilebanking&lt;/p&gt;

&lt;p&gt;com.unionbank.ecommerce.mobile.android&lt;/p&gt;

&lt;p&gt;com.unionbank.ecommerce.mobile.commercial.legacy&lt;/p&gt;

&lt;p&gt;com.snapwork.IDBI&lt;/p&gt;

&lt;p&gt;com.idbibank.abhay_card&lt;/p&gt;

&lt;p&gt;src.com.idbi&lt;/p&gt;

&lt;p&gt;com.idbi.mpassbook&lt;/p&gt;

&lt;p&gt;com.ing.mobile&lt;/p&gt;

&lt;p&gt;com.snapwork.hdfc&lt;/p&gt;

&lt;p&gt;com.sbi.SBIFreedomPlus&lt;/p&gt;

&lt;p&gt;hdfcbank.hdfcquickbank&lt;/p&gt;

&lt;p&gt;com.csam.icici.bank.imobile&lt;/p&gt;

&lt;p&gt;in.co.bankofbaroda.mpassbook&lt;/p&gt;

&lt;p&gt;com.axis.mobile&lt;/p&gt;

&lt;p&gt;cz.csob.smartbanking&lt;/p&gt;

&lt;p&gt;cz.sberbankcz&lt;/p&gt;

&lt;p&gt;sk.sporoapps.accounts&lt;/p&gt;

&lt;p&gt;sk.sporoapps.skener&lt;/p&gt;

&lt;p&gt;com.cleverlance.csas.servis24&lt;/p&gt;

&lt;p&gt;org.westpac.bank&lt;/p&gt;

&lt;p&gt;nz.co.westpac&lt;/p&gt;

&lt;p&gt;org.westpac.banknz.co.westpac&lt;/p&gt;

&lt;p&gt;au.com.suncorp.SuncorpBank&lt;/p&gt;

&lt;p&gt;org.stgeorge.bank&lt;/p&gt;

&lt;p&gt;org.banksa.bank&lt;/p&gt;

&lt;p&gt;au.com.newcastlepermanent&lt;/p&gt;

&lt;p&gt;au.com.nab.mobile&lt;/p&gt;

&lt;p&gt;au.com.mebank.banking&lt;/p&gt;

&lt;p&gt;au.com.ingdirect.android&lt;/p&gt;

&lt;p&gt;MyING.be&lt;/p&gt;

&lt;p&gt;com.imb.banking2&lt;/p&gt;

&lt;p&gt;com.fusion.ATMLocator&lt;/p&gt;

&lt;p&gt;au.com.cua.mb&lt;/p&gt;

&lt;p&gt;com.commbank.netbank&lt;/p&gt;

&lt;p&gt;com.cba.android.netbank&lt;/p&gt;

&lt;p&gt;com.citibank.mobile.au&lt;/p&gt;

&lt;p&gt;com.citibank.mobile.uk&lt;/p&gt;

&lt;p&gt;com.citi.citimobile&lt;/p&gt;

&lt;p&gt;org.bom.bank&lt;/p&gt;

&lt;p&gt;com.bendigobank.mobile&lt;/p&gt;

&lt;p&gt;me.doubledutch.hvdnz.cbnationalconference2016&lt;/p&gt;

&lt;p&gt;au.com.bankwest.mobile&lt;/p&gt;

&lt;p&gt;com.bankofqueensland.boq&lt;/p&gt;

&lt;p&gt;com.anz.android.gomoney&lt;/p&gt;

&lt;p&gt;com.anz.android&lt;/p&gt;

&lt;p&gt;com.anz.SingaporeDigitalBanking&lt;/p&gt;

&lt;p&gt;com.anzspot.mobile&lt;/p&gt;

&lt;p&gt;com.crowdcompass.appSQ0QACAcYJ&lt;/p&gt;

&lt;p&gt;com.arubanetworks.atmanz&lt;/p&gt;

&lt;p&gt;com.quickmobile.anzirevents15&lt;/p&gt;

&lt;p&gt;at.volksbank.volksbankmobile&lt;/p&gt;

&lt;p&gt;it.volksbank.android&lt;/p&gt;

&lt;p&gt;it.secservizi.mobile.atime.bpaa&lt;/p&gt;

&lt;p&gt;de.fiducia.smartphone.android.securego.vr&lt;/p&gt;

&lt;p&gt;com.isis_papyrus.raiffeisen_pay_eyewdg&lt;/p&gt;

&lt;p&gt;at.easybank.mbanking&lt;/p&gt;

&lt;p&gt;at.easybank.tablet&lt;/p&gt;

&lt;p&gt;at.easybank.securityapp&lt;/p&gt;

&lt;p&gt;at.bawag.mbanking&lt;/p&gt;

&lt;p&gt;com.bawagpsk.securityapp&lt;/p&gt;

&lt;p&gt;at.psa.app.bawag&lt;/p&gt;

&lt;p&gt;com.pozitron.iscep&lt;/p&gt;

&lt;p&gt;com.pozitron.vakifbank&lt;/p&gt;

&lt;p&gt;com.starfinanz.smob.android.sfinanzstatus&lt;/p&gt;

&lt;p&gt;com.starfinanz.mobile.android.pushtan&lt;/p&gt;

&lt;p&gt;com.entersekt.authapp.sparkasse&lt;/p&gt;

&lt;p&gt;com.starfinanz.smob.android.sfinanzstatus.tablet&lt;/p&gt;

&lt;p&gt;com.starfinanz.smob.android.sbanking&lt;/p&gt;

&lt;p&gt;com.palatine.android.mobilebanking.prod&lt;/p&gt;

&lt;p&gt;fr.laposte.lapostemobile&lt;/p&gt;

&lt;p&gt;fr.laposte.lapostetablet&lt;/p&gt;

&lt;p&gt;com.cm_prod.bad&lt;/p&gt;

&lt;p&gt;com.cm_prod.epasal&lt;/p&gt;

&lt;p&gt;com.cm_prod_tablet.bad&lt;/p&gt;

&lt;p&gt;com.cm_prod.nosactus&lt;/p&gt;

&lt;p&gt;mobi.societegenerale.mobile.lappli&lt;/p&gt;

&lt;p&gt;com.bbva.netcash&lt;/p&gt;

&lt;p&gt;com.bbva.bbvacontigo&lt;/p&gt;

&lt;p&gt;com.bbva.bbvawallet&lt;/p&gt;

&lt;p&gt;es.bancosantander.apps&lt;/p&gt;

&lt;p&gt;com.santander.app&lt;/p&gt;

&lt;p&gt;es.cm.android&lt;/p&gt;

&lt;p&gt;es.cm.android.tablet&lt;/p&gt;

&lt;p&gt;com.bankia.wallet&lt;/p&gt;

&lt;p&gt;com.jiffyondemand.user&lt;/p&gt;

&lt;p&gt;com.latuabancaperandroid&lt;/p&gt;

&lt;p&gt;com.latuabanca_tabperandroid&lt;/p&gt;

&lt;p&gt;com.lynxspa.bancopopolare&lt;/p&gt;

&lt;p&gt;com.unicredit&lt;/p&gt;

&lt;p&gt;it.bnl.apps.banking&lt;/p&gt;

&lt;p&gt;it.bnl.apps.enterprise.bnlpay&lt;/p&gt;

&lt;p&gt;it.bpc.proconl.mbplus&lt;/p&gt;

&lt;p&gt;it.copergmps.rt.pf.android.sp.bmps&lt;/p&gt;

&lt;p&gt;it.gruppocariparma.nowbanking&lt;/p&gt;

&lt;p&gt;it.ingdirect.app&lt;/p&gt;

&lt;p&gt;it.nogood.container&lt;/p&gt;

&lt;p&gt;it.popso.SCRIGNOapp&lt;/p&gt;

&lt;p&gt;posteitaliane.posteapp.apppostepay&lt;/p&gt;

&lt;p&gt;com.abnamro.nl.mobile.payments&lt;/p&gt;

&lt;p&gt;com.triodos.bankingnl&lt;/p&gt;

&lt;p&gt;nl.asnbank.asnbankieren&lt;/p&gt;

&lt;p&gt;nl.snsbank.mobielbetalen&lt;/p&gt;

&lt;p&gt;com.btcturk&lt;/p&gt;

&lt;p&gt;com.ingbanktr.ingmobil&lt;/p&gt;

&lt;p&gt;tr.com.hsbc.hsbcturkey&lt;/p&gt;

&lt;p&gt;com.att.myWireless&lt;/p&gt;

&lt;p&gt;com.vzw.hss.myverizon&lt;/p&gt;

&lt;p&gt;aib.ibank.android&lt;/p&gt;

&lt;p&gt;com.bbnt&lt;/p&gt;

&lt;p&gt;com.csg.cs.dnmbs&lt;/p&gt;

&lt;p&gt;com.discoverfinancial.mobile&lt;/p&gt;

&lt;p&gt;com.eastwest.mobile&lt;/p&gt;

&lt;p&gt;com.fi6256.godough&lt;/p&gt;

&lt;p&gt;com.fi6543.godough&lt;/p&gt;

&lt;p&gt;com.fi6665.godough&lt;/p&gt;

&lt;p&gt;com.fi9228.godough&lt;/p&gt;

&lt;p&gt;com.fi9908.godough&lt;/p&gt;

&lt;p&gt;com.ifs.banking.fiid1369&lt;/p&gt;

&lt;p&gt;com.ifs.mobilebanking.fiid3919&lt;/p&gt;

&lt;p&gt;com.jackhenry.rockvillebankct&lt;/p&gt;

&lt;p&gt;com.jackhenry.washingtontrustbankwa&lt;/p&gt;

&lt;p&gt;com.jpm.sig.android&lt;/p&gt;

&lt;p&gt;com.sterling.onepay&lt;/p&gt;

&lt;p&gt;com.svb.mobilebanking&lt;/p&gt;

&lt;p&gt;org.usemployees.mobile&lt;/p&gt;

&lt;p&gt;pinacleMobileiPhoneApp.android&lt;/p&gt;

&lt;p&gt;com.fuib.android.spot.online&lt;/p&gt;

&lt;p&gt;com.ukrsibbank.client.android&lt;/p&gt;

&lt;p&gt;ru.alfabank.mobile.ua.android&lt;/p&gt;

&lt;p&gt;ua.aval.dbo.client.android&lt;/p&gt;

&lt;p&gt;ua.com.cs.ifobs.mobile.android.otp&lt;/p&gt;

&lt;p&gt;ua.com.cs.ifobs.mobile.android.pivd&lt;/p&gt;

&lt;p&gt;ua.oschadbank.online&lt;/p&gt;

&lt;p&gt;ua.privatbank.ap24&lt;/p&gt;

&lt;p&gt;com.Plus500&lt;/p&gt;

&lt;p&gt;com.Plus500(Crypt)+&lt;/p&gt;

&lt;p&gt;eu.unicreditgroup.hvbapptan&lt;/p&gt;

&lt;p&gt;com.targo_prod.bad&lt;/p&gt;

&lt;p&gt;com.db.pwcc.dbmobile&lt;/p&gt;

&lt;p&gt;com.db.mm.norisbank&lt;/p&gt;

&lt;p&gt;com.bitmarket.trader&lt;/p&gt;

&lt;p&gt;com.bitmarket.trader(Crypt)+&lt;/p&gt;

&lt;p&gt;com.plunien.poloniex&lt;/p&gt;

&lt;p&gt;com.plunien.poloniex(Crypt)+&lt;/p&gt;

&lt;p&gt;com.mycelium.wallet&lt;/p&gt;

&lt;p&gt;com.mycelium.wallet(Crypt)+&lt;/p&gt;

&lt;p&gt;com.bitfinex.bfxapp&lt;/p&gt;

&lt;p&gt;com.bitfinex.bfxapp(Crypt)+&lt;/p&gt;

&lt;p&gt;com.binance.dev&lt;/p&gt;

&lt;p&gt;com.binance.dev(Crypt)+&lt;/p&gt;

&lt;p&gt;com.btcturk(Crypt)&lt;/p&gt;

&lt;p&gt;com.binance.odapplications&lt;/p&gt;

&lt;p&gt;com.binance.odapplications(Crypt)&lt;/p&gt;

&lt;p&gt;com.blockfolio.blockfolio&lt;/p&gt;

&lt;p&gt;com.blockfolio.blockfolio(Crypt)&lt;/p&gt;

&lt;p&gt;com.crypter.cryptocyrrency&lt;/p&gt;

&lt;p&gt;com.crypter.cryptocyrrency(Crypt)&lt;/p&gt;

&lt;p&gt;io.getdelta.android&lt;/p&gt;

&lt;p&gt;io.getdelta.android(Crypt)&lt;/p&gt;

&lt;p&gt;com.edsoftapps.mycoinsvalue&lt;/p&gt;

&lt;p&gt;com.edsoftapps.mycoinsvalue(Crypt)&lt;/p&gt;

&lt;p&gt;com.coin.profit&lt;/p&gt;

&lt;p&gt;com.coin.profit(Crypt)&lt;/p&gt;

&lt;p&gt;com.mal.saul.coinmarketcap&lt;/p&gt;

&lt;p&gt;com.mal.saul.coinmarketcap(Crypt)&lt;/p&gt;

&lt;p&gt;com.tnx.apps.coinportfolio&lt;/p&gt;

&lt;p&gt;com.tnx.apps.coinportfolio(Crypt)&lt;/p&gt;

&lt;p&gt;com.coinbase.android&lt;/p&gt;

&lt;p&gt;com.coinbase.android(Crypt)+&lt;/p&gt;

&lt;p&gt;com.portfolio.coinbase_tracker&lt;/p&gt;

&lt;p&gt;com.portfolio.coinbase_tracker(Crypt)+&lt;/p&gt;

&lt;p&gt;de.schildbach.wallet&lt;/p&gt;

&lt;p&gt;de.schildbach.wallet(Crypt)&lt;/p&gt;

&lt;p&gt;piuk.blockchain.android&lt;/p&gt;

&lt;p&gt;piuk.blockchain.android(Crypt)+&lt;/p&gt;

&lt;p&gt;info.blockchain.merchant&lt;/p&gt;

&lt;p&gt;info.blockchain.merchant(Crypt)+&lt;/p&gt;

&lt;p&gt;com.jackpf.blockchainsearch&lt;/p&gt;

&lt;p&gt;com.jackpf.blockchainsearch(Crypt)&lt;/p&gt;

&lt;p&gt;com.unocoin.unocoinwallet&lt;/p&gt;

&lt;p&gt;com.unocoin.unocoinwallet(Crypt)+&lt;/p&gt;

&lt;p&gt;com.unocoin.unocoinmerchantPoS&lt;/p&gt;

&lt;p&gt;com.unocoin.unocoinmerchantPoS(Crypt)+&lt;/p&gt;

&lt;p&gt;com.thunkable.android.santoshmehta364.UNOCOIN_LIVE&lt;/p&gt;

&lt;p&gt;com.thunkable.android.santoshmehta364.UNOCOIN_LIVE(Crypt)&lt;/p&gt;

&lt;p&gt;wos.com.zebpay&lt;/p&gt;

&lt;p&gt;wos.com.zebpay(Crypt)+&lt;/p&gt;

&lt;p&gt;com.localbitcoinsmbapp&lt;/p&gt;

&lt;p&gt;com.localbitcoinsmbapp(Crypt)+&lt;/p&gt;

&lt;p&gt;com.thunkable.android.manirana54.LocalBitCoins&lt;/p&gt;

&lt;p&gt;com.thunkable.android.manirana54.LocalBitCoins(Crypt)+&lt;/p&gt;

&lt;p&gt;com.thunkable.android.manirana54.LocalBitCoins_unblock&lt;/p&gt;

&lt;p&gt;com.thunkable.android.manirana54.LocalBitCoins_unblock(Crypt)+&lt;/p&gt;

&lt;p&gt;com.localbitcoins.exchange&lt;/p&gt;

&lt;p&gt;com.localbitcoins.exchange(Crypt)+&lt;/p&gt;

&lt;p&gt;com.coins.bit.local&lt;/p&gt;

&lt;p&gt;com.coins.bit.local(Crypt)+&lt;/p&gt;

&lt;p&gt;com.coins.ful.bit&lt;/p&gt;

&lt;p&gt;com.coins.ful.bit(Crypt)+&lt;/p&gt;

&lt;p&gt;com.jamalabbasii1998.localbitcoin&lt;/p&gt;

&lt;p&gt;com.jamalabbasii1998.localbitcoin(Crypt)+&lt;/p&gt;

&lt;p&gt;zebpay.Application&lt;/p&gt;

&lt;p&gt;zebpay.Application(Crypt)+&lt;/p&gt;

&lt;p&gt;com.bitcoin.ss.zebpayindia&lt;/p&gt;

&lt;p&gt;com.bitcoin.ss.zebpayindia(Crypt)&lt;/p&gt;

&lt;p&gt;com.kryptokit.jaxx&lt;/p&gt;

&lt;p&gt;com.kryptokit.jaxx(Crypt)&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://info.phishlabs.com/blog/bankbot-anubis-telegram-chinese-c2&quot;&gt;https://info.phishlabs.com/blog/bankbot-anubis-telegram-chinese-c2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blog.trendmicro.com/trendlabs-security-intelligence/anubis-android-malware-returns-with-over-17000-samples/&quot;&gt;https://blog.trendmicro.com/trendlabs-security-intelligence/anubis-android-malware-returns-with-over-17000-samples/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://eybisi.run/Mobile-Malware-Analysis-Tricks-used-in-Anubis&quot;&gt;https://eybisi.run/Mobile-Malware-Analysis-Tricks-used-in-Anubis&lt;/a&gt;&lt;/p&gt;</content><author><name>Abdallah Elshinbary</name></author><category term="Malware Analysis" /><summary type="html">Introduction</summary></entry><entry><title type="html">Deep Analysis of SmokeLoader</title><link href="https://n1ght-w0lf.github.io/malware%20analysis/smokeloader/" rel="alternate" type="text/html" title="Deep Analysis of SmokeLoader" /><published>2020-06-21T00:00:00+00:00</published><updated>2020-06-21T00:00:00+00:00</updated><id>https://n1ght-w0lf.github.io/malware%20analysis/smokeloader</id><content type="html" xml:base="https://n1ght-w0lf.github.io/malware%20analysis/smokeloader/">&lt;p&gt;SmokeLoader is a well known bot that is been around since 2011. It’s mainly used to drop other malware families. SmokeLoader has been under development and is constantly changing with multiple novel features added throughout the years.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sample SHA256: fc20b03299b8ae91e72e104ee4f18e40125b2b061f1509d1c5b3f9fac3104934&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/0.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/0.png&quot; alt=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;stage-1&quot;&gt;Stage 1&lt;/h1&gt;

&lt;p&gt;This stage starts off by allocating memory for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shellcode&lt;/code&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LocalAlloc()&lt;/code&gt; (not VirtualAlloc), then it fills this memory with the shellcode (86 KB).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/1.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/1.png&quot; alt=&quot;1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, it changes the protection of the allocated memory region to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PAGE_EXECUTE_READWRITE&lt;/code&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualProtect()&lt;/code&gt;, then it writes the shellcode and executes it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/2.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/2.png&quot; alt=&quot;2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;shellcode&quot;&gt;Shellcode&lt;/h2&gt;

&lt;p&gt;The shellcode starts by getting the addresses of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadLibraryA&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetProcAddress&lt;/code&gt; to resolve APIs dynamically, but first let’s see how it does that.&lt;/p&gt;

&lt;p&gt;First it passes some hash values to a sub-routine that returns the address of the requested function.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/3.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/3.png&quot; alt=&quot;3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After some digging, I found out that the algorithm for calculating the hashes is pretty simple.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;calc_hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The shellcode uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PEB traversal&lt;/code&gt; technique for finding a function.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Process Environment Block (PEB) is a user-mode data structure that can be used by applications (and by extend by malware) to  get information such as the list of loaded modules, process startup  arguments, heap address among other useful capabilities.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The shellcode traverses the PEB structure at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FS[:30]&lt;/code&gt; and iterating through loaded modules to search for the requested module (kernel32 in this case). It hashes the name of each module using the algorithm above and compares it with the supplied hash.&lt;/p&gt;

&lt;p&gt;Next, it iterates over the export table of the module to find the requested function, similar to the previous step.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/4.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/4.png&quot; alt=&quot;4&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/5.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/5.png&quot; alt=&quot;5&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The next step is to resolve APIs using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadLibraryA&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetProcAddress&lt;/code&gt;, the shellcode uses stack strings to complicate the analysis.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/6.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/6.png&quot; alt=&quot;6&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the list of imported functions:&lt;/p&gt;

&lt;details style=&quot;color: #EEFFFF; font-family: monospace !default; font-size: 0.85em; background: #263238; border: 1px solid #263238; border-radius: 3px; padding: 10px; line-height: 1.8&quot;&gt;
    &lt;summary style=&quot;outline: none; cursor: pointer&quot;&gt;
        &lt;span style=&quot;color: darkgray&quot;&gt;
            Expand to see more
        &lt;/span&gt;&lt;br /&gt;
&amp;emsp; ntdll.dll&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtUnmapViewOfSection&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtWriteVirtualMemory&lt;br /&gt;
&amp;emsp; kernel32.dll&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; CloseHandle&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; CreateFileA&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; CreateProcessA&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; ExitProcess&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetCommandLineA&lt;br /&gt;
&lt;/summary&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetFileAttributesA&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetModuleFileNameA&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetStartupInfoA&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetThreadContext&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; ReadProcessMemory&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; ResumeThread&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; SetThreadContext&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; VirtualAlloc&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; VirtualAllocEx&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; VirtualFree&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; VirtualProtectEx&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; WaitForSingleObject&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; WinExec&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; WriteFile&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; WriteProcessMemory&lt;br /&gt;
&amp;emsp; user32.dll&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; CreateWindowExA&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; DefWindowProcA&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetMessageA&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetMessageExtraInfo&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; MessageBoxA&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; PostMessageA&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; RegisterClassExA&lt;br /&gt;
&lt;/details&gt;
&lt;h2 id=&quot;process-hollowing&quot;&gt;Process Hollowing&lt;/h2&gt;

&lt;p&gt;The shellcode creates a new processes of SmokeLoader in a suspended state.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/7.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/7.png&quot; alt=&quot;7&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, it hollows out the memory at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x400000&lt;/code&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ZwUnmapViewOfSection()&lt;/code&gt; and then allocates it again using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualAllocEx()&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RWX&lt;/code&gt; permissions.&lt;/p&gt;

&lt;p&gt;Finally, it writes the next stage executable to the allocated memory region using two calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ZwWriteVirtualMemory()&lt;/code&gt;, the first one to write the MZ header and the other for the rest of the executable.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/8.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/8.png&quot; alt=&quot;8&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;stage-2&quot;&gt;Stage 2&lt;/h1&gt;

&lt;p&gt;After dumping the second stage from memory, I got a warm welcome from SmokeLoader :(&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/9.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/9.png&quot; alt=&quot;9&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This stage is full of anti-analysis tricks, so let’s dive in.&lt;/p&gt;

&lt;h2 id=&quot;opaque-predicates&quot;&gt;Opaque Predicates&lt;/h2&gt;

&lt;p&gt;The first anti-analysis trick is &lt;a href=&quot;https://en.wikipedia.org/wiki/Opaque_predicate&quot;&gt;Opaque Predicates&lt;/a&gt;, it’s a commonly used technique in program obfuscation, intended to add complexity to the control flow. There are many patterns of this technique so I will stick with the one used here.&lt;/p&gt;

&lt;p&gt;This obfuscation simply takes an absolute jump (JMP) and transforms it into two conditional jumps (JZ/JNZ). Depending on the value of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Zero flag (ZF)&lt;/code&gt;, the execution will follow the first or second branch.&lt;/p&gt;

&lt;p&gt;However, disassemblers are tricked into thinking that there is a fall-through branch if the second jump is not taken (which is impossible as one of them must be taken) and tries to disassemble the unreachable instructions (often invalid) resulting in garbage code.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/10.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/10.png&quot; alt=&quot;10&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The deobfuscation is so simple, we just need to patch the first conditional jump to an absolute jump and nop out the second jump, we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDAPython&lt;/code&gt; to achieve this:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;idc&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEARCH_NEXT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEARCH_DOWN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;74 ? 75 ?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# JZ / JNZ
&lt;/span&gt;              &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEARCH_NEXT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEARCH_DOWN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;75 ? 74 ?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# JNZ / JZ
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BADADDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    	&lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xEB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;# JMP
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;# NOP
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;# NOP
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;anti-debugging&quot;&gt;Anti Debugging&lt;/h2&gt;

&lt;p&gt;This stage first checks &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OSMajorVersion at PEB[0xA4]&lt;/code&gt; if it’s greater than 6 (Windows Vista and higher), it’s also reading &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BeingDebugged at PEB[0x2]&lt;/code&gt; to check for attached debuggers.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/11.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/11.png&quot; alt=&quot;11&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What’s interesting here is that these checks are used to calculate the return address. If the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OSMajroVersion&lt;/code&gt; is less than 6 or there’s an attached debugger, it will jump to an invalid memory location. That’s clever.&lt;/p&gt;

&lt;p&gt;Another neat trick is that instead of using direct jumps, the code pushes the jump address stored at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eax&lt;/code&gt;  into the stack then returns to it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/12.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/12.png&quot; alt=&quot;12&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;encrypted-functions&quot;&gt;Encrypted Functions&lt;/h2&gt;

&lt;p&gt;Most of the functions are encrypted. After deobfuscating the opaque predicates, I found the encryption function which is pretty simple.&lt;/p&gt;

&lt;p&gt;The function takes an offset and a size, it XORes the chunk at that offset with a single byte &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(0xA6)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/13.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/13.png&quot; alt=&quot;13&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDAPython&lt;/code&gt; again to decrypt the encrypted chunks:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;idc&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;idautils&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;xor_chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x400000&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xA6&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch_byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;xor_chunk_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x401294&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;# address of the xoring function
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xref&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idautils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeRefsTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xor_chunk_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;mov_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idautils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeRefsTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_operand_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mov_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xref&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x400000&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;xor_chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After the decryption:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/14.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/14.png&quot; alt=&quot;14&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing to note here, SmokeLoader tries to keep as many encrypted code as possible. So once it’s done with the decrypted functions, it encrypts it again.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/15.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/15.png&quot; alt=&quot;15&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;anti-hooking&quot;&gt;Anti Hooking&lt;/h2&gt;

&lt;p&gt;Many Sandboxes and Security Solutions hook user-land functions of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ntdll.dll&lt;/code&gt; to trace system calls. SmokeLoader tries to evade this by using its own copy of ntdll. It copies &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ntdll.dll&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;%TEMP%\&amp;lt;hardcoded_name&amp;gt;.tmp&quot;&lt;/code&gt; then loads it using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LdrLoadDll()&lt;/code&gt; and resolves its imports from it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/16.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/16.png&quot; alt=&quot;16&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;custom-imports&quot;&gt;Custom Imports&lt;/h2&gt;

&lt;p&gt;SmokeLoader stores a hash table of its imports, it uses the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PEB traversal&lt;/code&gt; technique explained earlier to walk through the DLLs’ export table and compare the hash of each API name with the stored hashes.&lt;/p&gt;

&lt;p&gt;The hashing function is an implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;djb2&lt;/code&gt; hashing algorithms:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;calc_hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;api_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x1505&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;api_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// null byte included&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;api_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here is a list of imported functions and their corresponding hashes:&lt;/p&gt;

&lt;details style=&quot;color: #EEFFFF; font-family: monospace !default; font-size: 0.85em; background: #263238; border: 1px solid #263238; border-radius: 3px; padding: 10px; line-height: 1.8&quot;&gt;
    &lt;summary style=&quot;outline: none; cursor: pointer&quot;&gt;
        &lt;span style=&quot;color: darkgray&quot;&gt;
            Expand to see more
        &lt;/span&gt;&lt;br /&gt;
&amp;emsp; ntdll.dll&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; LdrLoadDll                  (0x64033f83)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtClose                     (0xfd507add)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtTerminateProcess          (0xf779110f)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; RtlInitUnicodeString        (0x60a350a9)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; RtlMoveMemory               (0x845136e7)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; RtlZeroMemory               (0x8a3d4cb0)&lt;br /&gt;
&amp;emsp; kernel32.dll&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; CopyFileW                   (0x306cceb7)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; CreateEventW                (0xfd4027f2)&lt;br /&gt;
&lt;/summary&gt;
&amp;emsp; &amp;emsp; &amp;ensp; CreateFileMappingW          (0x5b3f901c)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; CreateThread                (0x60277e71)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; DeleteFileW                 (0xb7e96d0f)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; ExpandEnvironmentStringsW   (0x057074bb)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetModuleFileNameA          (0x8acccaed)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetModuleFileNameW          (0x8acccdc3)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetModuleHandleA            (0x9cbd2a58)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetSystemDirectoryA         (0xaebc5060)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetTempFileNameW            (0x9a376a33)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetTempPathW                (0x7e28b9df)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetVolumeInformationA       (0xf25ce6a4)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; LocalAlloc                  (0xeda647bb)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; LocalFree                   (0x742c61b2)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; MapViewOfFile               (0x4db4c713)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; Sleep                       (0xd156a5be)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; WaitForSingleObject         (0x8681d8fa)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; lstrcatW                    (0x2ab51a99)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; lstrcmpA                    (0x2abb9b4b)&lt;br /&gt;
&amp;emsp; user32.dll&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; EnumChildWindows            (0x9a8897c9)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; EnumPropsA                  (0x8f0f57cf)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetForegroundWindow         (0x5a6c9878)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetKeyboardLayoutList       (0x04e9de30)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetShellWindow              (0xd454e895)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetWindowThreadProcessId    (0x576a5801)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; SendMessageA                (0x41ecd315)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; SendNotifyMessageA          (0xc6123bae)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; SetPropA                    (0x90bc10d3)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; wsprintfW                   (0x0bafd3f9)&lt;br /&gt;
&amp;emsp; advapi32.dll&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; GetTokenInformation         (0x696464ac)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; OpenProcessToken            (0x74f5e377)&lt;br /&gt;
&amp;emsp; shell32.dll&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; ShellExecuteExW             (0xf8e40384)&lt;br /&gt;
&lt;/details&gt;

&lt;p&gt;And here is the list of the imported functions from the copied ntdll (for anti-hooking):&lt;/p&gt;

&lt;details style=&quot;color: #EEFFFF; font-family: monospace !default; font-size: 0.85em; background: #263238; border: 1px solid #263238; border-radius: 3px; padding: 10px; line-height: 1.8&quot;&gt;
    &lt;summary style=&quot;outline: none; cursor: pointer&quot;&gt;
        &lt;span style=&quot;color: darkgray&quot;&gt;
            Expand to see more
        &lt;/span&gt;&lt;br /&gt;
&amp;emsp; 4DD3.tmp&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtAllocateVirtualMemory     (0x5a0c2ccc)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtCreateSection             (0xd5f23ad0)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtEnumerateKey              (0xb6306996)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtFreeVirtualMemory         (0x2a6fa509)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtMapViewOfSection          (0x870246aa)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtOpenKey                   (0xc29efe42)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtOpenProcess               (0x507bcb58)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtQueryInformationProcess   (0xd6d488a2)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtQueryKey                  (0xa9475346)&lt;br /&gt;
&lt;/summary&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtQuerySystemInformation    (0xb83de8a8)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtUnmapViewOfSection        (0x8352aa4d)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; NtWriteVirtualMemory        (0x546899d2)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; RtlDecompressBuffer         (0xdeb36606)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; towlower                    (0xf7660ba8)&lt;br /&gt;
&amp;emsp; &amp;emsp; &amp;ensp; wcsstr                      (0xbb629f0b)&lt;br /&gt;
&lt;/details&gt;

&lt;h2 id=&quot;anti-vm&quot;&gt;Anti VM&lt;/h2&gt;

&lt;p&gt;SmokeLoader enumerates all the subkeys of these keys:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;System\CurrentControlSet\Enum\IDE&lt;/li&gt;
  &lt;li&gt;System\CurrentControlSet\Enum\SCSI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it transforms them into lowercase and searches for these strings in the enumerated keys names:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;qemu&lt;/li&gt;
  &lt;li&gt;virtio&lt;/li&gt;
  &lt;li&gt;vmware&lt;/li&gt;
  &lt;li&gt;vbox&lt;/li&gt;
  &lt;li&gt;xen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If one of them is found, the binary exits.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/17.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/17.png&quot; alt=&quot;17&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/18.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/18.png&quot; alt=&quot;18&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;process-injection&quot;&gt;Process Injection&lt;/h2&gt;

&lt;p&gt;SmokeLoader uses &lt;a href=&quot;http://www.hexacorn.com/blog/2017/10/26/propagate-a-new-code-injection-trick/&quot;&gt;PROPagate&lt;/a&gt; injection method to inject the next stage into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explorer.exe&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First it decompresses the next stage using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RtlDecompressBuffer()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/19.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/19.png&quot; alt=&quot;19&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then there is a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NtOpenProcess()&lt;/code&gt; to open &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explorer.exe&lt;/code&gt; for the injection.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/20.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/20.png&quot; alt=&quot;20&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The injection process starts by creating two shared sections between the current process and explorer process (one section for the modified property and the other for the next stage’s code), then SmokeLoader maps the created sections to the current process and explorer process memory space (so any changes in the sections will be reflected in explorer process).&lt;/p&gt;

&lt;p&gt;Note that both sections have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;RWX&quot;&lt;/code&gt; protection which might raise some red flags by security solutions.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/21.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/21.png&quot; alt=&quot;21&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/22.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/22.png&quot; alt=&quot;22&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;We can see that explorer got a handle to these two sections (this is similar to classic code injection but with much more stealth).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/23.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/23.png&quot; alt=&quot;23&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SmokeLoader then writes the next stage to one of the sections and the modified property (which will call the next stage’s code) to the other section.&lt;/p&gt;

&lt;p&gt;Finally, it sets the modified property using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetPropA()&lt;/code&gt; and sends a message to explorer window using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SendNotifyMessageA()&lt;/code&gt;, this will result in the injected code being executed in the context of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explorer.exe&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/24.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/24.png&quot; alt=&quot;24&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;stage-3&quot;&gt;Stage 3&lt;/h1&gt;

&lt;p&gt;This is the final stage of SmokeLoader, it starts by doing some anti-analysis checks.&lt;/p&gt;

&lt;h2 id=&quot;checking-running-processes&quot;&gt;Checking Running Processes&lt;/h2&gt;

&lt;p&gt;This stage loops through the running process, it calculates each process name’s hash and compares it against some hardcoded hashes.&lt;/p&gt;

&lt;p&gt;Here is the algorithm for calculating the hash of a process name:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ROL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;calc_hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;proc_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;	
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;proc_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;proc_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xDF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ROL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;proc_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xDF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xD781F33C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A quick guess and I could get the processes names:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;0xD384255C  →  Autoruns.exe
0x76BDCBAB  →  procexp.exe
0xA159E6BE  →  procexp64.exe
0x7E9CCCA5  →  procmon.exe
0xA24B8E63  →  procmon64.exe
0x63B3D1A4  →  Tcpview.exe
0xA28974F3  →  Wireshark.exe
0xA9B5F897  →  ProcessHacker.exe
0x6893EBAB  →  ollydbg.exe
0xF5FD94B7  →  x32dbg.exe
0xCBFD99B0  →  x64dbg.exe
0x8993DEE5  →  idaq.exe
0x8993D8CF  →  idaw.exe
0x8C083960  →  idaq64.exe
0xB6223960  →  idaw64.exe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If one of these processes is found to be running, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explorer.exe&lt;/code&gt; will exit.&lt;/p&gt;

&lt;h2 id=&quot;encrypted-strings&quot;&gt;Encrypted Strings&lt;/h2&gt;

&lt;p&gt;All strings of this stage are encrypted using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RC4&lt;/code&gt; and they are decrypted on demand. The RC4 key = &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xFA5F66D7&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The encrypted strings are stored continuously in a big blob in this form:&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/25.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/25.png&quot; alt=&quot;25&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/26.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/26.png&quot; alt=&quot;26&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Here is a small script for decrypting these strings (I used Go because it has native support for RC4).&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;fmt&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;io/ioutil&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;encoding/hex&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;crypto/rc4&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RC4_KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DecodeString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;FA5F66D7&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rc4_decrypt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;cipher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rc4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NewCipher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RC4_KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;cipher&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XORKeyStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ioutil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReadFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dump&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;	
		&lt;span class=&quot;n&quot;&gt;rc4_decrypt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And here is the decrypted strings:&lt;/p&gt;

&lt;details style=&quot;color: #EEFFFF; font-family: monospace !default; font-size: 0.85em; background: #263238; border: 1px solid #263238; border-radius: 3px; padding: 10px; line-height: 2.2; overflow-x: scroll;&quot;&gt;
    &lt;summary style=&quot;outline: none; cursor: pointer&quot;&gt;
        &lt;span style=&quot;color: darkgray&quot;&gt;
            Expand to see more
        &lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;height: 1px&quot;&gt;&lt;/div&gt;
&amp;emsp; http://www.msftncsi.com/ncsi.txt&lt;br /&gt;
&amp;emsp; Software\Microsoft\Internet Explorer&lt;br /&gt;
&amp;emsp; advapi32.dll&lt;br /&gt;
&amp;emsp; Location:&lt;br /&gt;
&amp;emsp; plugin_size&lt;br /&gt;
&amp;emsp; \explorer.exe&lt;br /&gt;
&amp;emsp; user32&lt;br /&gt;
&lt;/summary&gt;
&amp;emsp; advapi32&lt;br /&gt;
&amp;emsp; urlmon&lt;br /&gt;
&amp;emsp; ole32&lt;br /&gt;
&amp;emsp; winhttp&lt;br /&gt;
&amp;emsp; ws2_32&lt;br /&gt;
&amp;emsp; dnsapi&lt;br /&gt;
&amp;emsp; svcVersion&lt;br /&gt;
&amp;emsp; Version&lt;br /&gt;
&amp;emsp; &amp;amp;lt?xml version=&quot;1.0&quot;?&amp;amp;gt&amp;amp;ltscriptlet&amp;amp;gt&amp;amp;ltregistration classid=&quot;{00000000-0000-0000-0000-00000000%04X}&quot;&amp;amp;gt&amp;amp;ltscript language=&quot;jscript&quot;&amp;amp;gt&amp;amp;lt![CDATA[GetObject(&quot;winmgmts:Win32_Process&quot;).Create(&quot;%ls&quot;,null,null,null);]]&amp;amp;gt&amp;amp;lt/script&amp;amp;gt&amp;amp;lt/registration&amp;amp;gt&amp;amp;lt/scriptlet&amp;amp;gt&lt;br /&gt;
&amp;emsp; S:(ML;;NW;;;LW)D:(A;;0x120083;;;WD)(A;;0x120083;;;AC)&lt;br /&gt;
&amp;emsp; %s\%hs&lt;br /&gt;
&amp;emsp; %s%s&lt;br /&gt;
&amp;emsp; regsvr32 /s %s&lt;br /&gt;
&amp;emsp; regsvr32 /s /n /u /i:&quot;%s&quot; scrobj&lt;br /&gt;
&amp;emsp; %APPDATA%&lt;br /&gt;
&amp;emsp; %TEMP%&lt;br /&gt;
&amp;emsp; .exe&lt;br /&gt;
&amp;emsp; .dll&lt;br /&gt;
&amp;emsp; :Zone.Identifier&lt;br /&gt;
&amp;emsp; POST&lt;br /&gt;
&amp;emsp; Content-Type: application/x-www-form-urlencoded&lt;br /&gt;
&amp;emsp; runas&lt;br /&gt;
&amp;emsp; Host: %s&lt;br /&gt;
&amp;emsp; PT10M&lt;br /&gt;
&amp;emsp; 1999-11-30T00:00:00&lt;br /&gt;
&amp;emsp; NvNgxUpdateCheckDaily_{&amp;#37;08X-&amp;#37;04X-&amp;#37;04X-&amp;#37;04X-&amp;#37;08X&amp;#37;04X}&lt;br /&gt;
&amp;emsp; Accept: */*&lt;br /&gt;
&amp;emsp; Referer: %S&lt;br /&gt;
&lt;/details&gt;
&lt;h2 id=&quot;encrypted-c2-domains&quot;&gt;Encrypted C2 Domains&lt;/h2&gt;

&lt;p&gt;The C2 domains are encrypted using simple XOR operations.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/27.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/27.png&quot; alt=&quot;27&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They are stored in a in this form:&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/28.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/28.png&quot; alt=&quot;28&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/29.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/29.png&quot; alt=&quot;29&quot; /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;We can easily decrypt the domains:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decrypt_c2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;enc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromhex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromhex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xE4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# decrypt_c2(&quot;E7FBFBFFB5A0A0E2E0FCFBEAFCFBA2FCEAFDF9E6ECEABFBEBDBABFBAA1FDFAA0&quot;, &quot;EFC11A5F&quot;)
# http://mostest-service012505.ru/
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;c2-communications&quot;&gt;C2 Communications&lt;/h2&gt;

&lt;p&gt;SmokeLoader sleeps for 10 seconds (1000*10) before connecting to the Internet.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/30.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/30.png&quot; alt=&quot;30&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First it queries &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://www.msftncsi.com/ncsi.txt&lt;/code&gt; (This URL is usually queried by Windows to determine if the computer is connected to the Internet).&lt;/p&gt;

&lt;p&gt;If there’s no response, it sleeps for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;64 ms&lt;/code&gt; and queries it again until it receives a response.&lt;/p&gt;

&lt;p&gt;Then SmokeLoader sends a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST&lt;/code&gt; request to the C2 server. The payload is encrypted using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RC4&lt;/code&gt; before sending it.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST&lt;/code&gt; request returns a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;404 Not Found&quot;&lt;/code&gt; response but it contains a payload in the response body.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/malware-analysis/smokeloader/31.png&quot;&gt;&lt;img src=&quot;/assets/images/malware-analysis/smokeloader/31.png&quot; alt=&quot;31&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately most of the C2 domains are down so I couldn’t proceed with the analysis, but I think that’s enough with SmokeLoader :)&lt;/p&gt;

&lt;h1 id=&quot;iocs&quot;&gt;IOCs&lt;/h1&gt;

&lt;h4 id=&quot;hashes&quot;&gt;&lt;u&gt;Hashes&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;SmokeLoader fc20b03299b8ae91e72e104ee4f18e40125b2b061f1509d1c5b3f9fac3104934&lt;/p&gt;

&lt;h4 id=&quot;files&quot;&gt;&lt;u&gt;Files&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;%TEMP%\4dd3.dll&lt;/p&gt;

&lt;h4 id=&quot;c2-domains&quot;&gt;&lt;u&gt;C2 Domains&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;http://alltest-service012505[.]ru/&lt;br /&gt;
http://besttest-service012505[.]ru/&lt;br /&gt;
http://biotest-service012505[.]ru/&lt;br /&gt;
http://clubtest-service012505[.]ru/&lt;br /&gt;
http://domtest-service012505[.]ru/&lt;br /&gt;
http://infotest-service012505[.]ru/&lt;br /&gt;
http://kupitest-service012505[.]ru/&lt;br /&gt;
http://megatest-service012505[.]ru/&lt;br /&gt;
http://mirtest-service012505[.]ru/&lt;br /&gt;
http://mostest-service012505[.]ru/&lt;br /&gt;
http://mytest-service01242505[.]ru/&lt;br /&gt;
http://mytest-service012505[.]ru/&lt;br /&gt;
http://newtest-service012505[.]ru/&lt;br /&gt;
http://proftest-service012505[.]ru/&lt;br /&gt;
http://protest-01242505[.]tk/&lt;br /&gt;
http://protest-01252505[.]ml/&lt;br /&gt;
http://protest-01262505[.]ga/&lt;br /&gt;
http://protest-01272505[.]cf/&lt;br /&gt;
http://protest-01282505[.]gq/&lt;br /&gt;
http://protest-01292505[.]com/&lt;br /&gt;
http://protest-01302505[.]net/&lt;br /&gt;
http://protest-01312505[.]org/&lt;br /&gt;
http://protest-01322505[.]biz/&lt;br /&gt;
http://protest-01332505[.]info/&lt;br /&gt;
http://protest-01342505[.]eu/&lt;br /&gt;
http://protest-01352505[.]nl/&lt;br /&gt;
http://protest-01362505[.]mobi/&lt;br /&gt;
http://protest-01372505[.]name/&lt;br /&gt;
http://protest-01382505[.]me/&lt;br /&gt;
http://protest-01392505[.]garden/&lt;br /&gt;
http://protest-01402505[.]art/&lt;br /&gt;
http://protest-01412505[.]band/&lt;br /&gt;
http://protest-01422505[.]bargains/&lt;br /&gt;
http://protest-01432505[.]bet/&lt;br /&gt;
http://protest-01442505[.]blue/&lt;br /&gt;
http://protest-01452505[.]business/&lt;br /&gt;
http://protest-01462505[.]casa/&lt;br /&gt;
http://protest-01472505[.]city/&lt;br /&gt;
http://protest-01482505[.]click/&lt;br /&gt;
http://protest-01492505[.]company/&lt;br /&gt;
http://protest-01502505[.]futbol/&lt;br /&gt;
http://protest-01512505[.]gallery/&lt;br /&gt;
http://protest-01522505[.]game/&lt;br /&gt;
http://protest-01532505[.]games/&lt;br /&gt;
http://protest-01542505[.]graphics/&lt;br /&gt;
http://protest-01552505[.]group/&lt;br /&gt;
http://protest-02252505[.]ml/&lt;br /&gt;
http://protest-02262505[.]ga/&lt;br /&gt;
http://protest-02272505[.]cf/&lt;br /&gt;
http://protest-02282505[.]gq/&lt;br /&gt;
http://protest-03252505[.]ml/&lt;br /&gt;
http://protest-03262505[.]ga/&lt;br /&gt;
http://protest-03272505[.]cf/&lt;br /&gt;
http://protest-03282505[.]gq/&lt;br /&gt;
http://protest-05242505[.]tk/&lt;br /&gt;
http://protest-06242505[.]tk/&lt;br /&gt;
http://protest-service01242505[.]ru/&lt;br /&gt;
http://protest-service012505[.]ru/&lt;br /&gt;
http://rustest-service012505[.]ru/&lt;br /&gt;
http://rutest-service01242505[.]ru/&lt;br /&gt;
http://rutest-service012505[.]ru/&lt;br /&gt;
http://shoptest-service012505[.]ru/&lt;br /&gt;
http://supertest-service012505[.]ru/&lt;br /&gt;
http://test-service01242505[.]ru/&lt;br /&gt;
http://test-service012505[.]com/&lt;br /&gt;
http://test-service012505[.]eu/&lt;br /&gt;
http://test-service012505[.]fun/&lt;br /&gt;
http://test-service012505[.]host/&lt;br /&gt;
http://test-service012505[.]info/&lt;br /&gt;
http://test-service012505[.]net/&lt;br /&gt;
http://test-service012505[.]net2505[.]ru/&lt;br /&gt;
http://test-service012505[.]online/&lt;br /&gt;
http://test-service012505[.]org2505[.]ru/&lt;br /&gt;
http://test-service012505[.]pp2505[.]ru/&lt;br /&gt;
http://test-service012505[.]press/&lt;br /&gt;
http://test-service012505[.]pro/&lt;br /&gt;
http://test-service012505[.]pw/&lt;br /&gt;
http://test-service012505[.]ru[.]com/&lt;br /&gt;
http://test-service012505[.]site/&lt;br /&gt;
http://test-service012505[.]space/&lt;br /&gt;
http://test-service012505[.]store/&lt;br /&gt;
http://test-service012505[.]su/&lt;br /&gt;
http://test-service012505[.]tech/&lt;br /&gt;
http://test-service012505[.]website/&lt;br /&gt;
http://test-service012505[.]xyz/&lt;br /&gt;
http://test-service01blog2505[.]ru/&lt;br /&gt;
http://test-service01club2505[.]ru/&lt;br /&gt;
http://test-service01forum2505[.]ru/&lt;br /&gt;
http://test-service01info2505[.]ru/&lt;br /&gt;
http://test-service01land2505[.]ru/&lt;br /&gt;
http://test-service01life2505[.]ru/&lt;br /&gt;
http://test-service01plus2505[.]ru/&lt;br /&gt;
http://test-service01pro2505[.]ru/&lt;br /&gt;
http://test-service01rus2505[.]ru/&lt;br /&gt;
http://test-service01shop2505[.]ru/&lt;br /&gt;
http://test-service01stroy2505[.]ru/&lt;br /&gt;
http://test-service01torg2505[.]ru/&lt;br /&gt;
http://toptest-service012505[.]ru/&lt;br /&gt;
http://vsetest-service012505[.]ru/&lt;br /&gt;&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://www.cert.pl/en/news/single/dissecting-smoke-loader/&quot;&gt;https://www.cert.pl/en/news/single/dissecting-smoke-loader/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://research.checkpoint.com/2019/2019-resurgence-of-smokeloader/&quot;&gt;https://research.checkpoint.com/2019/2019-resurgence-of-smokeloader/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb&quot;&gt;https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.aldeid.com/wiki/PEB-Process-Environment-Block&quot;&gt;https://www.aldeid.com/wiki/PEB-Process-Environment-Block&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.hexacorn.com/blog/2017/10/26/propagate-a-new-code-injection-trick&quot;&gt;http://www.hexacorn.com/blog/2017/10/26/propagate-a-new-code-injection-trick&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://modexp.wordpress.com/2018/08/23/process-injection-propagate/&quot;&gt;https://modexp.wordpress.com/2018/08/23/process-injection-propagate/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpconnect#examples&quot;&gt;https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpconnect#examples&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.crowdstrike.com/blog/maze-ransomware-deobfuscation/&quot;&gt;https://www.crowdstrike.com/blog/maze-ransomware-deobfuscation/&lt;/a&gt;&lt;/p&gt;</content><author><name>Abdallah Elshinbary</name></author><category term="Malware Analysis" /><summary type="html">SmokeLoader is a well known bot that is been around since 2011. It’s mainly used to drop other malware families. SmokeLoader has been under development and is constantly changing with multiple novel features added throughout the years.</summary></entry></feed>