Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
BlackLotus-analysis-stage2-bootkit-rootkit-stage — Z2A-BlackLotus Challenge etapa 2 análisis de bootkit-rootkit | Kitploit
Herramientas/GitHubGitHub/spiralbl0ck/blacklotus-analysis-stage2-bootkit-rootkit-stage
Análisis EstáticoAnálisis Dinámico (Sandboxing)Ingeniería InversaDepuradoresAnálisis de MalwareAnálisis de BinariosAprendizaje y EducaciónAnálisis de Firmware
GitHub
spiralbl0ck/blacklotus-analysis-stage2-bootkit-rootkit-stage

BlackLotus-analysis-stage2-bootkit-rootkit-stage

Z2A-BlackLotus Challenge etapa 2 análisis de bootkit-rootkit

Ver Repositorio
1754hace 3 añosAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

BlackLotus-analysis-stage2-bootkit-rootkit-stage

Análisis del bootkit-rootkit de la etapa 2 de BlackLotus

Antes de sumergirnos en esta mierda divina (créeme, esto es mierda divina ya que nadie puede hacer esto sin la Voluntad de DIOS (al menos esa es mi opinión al respecto)) ,aquí está el hash del archivo bootkit

1

Primero lo primero, así es como se ve un sistema saludable

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:~
Ahora, en mi análisis, nunca logré infectar mi máquina, así que usaré el ejemplo de la publicación del blog del investigador asiático ya referenciado, que es así como se supone que se ve una infectada.```
    // 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

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

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

Antes de comenzar, ¿cómo se configura el entorno para el análisis de un módulo efi? Bueno, el crédito es para @MaverickMusic__ , durante una discusión con él me pasó esto( https://zhuanlan-zhihu-com.translate.goog/p/343293521?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=en-GB ). Ahora no seguí completamente los pasos de ahí, así que esto es exactamente lo que hice para tener el entorno funcionando :

-Primero instalé edk2(https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems)

-Segundo, configuré mi ovmf como debug, no release (esto nos ayudará más adelante). Aquí está el comando build -a X64 -t VS2019 -b DEBUG -p OvmfPkg/OvmfPkgX64.dsc

-Tercero tuve que configurar mi windbg. ¿Cómo demonios hice esto? Descargué todo desde este enlace(git clone https://github.com/microsoft/WinDbg-Samples). Luego compilé ExdiGdbSrv.sln. Después seguí todo desde este enlace(https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/setting-up-qemu-kernel-mode-debugging-using-exdi), desde donde decía Use regsvr32 to register the DLL in an Administrator command prompt. hasta PS>.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 -ExdiDropPath "C:\path\to\built\exdi\files". Sé que es confuso, pero ten paciencia, ¡definitivamente haré un video donde explicaré cada paso! Bien, ahora que tenemos un entorno configurado para depuración, ¿cómo demonios depuramos el código? Entonces iniciamos qemu; en mi caso lo hice ejecutando qemu-system-x86_64.exe -L . -bios OVMF.fd -hdd dos.img -debugcon file:debug.log -global isa-debugcon.iobase=0x402 . Una vez ejecuté el comando de qemu, fui inmediatamente y seleccioné compat_monitor0 desde el menú view de qemu. Debería verse así cuando haces eso.

también después de seleccionar esto, debes ingresar gdbserver para iniciar una instancia remota de depuración de gdb a la que nos adjuntaremos con windbg usando este comando .\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 Bien, una vez que nos conectemos, se verá así

1
1

Bien, ahora para darle sentido a esta salida, en nuestro caso la única línea relevante es EntryPoint=0x000062C9A8C, que viene a ser la dirección de carga preferida cuando ejecutamos el bootkit. Específicamente para el bootkit varía entre 0x62C4A8C or 0x62C9A8C. Ahora podemos reubicar el programa en ida y hacer nuestro trabajo normal :) . ¡Disfrutad el resto del blog!

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

Bindiffing del winload.efi original con el que suelta BlackLotus

1
2
3
4

Vemos algunas similitudes pero también algunas discrepancias, pero nada útil, en fin....

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

Bien, así que comencemos la fiesta.

1
1

Bien, empecemos a diseccionar. Primero vemos que tenemos una función a la que se llama. Bien, ¿y qué? Pues

1
2

Bien, otra función. No exactamente... ¿Notas algo familiar?

1
2
3

4

5

¿¿¿Nada todavía??? No hay problema, quizás ahora

1
2

¡La misma función demangle! Hola, viejo amigo :)))

Bien, pero ¿qué hay de return (*(a1 + 88))(v2, &unk_62CEABC, 3i64);? Bueno, sinceramente no sé qué decir solo desde una perspectiva estática, así que intentemos usar el depurador para entenderlo :))

Entonces, cuando hacemos demangle de la cadena obtenemos

1

Luego, cuando llegamos a la instrucción de llamada

1

y no obtenemos información... genial, pero ¿por qué? Porque no tenemos un archivo .pdb para obtener símbolos de depuración... Bien, al menos ida nos ayuda aquí. Así que sabemos que la función "grand" toma como entrada SystemTable->RuntimeServices, que es de tipo EFI_SYSTEM_TABLE. Bien, si lo inspeccionamos, esto es Un puntero a la Tabla de Servicios de Runtime EFI. . Si buscamos en Google, encontramos un montón de documentos, pero uno crucial que encontramos es https://uefi.org/sites/default/files/resources/UEFI\_Spec\_2\_1\_D.pdf . Allí dice

1

Bien, una estructura con un montón de punteros, sí, pero acerquémonos más.

Primero hace demangle de VbsPolicyDisable; si buscamos en Google nos topamos con el análisis de ESET que afirma que esta variable es evaluada por el cargador del sistema operativo Windows durante el arranque y, si está definida, las funciones principales de VBS, como HVCI y Credential Guard, no se inicializarán. , así que básicamente esta variable es responsable de la "seguridad" actual a nivel de arranque. Bien, luego tenemos la función que toma esa variable y

1

y así podemos llegar a la conclusión de que debe ser una función que de algún modo cambia el estado de esa variable. Bien, ¿qué posibles funciones podrían hacer esto? Solo hay una función así en EFI_SYSTEM_TABLE, que es EFI_SET_VARIABLE SetVariable;

Así que concluimos que esta función simplemente toma VbsPolicyDisable y la establece a``` 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:~
Ahora bien, ¿hay algo importante en estos bytes? Pues sí, si por casualidad has leído la primera parte del análisis de BlackLotus, sabrás que hice referencia al trabajo de un investigador asiático. Bueno, ese investigador fue tan amable de analizar también el bootkit dropeado. Por favor, échale un vistazo(https://www.cnblogs.com/DirWang/p/17294545.html#autoid-3-2-1) , así que en su análisis tuvo la amabilidad de darnos esa información. Nos señala https://github.com/Mattiwatti/EfiGuard/blob/master/EfiGuardDxe/PatchWinload.c . Allí vemos una línea similar

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

¿Hay una razón específica detrás de esto? Honestamente, no lo sé; es mi primera vez analizando un bootkit. Por favor, házmelo saber o haz una PR/pull request para editar este documento si tienes más experiencia que yo :) en esta área

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

