
RDP monstruo en el medio (mitm) y biblioteca para Python con la capacidad de observar conexiones en vivo o después del hecho
PyRDP es una herramienta y librería de protocolo de escritorio remoto (RDP) Monster-in-the-Middle (MITM) en Python.
Cuenta con varias herramientas:
PyRDP fue presentado en 2018 en el cual demostramos que podemos atrapar a un actor de amenazas real en acción. Esta herramienta se desarrolla pensando en casos de uso de pentesting e investigación de malware.

PyRDP debería funcionar en Python 3.7 y superiores en las plataformas x86-64, ARM y ARM64.
Esta herramienta ha sido probada para funcionar en Python 3.7 en Linux (Ubuntu 20.04, 22.04), Raspberry Pi y Windows. No ha sido probada en macOS.
Se recomiendan dos técnicas de instalación: mediante pipx o usando contenedores Docker.
La instalación desde el código fuente o la construcción de contenedores Docker se cubre en la documentación de desarrollo.
Primero, asegúrate de instalar los paquetes prerrequisito (estos están listados para Ubuntu 22.04, es posible que necesites ajustar para otras distribuciones). Proporcionamos dos tipos de instalación: una completa y una ligera. Instala las dependencias según tu caso de uso.```sh
sudo apt install python3 python3-pip python3-venv
build-essential python3-dev openssl
libegl1 libxcb-cursor0 libxkbcommon-x11-0 libxcb-icccm4 libxcb-keysyms1
libnotify-bin
libavcodec58 libavdevice58
sudo apt install python3 python3-pip python3-venv
build-essential python3-dev git openssl
Esto debería instalar las dependencias necesarias para ejecutar PyRDP. Si eliges instalar sin las dependencias de GUI o conversión de video, no será posible usar `pyrdp-player` sin el modo sin cabeza (`--headless`) o `pyrdp-convert` para producir salida de video. Asegúrate de tener `pipx` instalado. En Ubuntu 22.04:```sh
python3 -m pip install --user pipx
python3 -m pipx ensurepath
Asegúrate de tener Python instalado. Python de Windows Store no funcionó para mí en Windows 11. Recomendamos instalar Python mediante Scoop.```sh scoop install python # if not installed already scoop install pipx pipx ensurepath
Cierra sesión y vuelve a iniciarla (para actualizar tu PATH).
##### Otros SO
Para instalar `pipx` en otros sistemas operativos, consulta aquí: <https://github.com/pypa/pipx#install-pipx>
#### Instalación
Para disfrutar de la experiencia completa de PyRDP con la interfaz gráfica QT y la capacidad de convertir capturas a video:```sh
pipx install pyrdp-mitm[full]
Para la versión compacta diseñada para ejecutarse en entornos headless (servidores, RaspberryPi):```sh pipx install pyrdp-mitm
¡Estás listo! Consulta las [instrucciones de uso](#using-pyrdp).
### Usando la imagen Docker
Este es el método de instalación más sencillo si tienes docker instalado y funcionando.```sh
docker pull gosecure/pyrdp:latest
Como alternativa tenemos una imagen más ligera sin la interfaz gráfica ni las dependencias de ffmpeg. Esta es la única imagen proporcionada en plataformas ARM.```sh docker pull gosecure/pyrdp:latest-slim
Puedes encontrar la lista de todas nuestras imágenes Docker [en la página de DockerHub gosecure/pyrdp](https://hub.docker.com/r/gosecure/pyrdp/tags).
La etiqueta `latest` se refiere a la última versión lanzada, mientras que la etiqueta `devel` es la imagen Docker construida a partir de nuestra rama `main`.
## Usando PyRDP
### Usando el Monster-in-the-Middle de PyRDP
Usa `pyrdp-mitm <ServerIP>` o `pyrdp-mitm <ServerIP>:<ServerPort>` para ejecutar el MITM.
Suponiendo que tienes un servidor RDP ejecutándose en `192.168.1.10` y escuchando en el puerto 3389, ejecutarías:```sh
pyrdp-mitm 192.168.1.10
Al ejecutar el MITM por primera vez, se creará un directorio llamado pyrdp_output/ relativo al directorio de trabajo actual. Aquí hay un ejemplo de la estructura de ese directorio:```sh
pyrdp_output/
├── certs
│ ├── WinDev2108Eval.crt
│ └── WinDev2108Eval.pem
├── files
│ ├── e91c6a5eb3ca15df5a5cb4cf4ebb6f33b2d379a3a12d7d6de8c412d4323feb4c
│ ├── b14b26b7d02c85e74ab4f0d847553b2fdfaf8bc616f7c3efcc4771aeddd55700
├── filesystems
│ ├── romantic_kalam_8214773
│ │ └── device1
│ │ └── clipboard
| └── priv-esc.exe -> ../../../files/b14b26b7d02c85e74ab4f0d847553b2fdfaf8bc616f7c3efcc4771aeddd55700
│ └── happy_stonebraker_1992243
│ ├── device1
│ └── device2
| └── Users/User/3D Objects/desktop.ini -> ../../../../../../e91c6a5eb3ca15df5a5cb4cf4ebb6f33b2d379a3a12d7d6de8c412d4323feb4c
├── logs
│ ├── crawl.json
│ ├── crawl.log
│ ├── mitm.json
│ ├── mitm.log
│ ├── mitm.log.2021-08-26
│ ├── ntlmssp.log
│ ├── player.log
│ └── ssl.log
└── replays
├── rdp_replay_20231214_01-20-28_965_happy_stonebraker_1992243.pyrdp
└── rdp_replay_20231214_00-42-24_295_romantic_kalam_8214773.pyrdp
* `certs/` contiene los certificados generados almacenados usando el `CN` del certificado como nombre de archivo
* `files/` contiene todos los archivos capturados y se deduplican guardándolos usando el hash SHA-256 del contenido como nombre de archivo
* `filesystems/` contiene una recreación del sistema de archivos de los objetivos clasificados por IDs de sesión.
Para ahorrar espacio en sesiones similares, los archivos son enlaces simbólicos a los archivos reales en `files/`.
* `logs/` contiene todos los diversos registros, la mayoría en formatos JSON y texto plano:
* `crawl`: el registro del rastreador de archivos
* `mitm`: el registro principal del MITM
* `ntlmssp.log`: los hashes NetNTLM capturados
* `player.log`: el registro del reproductor
* `ssl.log`: los secretos maestros TLS almacenados en un formato compatible con Wireshark
* `replays/` contiene todas las sesiones de PyRDP grabadas previamente con marcas de tiempo y IDs de sesión en el nombre de archivo
#### Especificación de la clave privada y el certificado
Si la generación de claves no funcionó o desea utilizar una clave y un certificado personalizados, puede especificarlos usando los
argumentos `-c` y `-k`:```sh
pyrdp-mitm 192.168.1.10 -k private_key.pem -c certificate.pem
La autenticación a nivel de red (NLA) es una característica de seguridad disponible desde Windows Vista que agrega seguridad a las conexiones RDP. NLA se basa en el nuevo proveedor de soporte de seguridad CredSSP y a veces se refiere por ese nombre. Un servidor que aplica NLA es más difícil de atacar. Hay tres estrategias diferentes que se pueden usar:
Si tenemos acceso al certificado y la clave privada del servidor, podemos hacer MITM en RDP con éxito incluso si NLA está aplicada. Documentamos este ataque en nuestra publicación de blog de la versión 1.0. Las instrucciones para extraer el certificado y la clave privada de RDP están disponibles en nuestro GitHub.
Con el certificado y la clave privada accesibles, solo necesita configurar la autenticación en ssp agregando esto en la línea de comandos de pyrdp-mitm:```sh
--auth ssp -c <certificate.pem> -k <private-key.pem>
Esto permitirá la posibilidad de interceptar conexiones que requieren NLA.
###### Redirección alternativa de host cuando el servidor requiere NLA

Cuando PyRDP se conecta al servidor RDP de destino (1), si ese servidor requiere NLA, entonces PyRDP (2) reemplazará la conexión para ir a otro host de su elección (3) en su lugar.
Por ejemplo, esto se puede usar para redirigir a un servidor que se sabe que no requiere NLA, o incluso podría redirigir a una máquina virtual controlada por un atacante.
Para habilitar esta función, especifique la dirección y el puerto del host alternativo de la siguiente manera:```sh
--nla-redirection-host 192.168.1.12 --nla-redirection-port 3389
Esta característica se introdujo en PyRDP 1.1.0.
Los hashes NetNTLMv2 son útiles para un atacante ya que pueden ser descifrados relativamente fácilmente, permitiendo a los atacantes aprovechar el acceso legítimo a RDP o intentar relleno de credenciales.
A partir de la versión 1.1.0, PyRDP tiene la capacidad de capturar los hashes NetNTLMv2 del cliente a través de una conexión NLA (CredSSP) llevando a cabo la negociación y capturando los mensajes de autenticación NTLMSSP.
En la versión 1.2.0, ese soporte se extendió para funcionar incluso si no tenemos el certificado y la clave privada del servidor, lo que significa que la conexión no será MITM'ada con éxito.
Esto es similar a lo que Responder hace con RDP.
El hash NetNTLMv2 capturado se puede encontrar en el archivo de registro ntlmssp.log y está formateado para que herramientas de cracking como John The Ripper o hashcat puedan ingerirlo.
Esta técnica ha sido descrita en detalle en una publicación de blog: Capturando hashes NetNTLMv2 de RDP: Detalles del ataque y una guía técnica de cómo hacerlo
Esta característica es compatible con --auth ssp pero incompatible con --nla-redirection-host.
Si desea ver conexiones RDP en vivo a través del reproductor de PyRDP, deberá especificar la dirección IP y el puerto en el que el reproductor está escuchando usando los argumentos -i y -d. Nota: el argumento del puerto es opcional, el puerto predeterminado es 3000.```sh
pyrdp-mitm 192.168.1.10 -i 127.0.0.1 -d 3000
##### Conectarse a un reproductor de PyRDP cuando el MITM se ejecuta en un servidor
Si está ejecutando el MITM en un servidor y aún desea ver conexiones RDP en vivo, debe usar
[SSH remote port forwarding](https://www.booleanworld.com/guide-ssh-port-forwarding-tunnelling/)
para reenviar un puerto de su servidor al puerto del reproductor en su máquina. Una vez hecho esto, pase `127.0.0.1` y el puerto
reenviado como argumentos al MITM. Por ejemplo, si el puerto 4000 en el servidor se reenvía al puerto del reproductor en su máquina,
este sería el comando a utilizar:```sh
pyrdp-mitm 192.168.1.10 -i 127.0.0.1 -d 4000
PyRDP admite la ejecución automática de comandos de consola o payloads de PowerShell cuando se establecen nuevas conexiones. Debido a la naturaleza de RDP, el proceso es un poco rudimentario y no siempre es 100% confiable. Así es como funciona:
cmd.exe.powershell -enc <PAYLOAD>.Para que esto funcione, debe establecer 3 argumentos:
Puede usar uno de los siguientes argumentos para establecer el payload a ejecutar:
--payload, una cadena que contiene comandos de consola--payload-powershell, una cadena que contiene comandos de PowerShell--payload-powershell-file, una ruta a un script de PowerShellPor el momento, PyRDP no detecta cuándo el usuario ha iniciado sesión.
Debe indicarle un tiempo de espera antes de ejecutar el payload.
Una vez transcurrido este tiempo, enviará las secuencias falsas de teclas y esperará que el payload se ejecute correctamente.
Para ello, se utiliza el argumento --payload-delay. El retardo está en milisegundos.
Por ejemplo, si espera que el usuario inicie sesión dentro de los primeros 5 segundos, usaría los siguientes argumentos:```sh
--payload-delay 5000
Esto podría hacerse más preciso aprovechando algunos mensajes intercambiados durante la inicialización de RDPDR.
Consulte [este issue](https://github.com/GoSecure/pyrdp/issues/98) si está interesado en mejorar esto.
##### Elegir cuándo reanudar la actividad normal
Debido a que no hay una forma directa de saber cuándo la consola ha dejado de ejecutarse, debe indicarle a PyRDP cuánto tiempo desea
que se bloquee la entrada / salida del cliente. Recomendamos establecer esto como el tiempo máximo que esperaría que la
consola que está ejecutando su payload sea visible. En otras palabras, el tiempo que esperaría que su payload se
complete.
Para establecer la duración del payload, use el argumento `--payload-duration` con una cantidad de tiempo en milisegundos.
Por ejemplo, si espera que su payload tarde hasta 5 segundos en completarse, usaría el siguiente argumento:```sh
--payload-duration 5000
Esto bloqueará la entrada / salida del cliente durante 5 segundos para ocultar la consola y evitar interferencias. Después de 5 segundos, la entrada / salida se restablece a la normalidad.
Ejecute pyrdp-mitm --help para obtener una lista completa de argumentos.
--no-downgradeEste argumento es útil cuando se ejecuta PyRDP en escenarios de Honeypot para evitar la toma de huellas digitales por parte de escáneres. Cuando el interruptor está activado, PyRDP no degradará las extensiones no compatibles y dejará pasar el tráfico de forma transparente. Es probable que el reproductor no pueda reproducir correctamente el tráfico de video, pero los siguientes canales compatibles aún deberían ser accesibles:
Esta función aún está en desarrollo y actualmente es inevitable cierta degradación para permitir que se establezca la conexión. Los siguientes aspectos no se ven afectados por este interruptor y seguirán desactivados:
NOTA: Si es importante poder reproducir eventualmente la sesión completa, una buena solución es grabar el tráfico RDP sin procesar usando Wireshark y conservar los secretos maestros TLS. Cuando PyRDP agregue soporte para extensiones adicionales, entonces será posible extraer un archivo de reproducción RDP válido de la captura de red sin procesar.
--transparentIndica a PyRDP que intente suplantar la dirección IP de origen del cliente para que el servidor vea la dirección IP real en lugar de la del MITM. Esta opción solo es útil en ciertos escenarios donde el MITM es físicamente una puerta de enlace entre los clientes y el servidor y ve todo el tráfico. Se pueden encontrar ejemplos específicos aquí.
NOTA: Esto requiere privilegios de root, solo funciona en Linux y requiere configuración manual del firewall para garantizar que el tráfico se enrute correctamente.
--no-gdi: Deshabilitar la canalización de gráficos aceleradosPyRDP degrada el video a la canalización de gráficos más reciente que admite. Este interruptor le indica explícitamente al MITM que no use las extensiones de Aceleración de la Interfaz de Dispositivos Gráficos para transmitir video. La ventaja de este modo es una reducción significativa en el ancho de banda requerido para conexiones de alta resolución.
Tenga en cuenta que algunas órdenes de dibujo GDI actualmente no están implementadas porque parecen no usarse. Si tiene una reproducción que contenga alguna orden no compatible o no probada, no dude en compartirla con los mantenedores del proyecto para que se pueda agregar soporte según sea necesario. (Asegúrese de que el rastro no contenga información sensible)
Use pyrdp-player para ejecutar el reproductor.
Puede usar el menú para abrir un nuevo archivo de reproducción: Archivo > Abrir.
También puede abrir archivos de reproducción al iniciar el reproductor:```sh pyrdp-player ...
#### Escuchando conexiones en vivo
El reproductor siempre escucha conexiones en vivo. Por defecto, el puerto de escucha es 3000, pero se puede cambiar:```sh
pyrdp-player -p <PORT>
Por defecto, el reproductor solo escucha conexiones provenientes de la máquina local. No recomendamos abrir el reproductor a otras máquinas. Si aún así deseas cambiar la dirección de escucha, puedes hacerlo con -b:```sh
pyrdp-player -b
#### Otros argumentos del player
Ejecute `pyrdp-player --help` para obtener una lista completa de argumentos.
### Usando el Clonador de Certificados PyRDP
NOTA: El uso de esta herramienta es opcional.
Desde la versión 1.0, PyRDP genera certificados sobre la marcha exactamente como lo haría esta herramienta.
El clonador de certificados PyRDP crea un nuevo certificado X509 utilizando los valores del certificado de un servidor RDP existente.
Se conecta a un servidor RDP, descarga su certificado, genera una nueva clave privada y reemplaza la
clave pública y la firma del certificado usando la nueva clave privada. Esto se puede usar en una prueba de penetración si, por ejemplo,
está intentando engañar a un usuario legítimo para que pase a través de su MITM. Usar un certificado que se parece a un certificado
legítimo podría aumentar su tasa de éxito.
#### Clonando un certificado
Puede clonar un certificado usando `pyrdp-clonecert`:```sh
pyrdp-clonecert 192.168.1.10 cert.pem -o key.pem
El parámetro -o define la ruta a usar para la clave privada generada.
Si desea usar su propia clave privada en lugar de generar una nueva:```sh pyrdp-clonecert 192.168.1.10 cert.pem -i input_key.pem
#### Otros argumentos del clonador
Ejecute `pyrdp-clonecert --help` para obtener una lista completa de argumentos.
### Usando PyRDP Convert
`pyrdp-convert` es un script auxiliar que realiza varias conversiones útiles desde varios formatos de entrada a varios formatos de salida.
El script tiene la mayor probabilidad de funcionar en tráfico capturado por PyRDP debido a características del protocolo RDP no compatibles que podrían usarse en una conexión no interceptada.
Se admiten las siguientes entradas:
- Captura de red (PCAP) con secretos maestros TLS (menos fiable)
- Captura de red (PCAP) en formato de PDUs exportadas de capa 7 (más fiable)
- Archivo de reproducción generado por PyRDP
Se admiten las siguientes salidas:
- Archivo de video MP4
- JSON: una secuencia de eventos de bajo nivel serializados en formato JSON
- Archivo de reproducción compatible con `pyrdp-player`
Las capturas de red cifradas (TLS) requieren que los secretos maestros TLS se proporcionen usando `--secrets ssl.log`.```sh
# Export the session coming client 10.2.0.198 to a .pyrdp file.
pyrdp-convert --src 10.2.0.198 --secrets ssl.log -o path/to/output capture.pcap
# Or as an MP4 video
pyrdp-convert --src 10.2.0.198 --secrets ssl.log -o path/to/output -f mp4 capture.pcap
# List the sessions in a network trace, along with the decryptable ones.
pyrdp-convert --list-only capture.pcap
Tenga en cuenta que la conversión a MP4 requiere libavcodec y ffmpeg, por lo que puede requerir pasos adicionales en Windows.
Las trazas de red descifradas manualmente se pueden exportar desde Wireshark seleccionando File > Export PDUs y seleccionando OSI Layer 7.
Primero, asegúrese de haber configurado wireshark para cargar secretos TLS:

