Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
BlackLotus-analysis-stage2-bootkit-rootkit-stage — Z2A-BlackLotus Challenge analyse du bootkit-rootkit de l'étape 2 | Kitploit
Outils/GitHubGitHub/spiralbl0ck/blacklotus-analysis-stage2-bootkit-rootkit-stage
Analyse StatiqueAnalyse Dynamique (Sandboxing)Rétro-ingénierieDébogueursAnalyse de MalwareAnalyse de BinairesApprentissage et ÉducationAnalyse de Micrologiciel
GitHub
spiralbl0ck/blacklotus-analysis-stage2-bootkit-rootkit-stage

BlackLotus-analysis-stage2-bootkit-rootkit-stage

Z2A-BlackLotus Challenge analyse du bootkit-rootkit de l'étape 2

Voir le dépôt
1754il y a 3 ansPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

BlackLotus-analysis-stage2-bootkit-rootkit-stage

BlackLotus stage 2 bootkit-rootkit analysis

Avant de plonger dans cette merde divine (croyez-moi, c'est de la merde divine, car personne ne peut faire ça sans la Volonté de DIEU (du moins c'est mon avis sur la question)), voici le hash du fichier bootkit

1

Tout d'abord, voici à quoi ressemble un système sain

1
2
``` C:\Windows\system32>BCDEdit

Windows Boot Manager

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 ```

Windows Boot Loader

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

root@kitploit:~
Maintenant, dans mon analyse, je n'ai jamais réussi à infecter ma machine, donc j'utiliserai l'exemple du billet de blog du chercheur asiatique déjà référencé, qui montre à quoi est censé ressembler un appareil infecté.```
    // 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

=============================================================================

=============================================================================

Avant de commencer, au fait, comment configurer l'environnement pour l'analyse d'un module EFI pour commencer ? Eh bien, merci à @MaverickMusic__ , lors d'une discussion avec lui, il m'a donné ceci( https://zhuanlan-zhihu-com.translate.goog/p/343293521?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=en-GB ). Je n'ai pas suivi les étapes telles quelles, alors voici exactement ce que j'ai fait pour mettre l'environnement en place :

-Premièrement, j'ai installé edk2(https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems)

-Deuxièmement, j'ai configuré mon ovmf en debug et non en release (cela nous aidera plus tard). Voici la commande build -a X64 -t VS2019 -b DEBUG -p OvmfPkg/OvmfPkgX64.dsc

-Troisièmement, j'ai dû configurer mon windbg. Comment diable ai-je fait ? J'ai téléchargé tout depuis ce lien(git clone https://github.com/microsoft/WinDbg-Samples). Puis j'ai compilé ExdiGdbSrv.sln. Ensuite, j'ai suivi tout ce qui est indiqué sur ce lien(https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/setting-up-qemu-kernel-mode-debugging-using-exdi), depuis l'endroit où il était écrit Use regsvr32 to register the DLL in an Administrator command prompt. jusqu'à PS>.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 -ExdiDropPath "C:\path\to\built\exdi\files". Je sais que c'est déroutant, mais soyez patient, car je vais certainement faire une vidéo où j'expliquerai chaque étape ! Bon, maintenant que nous avons un environnement configuré pour le débogage, comment diable déboguer le code ? On démarre donc qemu ; dans mon cas, je l'ai fait en exécutant qemu-system-x86_64.exe -L . -bios OVMF.fd -hdd dos.img -debugcon file:debug.log -global isa-debugcon.iobase=0x402 . Aussitôt la commande qemu exécutée, je suis allé sélectionner compat_monitor0 dans le menu View de qemu. Cela devrait ressembler à ceci lorsque vous faites cela.

aussi, après avoir sélectionné cela, vous devez saisir gdbserver pour démarrer une instance distante de gdb, à laquelle nous nous attacherons avec windbg à l'aide de cette commande .\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 Cool, une fois que nous nous y connectons, cela ressemblera à ceci

1
1

Trop bien, maintenant, pour donner un sens à cette sortie, dans notre cas la seule ligne pertinente est EntryPoint=0x000062C9A8C qui est en quelque sorte l'adresse de chargement préférée chaque fois qu'on exécute le bootkit. Plus précisément, pour le bootkit, elle varie entre 0x62C4A8C or 0x62C9A8C. On peut maintenant rebaser le programme dans IDA et faire notre travail habituel :) . Profitez du reste du blog !

