Nikhil "Kaido" Hegde

M&M: Malware and Musings

View on GitHub

Source

Analysis

Obfuscation

A quick skim through the script indicated that there was some amount of junk code plus encoded/encrypted data. The obfuscation techniques are a subset of what was previously observed in a Telegram Stealer.

Deobfuscation

Utilities: https://github.com/nikhilh-20/re_tools/tree/main/powershell

> .\PsRemove-DeadCode.ps1 -InputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6.ps1 -OutputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass1.ps1
{"input_bytes":2310805,"output_path":"C:\\Users\\Ashura\\Desktop\\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass1.ps1","by_reason":"19x unreachable loop, 12x dead if (unreachable/empty), 2x pure statement, 5x dead try block, 68x dead store, 2x dead if (stores unused)","changed":108,"output_bytes":2307770,"aggressive":false}

> .\PsPropagate-Constants.ps1 -InputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass1.ps1 -OutputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass2.ps1
{"input_bytes":2307770,"output_path":"C:\\Users\\Ashura\\Desktop\\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass2.ps1","substituted_reads":54,"changed":106,"output_bytes":2304834,"folded_assignments":52}

> .\PsRemove-DeadCode.ps1 -InputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass2.ps1 -OutputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass3.ps1
{"input_bytes":2304834,"output_path":"C:\\Users\\Ashura\\Desktop\\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass3.ps1","by_reason":"52x dead store","changed":52,"output_bytes":2300641,"aggressive":false}

> .\PsDecode-ByteArray.ps1 -InputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass3.ps1 -OutputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass4.ps1
{"changed":1,"arrays_decoded":1,"output_path":"C:\\Users\\Ashura\\Desktop\\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass4.ps1","output_bytes":717477,"input_bytes":2300641}

> .\PsFold-ArrayJoins.ps1 -InputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass4.ps1 -OutputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass5.ps1
{"changed":1,"output_path":"C:\\Users\\Ashura\\Desktop\\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass5.ps1","output_bytes":716324,"input_bytes":717477}

> .\PsCollapse-BlankLines.ps1 -InputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass5.ps1 -OutputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass6.ps1
{"changed":20,"output_path":"C:\\Users\\Ashura\\Desktop\\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass6.ps1","output_bytes":715752,"input_bytes":716324}

> .\PsFold-Strings.ps1 -InputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass6.ps1 -OutputFile C:\Users\Ashura\Desktop\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass7.ps1
{"changed":3,"output_path":"C:\\Users\\Ashura\\Desktop\\fafb855519e1404ba4300e7beabe44c20172042582b1658b79e589206ff5c2e6_pass7.ps1","output_bytes":714593,"input_bytes":714663}

Functionality

Once the script was deobfuscated, it was straightforward to see that the embedded payload was base64-decoded + xor-decrypted and then executed via a dynamically created Script Block. This embedded payload was similar to a previously observed PowerShell loader that leverages Early Bird APC Injection.

Unexplained Code

The deobfuscated script had the below code which was executed through Invoke-Expression:

${Get-Partition -Include * -TaskPath \Backup\ && ($gtapam)} = 'ZnVuY3Rpb24gR2V0LUNvbnNvbGVDb2xvcgp7CiAgICBbQ21kbGV0QmluZGluZygpXQogICAgcGFyYW0oCiAgICAgICAgCiAgICApCgogICAgQmVnaW57CgogICAgfQoKICAgIFByb2Nlc3N7CiAgICAgICAgJENvbG9ycyA9IFtFbnVtXTo6R2V0VmFsdWVzKFtDb25zb2xlQ29sb3JdKQoKICAgICAgICBmb3JlYWNoKCRDb2xvciBpbiAkQ29sb3JzKQogICAgICAgIHsKICAgICAgICAgICAgW3BzY3VzdG9tb2JqZWN0XSBAewogICAgICAgICAgICAgICAgQ29uc29sZUNvbG9yID0gJENvbG9yCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgRW5kewoKICAgIH0KfQpHZXQtQ29uc29sZUNvbG9yIHwgT3V0LU51bGw='; [Text.Encoding]::('UTF8').('GetString')([Convert]::('FromBase64String')(${Get-Partition -Include * -TaskPath \Backup\ && ($gtapam)})) | &(Get-Command i*e-exp*)

The actual code decodes to:

function Get-ConsoleColor
{
    [CmdletBinding()]
    param(
        
    )

    Begin{

    }

    Process{
        $Colors = [Enum]::GetValues([ConsoleColor])

        foreach($Color in $Colors)
        {
            [pscustomobject] @{
                ConsoleColor = $Color
            }
        }
    }

    End{

    }
}
Get-ConsoleColor | Out-Null

The purpose of this code is not clear to me. It doesn’t take much time to run, so it’s not a time-based evasion. It doesn’t have any “side-effects” because the output of the function is redirected to Out-Null. A far-fetched observation is that this code could potentially influence code scanners and push the score towards “benign”.