Genial, a continuación, la fortuna nos favorece y el pseudocódigo de IDA es similar al ensamblador

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

así que lo que supongo que ocurre aquí es la inicialización normal de EFI\_SYSTEM\_TABLE, que básicamente inicializa qué proceso debe continuar el proceso de arranque. Y luego tenemos la llamada a la función 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>

Y del pseudocódigo

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

Genial, así que la primera llamada a función que vemos que hace es HandleProtocol. Entonces, ¿qué hace el código? Por suerte, nos topamos con esto al hacer una búsqueda rápida en Google (https://tianocore-docs.github.io/edk2-ModuleWriteGuide/draft/5\_uefi\_drivers/54\_communication\_between\_uefi\_drivers.html) y vemos que `recupera protocolos`. Genial, no hay nada que realmente pueda entender. Sí, te entiendo, colega. Así que básicamente esto recupera los métodos de información de comunicación utilizados por otros controladores UEFI. Genial, un poco más de excavación. Vemos que el segundo parámetro es

<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 buscamos esos bytes específicos, nos encontramos con esto

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

entonces, ¿qué demonios hace EFI\_LOADED\_IMAGE\_PROTOCOL\_GUID? Citando de(https://uefi.org/specs/UEFI/2.10/09\_Protocols\_EFI\_Loaded\_Image.html) `Puede usarse en cualquier manejador de imagen para obtener información sobre la imagen cargada.` , ¿qué tipo de información? \`\`\`Esta sección define EFI\_LOADED\_IMAGE\_PROTOCOL y EFI\_LOADED\_IMAGE\_DEVICE\_PATH\_PROTOCOL. Respectivamente, estos protocolos describen una imagen que ha sido cargada en memoria y especifican la ruta de dispositivo utilizada cuando una imagen PE/COFF se cargó a través del Servicio de Arranque EFI LoadImage(). Estas descripciones incluyen la fuente desde la que se cargó la imagen, la ubicación actual de la imagen en memoria, el tipo de memoria asignado para la imagen y los parámetros pasados a la imagen cuando se invocó.\`\`\`\`

Así que en nuestro caso obtiene información sobre el bootkit. Ahora hay un problema: no podemos inspeccionar realmente el resultado de la función porque no tenemos símbolos de depuración :/ pero podemos suponer. Y tiendo a suponer que la estructura (resultado de la llamada anterior a la función) estará en rbx.

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

A continuación llamamos a demangle string

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

que nos da

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

y luego llamamos a

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

y pseudocódigo

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

Genial, hasta el `if` todo es autoexplicativo; ahora, ¿qué hay del `if`? Vemos que de nuevo hace una llamada con unk\_180005010 como parámetro, que vuelve a ser un array de bytes; al inspeccionarlo más a fondo, se ve así

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

Ahora, si inspeccionamos los primeros bytes de nuevo y hacemos una búsqueda rápida, nos encontramos con esto (https://github.com/theopolis/uefi-firmware-parser/blob/master/uefi\_firmware/guids/efiguids\_ami.py) más precisamente esto `'EFI_DEVICE_PATH_PROTOCOL_GUID': [0x09576e91, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]` .

Si volvemos a la página de especificaciones de UEFI, vemos que `Puede usarse en cualquier manejador de dispositivo para obtener información genérica de ruta/ubicación sobre el dispositivo físico o lógico.`. Luego también vemos algo como `La ruta de dispositivo describe la ubicación del dispositivo para el que es el manejador`. OK, genial, y si bajamos un poco, vemos una función llamada \_EFI\_DEVICE\_PATH\_PROTOCOL. Bien, para concluir, sabemos que esto tiene que ver con EFI\_DEVICE\_PATH\_PROTOCOL\_GUID, pero nuestra función es de tipo EFI\_BOOT\_SERVICES. Entonces, ¿hay alguna función en EFI\_BOOT\_SERVICES que pueda hacer algo como manejar un protocolo? Sí, la hay. Si inspeccionamos https://www.intel.com/content/dam/doc/product-specification/efi-v1-10-specification.pdf sección 4.4, vemos

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

más concretamente, tiene una función que nos resulta familiar (HandleProtocol). Genial.

A continuación vemos otra llamada a una función, esta vez desconocida para nosotros. Veamos qué argumentos toma: toma 2, luego la longitud de la cadena pasada como Unicode, y un puntero a una 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>

Ahora, si inspeccionamos esto en un depurador

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

vemos algo raro: rcx tiene una cadena de depuración que dice AllocatePool, que aparece después de una llamada a función, por lo que concluimos que esto era posiblemente una llamada a AllocatePool. Curiosamente, si también inspeccionas las especificaciones, verás que boot\_services también tiene un puntero a AllocatePool, lo que solo hace más fuerte nuestra suposición.

Genial, así que si conseguimos asignar suficiente espacio (la comprobación de `>= 0` es para verificar si la asignación tuvo éxito, porque si EFI\_OUT\_OF\_RESOURCES se implementa como

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

es seguro asumir

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

se usa para indicar asignación exitosa)

Un dato interesante es que el búfer después de asignarlo no es cero, sino que contiene estos bytes. Si alguien sabe más sobre esto, por favor haga una PR para editar este documento

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

Así que, en fin, terminamos llamando a memcpy; después de la llamada, nuestro búfer se ve así

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

Luego añadimos algunos bytes para que el búfer se vea así

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

Y luego llamamos a una función llamada FileDevicePath\_call, que se ve más o menos así&#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>

Y que se traduce a esto

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

Genial, pero esto no tiene sentido si no se explica, así que....

primero tenemos una implementación personalizada de strlen que no vamos a diseccionar porque es inútil :) Pero aquí está el resultado

<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 caracteres de len(of(str)+"\x00" y luego los últimos 4 bytes añadidos antes de la llamada a la función 0x4FF7F

A continuación llamamos a lo que también usé desde la publicación del blog de investigación asiático, PxepDevicePathInstanceCount, que es simplemente strlen, porque simplemente cuenta cada letra y tiene un contador, como se ve aquí

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

Así que sí, vemos pop rbx y después de la llamada vemos 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>

luego volvemos a llamar a strlen sobre la misma cadena; supongo que esto es solo porque en la siguiente línea, precisamente `v6 + v4 * v5;`, hacemos v4 \* v5, que es como supongo una forma de tener cadenas Unicode, supongo.

De todos modos, luego asignamos memoria de nuevo usando gEfiBootServices + 64, que ya encontramos antes y que resultó ser AllocatePool.

Así que aquí también vemos algo interesante, que es

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

el hecho de que aquí el bloque de memoria tiene el patrón afafafaf en él.

Entonces, lo que sucede a continuación es que obtenemos dos búferes que se ven así después de ejecutar el bucle principal

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

Y, sinceramente, solo nos interesa el primero porque es lo que se devuelve, así que podemos concluir que esto simplemente copia la ruta del dispositivo y limpia algo de basura del búfer. :))

Ahora, después de terminar con esto, comprobamos si la ruta del dispositivo en nuestro caso ya está, supongo, inicializada y liberamos el pool si no es así; devolvemos el búfer más limpio de la función mencionada anteriormente.

Antes de terminar con esta función, me gustaría señalar otro dato interesante: así es como se ve en memoria la tabla de servicios de arranque (boot service table) :) Según las especificaciones, con la cabecera inicial; pensé que podría ser interesante dejarlo aquí para cualquiera que quiera hacer trabajo futuro y se encuentre con la cadena BOOTSERVF en un volcado de memoria: definitivamente es una tabla de servicios de arranque.

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