=============================================================================

Bindiffing du winload.efi original avec celui déposé par le blacklotus

1
2
3
4

On voit des similitudes mais aussi des différences, mais rien d'utile, bref....

=============================================================================

Cool, alors c'est parti.

1
1

Bon, commençons à disséquer. D'abord, on voit qu'il y a une fonction qui est appelée. Cool, et alors ? Eh bien

1
2

Cool, une autre fonction. Pas exactement... Vous remarquez quelque chose de familier ?

1
2
3

4

5

Toujours rien ???

Pas de problème, peut-être maintenant

1
2

Même fonction de demangle ! Salut, vieille amie :)))

Cool, mais qu'en est-il de return (*(a1 + 88))(v2, &unk_62CEABC, 3i64); ?? Franchement, je ne sais pas quoi dire d'un point de vue purement statique, alors essayons d'utiliser le débogueur pour le comprendre :))

Donc quand on demangle la chaîne, on obtient

1

Ensuite, quand on arrive à l'instruction d'appel

1

et on n'obtient aucune info.... super, mais pourquoi ? Parce qu'on n'a pas de fichier .pdb pour obtenir les symboles de débogage.... Bon, au moins IDA est utile ici. On sait donc que la fonction « grand » prend en entrée SystemTable->RuntimeServices, qui est de type EFI_SYSTEM_TABLE. Cool, si on l'inspecte, c'est un pointeur vers la table des services d'exécution EFI. . Si on cherche sur Google, on tombe sur un tas de documents, mais un document crucial est https://uefi.org/sites/default/files/resources/UEFI\_Spec\_2\_1\_D.pdf . Il y est dit :

1

Cool, donc une structure avec un tas de pointeurs, ouais, mais zoomons un peu plus.

Donc d'abord, il demangle VbsPolicyDisable. Si on cherche sur Google, on tombe sur l'analyse d'ESET qui indique que cette variable est évaluée par le chargeur du système d'exploitation Windows au démarrage et, si elle est définie, les fonctionnalités VBS de base, telles que HVCI et Credential Guard, ne seront pas initialisées. , donc en gros cette variable est responsable de la « sécurité » actuelle au niveau du démarrage. Cool, ensuite on a la fonction qui prend cette variable et

1

et donc on peut en conclure que ça doit être une fonction qui change d'une manière ou d'une autre l'état de cette variable. Bon, quelles fonctions pourraient faire ça ? Il n'y a qu'une seule fonction de ce type dans EFI_SYSTEM_TABLE, à savoir EFI_SET_VARIABLE SetVariable;

