Muy buenas a todos!
Comenzamos el año con un nuevo proyecto. En esta ocasión, se trata de una pequeña herramienta llamada PyShell, que nos permitirá obtener una webshell con diferentes funcionalidades (subida y bajada de ficheros, movimiento entre directorios..), disponible en muchos lenguajes (aspx, php, jsp, sh, py..) y totalmente compatible con sistemas Windows y sistemas Linux.
Uno de los puntos de entrada más comunes durante los ejercicios de Red Team o en las auditorías de Hacking Ético, suelen ser las aplicaciones web. No importa si se trata de un gestor de contenido o de una aplicación empresarial, la mayoría de ellas suelen ser susceptibles a diferentes vulnerabilidades conocidas en algún punto de su desarrollo.
Gracias a esto, existen diferentes formas de comprometer dicho servicio, abriéndonos así las puertas a la infraestructura que soporta la aplicación y a toda la red adyacente de la misma. No importa si el lenguaje del servidor es PHP, ASP o Python (por nombrar algunos), si el contenido de la aplicación es dinámico, seguramente podremos ejecutar código arbitrario de una manera u otra.
Por ejemplo, supongamos que una aplicación web nos permite subir una imagen a través de una funcionalidad de file upload, pero esta no controla de forma adecuada lo que se está enviando. Esto nos permitiría subir un script con nuestro código malicioso y obtener una shell remota.
Uno de los problemas más habituales llegados a este punto, es la elección del sistema que utilizaremos como command & control durante la siguiente fase. Básicamente, esto se debe a que nos podemos encontrar en tres escenarios diferentes:
• Podemos ejecutar código, pero el servidor no tiene conectividad al exterior
• El código nos permite obtener una shell remota interactiva a través de netcat
• Conseguimos crear un usuario y entramos por otro servicio (SSH, RDP, etc..)
Evidentemente, existen muchos más casos de uso, pero es muy probable que tarde o temprano nos encontremos en una de estas situaciones.
Ya que en los dos últimos casos ya lo tendríamos todo resuelto, nos centraremos en el primero. Una forma sencilla de no tener que estar ejecutando comandos a través de peticiones web (vía web, curl o BurpSuite) es utilizar una webshell.
Este tipo de «pseudo-shells» nos permiten, interactuar con el servidor a través de peticiones web, pero de una forma mucho más cómoda y con todo tipo de funcionalidades (subir y descargar ficheros, movernos entre directorios y mucho más).
El problema es que muchas de las webshells que podemos encontrar por internet pueden contener código malicioso (y no me refiero al que queremos utilizar nosotros), son fácilmente detectables por la mayoría de antivirus o incluso tienen una interfaz de usuario bastante compleja que no aporta demasiado.
Por eso, decidí crear mi propia webshell (en esta ocasión he contado con la gran ayuda de 3v4si0n) y como de costumbre, hice una lista de premisas que tenía que cumplir la herramienta:
• Uso desde la consola, como un netcat o una conexión SSH
• Compatibilidad con el mayor número de lenguajes posible
• Utilizar el menor código posible en la parte servidor
• Funcionalidad en servidores Windows y en servidores Linux
• Posibilidad de navegar entre directorios, subir ficheros, etc..
Una vez claros los objetivos, nos pusimos manos a la obra y así nació la herramienta que hoy os traigo en el blog: PyShell – Multiplatform Python WebShell
A continuación os dejo el link de la herramienta en GitHub para más información: https://github.com/JoelGMSec/PyShell
Ahora que ya conocemos un poco mejor a PyShell, veamos cómo funciona 😋
En primer lugar, como suele ser habitual, descargaremos el proyecto e instalaremos las dependencias con los siguientes comandos:
git clone https://github.com/JoelGMSec/PyShell cd PyShell ; pip install -r requirements.txt
Dentro de la carpeta «Shells» encontraremos diferentes tipos de webshells para utilizar en función de nuestras necesidades. Para este ejemplo, levantaré un servidor PHP y utilizaré peticiones GET para interactuar con el servidor:
Como podéis ver en la imagen, el uso de la herramienta es completamente trivial. Solo tenemos que introducir la dirección donde hemos subido nuestra webshell y el tipo de conexión que queremos utilizar (GET o POST).
De forma totalmente automática, la herramienta nos mostrará el usuario actual en la barra de comandos, así como el nombre de host y el directorio en el que nos encontramos. Para movernos entre ellos, podremos hacerlo de la forma habitual como en cualquier intérprete de comandos.
Ahora bien, supongamos que no hemos sido capaces de subir una webshell, o simplemente hemos encontrado una vulnerabilidad que nos permitiría ejecutar código arbitrario:
Como podéis ver en la imagen anterior, se muestra una utilidad que nos permite hacer ping a un host remoto. Qué pasaría si alguien quisiera explotar esa función para conseguir RCE?
Seguramente, no sería muy difícil escapar del primer comando para poder ejecutar un segundo:
Aunque la explotación resulta muy sencilla, ahora nos encontramos ante una situación mucho más exótica. En esta ocasión, nuestra shell tendrá que utilizar un parámetro (en este caso, «domain») y además, tendrá que introducir un pipe antes de cada comando.
Por suerte para nosotros, con PyShell es tan fácil como utilizar un parámetro personalizado con -p y utilizar el parámetro –pipe para que todo funcione sin problemas:
Llegados a este punto, vamos a complicar aún más las cosas. Supongamos que hemos subido nuestra webshell en formato ASPX a un servidor Windows. Y además, queremos subir un exploit para escalar privilegios en la máquina.
Por defecto, la ejecución de comandos en Windows siempre se realizará a través de PowerShell en el servidor. Si utilizamos cualquier otra shell que no disponga de esta funcionalidad, solo tendremos que añadir el parámetro -ps al ejecutar PyShell.
Continuando con nuestro ejemplo, si queremos subir ficheros a través de upload en nuestra terminal:
Y si queremos descargar ficheros, haremos lo mismo con download desde la consola:
Si habéis prestado atención a las imágenes, podréis comprobar que no importa que tipo de conexión estemos utilizando, aunque para subir ficheros grandes se recomienda utilizar peticiones de tipo POST.
Uno de los escenarios más comunes en el que nos podemos encontrar la posibilidad de subir una webshell es en un CMS, como puede ser WordPress. Por ello, aparte del resto de shells habituales, también encontraremos un «plugin» creado para este fin.
De esta forma, lo único que necesitaremos hacer, es instalarlo de la forma habitual desde el panel de administración:
Una vez instalado y activado, copiaremos el enlace que podemos ver a continuación:
Por último, solo tendremos que copiar la ruta anterior en PyShell para obtener nuestra conexión remota sin ningún tipo de problema:
Aunque en este caso el usuario actual es «www-data», si pudiéramos ejecutar comandos como root (a través de su), sería tan sencillo como utilizar el parámetro -su para obtener permisos de superusuario en todos los comandos.
Por último, también podemos desplegar una webshell en formato WAR en Apache Tomcat:
Una vez desplegada la aplicación, copiaremos el enlace al igual que en WordPress:
Y finalmente, obtendremos nuestra conexión remota con los máximos privilegios posibles:
Aunque no se contempla en esta guía, disponemos de otros parámetros que nos permitirán utilizar cookies de sesión y autenticación a través de headers en caso de subir nuestra webshell en una zona restringida para usuarios no autenticados.
Como dato adicional, este software fue diseñado y utilizado durante el proceso de estudio (y durante el examen) para la obtención de la certificación OSCP.
Actualmente, la herramienta se encuentra en fase «beta» y es probable que se produzcan fallos en algunos escenarios. Si encuentras alguno, no dudes en hacérmelo saber 🙂
Espero que os haya gustado y os resulte útil en vuestras próximas auditorías.
Nos vemos en la próxima!