Bien, ¿y qué sucede después? Bueno, comprobamos si logramos localizar el archivo winload.efi y lo cargamos en memoria. Este es el pseudocódigo :)

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

Y así es como se ve en memoria

<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é es rax? rax es un manejador (handle) de la imagen :) No seas tonto como yo cuando pensé por primera vez que era una zona de memoria :)

Genial, antes de seguir adentrándonos, déjame explicarte rápidamente qué demonios es winload.efi. Así que, `con el desarrollo de las computadoras, el arranque tradicional de BIOS está obsoleto, y ha comenzado la confrontación de seguridad sobre el arranque UEFI. En el diagrama de flujo de abajo, podemos ver que MBR y VBR ya no existen en UEFI, pero el propio UEFI se encarga de cargar bootmgr, lo que también significa más seguro y rápido`

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

Entonces, ¿cómo arranca un PC Windows normal? Después de BDS, el código de firmware UEFI almacenado en SPI ha completado su trabajo; luego, el administrador de arranque del firmware UEFI primero consulta la variable UEFI en NVRAM para encontrar la ESP, y localiza el administrador de arranque específico del sistema operativo, bootmgfw.efi, para llamar a su función de entrada (controlador DXE).

Esta función llamará primero a EfiInitCreateInputParametersEx, que se usa principalmente para convertir el parámetro EfiEntry al formato de parámetro esperado por bootmgfw.efi.