Nous concluons donc que cette fonction prend simplement VbsPolicyDisable et la définit à``` 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.

root@kitploit:~
Maintenant, ces octets ont-ils quelque chose d'important ? Eh bien oui, si par hasard vous avez lu la première partie de l’analyse de BlackLotus, vous saurez que j’ai fait référence au travail d’un chercheur asiatique. Ce chercheur a eu la gentillesse d’analyser également le bootkit déposé. Veuillez le consulter (https://www.cnblogs.com/DirWang/p/17294545.html#autoid-3-2-1). Dans son analyse, il a eu la gentillesse de nous donner cette info. Il nous pointe vers https://github.com/Mattiwatti/EfiGuard/blob/master/EfiGuardDxe/PatchWinload.c. Là, on voit une ligne similaire

<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>

Y a-t-il une raison précise derrière tout ça ? Honnêtement, je n’en sais rien, c’est la première fois que j’analyse un bootkit. Merci de me le faire savoir ou de faire une PR/pull request pour modifier ce document si vous avez plus d’expérience que moi :) dans ce domaine

\=============================================================================

Cool, ensuite, la fortune nous sourit et le pseudo-code d’IDA est similaire à l’assembleur

<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>

donc ce que je suppose qu’il se passe ici, c’est une initialisation normale de EFI\_SYSTEM\_TABLE qui, je suppose, initialise quel processus doit continuer le processus de démarrage. Et ensuite, nous avons l’appel de fonction 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>

Et à partir du pseudo-code

<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, donc le premier appel de fonction que l’on voit est HandleProtocol. Alors, qu’est-ce que ce code fait ? Par chance, on tombe dessus lors d’une recherche Google rapide (https://tianocore-docs.github.io/edk2-ModuleWriteGuide/draft/5\_uefi\_drivers/54\_communication\_between\_uefi\_drivers.html) et on voit que ça `retrieve protocols`. Cool, rien que je ne puisse vraiment comprendre. Ouais, je vous reçois. Donc en gros, ça récupère les méthodes d’informations de communication utilisées par d’autres pilotes UEFI. Cool, encore un peu de recherche. On voit que le deuxième paramètre est

<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>

Si on recherche ces octets spécifiques, on tombe sur ceci

<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>

alors qu’est-ce que fait EFI\_LOADED\_IMAGE\_PROTOCOL\_GUID ? en citant (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.` , quel type d’info ? \`\`\`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.\`\`\`\`

Donc dans notre cas, ça récupère des infos sur le bootkit. Maintenant, il y a un problème : on ne peut pas vraiment inspecter le résultat de la fonction car nous n’avons pas de symboles de débogage :/ mais on peut présumer. Et j’ai tendance à présumer que la structure (résultat de l’appel de fonction précédent) se trouvera dans rbx.

<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/b8f744ecd9fd4be572a1e2d191b06231559eca2b32aeaa981a399eec7f3ee710.png" alt=""><figcaption></figcaption></figure>

Ensuite, on appelle demangle string

<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/1fdc75d2dc9221250e6d46692770ad5240f7a0d6cda9cc5634749b327fc8c146.png" alt=""><figcaption></figcaption></figure>

ce qui nous donne

<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>

et ensuite on appelle

<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>

et le pseudo-code

<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, donc jusqu’au if, tout est explicite. Maintenant, qu’en est-il du if ? On voit encore qu’il fait un appel avec unk\_180005010 comme paramètres, qui est à nouveau un tableau d’octets ; en y regardant de plus près, cela ressemble à ceci

<figure><img src="https://assets.kitploit.com/production/public/readmes/44336/c3bb66f35a4e559ae793ba590fc0c342bdde1e1c9765e144cb450a809009655d.png" alt=""><figcaption></figcaption></figure>

Maintenant, si on inspecte à nouveau les premiers octets et qu’on fait une recherche rapide, on trouve ceci (https://github.com/theopolis/uefi-firmware-parser/blob/master/uefi\_firmware/guids/efiguids\_ami.py) plus précisément ceci `'EFI_DEVICE_PATH_PROTOCOL_GUID': [0x09576e91, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]` .

Si on retourne sur la page de spécification de l’UEFI, on voit que `Can be used on any device handle to obtain generic path/location information concerning the physical device or logical device.`. Ensuite, on voit aussi ceci `The device path describes the location of the device the handle is for`. OK cool, et si on fait défiler un peu, on voit une fonction appelée \_EFI\_DEVICE\_PATH\_PROTOCOL. Ok, donc pour conclure, on sait que ça a à voir avec EFI\_DEVICE\_PATH\_PROTOCOL\_GUID, mais notre fonction est de type EFI\_BOOT\_SERVICES. Alors, y a-t-il une fonction dans EFI\_BOOT\_SERVICES qui pourrait faire quelque chose comme gérer un protocole ? Oui, il y en a une. Si on inspecte https://www.intel.com/content/dam/doc/product-specification/efi-v1-10-specification.pdf section 4.4, on voit

<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>

plus précisément, elle dispose d’une fonction qui nous est familière (HandleProtocol). Cool

Ensuite, on voit un autre appel de fonction, inconnu cette fois pour nous. Voyons quels arguments il prend. Il en prend 2, puis la longueur de la chaîne passée en Unicode, et un pointeur vers une 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>

Maintenant, si on inspecte ceci dans un débogueur

<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>

on voit une chose étrange : rcx contient une chaîne de débogage, AllocatePool, qui vient après un appel de fonction. On conclut donc qu’il s’agissait probablement d’un appel à AllocatePool. Assez drôle, si vous inspectez aussi les spécifications, vous verrez que boot\_services dispose également d’un pointeur vers AllocatePool, ce qui ne fait que renforcer notre hypothèse.

Cool, donc si nous parvenons à allouer assez d’espace (la vérification `si >= 0` sert à vérifier si l’allocation a réussi, car si EFI\_OUT\_OF\_RESOURCES est implémenté comme

<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>

il est seulement prudent de supposer

<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>

est utilisé pour une allocation réussie)

Un fait intéressant : le buffer après allocation n’est pas zéro, mais contient plutôt ces octets. Si quelqu’un en sait plus à ce sujet, merci de faire une PR pour modifier ce document

<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>

Donc ouais, de toute façon, on finit par appeler memcpy ; après l’appel, notre buffer ressemble à ceci

<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>

On ajoute ensuite quelques octets pour que le buffer ressemble à ceci

<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>

Et ensuite, on appelle une fonction appelée FileDevicePath\_call qui ressemble à peu près à ceci&#x20;

<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>

Et qui se traduit par ceci

<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, mais cela n’a aucun sens si ce n’est pas expliqué alors....

D’abord, on a une implémentation personnalisée de strlen que nous ne disséquerons pas car elle est inutile :) Mais voici le résultat

<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 caractères depuis len(of(str)+"\x00" puis les 4 derniers octets ajoutés avant l’appel de fonction 0x4FF7F

Ensuite, on appelle ce que j’ai aussi utilisé depuis le billet de blog du chercheur asiatique : PxepDevicePathInstanceCount, qui est simplement strlen, car il compte simplement chaque lettre et possède un compteur. Comme on le voit ici

<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>

Donc ouais, on voit pop rbx et après l’appel on voit 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>

Ensuite, on appelle encore strlen sur la même chaîne ; je suppose que c’est simplement parce qu’à la ligne suivante, précisément, `v6 + v4 * v5;` on fait v4\*v5, ce qui est, je suppose, une façon d’avoir des chaînes Unicode, je suppose.

Quoi qu’il en soit, on alloue à nouveau de la mémoire en utilisant gEfiBootServices + 64, ce que nous avons précédemment rencontré et qui s’est résolu en AllocatePool.

Ici, on voit aussi quelque chose de sympa, à savoir

<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>

le fait qu’ici le bloc mémoire contient le motif afafafaf.

Ensuite, ce qui se passe, c’est qu’on obtient deux buffers qui ressemblent à ceci après l’exécution de la boucle principale

<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>

Et pour être honnête, seul le premier nous intéresse, car c’est ce qui est retourné. On peut donc conclure que ça copie simplement le device path et nettoie quelques déchets du buffer. :))

Maintenant, après avoir terminé cela, on vérifie si le device path dans notre cas est déjà, je suppose, initialisé, et on libère le pool sinon ; on retourne le buffer plus propre de la fonction mentionnée précédemment.

Avant de terminer avec cette fonction, j’aimerais souligner un autre fait intéressant : voici à quoi ressemble en mémoire la table des services de démarrage :) d’après les spécifications, avec l’en-tête de début. Je me suis dit que ça pourrait être intéressant de le laisser ici pour quiconque voudrait faire du travail futur et se retrouverait à trouver cette chaîne BOOTSERVF dans un dump ; c’est définitivement une table des services de démarrage.

\=============================================================================

Bon, alors que se passe-t-il ensuite ??? Eh bien, on vérifie si on a réussi à localiser le fichier winload.efi et on le charge en mémoire. Voici le pseudo-code :)

<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>

Et voici à quoi cela ressemble en mémoire

<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>

Qu’est-ce que rax ? rax est un handle vers l’image :) ne soyez pas stupide comme moi quand j’ai d’abord cru que c’était une zone mémoire :)

Cool, avant de continuer, laissez-moi expliquer rapidement ce qu’est winload.efi. Alors, `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>