A continuación, exporte los PDU de la Capa 7 del modelo OSI:

Y opcionalmente, filtre la traza para que contenga solo la(s) conversación(es) de interés aplicando un filtro de visualización y haciendo clic en File > Export Specified Packets...

Ahora esta traza se puede usar directamente en pyrdp-convert.
La mayor parte de la configuración de PyRDP se realiza a través de opciones de línea de comandos, pero también es posible usar un archivo de configuración para ciertos ajustes, como la configuración de registros.
Los archivos de configuración predeterminados utilizados por PyRDP se encuentran en mitm.default.ini y player.default.ini. Ambos archivos están completamente documentados y pueden servir como base para una configuración adicional.
En el futuro, hay planes para admitir otros aspectos de la configuración de PyRDP a través de esos archivos de configuración.
Si está interesado en experimentar con RDP y crear sus propias herramientas, diríjase a nuestra sección de documentación para obtener más información.
El componente MITM de PyRDP también se implementó como un complemento de twistd. Esto le permite ejecutarlo en modo de depuración y le permite obtener un repl interactivo de depuración (pdb) si envía una señal SIGUSR2 al proceso de twistd. Consulte la documentación de twistd para obtener más información.
Desarrollamos nuestro propio módulo de Bettercap, rdp.proxy, para hacer 'hombre en el medio' en todas las conexiones RDP en una LAN determinada. Consulte este documento para obtener más información.
Dado que Docker restringe las interacciones con el sistema anfitrión (sistema de archivos y red), la imagen de Docker de PyRDP debe ejecutarse con algunos parámetros dependiendo de su caso de uso. Esta sección documenta esos parámetros.
Nos referimos a la imagen de Docker proporcionada públicamente, pero si compiló la suya propia, reemplace gosecure/pyrdp con el nombre de su imagen compilada localmente.
En la mayoría de los casos de 'hombre en el medio', necesitará mapear un puerto de su anfitrión en la imagen de Docker. Esto se logra mediante los parámetros --publish (-p) aplicados a docker run.
Por ejemplo, para escuchar en el puerto 3389 (puerto predeterminado de RDP) en todas las interfaces, use:
docker run -p 3389:3389 --rm -it gosecure/pyrdp pyrdp-mitm.py
``````sh
docker run -p 3389:3389 gosecure/pyrdp pyrdp-mitm 192.168.1.10
Para almacenar la salida de PyRDP de forma permanente (registros, archivos, etc.), agregue la opción --volume (-v) al comando anterior. En este ejemplo, almacenamos los archivos de forma relativa al directorio actual en pyrdp_output:```sh
docker run -v $PWD/pyrdp_output:/home/pyrdp/pyrdp_output -p 3389:3389 gosecure/pyrdp pyrdp-mitm 192.168.1.10
Asegúrate de que tu directorio de destino sea propiedad de un usuario con un UID de 1000, de lo contrario obtendrás errores de permiso denegado.
Si eres el único usuario no root en el sistema, normalmente a tu usuario se le asignará el UID 1000.
#### Registro de la dirección IP del host
Si quieres que PyRDP registre la dirección IP del host en sus registros, puedes establecer la variable de entorno `HOST_IP` al usar `docker run`:```sh
docker run -p 3389:3389 -e HOST_IP=192.168.1.9 gosecure/pyrdp pyrdp-mitm 192.168.1.10
Usar el reproductor requerirá que exportes la variable de entorno DISPLAY del host al docker.
Esto redirige la GUI del reproductor a la pantalla del host.
También necesitas exponer la red del host y evitar que Qt use la Extensión de Memoria Compartida MIT-SHM X11.
Para ello, agrega las opciones -e y --net al comando run:```sh
docker run -e DISPLAY=$DISPLAY -e QT_X11_NO_MITSHM=1 --net=host gosecure/pyrdp pyrdp-player
Tenga en cuenta que exponer la red del host a Docker puede comprometer el aislamiento entre su contenedor y el host.
Si planea usar el reproductor, el reenvío X11 mediante una conexión SSH sería una forma más segura.
#### Conversión de videos en Docker
El proceso de conversión de video depende de PyAV, ffmpeg y QT, por lo que necesita la imagen de Docker normal, no la slim.
Necesita un montaje de volumen (`-v`) para compartir archivos con el contenedor.
Aquí asignamos nuestro directorio local con `/shared/` en el contenedor.```sh
docker run -e QT_QPA_PLATFORM=offscreen -v $PWD/:/shared gosecure/pyrdp pyrdp-convert -f mp4 <filename-relative-to-volume-in-/shared/> -o /shared/
La variable de entorno QT_QPA_PLATFORM=offscreen es requerida debido a un error documentado aquí.
Le indica a QT que es correcto que no haya un entorno de pantalla disponible.
Consulte nuestras pautas de contribución.
PyRDP utiliza código de los siguientes programas de código abierto: