
Cifrado de extremo a extremo para sesiones tty de múltiples saltos o portshells + reenvío de puertos TCP/UDP
Este proyecto - así como su proyecto hermano crash - pertenece a mi conjunto de herramientas contra la censura que permite configurar shells encriptados y reenvío TCP/UDP completamente funcionales en entornos hostiles de censura. También es útil para forense para volcar datos de dispositivos a través de UART o adb cuando no hay otros medios disponibles.
Búsqueda de DNS y sesión SSH reenviadas a través de una conexión UART a una Pi
PSC permite encriptar de extremo a extremo sesiones de shell, de un solo salto o múltiples, siendo agnóstico del transporte subyacente, siempre que sea confiable y pueda enviar/recibir datos codificados en Base64 sin modificaciones/filtros. Junto con la pty e2e que recibes (por ejemplo dentro de un port-shell), puedes reenviar conexiones TCP y UDP, similar al parámetro -L de OpenSSH. Esto funciona de manera transparente y sin necesidad de una dirección IP asignada localmente en el punto de inicio. Esto permite a los forenses y testers de penetración crear conexiones de red, por ejemplo a través de:
adb shell, si el adbd del OEM no soporta reenvío TCPImagina que tuvieras una sesión ppp invisible dentro de tu sesión de shell, sin que el peer remoto soporte realmente ppp.
Se ejecuta en Linux, Android, OSX, Windows, FreeBSD, NetBSD y (posiblemente) OpenBSD.
PSC también incluye soporte de proxy SOCKS4 y SOCKS5 para tener sesiones de navegación web reales a través de port-shells o conexiones de módem de forma remota.
Edita el Makefile para reflejar tus claves precompartidas, según se define al inicio del Makefile.
Luego simplemente escribe make en Linux y OSX.
En BSD necesitas instalar GNU make e invocar gmake en su lugar.
En Windows necesitas instalar cygwin y seleccionar los paquetes apropiados gcc, gcc-g++, make y git.
En Linux, PSC usará pseudo terminales Unix98, en otros sistemas usará pty POSIX pero eso debería ser transparente para ti. Una vez añadí soporte para pty 4.4BSD y SunOS en la edad de piedra por una razón particular, por lo que puede o no compilar incluso con Solaris.
orgullosamente patrocinado por:
Simple y directo. En tu máquina local, ejecuta pscl, y pasa cualquier puerto TCP o UDP que quieras reenviar desde el sitio remoto a una dirección particular. Por ejemplo:
linux:~ > ./pscl -T 1234:[192.168.0.254]:22 -U 1234:[8.8.8.8]:53
PortShellCrypter [pscl] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: set up local TCP port 1234 to proxy to 192.168.0.254:22 @ remote.
pscl: set up local UDP port 1234 to proxy to 8.8.8.8:53 @ remote.
pscl: Waiting for [pscr] session to appear ...
linux:~ >
[ UART / SSH / ... login to remote side ... ]
En el sitio remoto (el último salto) con la sesión de shell, sin importar si está en un port-shell, SSH, inicio de sesión de consola, etc., ejecutas pscr:
linux:~ > ./pscr
PortShellCrypter [pscr] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: Seen STARTTLS sequence, enabling crypto.
linux:~ >
Una vez que ejecutas pscr, ambos extremos establecen un handshake criptográfico y colocan un protocolo adicional sobre tu sesión existente que es transparente para ti. Luego puedes conectarte a 127.0.0.1:1234 en tu máquina local para alcanzar 192.168.0.254:22 vía TCP o el resolver 8.8.8.8 vía UDP. Esto también funciona con direcciones [IPv6], si el sitio remoto tiene conectividad IPv6. De hecho, incluso puedes usarlo para traducir software IPv4 a IPv6, ya que siempre te conectas a 127.0.0.1 en el lado local.
Puedes pasar múltiples parámetros -T y -U. Si pierdes el rastro de si tu sesión ya está encriptada e2e, puedes enviar una SIGUSR1 al proceso pscl local, y te lo dirá.
PSC también es útil si quieres usar tor desde un shell SSH remoto, donde puedes reenviar el socks5 y el puerto DNS a la dirección 127.0.0.1 del host remoto. Dado que SSH no reenvía paquetes UDP, normalmente usarías dos conectores socat o similares para resolver a través del nodo tor. PSC tiene la ventaja de mantener los límites de los datagramas UDP, mientras que socat sobre SSH -L puede romper los límites de datagramas y crear solicitudes DNS malformadas.
La sesión se encriptará con aes_256_ctr de una PSK que elijas en el Makefile. Este esquema criptográfico es maleable, pero agregar datos AAD o OAD aumenta el tamaño del paquete, donde cada byte cuenta ya que en sesiones interactivas y debido a la codificación Base64, cada carácter escrito ya provoca que se envíen muchos más datos.
Las sesiones UART pueden usarse a través de screen pero, por ejemplo, no a través de minicom ya que minicom creará ventanas invisibles con líneas de estado y actúa como un filtro que destruye el protocolo de PSC. PSC intenta detectar el filtrado y puede soportar cierta cantidad de alteración de datos, pero en algunas situaciones no es posible recuperarse. Algo similar ocurre con tmux. Debes evitar apilar manejadores de pty con PSC que alteren/manipulen demasiado sus datos entrantes.
La variable de entorno SHELL debe estar configurada tanto para pscl como para pscr para que PSC sepa qué shell ejecutar en la pty. SHELL está configurada en la mayoría de entornos por defecto, pero en caso de que no lo esté, PSC debe ejecutarse como SHELL=/bin/bash pscl etc.
pscl también soporta el reenvío de conexiones TCP a través de SOCKS4 (-4 puerto) y SOCKS5 (-5 puerto). Esto configura puerto como puerto SOCKS para conexiones TCP, por lo que, por ejemplo, puedes navegar por redes remotas desde una sesión de port-shell sin necesidad de abrir ninguna otra conexión durante una prueba de penetración. Si pasas -N a pscl, habilita la resolución de nombres DNS en el lado remoto, por lo que también puedes usar chrome con él. Pero cuidado: Hay un problema de privacidad con los navegadores que intentan resolver una secuencia de nombres DNS al inicio que no está bajo tu control. Además, si tu lado remoto tiene una configuración DNS defectuosa, tu shell de escritura puede bloquearse durante varios segundos si faltan paquetes de respuesta DNS. No hay buenas funciones de resolución asíncrona que sean incrustables y portátiles, así que tuve que confiar en getaddrinfo() en un solo hilo al precio de posibles bloqueos de varios segundos si existen problemas de DNS. Por eso la resolución de nombres debe habilitarse explícitamente. pscr intenta minimizar este posible problema con cachés de búsqueda DNS, por lo que en la mayoría de las situaciones debería funcionar sin problemas. Si pasas -X dirección-IP (debe ser el primer argumento), puedes vincular tu proxy local a una dirección diferente de 127.0.0.1, para compartir el proxy en tu red local.
Las características de psc permiten que conexiones TCP o blobs de datos binarios se reenvíen desde/hacia dispositivos remotos a través de múltiples saltos incluso si no es posible instalar el binario pscr en el sitio remoto. Esto es muy útil para fines forenses si no tienes ningún medio para descargar artefactos del dispositivo (que puede ser un teléfono conectado por UART, por ejemplo) o necesitas reenviar conexiones sin tocar el sistema de archivos para no destruir evidencia en el sistema o cuando el sistema de archivos raíz está montado como solo lectura y no puedes subir tu conjunto de herramientas.
Esta es una característica realmente genial, ya que puedes ver cómo tu conexión TCP salta a través de tu tty local a una máquina remota sin necesidad de instalar nada de forma remota.
Esto funciona únicamente mediante punkrock de pty local y entregando un comando de rebote a pscl que se soltará en el shell remoto (sin que pscr esté en ejecución) y algo de magia de máquina de estados que filtra y maneja los datos en el lado local. Normalmente esto requiere poner la pty remota en modo raw primero antes de emitir el comando real y algunos otros detalles que se pasan a -B. El argumento se divide en las siguientes partes:
:, por ejemplo 1234:.stty -echo raw o python -c "import tty;tty.setraw(0)" (ten cuidado con las comillas, ya que -B también necesita ser entrecomillado) o cualquier cosa similar.pscl que comience a enviar datos para evitar una condición de carrera entre que stty realmente ocurra y el inicio del comando, por ejemplo, un echo GO es perfecto.nc 127.0.0.1 22 para rebotar el puerto local 1234 al servidor SSH remotopscl restablecer su estado tty. echo FIN hará esto. Recomendado, ya que de lo contrario puedes tener problemas para reconocer el final de tu comando.Ejemplos:
Si quieres reenviar una conexión TCP, este ejemplo requiere stty y nc instalados en el dispositivo, pero teóricamente podría ser cualquier otra cosa que haga lo equivalente.
Inicia una sesión local:
./pscl -B '1234:[stty -echo raw;echo GO;nc example.com 22;echo FIN]'
Esto emitirá el comando stty -echo raw;echo GO;nc example.com 22;echo FIN al dispositivo remoto si te conectas localmente al puerto 1234 y luego simplemente reenvía cualquier dato que vea de ida y vuelta y limita la velocidad del tráfico para que no exceda la velocidad tty del dispositivo (115200 es la predeterminada).
Cuando se inicia la sesión de pscl, conéctate al dispositivo remoto mediante UART, ssh -e none ... o lo que sea y una vez que tengas el shell remoto, también escribe localmente:
ssh [email protected] -p 1234 para rebotar la conexión SSH desde tu máquina local a través del dispositivo remoto hacia el destino example.com. Por supuesto, la variante pscr es preferida ya que -B solo puede rebotar una conexión a la vez (aunque puedes pasar múltiples comandos -B para varios reenvíos) y existe la posibilidad de que el shell se cuelgue después de la sesión TCP, ya que la pty está en modo raw -echo y dependiendo de si el peer remoto final también cierra la conexión, podría ser que el shell simplemente se cuelgue después de eso. Si te encuentras con una notificación de pscl de que la conexión ha finalizado y ves un prompt, debes resetearlo, para que se pueda iniciar una nueva conexión. Mientras se reenvían datos, verás notificaciones ASCII de 7 bits < y > en pscl que son solo locales para facilitar la depuración y la detección del progreso.
Ten en cuenta que la conexión al sitio remoto debe ser de 8 bits limpios, es decir, el canal ssh, telnet, UART o cualquier otro no debe manejar secuencias de escape (a diferencia de cuando se usa pscr). Para conexiones ssh, esto significa que debes usar ssh -e none en la sesión pscl.
A continuación, algunos ejemplos para manejar la transferencia de archivos binarios donde rfile denota el archivo remoto y lfile el archivo local.
Para iniciar una sesión para colocar archivos remotos, localmente:
./pscl -B '1234:[stty -echo raw;echo GO;dd of=rfile.bin bs=1 count=7350;echo FIN]'
Donde necesitas especificar la cantidad de datos que el lado remoto espera. También funcionaría sin ello (por ejemplo, cat>...) pero entonces la sesión se colgará después de que la transmisión haya finalizado, ya que cat está esperando entrada sin fin. Al usar dd count=..., obtendrás una salida limpia y serás notificado de ello mediante el marcador FIN.
Luego, ssh o lo que sea necesario para obtener un shell en el dispositivo remoto desde dentro de la sesión pscl que acaba de iniciarse. En un segundo terminal localmente:
dd if=lfile.bin|nc 127.0.0.1 1234
lo cual se conectará al puerto local 1234 de pscl y activará el comando de volcado en el lado remoto, reenviando los datos binarios del lfile.bin local al rfile.bin remoto. Debido a la limitación de velocidad, esto puede llevar un tiempo y solo confías en tu pantalla de progreso de psc para saber si la transferencia ha terminado. El comando local dd ...|nc ... solo te mostrará el estado local, que puede consumir archivos enteros en milisegundos debido a los búferes TCP locales mientras el archivo aún se está transfiriendo a través de la pty. Así que asegúrate de presionar Ctrl-C solo cuando la pantalla de pscl te indique que ha terminado o cuando veas el marcador de fin FIN siendo repetido de vuelta en la sesión dd ...|nc ....
Del mismo modo, se podrían usar comandos similares para transferir datos binarios desde un dispositivo remoto a la máquina local con fines forenses. Nuevamente, inicio de la sesión localmente:
./pscl -B '1234:[stty -echo raw;echo GO;dd if=rfile.bin]' o
./pscl -B '1234:[stty -echo raw;echo GO;cat rfile.bin]'
Luego, ssh al dispositivo remoto para obtener el shell, luego nuevamente localmente:
nc 127.0.0.1 1234|dd of=lfile.bin bs=1 count=7350
Para obtener rfile.bin de tamaño 7350 copiado al archivo local lfile.bin
Si stty -echo raw no está disponible en el dispositivo, algo como python -c "import tty;tty.setraw(0)" también funciona. Ten en cuenta que en el dispositivo remoto necesitas tener una tty (no solo un port-shell) al usar comandos de rebote, ya que el comando stty para establecer modo raw requiere una tty real.
Si psc se ejecuta a través de una conexión serie, los bits perdidos pueden arruinar toda la diversión. Si ejecutas sin control de flujo por hardware (HW FC), eventualmente experimentarás pérdida de bits y conexiones colgadas, en particular porque no hay limitación cuando el dispositivo envía datos en tu dirección al usar comandos de rebote. Volcar datos al dispositivo funciona mejor ya que estos datos pasan a través de los límites de velocidad de pscl.
Sin embargo, aquí hay algunos consejos que me funcionaron en circunstancias en las que no es posible usar pscr en el dispositivo y control de flujo por hardware. Esto solo aplica cuando se usan UART, ya que este es un canal de transporte potencialmente no confiable.
pscr en el dispositivo para poder establecer limitación de velocidad para los datos que se envían en tu dirección. Como la dirección hacia el dispositivo siempre está limitada en velocidad, puedes usar comandos de rebote para volcar un binario pscr compilado de forma cruzada al dispositivo e iniciar una sesión limitada en velocidad bidireccional con él.tio -o 1 o -o 2 para agregar demoras entre los bytes de salida enviados38400 aunque la línea serie tenga configurado 115200)psc con -DRESPECT_UART_BUFSIZE=4096, sin embargo esto hará que la sesión sea muy lentaDentro de la carpeta contrib también encontrarás un parche tio-noprefix para deshabilitar el procesamiento de caracteres de escape, pero este parche solo es necesario para versiones antiguas, ya que el proyecto upstream ya aceptó e integró este parche. Recomiendo encarecidamente usar tio cuando se usan UART.
Cuando uses comandos de rebote a través de tio, debes agregar a tu archivo ~/.tioconfig:
[default]
prefix-ctrl-key = none
lo cual deshabilita el manejo de ESC y te da un canal limpio de 8 bits.
Puedes enviar SIGUSR1 a pscl para que te indique si la sesión está encriptada. Si el pscr remoto muere o sale sin posibilidad de señalizarlo a la parte local, pscl permanecerá en modo de encriptación y, por lo tanto, se colgará. En este caso, puedes forzar un reinicio al modo de texto plano enviando SIGUSR2, para que se pueda iniciar una nueva sesión.
A partir de la versión 0.64, psc soporta sockets de scripting, por lo que ya no necesitas screen para obtener/colocar archivos o volcar búferes de pegado a la consola remota. En su lugar, inicias tu sesión local de la siguiente manera:
~ > ./pscl -S ~/psc.script_sock
Luego puedes continuar y usarlo como antes. Si necesitas 'pegar' algo, haces lo siguiente:
~ > ./pscsh -S ~/psc.script_sock -f script_/helloworld
Esto 'escribirá' el contenido de script_/helloworld en la consola. Durante el scripting, la entrada estándar de pscl está bloqueada para que la entrada inyectada no se mezcle con ninguna escritura. Si se omite -S en pscsh, se usa automáticamente ~/psc.script_sock. Por razones de seguridad, los scripts deben comenzar con el prefijo script_.
Como beneficio adicional, pscr ahora contiene la capacidad de codificar/decodificar archivos en base64, incluso con caracteres CR incrustados por conveniencia. Es compatible con uuencode -m.
; y encerrados entre corchetes.