Alors, comment un PC Windows normal démarre-t-il ? Après le BDS, le code du firmware UEFI stocké dans SPI a terminé son travail, puis le gestionnaire de démarrage du firmware UEFI interroge d’abord la variable UEFI NVRAM pour trouver l’ESP, et trouve le gestionnaire de démarrage spécifique au système d’exploitation bootmgfw.efi pour appeler sa fonction d’entrée (driver DXE).

Cette fonction appellera d’abord la fonction EfiInitCreateInputParametersEx, qui est principalement utilisée pour convertir le paramètre EfiEntry dans le format de paramètre attendu par bootmgfw.efi.

La fonction BmMain du point d’entrée du gestionnaire de démarrage Windows est ensuite appelée.

Dans cette fonction, BmFwInitializeBootDirectoryPath est appelé pour initialiser le chemin de l’application de démarrage (BootDirectory) (\EFI\Microsoft\Boot).

Ensuite, BootMgr lira la lettre de configuration de démarrage du système (BCD) ; s’il y a plusieurs options de démarrage, il appellera BmDisplayGetBootMenuStatus pour afficher le menu de démarrage.

Ensuite, il appellera la fonction BmpLaunchBootEntry pour démarrer l’application (winload.efi).

Bien sûr, bootmgfw.efi fait plus que cela, notamment la vérification de l’intégrité du code de la politique de démarrage et l’initialisation des composants de démarrage sécurisé, donc je n’entrerai pas dans les détails.