Luego se llama a la función BmMain, el punto de entrada del Administrador de arranque de Windows.

En esta función, se llama a BmFwInitializeBootDirectoryPath para inicializar la ruta de la aplicación de inicio (BootDirectory) (\EFI\Microsoft\Boot).

Luego BootMgr leerá los datos de configuración de arranque del sistema (BCD); si hay múltiples opciones de arranque, llamará a BmDisplayGetBootMenuStatus para mostrar el menú de arranque.

Luego llamará a la función BmpLaunchBootEntry para iniciar la aplicación (winload.efi).

Por supuesto, bootmgfw.efi hace más que eso, además de la verificación de la integridad del código de la política de arranque y la inicialización de los componentes de arranque seguro, así que no entraré en detalles.

En la etapa final del Administrador de arranque de Windows (BootMgr), la función BmpLaunchBootEntry seleccionará la entrada de arranque correcta según el valor BCD anterior. Si el cifrado de volumen completo (BitLocker) está habilitado, la partición del sistema se descifrará primero, y luego el control puede transferirse a winload.efi.

A continuación, se llama a la función BmTransferExecution, se comprueban las opciones de arranque y el flujo de ejecución se pasa a la función BlImgStartBootApplication.

Entonces la función BlImgStartBootApplication llamará a ImgFwStartBootApplication y, finalmente, a ImgArchStartBootApplication. En ella se inicializará el modo de protección de memoria de winload.efi. Luego se llama a BlpArchTransferTo64BitApplication; BlpArchTransferTo64BitApplication llama a la función Archpx64TransferTo64BitApplicationAsm, que finalmente entrega el control a winload.efi.

