Z2A-BlackLotus Challenge Stufe 2 Bootkit-Rootkit-Analyse
BlackLotus Stage-2-Bootkit-Rootkit-Analyse
Bevor wir in diese göttliche Scheiße eintauchen (glaub mir, das ist göttliche Scheiße, denn niemand kann das ohne Gottes Willen tun (zumindest ist das meine Meinung dazu)), hier ist der Hash für die Bootkit-Datei
Das Wichtigste zuerst: So sieht ein gesundes System aus
identifier {bootmgr} device partition=\Device\HarddiskVolume9 path \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI description Windows Boot Manager locale en-US inherit {globalsettings} default {current} resumeobject {3f80ecd0-df10-11ed-bafc-80a84b2564bb} displayorder {current} toolsdisplayorder {memdiag} timeout 30
``` So how do we set up a breakpoint in order to debug the bootkit? Well that's we we compiled the ovmf image as debug rather than release. If you specifically start qemu with that command you'll have qemu run and debug messages will be logged in a file called debug.log , which looks like this ```identifier {current} device partition=C: path \Windows\system32\winload.efi description Windows 10 locale en-US inherit {bootloadersettings} recoverysequence {3f80ecd2-df10-11ed-bafc-80a84b2564bb} displaymessageoverride Recovery recoveryenabled Yes isolatedcontext Yes allowedinmemorysettings 0x15000075 osdevice partition=C: systemroot \Windows resumeobject {3f80ecd0-df10-11ed-bafc-80a84b2564bb} nx OptIn bootmenupolicy Standard
Nun, in meiner Analyse gelang es mir nie, meinen Rechner zu infizieren, daher verwende ich das Beispiel aus dem bereits referenzierten Blogbeitrag des asiatischen Forschers, der zeigt, wie ein infizierter Rechner aussehen soll.```
// Windows Boot Manager
// --------------------
// identifier {9dea862c-5cdd-4e70-acc1-f32b344d4795}
// description Windows Boot Manager
// locale en-US
// inherit {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}
// bootdebug Yes
// displayorder {57e1b615-0355-11ec-abb0-005056c00008}
// timeout 30
// Windows Boot Loader
// -------------------
// identifier {57e1b615-0355-11ec-abb0-005056c00008}
// device boot
// path \system32\hvloader.efi
// description Hoy la disco se flota
// locale en-US
// inherit {6efb52bf-1766-41db-a6b3-0ee5eff72bd7}
// truncatememory 0x10000000
// avoidlowmemory 0x1000
// nointegritychecks Yes
// testsigning Yes
// isolatedcontext Yes
// osdevice boot
// systemroot \
// ems Yes
=============================================================================
=============================================================================
Bevor wir loslegen: Wie richtet man überhaupt die Umgebung für die Analyse eines EFI-Moduls ein? Nun, der Dank gebührt @MaverickMusic__ , während einer Diskussion mit ihm hat er mir das hier gegeben ( https://zhuanlan-zhihu-com.translate.goog/p/343293521?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=en-GB ). Nun, ich bin den Schritten dort nicht ganz gefolgt, also hier ist genau das, was ich getan habe, um die Umgebung zum Laufen zu bringen:
-Zuerst habe ich edk2 installiert(https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems)
-Zweitens habe ich mein ovmf als Debug konfiguriert, nicht als Release(das wird uns später helfen). Hier ist der Befehl build -a X64 -t VS2019 -b DEBUG -p OvmfPkg/OvmfPkgX64.dsc
-Drittens musste ich meinen windbg konfigurieren. Wie zum Teufel habe ich das gemacht? Ich habe alles von diesem Link heruntergeladen(git clone https://github.com/microsoft/WinDbg-Samples). Dann habe ich ExdiGdbSrv.sln kompiliert. Dann bin ich allem von diesem Link gefolgt(https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/setting-up-qemu-kernel-mode-debugging-using-exdi), von der Stelle, an der Use regsvr32 to register the DLL in an Administrator command prompt. stand, bis zu PS>.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 -ExdiDropPath "C:\path\to\built\exdi\files". Ich weiß, das ist verwirrend, aber bitte hab etwas Geduld, denn ich werde auf jeden Fall ein Video machen, in dem ich jeden Schritt erkläre! Cool, jetzt wo wir eine eingerichtete Umgebung zum Debuggen haben, wie zum Teufel debuggen wir den Code? Also starten wir QEMU – in meinem Fall habe ich es durch Ausführen von qemu-system-x86_64.exe -L . -bios OVMF.fd -hdd dos.img -debugcon file:debug.log -global isa-debugcon.iobase=0x402 . Sobald ich den QEMU-Befehl ausgeführt hatte, ging ich sofort und wählte compat_monitor0 aus dem View-Menü von QEMU. Es sollte so aussehen, wenn du das tust.

Außerdem solltest du nach der Auswahl gdbserver eingeben, um eine entfernte Instanz des GDB-Debugging zu starten, mit der wir uns mit windbg über diesen Befehl verbinden .\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 Cool, sobald wir uns verbunden haben, wird es so aussehen
So cool, um diesen Output zu verstehen: Für unseren Fall ist die einzige relevante Zeile EntryPoint=0x000062C9A8C, die so etwas wie die bevorzugte Ladeadresse ist, wenn wir das Bootkit ausführen. Speziell für das Bootkit variiert sie zwischen 0x62C4A8C oder 0x62C9A8C. Jetzt können wir das Programm in ida rebasen und unsere normale Arbeit erledigen :) . Genießt den Rest des Blogs!
=============================================================================
Bindiffing der ursprünglichen winload.efi mit der von BlackLotus abgelegten
Wir sehen einige Ähnlichkeiten, aber auch einige Abweichungen, aber nichts Nützliches, jedenfalls....
=============================================================================
Cool, also lasst uns diese Party starten.
Cool, also lasst uns mit dem Zerlegen beginnen. Zuerst sehen wir, dass wir eine Funktion haben, die aufgerufen wird. Cool, und was ist damit? Nun,
Cool, eine weitere Funktion. Nicht ganz... Fällt dir etwas Vertrautes auf?

Immer noch nichts???
Kein Problem, vielleicht jetzt
Dieselbe Demangle-Funktion! Hallo alter Freund :)))
Cool, aber was ist mit return (*(a1 + 88))(v2, &unk_62CEABC, 3i64); ?? Nun, ehrlich gesagt weiß ich nicht, was ich allein aus statischer Perspektive sagen soll, also versuchen wir, den Debugger zu nutzen, um es zu verstehen :))
Wenn wir also den String demanglen, erhalten wir
Als Nächstes, wenn wir zur Call-Instruktion gelangen
und wir erhalten keine Informationen.... großartig, aber warum ist das so? Weil wir keine .pdb-Datei haben, um Debugsymbole zu bekommen.... Cool, wenigstens ist ida hier hilfreich. Wir wissen also, dass die „grand"-Funktion als Eingabe SystemTable->RuntimeServices nimmt, was vom Typ EFI_SYSTEM_TABLE ist. Cool, wenn wir es untersuchen, ist dies ein Ein Zeiger auf die EFI Runtime Services Table. . Wenn wir bei Google suchen, stoßen wir auf eine Reihe von Dokumenten, aber ein entscheidendes Dokument, auf das wir stoßen, ist https://uefi.org/sites/default/files/resources/UEFI\_Spec\_2\_1\_D.pdf . dort steht
Cool, also eine Struktur mit einem Haufen Zeigern, ja, aber lass uns näher heranzoomen.
Zuerst demangelt es VbsPolicyDisable. Wenn wir bei Google suchen, stoßen wir auf eine ESET-Analyse, die besagt, dass diese Variable während des Bootvorgangs vom Windows-OS-Loader ausgewertet wird und falls sie definiert ist, die zentralen VBS-Funktionen wie HVCI und Credential Guard nicht initialisiert werden. , im Grunde ist diese Variable also für die aktuelle „Sicherheit" auf Boot-Ebene verantwortlich. Cool, als Nächstes haben wir die Funktion, die diese Variable nimmt und
und so können wir zu dem Schluss kommen, dass dies eine Funktion sein muss, die den Zustand dieser Variable irgendwie verändert. Cool, welche möglichen Funktionen könnten das tun? Es gibt nur eine solche Funktion in EFI_SYSTEM_TABLE, nämlich EFI_SET_VARIABLE SetVariable;
Also schließen wir, dass diese Funktion einfach VbsPolicyDisable nimmt und setzt es auf``` db 77h ; w .data:0000000180005034 db 59h ; Y .data:0000000180005035 db 3 .data:0000000180005036 db 32h ; 2 .data:0000000180005037 db 4Dh ; M .data:0000000180005038 db 0BDh ; ½ .data:0000000180005039 db 60h ; ` .data:000000018000503A db 28h ; ( .data:000000018000503B db 0F4h ; ô .data:000000018000503C db 0E7h ; ç .data:000000018000503D db 8Fh .data:000000018000503E db 78h ; x .data:000000018000503F db 4Bh ; K.
Nun, gibt es etwas Wichtiges an diesen Bytes? Nun ja, falls du zufällig den ersten Teil der BlackLotus-Analyse gelesen hast, weißt du, dass ich auf die Arbeit eines asiatischen Forschers verwiesen habe. Nun, dieser Forscher war so freundlich, auch das abgeworfene Bootkit zu analysieren. Bitte schau es dir an(https://www.cnblogs.com/DirWang/p/17294545.html#autoid-3-2-1) , und in seiner Analyse war er so freundlich, uns diese Info zu geben. Er verweist uns auf https://github.com/Mattiwatti/EfiGuard/blob/master/EfiGuardDxe/PatchWinload.c . Dort sehen wir eine ähnliche Zeile
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/33c755aa460f5bdc338c75f3f5e1322c731123299d59c43dcdf2be3b72d1276c.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/144b057568871a60a32e477ed1ae7e8d7090778a67b7fc24222f0f58fe44afc1.png" alt=""><figcaption></figcaption></figure>
</div>
Gibt es einen spezifischen Grund dahinter? Ehrlich gesagt, ich weiß es nicht, es ist mein erstes Mal, dass ich ein Bootkit analysiere. Bitte lass es mich wissen oder erstelle eine PR/Pull-Request, um dieses Dokument zu bearbeiten, falls du mehr Erfahrung als ich :) in diesem Bereich hast.
\=============================================================================
Cool, als Nächstes: Das Glück ist uns hold und der Pseudocode von IDA ist dem Assembly ähnlich.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/7457c9d8beb807556618728c7aba102109a472ef2f990f35ec344038fafc4cd5.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/e11c4b4e4260f7a91e6dc08bcabb7c3ac420dcee346b1bf9dff02835342f7837.png" alt=""><figcaption></figcaption></figure>
</div>
Was ich hier also vermute, ist eine normale Initialisierung von EFI\_SYSTEM\_TABLE, die meiner Vermutung nach festlegt, welcher Prozess den Bootvorgang fortsetzt. Und dann haben wir den Funktionsaufruf PatchBootManager
\=============================================================================
PatchBootManager
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/66c49bf5b64655af7e0edfe384ad715912c02fbeea1ac1313e4f65479ab58f80.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/7a1dc3ac7c01cbd4cfd9b3ec614c357895210e4f03ae5d58000e6b047f84eb96.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/3fc22a51052c24c9e436ace83a1672ce88bf25fb11103b32d0143fa0ab4d7216.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/22c7869b067f26c6469e4baffcd4226535c47e82d4baaf7fa8e27820915b1580.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/38cf7697523141faa68a59b52abd2a1ca14d0d9053f1e6960052a5093e3a94bb.png" alt="3">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/505a3fd02b96bcb823bf108ee03a8a1204827852260c1e8ce3902638237259b3.png" alt=""><figcaption></figcaption></figure>
</div>
Und vom Pseudocode
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/9c8482f0faa4d4de5f8643acc4276ebbbfc57386e9b00a4057793b5c67b1bf3b.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/c44de61b9f089fd8972bcc8567110bc2d58c21e5465a7b4f14fc7beaefee30a3.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/6809c28e881b3626d73a476cd31631891539f6a7b71cf276619f9cd2244d83e9.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/c8cd4870cd0488e57cde3448ba01fdd44063f266516d8530731f42e6ccc5be78.png" alt=""><figcaption></figcaption></figure>
</div>
Cool, also der erste Funktionsaufruf, den wir sehen, ist HandleProtocol. Was macht der Code also? Glücklicherweise stoßen wir bei einer schnellen Google-Suche darauf (https://tianocore-docs.github.io/edk2-ModuleWriteGuide/draft/5\_uefi\_drivers/54\_communication\_between\_uefi\_drivers.html) und sehen, dass es `retrieve protocols` ausführt. Cool, ich kann daraus nicht wirklich etwas ableiten. Ja, ich verstehe dich, Kumpel. Also ruft das im Grunde Kommunikationsinformationsmethoden ab, die von anderen UEFI-Treibern verwendet werden. Cool, etwas mehr Graben. Wir sehen, dass der zweite Parameter ist
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/703c3f52bd8c3d10eaf046fc801cbc60ca7a62e9162d67a6ba63caf4c9e9038d.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/9d41aacaed9c15391beb8b1b62739572bf7f873508938ade770610eec371a17c.png" alt=""><figcaption></figcaption></figure>
</div>
Wenn wir nach diesen spezifischen Bytes suchen, stoßen wir auf Folgendes
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/f4a8ed3b81486c8481c0f8894175f9d7390ddf62f9974ba025aad9827dea119e.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/882b5116cfd08886c3dac510443fb77c9aa31781eb234208ec81fdf313544c29.png" alt=""><figcaption></figcaption></figure>
</div>
Also, was zum Teufel macht EFI\_LOADED\_IMAGE\_PROTOCOL\_GUID? Zitat von (https://uefi.org/specs/UEFI/2.10/09\_Protocols\_EFI\_Loaded\_Image.html) `Can be used on any image handle to obtain information about the loaded image.`, welche Art von Informationen? \`\`\`This section defines EFI\_LOADED\_IMAGE_PROTOCOL and the EFI\_LOADED\_IMAGE\_DEVICE\_PATH\_PROTOCOL. Respectively, these protocols describe an Image that has been loaded into memory and specifies the device path used when a PE/COFF image was loaded through the EFI Boot Service LoadImage(). These descriptions include the source from which the image was loaded, the current location of the image in memory, the type of memory allocated for the image, and the parameters passed to the image when it was invoked.\`\`\`\`
In unserem Fall holt es also Informationen über das Bootkit. Nun gibt es ein Problem: Wir können das Ergebnis der Funktion nicht wirklich inspizieren, weil wir keine Debug-Symbole haben :/ aber wir können vermuten. Und ich neige dazu zu vermuten, dass die Struktur (Ergebnis des vorherigen Funktionsaufrufs) in rbx liegt.
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/b8f744ecd9fd4be572a1e2d191b06231559eca2b32aeaa981a399eec7f3ee710.png" alt=""><figcaption></figcaption></figure>
Als Nächstes rufen wir demangle string auf.
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/1fdc75d2dc9221250e6d46692770ad5240f7a0d6cda9cc5634749b327fc8c146.png" alt=""><figcaption></figcaption></figure>
was uns Folgendes liefert
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/e073b265ff13675b755ec8413554bec74ab4eae57dd002b25694632eb43cbc8e.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/3654bb54071386cd020c43ed4a35fae40aec386897a0ca26a27b58b8e1a91c95.png" alt=""><figcaption></figcaption></figure>
</div>
und dann rufen wir Folgendes auf
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/c433aa63cddd2ecfb5ce0fd57a6774ad35b1c1ed4ee71e7cecb566cc861d2b80.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/6834be566cdd81f2410ec7d4ee97936d14a27017a723371eea3046b8590609f4.png" alt=""><figcaption></figcaption></figure>
</div>
\=============================================================================
sub\_180002B14
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/483f2b789c0fa6fe9378ba324f8e349bc72cbb45e540bbc2355ef55acaf1b6b4.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/d84d79115facbc0f9ff7afe06d70a18555e7d94bc196f6f9d0ff6b5cfd40408a.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/19e2366fddab99fa3aa4375b8306475ee31d3bf9a3c3737efeeb4d627868404e.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/6c808c76821c756eca776cf6290482f6f9829167f539bf31b2ad82b3de0af829.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/ad0d06238e39e4ba1decb2f1305510a8375822b13ae9148d91e267d14762eb3b.png" alt="3">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/0e45e9ae64c3fbd8a61ffdf60ec2e532529d8cab6cfc7786fa2c91824233d347.png" alt=""><figcaption></figcaption></figure>
</div>
und Pseudocode
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/c14b1eacbe8eef4155c4148b66fa95f93bbd9e6fc81e5ca80f1ddc5b2b9a7a16.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/b7c452865661d95b79886a48a455eba663c2e3915e0a81ad16dc7ddd8c2c0189.png" alt=""><figcaption></figcaption></figure>
</div>
Cool, bis zum if ist alles selbsterklärend. Was ist nun mit dem if? Wir sehen, dass es wieder einen Aufruf mit unk\_180005010 als Parameter macht, was wiederum ein Array von Bytes ist. Bei näherer Betrachtung sieht es so aus
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/c3bb66f35a4e559ae793ba590fc0c342bdde1e1c9765e144cb450a809009655d.png" alt=""><figcaption></figcaption></figure>
Wenn wir nun die ersten Bytes erneut untersuchen und eine schnelle Suche durchführen, stoßen wir auf das hier (https://github.com/theopolis/uefi-firmware-parser/blob/master/uefi\_firmware/guids/efiguids\_ami.py) , genauer gesagt auf `'EFI_DEVICE_PATH_PROTOCOL_GUID': [0x09576e91, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]` .
Wenn wir uns wieder die UEFI-Spezifikationsseite ansehen, sehen wir, dass `Can be used on any device handle to obtain generic path/location information concerning the physical device or logical device.`. Außerdem sehen wir so etwas wie `The device path describes the location of the device the handle is for`. OK cool, und wenn wir nur ein wenig scrollen, sehen wir eine Funktion namens \_EFI\_DEVICE\_PATH\_PROTOCOL. Ok, um zusammenzufassen: Wir wissen, dass dies mit EFI\_DEVICE\_PATH\_PROTOCOL\_GUID zu tun hat, aber unsere Funktion ist vom Typ EFI\_BOOT\_SERVICES. Gibt es also eine Funktion in EFI\_BOOT\_SERVICES, die so etwas wie die Behandlung eines Protokolls übernehmen könnte? Ja, die gibt es. Wenn wir https://www.intel.com/content/dam/doc/product-specification/efi-v1-10-specification.pdf Abschnitt 4.4 untersuchen, sehen wir
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/918a0a5184849cbb87454df44c5ffa5e5fa586f223213287f6c7fbe737a0fbc8.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/fab94604327fe596d9eeb68368efcf0afc721ef7bfcdc07a8977392b4309238c.png" alt=""><figcaption></figcaption></figure>
</div>
Genauer gesagt enthält es eine Funktion, die uns vertraut ist (HandleProtocol). Cool
Als Nächstes sehen wir einen weiteren Funktionsaufruf, diesmal einen, den wir nicht kennen. Schauen wir uns an, welche Argumente er nimmt: Es nimmt 2, dann die Länge der übergebenen Zeichenkette als Unicode und einen Zeiger auf eine Variable.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/39e0d1d9baabff8d95da7109294db94f9fc4409a6ede34d37ece9662fb73651d.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/e116e90f20a09d48f21a981e7d24c49f7474ea9ac6007b6fa41973300af4e83d.png" alt=""><figcaption></figcaption></figure>
</div>
Wenn wir das nun in einem Debugger untersuchen
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/f412c3bf83f60da9213f4c29b39350c925a0aa6411c42de52d7fa4530c5bc3fe.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/5285bf4d5e52dbbef857e46e8738c3ba6e7f6cda87f9b67a4965b23cc70aba0e.png" alt=""><figcaption></figcaption></figure>
</div>
sehen wir etwas Seltsames: rcx enthält einen Debug-String, der AllocatePool lautet, der nach einem Funktionsaufruf kommt. Daraus schließen wir, dass dies möglicherweise ein Aufruf von AllocatePool war. Witzigerweise: Wenn du auch die Spezifikationen untersuchst, siehst du, dass boot\_services ebenfalls einen Zeiger auf AllocatePool hat, was unsere Annahme nur bestärkt.
Cool, wenn wir also genug Speicherplatz allokieren können (die Prüfung >= 0 dient dazu, zu prüfen, ob die Allokation erfolgreich war, denn wenn EFI\_OUT\_OF_RESOURCES implementiert ist als
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/bf08cd5dd33ad9ca16ff4e6a44a4cbfd51cd1f8b0300d9b6b44984c4306fcb6e.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/c28af9995294473937be13a6094de90cb57a688c83727617ca9f667c2705d7cd.png" alt=""><figcaption></figcaption></figure>
</div>
ist es nur sicher anzunehmen
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/3741ef8be2dc989f601d26568907381f1847d29c0bf514add76485b0f0fef4b6.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/cdfc6ccb296659fc8156d4bfba6d777da8b2792e4af56677d0f0d57695932216.png" alt=""><figcaption></figcaption></figure>
</div>
für eine erfolgreiche Allokation verwendet wird)
Eine interessante Tatsache ist, dass der Puffer nach der Allokation nicht Null ist, sondern diese Bytes enthält. Wenn jemand mehr darüber weiß, bitte erstelle eine PR-Anfrage, um dieses Dokument zu bearbeiten.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/e4b15da615e07faa4965d864435bf4deec0e01270f9d1ac1134fb5b20ad46892.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/b229a700b321040fc8978f4f0f489a058381795c128d27dbcfbcfff5f9ffd3b2.png" alt=""><figcaption></figcaption></figure>
</div>
Also ja, wir rufen schließlich memcpy auf; nach dem Aufruf sieht unser Puffer wie folgt aus
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/28e61d8725687245e9a9dae7e467929ac15d5a81e33178262f0ce886a3c4555c.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/f161ab0441b14d71dbade9fc3acebbd12b1453de5d53b77b09af98c0cf0ac6d6.png" alt=""><figcaption></figcaption></figure>
</div>
Dann hängen wir einige Bytes an, um den Puffer dazu zu bringen, wie folgt auszusehen
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/80906384a49ef1d6eaea9667cb962459c27feb8e9deac857491a248be5443a4f.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/7c703952c72c154d156603c457a00013305c48519ddee808925c32a62499135f.png" alt=""><figcaption></figcaption></figure>
</div>
Und dann rufen wir eine Funktion namens FileDevicePath\_call auf, die ungefähr so aussieht 
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/66c77ae12715ee6d982ba2cfb769ba6a650f52ce56d7bae54e3bd93686695f02.png" alt=""><figcaption></figcaption></figure>
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/5f7e06800ec3eecb9559d1592b8a76868038c0cbb64744e5c928b65d189ef183.png" alt=""><figcaption></figcaption></figure>
Und das übersetzt sich zu Folgendem
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/2b36492bb7dd46a7139c27de61371b59adac5bfbec989bbb542b58d34ce7982d.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/361e2b338c676b99393f7baa48e970ba886894f579065a4468fe113841c0783b.png" alt=""><figcaption></figcaption></figure>
</div>
Cool, aber das ergibt keinen Sinn, wenn es nicht erklärt wird, also....
Zuerst haben wir eine benutzerdefinierte Implementierung von strlen, die wir nicht sezieren werden, weil sie nutzlos ist :) Aber hier ist das Ergebnis
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/03a0aabe9f7c87f42b7e64bb284d74738ecdc81134136cfec68c70084644c3ea.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/823c30bd0a6a8c1d750ef1dfb0bce5be67a13a96de12e53b3e46b2226a1c2be1.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/5dd4684c37f3129c8234cd69574bb6371b4bef72ff7e027199b7900134cdd101.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/118ee749874a6b08d40286821735190f67af45ca8d4573fc94aee3a2cea04af2.png" alt=""><figcaption></figcaption></figure>
</div>
32 Zeichen von len(of(str)+"\x00" und dann die letzten 4 Bytes, die vor dem Funktionsaufruf 0x4FF7F angehängt wurden.
Als Nächstes rufen wir das auf, was ich auch aus dem Forschungsblogbeitrag des Asiaten verwendet habe: PxepDevicePathInstanceCount, was einfach strlen ist, weil es einfach jeden Buchstaben zählt und einen Zähler hat. Wie hier zu sehen
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/130931a6676f0519da2b50a9762955b7581e7102434e587236137b216cc62ead.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/ce1a6ad93452a8092d2fb71ffd6418df78c32fc8cdf4fb99133924cc9037f12e.png" alt=""><figcaption></figcaption></figure>
</div>
Also ja, wir sehen pop rbx und nach dem Aufruf sehen wir rbx=0x48
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/4c2eabdd91ec40fc82c100e67579d729def9e74c6bfd000fff287bc9c10b0f38.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/818bb3c8398d4a53c0260d9310d4d192cfa5b65a404348df5516c94fa3d8dcaa.png" alt=""><figcaption></figcaption></figure>
</div>
Dann rufen wir erneut strlen auf, mit derselben Zeichenkette. Ich vermute, das liegt daran, dass wir in der nächsten Zeile, genau gesagt `v6 + v4 * v5;`, v4\*v5 berechnen, was meiner Vermutung nach irgendeine Methode ist, Unicode-Zeichenketten zu haben, schätze ich.
Wie auch immer, danach allokieren wir erneut Speicher mit gEfiBootServices + 64, was wir bereits zuvor gesehen haben und das sich als AllocatePool herausstellte.
Hier sehen wir auch etwas Schönes, nämlich
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/26d19e06bd335f1267946a5da2542cf3eb9f2965fab788d0bcf720d7e3c08d37.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/225c92cbe9a5e72214cb279e61ad5fcbaef0a243db835b67fce5ff7ef74e7c86.png" alt=""><figcaption></figcaption></figure>
</div>
die Tatsache, dass der Speicherblock hier das Muster afafafaf enthält.
Was als Nächstes passiert, ist, dass wir zwei Puffer erhalten, die nach Ausführung der Hauptschleife wie folgt aussehen
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/35f257d96c752ac436e81778da5f37c28bfcb79fc5614f3ea8e099888cc011c3.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/b9c706cc28161a6e7274c5cabc895bedc1279728b3ed7c11084cb6cb38dbf9e3.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/52477a3825650e47112a5e619a098c74e7e0de778ebfeda5682e5b49d48f3923.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/762a6dd3897f3b630ce1d0faa371e58ed9b2bce755bb8edd54f958aab7c3b69b.png" alt=""><figcaption></figcaption></figure>
</div>
Und ehrlich gesagt interessiert uns nur der erste, weil das zurückgegeben wird. Wir können also einfach schlussfolgern, dass dies vermutlich den Gerätepfad kopiert und etwas Müll aus dem Puffer entfernt. :))
Nachdem wir damit fertig sind, prüfen wir, ob der Gerätepfad in unserem Fall bereits initialisiert ist, und geben den Pool frei; wenn nicht, geben wir den klareren Puffer aus der zuvor erwähnten Funktion zurück.
Bevor wir diese Funktion abschließen, möchte ich auf eine weitere interessante Tatsache hinweisen: So sieht die Bootservice-Tabelle im Speicher aus :) Sie sieht gemäß den Spezifikationen mit dem Anfang-Header aus. Ich dachte nur, es könnte interessant sein, das hier zu hinterlassen, für alle, die zukünftige Arbeiten durchführen möchten und sich dabei in einem Dump wiederfinden, in dem sie diesen String BOOTSERVF entdecken – das ist definitiv eine Bootservice-Tabelle.
\=============================================================================
Also gut, was passiert als Nächstes??? Nun, wir prüfen, ob wir die Datei winload.efi lokalisieren konnten, und laden sie in den Speicher. Das ist der Pseudocode :)
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/b59f211cb997e5ad783cbb6421833c23bea4ef4f7f21743577cd8aba4656ad2f.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/a96f7410f6bd6f7e207b76dff36a411f3c17a3f40dcb1a9433d5292b46f775e2.png" alt=""><figcaption></figcaption></figure>
</div>
Und so sieht es im Speicher aus
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/e3ee7b08fdc84433a08e60c7065c74692fb3a4e26eb81def063b662aa5229558.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/445d40332ba97516eebf129d17c56a38e28688858515d787ebf90a99580daa51.png" alt=""><figcaption></figcaption></figure>
</div>
Was ist rax? rax ist ein Handle auf das Image :) sei nicht so dumm wie ich, als ich zuerst dachte, dass es eine Speicherzone ist :)
Cool, bevor wir uns weiter damit befassen, lass mich kurz erklären, was zum Teufel winload.efi ist. Also, `with the development of computers, the traditional BIOS boot is outdated, and the security confrontation about UEFI boot has started. From the flow chart below, we can see that MBR and VBR no longer exist in UEFI, but UEFI itself is responsible for loading bootmgr, which also means safer and faster`
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/d2443977ce3d56790e424fd6236d1d0594db283caa9357ed4e6abb9b8b30b8ed.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/1259e1f45b2d2bb8edcb12609e057d089f7c1dcf907677973d799049c58bee4a.png" alt=""><figcaption></figcaption></figure>
</div>
Wie bootet also ein normaler Windows-PC? Nach BDS hat der im SPI gespeicherte UEFI-Firmwarecode seine Arbeit abgeschlossen. Danach fragt der UEFI-Firmware-Bootmanager zuerst die NVRAM-UEFI-Variable ab, um die ESP zu finden, und findet den OS-spezifischen Bootmanager bootmgfw.efi, um dessen Einstiegsfunktion (DXE-Treiber) aufzurufen.
Diese Funktion ruft zuerst die Funktion EfiInitCreateInputParametersEx auf, die hauptsächlich dazu dient, den EfiEntry-Parameter in das von bootmgfw.efi erwartete Parameterformat umzuwandeln.
Anschließend wird die Einstiegsfunktion BmMain des Windows-Bootmanagers aufgerufen.
In dieser Funktion wird BmFwInitializeBootDirectoryPath aufgerufen, um den Pfad der Startanwendung (BootDirectory) (\EFI\Microsoft\Boot) zu initialisieren.
Dann liest BootMgr den Systemstartkonfigurationsbuchstaben (BCD). Wenn es mehrere Startoptionen gibt, ruft es BmDisplayGetBootMenuStatus auf, um das Startmenü anzuzeigen.
Dann ruft es die Funktion BmpLaunchBootEntry auf, um die Anwendung (winload.efi) zu starten.
Natürlich macht bootmgfw.efi noch mehr, darunter die Codeintegritätsprüfung der Startrichtlinie und die Initialisierung der Secure-Boot-Komponenten, aber darauf werde ich nicht näher eingehen.
In der Endphase des Windows-Bootmanagers (BootMgr) wählt die Funktion BmpLaunchBootEntry den korrekten Starteintrag basierend auf dem vorherigen BCD-Wert aus. Wenn die Vollvolumenverschlüsselung (BitLocker) aktiviert ist, wird zuerst die Systempartition entschlüsselt, und dann kann die Kontrolle an winload.efi übergeben werden.
Als Nächstes wird die Funktion BmTransferExecution aufgerufen, die Startoptionen werden geprüft und der Ausführungsfluss wird an die Funktion BlImgStartBootApplication übergeben.
Dann ruft die Funktion BlImgStartBootApplication die Funktion ImgFwStartBootApplication auf und schließlich die Funktion ImgArchStartBootApplication. Darin wird der Speicherschutzmodus von winload.efi initialisiert. Dann wird die Funktion BlpArchTransferTo64BitApplication aufgerufen; BlpArchTransferTo64BitApplication ruft die Funktion Archpx64TransferTo64BitApplicationAsm auf, die schließlich die Kontrolle an winload.efi übergibt.
Diese Funktion aktiviert die neue GDT und IDT und übergibt dann vollständig die Kontrolle an winload.efi. An diesem Punkt beendet BootMgr seine Mission und Winload beginnt zu arbeiten. – Ende der Zitate, die von einer chinesischen Website geklaut wurden, die darüber spricht (bitte sieh dir das für weitere Inhalte an https://bbs.kanxue.com/thread-268267.htm )Und von dort aus erledigt winload.efi seine Aufgabe, nämlich Windows zu laden und noch etwas Hardware-Arbeit zu verrichten, bevor es die Kontrolle an den Kernel übergibt.
Nun, nach dieser kurzen Einführung, wie wir schon sagten
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/65537ae888c278e8e487029f93d909fb1e4699069699cf1b7d5ad8fa1f9e0d69.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/3b00c68a215f4568fca5d672ea6f892fecf9809e671c68795c067d2660fa3f1f.png" alt=""><figcaption></figcaption></figure>
</div>
prüfen wir weiter, ob das Laden in den Speicher erfolgreich war, und dann führen wir eine Funktion namens ati\_analysis\_rdtsc\_aia\_cu\_4e1f aus, die dir vertraut sein sollte, wenn du bereits den ersten Teil dieser Analyse gelesen hast.
Jetzt zum Spaß: Stellen wir uns vor, wir schaffen es nicht, diese Funktion zu analysieren, und wir werden erkannt. Schauen wir uns an, wie sub\_180002A08 aussieht.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/4eb3ae379ab937e19e6a699339d992b2a5fd1fcb33202ca67355f62a5b1203b4.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/a4b252df16a31b5bf165d2a500ebe3c54ad5dad3c58cf9fe88a8a1da11ed6b63.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/dd594955a663274e25603804c348b516ca22755886b2732ef81dc8e1e0177544.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/6fba01328584e8abb254912b81b048e8dcf80bda6d3eadc11573a52a5e84dd15.png" alt=""><figcaption></figcaption></figure>
</div>
Wir sehen wieder gEfiSystemTable + 64, das wir diesmal eigentlich nicht kennen, weil es von einem anderen Typ ist. Diesmal ist es nicht vom Typ BootServices, sondern vom Typ EfiSystemTable, dann memcpy und noch ein weiterer Funktionsaufruf – drei insgesamt? – die wir jetzt nicht kennen. Wenn wir ausführen, bis die Schleife beginnt
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/20e0db7308860023b613310ea14e0880529a588540d9dabac2218b52dc93cefb.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/b8f498165a4016c19d8d5797517680fc32dea241d343b38fcc613620270d58dd.png" alt=""><figcaption></figcaption></figure>
</div>
und wenn wir die vorherigen Parameter von memcpy untersuchen
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/21f546fbfb10a39e0e603186c8c505a3ae0679e8c7bad40f31643022f9ebfbcd.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/2ef8c97938b8f961abf92c03937ca15d5a48cd03eb58a0169891559fad27dde5.png" alt=""><figcaption></figcaption></figure>
</div>
und wir das Ausgabebild von qemu untersuchen, erhalten wir
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/e4325617bfda31fb45f7920d0d1d977103fd6b85260e590fc7cfdca1efacb787.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/04e29142b4cf543a6e5b8f55de2c27d1f3f0034707a6d19e2b1ea45b8251e899.png" alt=""><figcaption></figcaption></figure>
</div>
Cool, also lass uns versuchen, das zu verstehen. Ich verweise wieder auf den Forschungsblogbeitrag des Asiaten, denn ehrlich gesagt bin ich hier verloren.
In seinem Blog sagt er also, dass die beiden Funktionen eigentlich...```
ConOut->ClearScreen(ConOut);
ConOut->OutputString(ConOut, String);
Ok, aber was zur Hölle ist conOut? Nun, er sagt auch, dass conout vom Typ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL ist und dass conout durch ConOut = gEfiSystemTable->ConOut; erhalten wird. Ok, was bedeutet das also im Code??
Ok, dann lass uns eintauchen
die Definition
und die GUID
Jetzt hat mein Schlauberger vergessen, das tatsächlich in einem Debugger festzuhalten, denn als ich das zuerst analysiert habe, habe ich die Datentypen von efisystemtable und bootservices verwechselt und dachte, das sei eigentlich allocatepool.
Was machen diese Funktionen nun?
Nun, ClearScreen sollte ziemlich selbsterklärend sein, und OutputString auch. Wie konnte der Forscher zu dem Schluss kommen, dass diese Variable vom Typ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL ist? Nun, wahrscheinlich hat er die GUID-Bytes im Debugger gesehen.
Und was ist mit der letzten Funktion?
Nun, in seinem Blogbeitrag sagt er, dass die letzte Funktion gEfiBootServices->Stall ist? Also, was zum Teufel macht das? Aus den UEFI-Spezifikationen: The Stall() function stalls execution on the processor for at least the requested number of microseconds. Execution of the processor is not yielded for the duration of the stall.
Also im Grunde friert es unsere CPU ein. Cool, für wie lange? 0x1C9C380 Sekunden. Eine verdammt lange Zeit, wenn du mich fragst. Was wiederum in eine Endlosschleife gepackt ist, also ja, wir sind gefickt :)))
Und so sieht das in einem Debugger aus
Weiter geht's mit unserer Hauptfunktion
Wenn wir es schaffen, bootmgfrw.efi zu laden (weil winload.efi hier der eigentliche Windows-Bootloader ist), rufen wir sub_180002538 auf
============================================================================= sub_180002538
Aus der Graphen-Perspektive
Aus ASM-Perspektive
Klingelt da schon irgendwas? Nein? Na ja, gib ihm eine Minute, es wird schon einsickern. In der Zwischenzeit schauen wir uns die Pseudo-Code-Sicht an
Wir sehen ein Parsen einer EXE :) Nun, ich weiß nicht, wie sehr es dem aus dem vorherigen Teil (Teil 1) ähneln wird, aber mal sehen :)
Also vergleichen wir unsere In-Memory-Version der Binärdatei (bootmgfrw.efi) mit dem klassischen MZ-Header (0x5A4D), wie du sehen kannst
Ok, als Nächstes machen wir einen weiteren klassischen Check, nämlich ob wir den PE-Header finden können
Cool, als Nächstes rufen wir sub_1800024C4() auf, das so aussieht
Cool, was hier passiert, ist, dass wir bestimmte Werte im Speicher suchen und, wenn wir sie finden, zurückgeben. Bitte beziehe dich für die Emulation auf sub_180002538.py.py.
Wie auch immer, hier ist sub_180002464
Wenn wir sub_1800024C4 erfolgreich ausführen, kehren wir in die größere Funktion zurück und folgen ein paar weiteren Checks. Cool, lass uns versuchen, daraus schlau zu werden.
Cool, wir vergleichen also weiter, was auch immer an rax+0xe liegt, mit 0x64. Hmm, cool, interessant. Untersuchen wir rax+0xe
Gibt es einen besonderen Grund für diesen speziellen Check? Ehrlich gesagt, ich weiß es nicht? Vielleicht. Falls du es weißt, erstelle bitte einen Pull Request und bearbeite dieses Dokument.
Wir führen noch eine Addition durch und dann einen Vergleich
Ich möchte hier kurz innehalten und mich erneut auf die vorherige Inspirationsquelle für diesen Artikel beziehen, wenn ich mich verlaufen habe. In seinem Blog hat er die Funktion, die Werte verglichen hat, in RtlpImageDirectoryEntryToDataEx umbenannt. Wenn wir danach suchen, erhalten wir keine Ergebnisse, aber es gibt etwas, das seinen Namen nahe genug kommt, und das ist RtlImageDirectoryEntryToData, was im Grunde Folgendes tut: Given the base address of a kernel module and the index of an entry in the data directory, RtlImageDirectoryEntryToData() returns the virtual address and the size of the directory entry(https://codemachine.com/articles/top\_ten\_kernel\_apis.html). In unserem Fall, da wir uns in einer EFI/UEFI-App befinden, können wir annehmen, dass die 50, die wir sehen, die Größe in Bytes/MB (keine Ahnung) unserer Root-Partition in diesem Fall ist und dass diese Adresse in rax ein Eintrag in unserem Verzeichnis ist.
Bevor wir fortfahren, gibt es noch ein weiteres interessantes Detail zu erklären. In seiner Forschung konvertiert er die Ausgabe von RtlImageDirectoryEntryToData in diese Struktur``` typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { union { struct { DWORD NameOffset : 31; DWORD NameIsString : 1; }; DWORD Name; WORD Id; }; union { DWORD OffsetToData; struct { DWORD OffsetToDirectory : 31; DWORD DataIsDirectory : 1; }; }; } IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
Jetzt, was zum Teufel ist mit dieser Struktur?
Nun, eine schnelle Suche über diese Struktur führt uns hierher(http://www.brokenthorn.com/Resources/OSDevPE.html), die uns sagt, dass `Parsing resources is a bit more complex then the other directory types, however. Like the other sections, there is a base IMAGE_RESOURCE_DIRECTORY structure that can be obtained from the DataDirectory member of the optional header: blah blah` und auch, dass ```This structure doesnt have much of any interesting fields, except the last three.
If you have worked with Win32 resources, you might know that resources can be idenitified by ID or name. Two of the members in this structure will let us know the number of these entries, and the total amount of entries (NumberOfNamedEntries + NumberOfIdEntries), which is useful in looping through all of the entries. As you can probably guess, the entries are in the DirectoryEntries array. DirectoryEntries consists of an array of IMAGE\_RESOURCE\_DIRECTORY\_ENTRY structures, which follow the format:```
Also im Grunde wird dieser Mist intern zum Parsen von Zeug verwendet, und für uns ergibt das im Kontext der Tatsache Sinn, dass wir mit einem Verzeichnis arbeiten, das Ressourcen enthält, cool.
Mehr, bitte!
Also als Nächstes
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/137d3d2aebf0db9501f550b09baddf01c3e50bf703ca8d13386a7185a567f19a.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/045c3a8a2bab306f516cdc7e9a59954e3c1ff16efe4189273c50f54b9e84f3e6.png" alt=""><figcaption></figcaption></figure>
</div>
Was das tut, ist im Grunde über jede Ressource im Verzeichnis zu iterieren und zu prüfen, ob sie vom Typ String ist.
Ehrlich gesagt, ich weiß nicht, warum er das tun würde, also falls ich falsch liege, tut mir leid, falls nicht, Prost!
Weiter
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/a57c5815ee8b5498fed6d8dde92f48b9fc2bdfd2d4f4e231796ba96e5e28bea9.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/bd4513fdf1f8f165fc404b8462d6bc36644de4937e42d560d54f1a5f1c0e8799.png" alt=""><figcaption></figcaption></figure>
</div>
Was hier passiert, ist, dass wir einige Offsets addieren und am Ende bei dem landen, was der chinesische Forscher als zweite Ressourcentabelle bezeichnet, wie du sehen kannst.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/8f6655fb8117abf8a4d38b5173d51e4bc3ce67b86803c57cce36d47b73cd1e76.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/ebdf5a9a749f2cb1b7a656be5f2d99419edfc9cd2a737e15c6845f2c008e3f11.png" alt=""><figcaption></figcaption></figure>
</div>
und dann wiederholen wir denselben Prozess, um einige Offsets zu erhalten.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/faa12c96d0b22e6128ef1cdf14110c31cc9ebca89325f28a07fc6a0a064daeba.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/216539eaf48a407a7f691d10cca06679a545471c3e54f25fedb31c38f0c61a66.png" alt=""><figcaption></figcaption></figure>
</div>
und wiederholen denselben Prozess, diesmal prüfen wir auf den Typ VS\_VERSION\_INFO.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/ac2d2e82085f4ddbc3f5ae1ce35528dd8420924b0298c65db056d0837c3e4b6d.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/23788c642b82988c14654e9dac2afd2504cd22846be0487efce96cae4d6fe094.png" alt=""><figcaption></figcaption></figure>
</div>
Also, was zur Hölle ist VS\_VERSION\_INFO? Nun, Microsoft(https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource) sagt, dass es `Defines a version-information resource` ist, z.B. ich glaube, es gibt einfach die Version von bootmgfrw.ef an.
Und schließlich, wenn wir VS\_VERSION\_INFO gefunden haben, wiederholen wir denselben Algorithmus.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/4f00ecf2c2c9b32b2d25fcbf3c62e9bb45679df1390a085371f5166a70d67933.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/facd25069491b5d7826500e4f2c04cafe213191075012ddb4c1fa9a8bc97c4c5.png" alt=""><figcaption></figcaption></figure>
</div>
diesmal mit einer Wendung, die darin besteht, dass wir die Build-ID zurückgeben :) wie wir sehen können.
Also als Fazit, was zum Teufel ist hier eigentlich passiert? Nun, basierend auf dem Namen, den der chinesische Forscher verwendet hat (GetPeFileVersionInfo\_BuildNumber\_), können wir schließen, dass wir tatsächlich die Build-Nummer für den Bootloader erhalten, wie aus dem ersten Bild ersichtlich ist.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/b28007dda110fc31d53233931ff077ac42fc81146d803b91999069e204020a4d.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/d19f1311c2ee242ced63da8334db384929ada3acae147009becc0dbf34d2b7fb.png" alt=""><figcaption></figcaption></figure>
</div>
wo wir hier den geladenen Bootloader im Speicher sehen.
Im zweiten Bild sehen wir
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/2000f17c51ccc65267b46ac2c1d191bd033b3bc6e6b655973423dbbd8a1fc77e.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/7c47fe45fe4b422618a400f2c26c28cd33fea9416f2b24086a2c852d08f1614b.png" alt=""><figcaption></figcaption></figure>
</div>
einen Integer in rcx, der entweder die Build-Nummer oder die PE-Dateiversion sein könnte.
Und im dritten Bild
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/41729b1d4a4701480d64f058f421cd2ad8a8b9b871bf17675fd7b537cec3dd85.png" alt="3">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/d2b17725eeb9af2336d725be9c556565fba221fd2a3517912c942f411f9ed33b.png" alt=""><figcaption></figcaption></figure>
</div>
was wir als Build-Nummer vermuten könnten, da ebx in rax verschoben wird :)
Als letzte Anmerkung zu dieser Funktion: wow, erstaunliche Ingenieurskunst.
\=============================================================================
Weiter zur nächsten Herausforderung :) Basierend auf der Ausgabe der vorherigen Stufe setzen wir v10 entweder auf sub\_180001D80 oder sub\_180001D48, wie gesehen.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/33581031e03f29b5997d46b708c467bfd49ce58625e99381dd28c109cadae7d3.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/6647119081cffb664dcca365392271398b2572ee04c24a0456141f33cbaaeecf.png" alt=""><figcaption></figcaption></figure>
</div>
und in unserem Fall v10=sub\_180001D80
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/2af043a1449f6bf10e2925f06697438716976d24a1539a61ab42c4301c4a8435.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/0769d4dff6e1da51acaf9c5bac3a9a9b4b446aae9d7c593e7e54d865ec13c2ea.png" alt=""><figcaption></figcaption></figure>
</div>
\=============================================================================
Dann machen wir ein strcmp zwischen unserem Bootloader-Manager und diesem Byte-Array.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/59164794afc69304133f0a4c008b9e4755671e8d57bd8dc4ea5a2b2e6ae54164.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/03b00f7c18ff7db73dfd5253f02d6966955e38732fa7d1cfb4840366c17355a1.png" alt=""><figcaption></figcaption></figure>
</div>
Ich möchte hier kurz innehalten, denn wie du vielleicht schon vermutet hast, habe ich etwas Interessantes im Blogbeitrag des chinesischen Forschers gesehen. Er nannte das Byte-Array SigImgArchStartBootApplication. Also, was zur Hölle ist SigImgArchStartBootApplication, wem gehört es und warum zum Teufel wird dieses Array so genannt (migos)? Wenn wir also bei Google (gulugulu) nach SigImgArchStartBootApplication suchen, bekommen wir nichts. Da im aktuellen Kontext der Windows-Bootloader-Manager verwendet wird, öffnen wir ihn in IDA. Wir gehen zu C:\Windows\Boot\EFI, öffnen die Binärdatei in IDA und suchen nach SigImgArchStartBootApplication – nichts. Wir suchen nach ImgArchStartBootApplication und werden mit Folgendem konfrontiert:
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/1ad42d5236e8ca4da08688fe3d4c72e6b3de01fdce633a1bdaa870de421cdc40.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/d6e211aa12b37dfba0244d48516a08703248484c070f8d7ffcf0a28f08e8a833.png" alt=""><figcaption></figcaption></figure>
</div>
Also ImgArchStartBootApplication .... was macht der Hund da...!? Also ähm...hh ich werde das von `@_xeroxz` stehlen (folgt ihm, was tut ihr, wenn ihr nicht seiner Arbeit folgt....). Also im Grunde sagt er in einem Artikel, dass `bootmgfw.ImgArchStartBootApplication between windows versions 2004-1709 is invoked to start winload.efi`, wie wir auch auf seinem Bild sehen können(https://guidedhacking.com/threads/hyper-v-hacking-framework-works-on-every-version-of-windows-10-2004-1511-amd-intel.16251/)
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/4967559cb05e49785841a2dc216e13fc0b94fe8be8f17d9bceaf1914722156ff.jpg" alt="1603213912596">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/4967559cb05e49785841a2dc216e13fc0b94fe8be8f17d9bceaf1914722156ff.jpg" alt=""><figcaption></figcaption></figure>
</div>
Falls das nicht klar genug war, sehen wir in einem Artikel(), dass `ImgArchStartBootApplication to catch the moment when the Windows OS loader (winload.efi) is loaded in the memory but still has not been executed`(https://rustrepo.com/repo/rusty-bootkit--uefi-bootkit-in-rust)
Cool, also was hat strcmp mit ImgArchStartBootApplication zu tun? Nun, schauen wir uns IDA genauer an, und bald wird uns die Antwort offenbart. Wenn wir im Bootloader-Code nach den Bytes 41 b8 09 suchen, treffen wir bald auf den Übeltäter.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/91050c01f95eb88488cbc575c21af7f453228eeb13c665b94d415eecf5682a55.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/7239d85f2dc9e220a2eab80f79b5db9705285a17c074f85958c041d122bfaf8e.png" alt=""><figcaption></figcaption></figure>
</div>
Und falls wir die Byte-Image unseres Bootloaders im Speicher mit der Byte-Signatur abgleichen, führen wir sub\_180002398 aus.
Und wie man sicher sehen kann, haben wir das Muster gefunden; wir haben in eax den Speicherbereich zurückbekommen, in dem sich die Bytes befinden, und fahren sicher damit fort, sub\_180002398 auszuführen.
\=============================================================================
sub\_180002398
"Assembly-Perspektive"
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/5aa624d92161499019e7ce6597bf46853c59ba89d37fec483a8ac7ee168ddbeb.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/afbf940a1eb535d73dce744606cc63c568c2b447c9cf85034c422a8e900859f4.png" alt=""><figcaption></figcaption></figure>
</div>
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/6468513a220946bbccfab53328c056a620755e1fe94ad3e36d8c8958ed777794.png" alt=""><figcaption></figcaption></figure>
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/c5c36e7c29f1cdea6f42d55d7605ad3c2044d66397c867c221da6c0bf74f8d6a.png" alt=""><figcaption></figcaption></figure>
"Pseudo-Code-Perspektive"
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/5b1d8a264dad55f34a0cc958a2f4a26014a31987af5b66754e754589ea085097.png" alt="3">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/1d3db7165e0f71a3fa76862ba8afb3869f821f59db6fc5a5c5e99d5002ecfba1.png" alt=""><figcaption></figcaption></figure>
</div>
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/ae65504884fa2881cb50af2f88e846a0ad029c9431ee6296b28993de8f2e4a0d.png" alt=""><figcaption></figcaption></figure>
Also, was macht der Hund? Ehrlich gesagt führt er einige Berechnungen und Additionen/Subtraktionen durch, und nichts wirklich Wichtiges? Warum? Weil es nicht so interessant ist. Was uns interessiert, ist, was passiert, nachdem wir aus der Funktion zurückkehren. Wir sehen rax.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/4eae862955421b2b1629c120bb09970714cf085e9255590d6cfa36a77bbc69e9.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/43917bf46096449ad92172baa282fd3e70ec0bec67fec2bbf2a276285d878b52.png" alt=""><figcaption></figcaption></figure>
</div>
Ok, cool, ich verstehe es immer noch nicht. Nun, rax = 0x5eec108, was auf 0x48c48b48 zeigt, ok, und was? Nun, ich war genauso verwirrt wie du, also bin ich erneut zum chinesischen Blog zurückgekehrt. Was dieser Forscher beschreibt, was hier passiert, ist Folgendes: Es geht zurück zum Anfang der Funktion ImgArchStartBootApplication. Aber wie zum Teufel ist er darauf gekommen? Nun, wie bereits erwähnt, rax =\
0x48c48b48, und wenn wir die booloadermnfr.efi untersuchen, sehen wir:
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/2dbe283fa0b0dd9cf837e79f1f42eaeb6dcd61252e76979c0a4af3cf2f68e8d8.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/624e1927cac5a0011d6fabea0f2ce4740b8dfd14102509656d6e5c0395a9c08d.png" alt=""><figcaption></figcaption></figure>
</div>
was genau dieselbe Byte-Sequenz an 0x5eec108 ist. Ok, das ist jetzt cool :)
Bitte sieh dir sub\_180002398.py an, um meinen fehlgeschlagenen Versuch zu sehen, dieses Verhalten zu emulieren :)
\=============================================================================
Cool, weiter?
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/432ad1832fa35743bc5676f7f8362ad9e2043e17387121136a1f6dfe1bdf16f1.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/aab798c5c80621b1c367ea6eecfff0d7caf9ecc368ae2fe2e947538e4f0e2b0c.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/f04ebd9c650ddadb5553e4f2c43c72af8a5ccbef372a4dbdc811600e9583b0c9.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/3411e1620450739ea98f6db634346748487377106547324591b148cefe358df2.png" alt=""><figcaption></figcaption></figure>
</div>
Was als Nächstes passiert, ist RaiseTPL. Ok, also was macht das? Es erhöht die Priorität der aktuell ausgeführten Aufgabe und gibt ihre vorherige Prioritätsstufe zurück. In unserem Fall wird es mit den höchsten Ausführungsprivilegien ausgeführt.
Als Nächstes rufen wir das auf, was ich patch\_something genannt habe, das so aussieht:
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/0a31b0c154406b340e9bb044c4211afd6494bcac6ec197c99a10a6d0effb6a31.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/3fcff1b34a5d9af3cdd70e4dac1188abd3edd13e74d11e4f0bba5d667d4f53a1.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/c2f9bb8ca36961def04d4a3111a7d4213bb219949d13094b525a1a906ab788f7.png" alt="2">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/accdd93e3428b9b03132eafceda3ec5e1cfda742a978f1cd7f2c6bcf1904ceaa.png" alt=""><figcaption></figcaption></figure>
</div>
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/e0f6c806d296e47269b9908ceab7b90954bbd219d3d9c13462ebee8344f854f3.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/1ed164077989d04273ae3b40ec6daf7cf9b93ec42d917533b1e9758525231b7b.png" alt=""><figcaption></figcaption></figure>
</div>
Aus der statischen Analyse können wir also sehen, dass dies das ist, was als Hooking bekannt ist. :) Es patcht also im Grunde die Bytes von ImgArchStartBootApplication so, dass sie auf sub\_180001D80 zeigen, und speichert die ursprüngliche Funktion von ImgArchStartBootApplication in byte\_180015C78.
Und wie wir sehen können, ändert es sich zu genau sub\_180001D80.
<div>
<img src="https://assets.kitploit.com/production/public/readmes/44336/6c48bf4c9126a9a1466493aed943113cc27b4bbf9f7d68cdd251d0e14303ad8a.png" alt="1">
<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/633d84a62c16dba91229fe6bb73ed0318719fc06f63f7f2a9d19adba0d0e8cfe.png" alt=""><figcaption></figcaption></figure>
</div>
Als Nächstes setzen wir die Privilegien zurück und übergeben von dort aus die Kontrolle an boomgrfw.efi :)
Damit ist offiziell die erste Hälfte der Analyse abgeschlossen :) Im nächsten Teil lernen wir, wie man sub\_180001D80 und boomgrfw.efi (in unserem Fall winload.efi) weiter debuggt. Bitte bleibt also gespannt, bis ich lerne, wie man die Umgebung für den zweiten Teil der Analyse vorbereitet.
\=============================================================================
Nun zur zweiten Hälfte der Analyse.... Wie debuggen wir boomgrfw.efi?