Dans l’étape finale du gestionnaire de démarrage Windows (BootMgr), la fonction BmpLaunchBootEntry sélectionnera l’entrée de démarrage correcte selon la valeur BCD précédente. Si le chiffrement de volume complet (BitLocker) est activé, la partition système sera d’abord déchiffrée, puis le contrôle pourra être transféré à winload.efi.

Ensuite, la fonction BmTransferExecution est appelée, les options de démarrage sont vérifiées et le flux d’exécution est passé à la fonction BlImgStartBootApplication.

Ensuite, la fonction BlImgStartBootApplication appellera la fonction ImgFwStartBootApplication, puis finalement la fonction ImgArchStartBootApplication. Dans celle-ci, le mode de protection mémoire de winload.efi sera initialisé. Ensuite, la fonction BlpArchTransferTo64BitApplication est appelée ; BlpArchTransferTo64BitApplication appelle la fonction Archpx64TransferTo64BitApplicationAsm qui remet finalement le contrôle à winload.efi.

Cette fonction activera les nouveaux GDT et IDT, puis remettra complètement le contrôle à winload.efi. À ce stade, BootMgr termine sa mission et Winload commence à travailler. - Fin des citations volées à un site web chinois qui parle de ce sujet (veuillez consulter ce lien pour plus de contenu https://bbs.kanxue.com/thread-268267.htm )Et à partir de là, winload.efi fait son travail, à savoir charger Windows et effectuer encore un peu de travail matériel avant de passer le contrôle au noyau.

Maintenant, après ce bref briefing, comme nous le disions,

<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>

nous vérifions ensuite si son chargement en mémoire a réussi, puis nous exécutons une fonction nommée ati\_analysis\_rdtsc\_aia\_cu\_4e1f que vous devriez connaître si vous avez déjà lu la première partie de cette analyse.

Passons maintenant à la partie amusante : imaginons que nous échouions à analyser cette fonction et que nous soyons détectés. Voyons à quoi ressemble sub\_180002A08.

<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>

Nous revoyons encore gEfiSystemTable + 64, que nous ne connaissons en réalité pas cette fois-ci, car il est d'un type différent : ce n'est pas cette fois de type bootservices, mais de type efisystemtable, puis memcpy et encore trois appels de fonction que nous ne connaissons pas. Maintenant, si nous exécutons jusqu'au début de la boucle,

<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>

et si nous inspectons les paramètres précédents de memcpy,

<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>

et que nous inspectons l'image de sortie de QEMU, nous obtenons

<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, alors essayons de donner un sens à tout cela. Je vais me référer à nouveau au blog de recherche du chercheur asiatique, car honnêtement, je suis perdu ici.

Donc, sur son blog, il dit que les deux fonctions étaient en réalité```
ConOut->ClearScreen(ConOut);
ConOut->OutputString(ConOut, String);

Ok mais c'est quoi ce bordel conOut ? bon il dit aussi que conout est de type EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL et que conout est obtenu par ConOut = gEfiSystemTable->ConOut; . ok donc qu'est-ce que ça veut dire dans le code ??

Ok donc creusons

la définition

1

et le guid

2

Et là, mon petit génie de mes deux a oublié de capturer ça dans un débogueur parce qu'au départ quand j'ai analysé ça, j'ai confondu le type de données entre efisystemtable et bootservices et je pensais que c'était en fait allocatepool.

Maintenant, que font ces fonctions ?

Bon, ClearScreen devrait être assez explicite, tout comme OutputString. Comment le chercheur a-t-il pu conclure que cette variable est de type EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL ? eh bien probablement parce qu'il a vu les octets du guid dans le débogueur.

Et la dernière fonction alors ?

eh bien dans son article de blog, il dit que la dernière fonction est gEfiBootServices->Stall ? alors c'est quoi ce bordel que ça fait ? . D'après les spécifications UEFI 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.

Donc en gros ça gèle notre cpu. cool, pour combien de temps 0x1C9C380 secondes. un temps de merde si vous voulez mon avis. ce qui est encore une fois mis dans une boucle infinie donc ouais on est foutus :)))

Et voilà à quoi ça ressemble dans un débogueur

1

Maintenant, on continue avec notre fonction principale

1

si on arrive à charger bootmgfrw.efi (car winload.efi ici est le vrai chargeur de démarrage Windows) on appelle sub_180002538

============================================================================= sub_180002538

D'un point de vue graphe

1

D'un point de vue assembleur

2
3
4
5
6

Ça vous dit quelque chose ? non, bon, accordez-lui une minute, ça va faire tilt, en attendant regardez du point de vue pseudo-code

1
2

on voit un parsing d'un exe :) alors je ne sais pas à quel point ce sera identique à celui de la partie précédente (part1) mais voyons :)

donc on compare notre version en mémoire du binaire (bootmgfrw.efi) avec l'en-tête MZ classique (0x5A4D), comme vous pouvez le voir

1
1

ok ensuite on fait un autre contrôle classique : voir si on peut trouver l'en-tête PE

1

Cool, ensuite on appelle sub_1800024C4() qui ressemble à ça

1
2

Cool, donc ce qui se passe ici c'est qu'on localise certaines valeurs en mémoire et si on les trouve, on les retourne. Veuillez vous référer à sub_180002538.py.py pour l'émulation.

Bref, voici sub_180002464

1

Si on exécute avec succès sub_1800024C4, on revient dans la fonction plus grande et on suit quelques contrôles supplémentaires, cool, essayons d'y voir plus clair

1

Cool, donc on compare en outre ce qui se trouve à rax+0xe avec 0x64 hmm cool, intéressant, inspectons rax+0xe

1

Une raison particulière derrière ce contrôle précis ? honnêtement je n'en sais rien ? peut-être ; si vous savez, faites une pull request et modifiez ce document

on fait encore quelques additions puis une comparaison

1

Je veux m'arrêter ici une minute et référencer à nouveau la source d'inspiration précédente de cet article chaque fois que je me suis perdu, donc dans son blog il a renommé la fonction qui comparait des valeurs en RtlpImageDirectoryEntryToDataEx, qui si on cherche ne donne aucun résultat mais il y a quelque chose d'assez proche de ses noms, à savoir RtlImageDirectoryEntryToData, qui en gros fait ceci 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) dans notre cas, puisque nous sommes dans une application efi/uefi, on peut considérer que le 50 qu'on voit est la taille en octets/mo, je ne sais pas, de notre partition racine dans ce cas, et que cette adresse qui est dans rax est une entrée dans notre répertoire.

Avant d'aller plus loin, il reste un détail intéressant à expliquer. Dans ses recherches, il convertit la sortie de RtlImageDirectoryEntryToData en cette structure``` 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;

root@kitploit:~
Bon, et WTF avec cette structure ?

bon, une recherche rapide sur cette structure nous amène ici(http://www.brokenthorn.com/Resources/OSDevPE.html) qui nous dit que `Analyser les ressources est un peu plus complexe que les autres types de répertoires, cependant. Comme pour les autres sections, il y a une structure de base IMAGE_RESOURCE_DIRECTORY qui peut être obtenue à partir du membre DataDirectory de l'en-tête optionnel : bla bla` et aussi que \`\`\`Cette structure n'a pas beaucoup de champs intéressants, à l'exception des trois derniers.

Si vous avez déjà travaillé avec les ressources Win32, vous savez peut-être que les ressources peuvent être identifiées par ID ou par nom. Deux des membres de cette structure nous indiquent le nombre de ces entrées et le nombre total d'entrées (NumberOfNamedEntries + NumberOfIdEntries), ce qui est utile pour boucler sur toutes les entrées. Comme vous pouvez probablement le deviner, les entrées se trouvent dans le tableau DirectoryEntries. DirectoryEntries se compose d'un tableau de structures IMAGE\_RESOURCE\_DIRECTORY\_ENTRY, qui suivent le format :\`\`\`

donc en gros cette merde est utilisée en interne pour analyser des trucs en interne et pour nous, ça a du sens dans le contexte du fait que nous travaillons avec un répertoire qui contient des ressources, cool.

Encore !

Donc ensuite

<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>

ce que ça fait, c'est essentiellement itérer sur chaque ressource du répertoire et vérifier si elle est de type chaîne

pour être honnête, je ne sais pas pourquoi il ferait ça, donc si je me trompe, désolé, si je ne me trompe pas, bravo !

ensuite

<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>

ce qui se passe ici, c'est que nous ajoutons quelques offsets et nous aboutissons à ce que le chercheur chinois appelle la seconde table de ressources, comme vous pouvez le voir

<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>

et ensuite on répète le même processus pour obtenir quelques offsets

<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>

et on répète le même processus, cette fois on vérifie le type 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>

alors c'est quoi VS\_VERSION\_INFO ? eh bien microsoft(https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource) dit que `Définit une ressource d'informations de version`, par ex. je crois que ça dit simplement la version de bootmgfrw.ef

et finalement si on trouve VS\_VERSION\_INFO, on répète le même algorithme

<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>

cette fois avec une petite variante, la variante étant qu'on retourne le build id :) comme on peut le voir

Donc pour conclure, qu'est-ce qui s'est passé ici en fait ? eh bien, d'après le nom utilisé par le chercheur chinois (GetPeFileVersionInfo\_BuildNumber\_) on peut conclure qu'on obtient en fait le numéro de build du bootloader, comme on peut le voir sur la première image

<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>

où l'on voit le bootloader chargé en mémoire

sur la deuxième image on voit

<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>

un entier dans rcx qui pourrait être soit le numéro de build, soit pefileversion

et la 3ème image

<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>

ce que l'on pourrait supposer être le numéro de build car ebx sera déplacé dans rax :)

Donc en dernière note sur cette fonction, wow, ingénierie incroyable

=============================================================================

Passons au défi suivant :) en fonction de la sortie de l'étape précédente, on définit v10 sur sub\_180001D80 ou sub\_180001D48, comme vu

<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>

et dans notre cas 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>

=============================================================================

On fait ensuite un strcmp entre notre bootloader manager et ce tableau d'octets

<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>

Je veux m'arrêter ici un court instant, car comme vous l'avez peut-être deviné, j'ai vu quelque chose d'intéressant dans l'article du chercheur chinois. Il a appelé le tableau d'octets SigImgArchStartBootApplication. Alors c'est quoi SigImgArchStartBootApplication, à qui appartient-il et pourquoi diable ce tableau s'appelle-t-il comme ça (migos). Donc si on cherche sur google (gulugulu) SigImgArchStartBootApplication, on ne trouve rien. Maintenant, étant donné le contexte actuel, on utilise le bootloader manager de Windows, ouvrons-le dans IDA. On va dans C:\Windows\Boot\EFI, on ouvre le binaire dans IDA et on cherche SigImgArchStartBootApplication, rien. On cherche ImgArchStartBootApplication et on tombe sur

<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>

Donc ImgArchStartBootApplication .... qu'est-ce que le chien fout... !? Bien euh...hh je vais voler ça à `@_xeroxz` (allez le suivre, qu'est-ce que vous foutez si vous ne suivez pas son travail....) donc en gros dans un article il dit que `bootmgfw.ImgArchStartBootApplication entre les versions de Windows 2004-1709 est invoqué pour démarrer winload.efi` comme on peut le voir aussi sur son image(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>

Si ce n'était pas assez clair, dans un article() on voit que `ImgArchStartBootApplication pour attraper le moment où le chargeur Windows (winload.efi) est chargé en mémoire mais n'a pas encore été exécuté`(https://rustrepo.com/repo/rusty-bootkit--uefi-bootkit-in-rust)

Cool, donc quel est le rapport entre strcmp et ImgArchStartBootApplication ? eh bien, regardons de plus près IDA et la réponse va bientôt nous être révélée. Si on cherche dans le code du bootloader les octets 41 b8 09, on rencontre vite le coupable

<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>

Et si les octets de notre image mémoire du bootloader correspondent à la signature d'octets, on exécute sub\_180002398

Et comme on peut le voir, on a localisé le motif, on a retourné dans eax la zone mémoire où se trouvent les octets, et on procède prudemment à l'exécution de sub\_180002398

=============================================================================

sub\_180002398

"Perspective assembleur"

<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>

"Perspective pseudo-code"

<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>

Donc qu'est-ce que le chien fait ? honnêtement, il fait quelques calculs, quelques additions et soustractions et rien de vraiment important ? pourquoi parce que ce n'est pas si intéressant. Ce qui nous intéresse, c'est ce qui se passe après le retour de la fonction. On voit 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, mais je ne comprends toujours pas. Eh bien, rax = 0x5eec108 qui pointe vers 0x48c48b48, ok et alors ? eh bien, j'étais aussi confus que vous, alors je suis retourné une fois de plus au blog chinois. Donc ce que ce chercheur décrit, ce qui se passe ici, c'est ça : on retourne au début de la fonction ImgArchStartBootApplication. Mais comment a-t-il fait pour trouver ça ? eh bien, comme mentionné plus tôt, rax =\
0x48c48b48 et si on inspecte le booloadermnfr.efi on voit

<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>

qui est exactement la même séquence d'octets dans 0x5eec108. ok maintenant c'est cool :)

Merci de vous référer à sub\_180002398.py pour voir ma tentative ratée d'émuler ce comportement :)

=============================================================================

Cool, ensuite ?

<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>

Donc ce qui se passe ensuite, c'est RaiseTPL. ok, et ça fait quoi ? Ça augmente la priorité de la tâche en cours d'exécution et retourne son niveau de priorité précédent. Dans notre cas, ça sera exécuté avec les privilèges d'exécution les plus élevés.

Ensuite, on appelle ce que j'ai appelé patch\_something, qui ressemble à ceci

<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>

Donc d'après l'analyse statique, on peut voir que c'est ce qu'on appelle du hooking. :) donc en gros, ça patch les octets de ImgArchStartBootApplication pour pointer vers sub\_180001D80 et sauvegarde la fonction originale de ImgArchStartBootApplication dans byte\_180015C78

et comme on peut le voir, ça change exactement vers 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>

ensuite on réinitialise les privilèges et à partir de là, on passe le contrôle à boomgrfw.efi :)

Donc ceci marque officiellement la fin de la première moitié de l'analyse :) dans la prochaine partie, nous apprendrons comment déboguer davantage sub\_180001D80 et boomgrfw.efi (dans notre cas winload.efi). Alors, tenez bon jusqu'à ce que j'apprenne à préparer l'environnement pour la deuxième partie de l'analyse

=============================================================================

Maintenant, pour la deuxième moitié de l'analyse.... Comment déboguer boomgrfw.efi ?
Télécharger l’outil