Esta función habilitará la nueva GDT e IDT, y luego entregará completamente el control a winload.efi. En este punto, BootMgr completa su misión y Winload comienza a funcionar. -Fin de las citas robadas de un sitio web chino que habla sobre esto (por favor, revisa este enlace para más contenido https://bbs.kanxue.com/thread-268267.htm )Y desde ahí winload.efi hace su trabajo, que es cargar Windows y realizar algo más de trabajo de hardware antes de pasar el control al kernel.

Ahora, después de este breve resumen, como decíamos,

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

comprobamos además si su carga en memoria tuvo éxito y luego llamamos a una función llamada ati\_analysis\_rdtsc\_aia\_cu\_4e1f, que debería resultarte familiar si ya has leído la primera parte de este análisis.

Ahora, por diversión, supongamos que fallamos al analizar esa función y somos detectados. Veamos cómo se ve 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>

volvemos a ver gEfiSystemTable + 64, que en realidad esta vez no conocemos porque es de un tipo diferente; esta vez no es del tipo bootservices, sino del tipo efisystemtable. Luego hay un memcpy y otras 3 llamadas a funciones que desconocemos. Ahora, si ejecutamos hasta que comience el bucle,

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

y si inspeccionamos los parámetros anteriores 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>

y si inspeccionamos la imagen de salida de QEMU, obtenemos

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

Bien, así que intentemos darle sentido a esto. Volveré a referirme a la publicación de investigación del asiático, porque honestamente estoy perdido aquí.

Así que en su blog dice que las dos funciones eran en realidad```
ConOut->ClearScreen(ConOut);
ConOut->OutputString(ConOut, String);

Ok, pero ¿qué demonios es conOut? Bueno, también dice que conout es de tipo EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL y que conout se obtiene mediante ConOut = gEfiSystemTable->ConOut; . ok, entonces, ¿qué significa esto en el código ??

Ok, así que vamos a indagar

la definición

1

y el guid

2

Ahora bien, mi yo listillo olvidó capturar esto realmente en un depurador porque cuando analicé esto por primera vez confundí el tipo de datos entre efisystemtable y bootservices y pensé que en realidad era allocatepool.

Ahora, ¿qué hacen esas funciones?

Bueno, ClearScreen debería ser bastante autoexplicativo, y OutputString también. ¿Cómo pudo el investigador llegar a la conclusión de que esa variable es de tipo EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL? Bueno, probablemente vio los bytes del guid en el depurador.

Ahora, ¿y la última función?

Bueno, en su entrada de blog dice que la última función es gEfiBootServices->Stall. Entonces, ¿qué demonios hace esto? De las especificaciones 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.

Así que básicamente congela nuestra CPU. Genial, ¿por cuánto tiempo? 0x1C9C380 segundos. Una cantidad de tiempo de la hostia, si me preguntas. Que, de nuevo, está metido en un bucle infinito, así que sí, estamos jodidos :)))

Y así es como se ve en un depurador

1

Ahora, continuando con nuestra función principal

1

si logramos cargar bootmgfrw.efi (porque aquí winload.efi es el cargador de arranque real de Windows) llamamos a sub_180002538

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

Desde la perspectiva del grafo

1

Desde la perspectiva de asm

2
3
4
5
6

¿Te suena de algo todavía? Nah, bueno, dale un minuto y te encajará. Mientras tanto, echa un vistazo a la vista de pseudocódigo.

1
2

vemos algo de parseo de un exe :) ahora no sé cuánto se parecerá al de la parte anterior (parte 1), pero veamos :)

así que comparamos nuestra versión en memoria del binario (bootmgfrw.efi) con el clásico encabezado mz (0x5A4D), como puedes ver

1
1

ok, luego hacemos otra comprobación clásica: si podemos encontrar el encabezado pe

1

Genial, a continuación llamamos a sub_1800024C4(), que se ve así

1
2

Genial, lo que ocurre aquí es que localizamos ciertos valores en memoria y, si los encontramos, los devolvemos. Consulta sub_180002538.py.py para la emulación.

Como sea, aquí está sub_180002464

1

Si ejecutamos sub_1800024C4 con éxito, volvemos a la función más grande y seguimos con algunas comprobaciones más. Genial, vamos a encontrarle sentido a esto.

1

Genial, así que además comparamos lo que haya en rax+0xe con 0x64. Hmm, genial, interesante. Inspeccionando rax+0xe

1

¿Hay alguna razón especial detrás de esta comprobación? Honestamente, no lo sé. Podría ser. Si lo sabes, por favor haz un pull request y edita este documento.

hacemos algunas sumas más y luego una comparación

1

Quiero detenerme aquí un minuto y referenciar de nuevo la fuente de inspiración anterior de este artículo cada vez que me perdía. Así que en su blog renombró la función que comparaba valores a RtlpImageDirectoryEntryToDataEx, que si buscamos no obtenemos resultados, pero hay algo lo suficientemente parecido a sus nombres, y eso es RtlImageDirectoryEntryToData, que básicamente hace esto: 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). En nuestro caso, dado que estamos en una app efi/uefi, podemos considerar que el 50 que vemos es el tamaño de bytes/mb (no sé) de nuestra partición raíz en este caso, y que esa dirección que está en rax es una entrada en nuestro directorio.

Antes de continuar, hay un detalle más interesante que explicar. En su investigación, convierte la salida de RtlImageDirectoryEntryToData en esta estructura``` 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:~
Ahora, ¿qué coño pasa con esta estructura ?

bien, haciendo una búsqueda rápida sobre esa estructura nos lleva aquí(http://www.brokenthorn.com/Resources/OSDevPE.html), que nos dice que `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` y también que \`\`\`Esta estructura no tiene muchos campos interesantes, excepto los últimos tres.

Si has trabajado con recursos de Win32, quizás sepas que los recursos pueden identificarse por ID o por nombre. Dos de los miembros de esta estructura nos permitirán saber el número de estas entradas y la cantidad total de entradas (NumberOfNamedEntries + NumberOfIdEntries), lo cual es útil para recorrer todas las entradas. Como probablemente adivinarás, las entradas están en el array DirectoryEntries. DirectoryEntries consiste en un array de estructuras IMAGE\_RESOURCE\_DIRECTORY\_ENTRY, que siguen el formato:\`\`\`

así que básicamente esta mierda se usa internamente para parsear cosas internamente y para nosotros tiene sentido en el contexto de que trabajamos con un directorio que contiene recursos, genial.

¡Más, por favor!

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

lo que esto hace es básicamente iterar sobre cada recurso del directorio y comprobar si es de tipo string

ngl no sé por qué lo haría, así que si me equivoco lo siento, y si no, ¡saludos!

siguiente

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

así que lo que ocurre aquí es que sumamos algunos offsets y terminamos en lo que el investigador chino dice que es la segunda tabla de recursos, como puedes ver

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

y luego repetimos el mismo proceso para obtener algunos 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>

y repetimos el mismo proceso, esta vez comprobamos el tipo 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>

así que, ¿qué coño es VS\_VERSION\_INFO? bueno, microsoft(https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource) dice que `Defines a version-information resource`, p.ej. creo que simplemente dice la versión de bootmgfrw.ef

y finalmente si encontramos VS\_VERSION\_INFO repetimos el mismo algoritmo

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

esta vez con un giro, y el giro es que devolvemos el build id :) como podemos ver

Así que, como conclusión, ¿qué coño pasó aquí realmente ? bueno, basándonos en el nombre que usó el investigador chino(GetPeFileVersionInfo\_BuildNumber\_) podemos concluir que en realidad obtenemos el número de build para bootload, como se puede ver en la primera imagen

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

donde aquí vemos el bootload cargado en memoria

en la segunda imagen vemos

<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 entero en rcx que podría ser el número de build o pefileversion

y la tercera imagen

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

lo que podríamos especular que es el número de build, ya que ebx se moverá a rax :)

Así que, como última nota sobre esta función, wow, ingeniería asombrosa

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

Ahora al siguiente reto :) basándonos en la salida de la etapa anterior, establecemos v10 a sub\_180001D80 o sub\_180001D48, como se ve

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

y en nuestro caso 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>

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

Luego hacemos un strcmp entre nuestro gestor de bootloade y ese array de bytes

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

Quiero detenerme aquí por un breve periodo de tiempo, porque como habrás adivinado vi algo interesante en la publicación del blog del investigador chino. Llamó al array de bytes SigImgArchStartBootApplication. Entonces, ¿qué coño es SigImgArchStartBootApplication y a quién pertenece y por qué demonios ese array se llama así(migos)? Así que si buscamos en google(gulugulu) SigImgArchStartBootApplication no obtenemos nada. Ahora, dado que en el contexto actual usamos el gestor de arranque de Windows, abrámoslo en IDA. Vamos a C:\Windows\Boot\EFI, abrimos el binario en ida y buscamos SigImgArchStartBootApplication, nada. Buscamos ImgArchStartBootApplication y nos encontramos con

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

Así que ImgArchStartBootApplication .... ¿qué está haciendo el perro...!? Bueno, amm...hh robaré esto de `@_xeroxz`(ve a seguirlo, ¿qué coño haces si no sigues su trabajo....) así que básicamente en un artículo dice que `bootmgfw.ImgArchStartBootApplication between windows versions 2004-1709 is invoked to start winload.efi` como también podemos ver en su imagen(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 eso no fue lo suficientemente claro en un artículo() vemos que `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)

Genial, ¿y qué coño tiene que ver strcmp con ImgArchStartBootApplication? bueno, echemos un vistazo más de cerca a ida y pronto se nos revelará la respuesta. Si buscamos en el código del bootloader los bytes 41 b8 09, pronto nos topamos con el culpable

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

Y en caso de que hagamos coincidir los bytes de la imagen en memoria de bootloade con la firma de bytes, ejecutamos sub\_180002398

Y ciertamente, como se puede ver, localizamos el patrón; nos devolvió en eax la zona de memoria donde están los bytes y procedemos con seguridad a ejecutar sub\_180002398

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

sub\_180002398

"Perspectiva del ensamblador"

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

"Perspectiva del pseudocódigo"

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

Entonces, ¿qué está haciendo el perro ? honestamente hace algunos cálculos y algunas sumas y restas y nada realmente importante ¿por qué? porque no es tan interesante. Lo que nos interesa es lo que pasa después de que volvamos de la función. Vemos 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 genial, pero aún no lo entiendo. Bien, rax = 0x5eec108 que apunta a 0x48c48b48, ok ¿y qué ? bueno, yo estaba tan confundido como tú, así que volví una vez más al blog chino. Lo que ese investigador describe que ocurre aquí es esto: vuelve al inicio de la función ImgArchStartBootApplication. Pero ¿cómo demonios llegó a esto ? bueno, como mencioné antes, rax =\ 0x48c48b48 y si inspeccionamos el booloadermnfr.efi vemos

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

que es exactamente la misma secuencia de bytes en 0x5eec108. ok, ahora eso es genial :)

Por favor, consulta sub\_180002398.py para ver mi fallido intento de emular este comportamiento :)

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

¿Genial, siguiente ?

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

Así que lo que pasa después es RaiseTPL . ok, ¿y qué hace esto ? Eleva la prioridad de la tarea actualmente en ejecución y devuelve su nivel de prioridad anterior. En nuestro caso se ejecutará con los privilegios de ejecución más altos.

Luego llamamos a lo que llamé patch\_something, que se ve así

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

Así que, desde el análisis estático, podemos ver que esto es lo que se conoce como hooking. :) así que básicamente parchea los bytes de ImgArchStartBootApplication para que apunten a sub\_180001D80 y guarda la función original de ImgArchStartBootApplication en byte\_180015C78

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

y como podemos ver, cambia exactamente a sub\_180001D80

luego restablecemos los privilegios y desde allí entregamos el control a boomgrfw.efi :)

Así que esto marca oficialmente la primera mitad del análisis terminada :) en la siguiente parte aprenderemos cómo depurar más a fondo sub\_180001D80 y boomgrfw.efi (en nuestro caso winload.efi). Así que por favor, permanece atento hasta que aprenda a preparar el entorno para la segunda parte del análisis

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

Ahora para la segunda mitad del análisis.... ¿Cómo depuramos boomgrfw.efi ?
Descargar herramienta