HoneyTrapで流行りの脆弱性に対する攻撃を観察する
OSやミドルウェアの脆弱性が公開された際に、その脆弱性に対する攻撃やスキャンが発生しているか、自分のハニーポットで確認してみたいケースがあります。
今回は、現在T-Potを運用していて、そういった思いを持った人向けの記事です。
1. 背景、課題
T-Potは、複数のハニーポットを集めたハニーポットです。各ハニーポットに割り当てられているポート(80番ポートや22番ポート等)に対する攻撃であれば、ダッシュボードや検索により、攻撃の着弾を確認できます。
しかし、ミドルウェア特有のポートに対する攻撃の場合、そのポートに割り当てているハニーポットがありません。
T-Potでは、HoneyTrapというハニーポットが、未割当ポートが受信したデータを拾ってくれるのですが、ペイロードが16進数文字列に変換されているため、そのまま検索や確認ができません。
以下の通りattack_connection.payload.data_hexが16進数文字列の値になっています。

今回は、2つの方法でHoneyTrapに着弾した攻撃を検索および確認します。
2. 方法1「手動で変換」
検索および表示の際に、都度、16進数文字列との変換をするという方法です。
この方法は、特にT-Potの設定変更は必要ありません。
2.1. HoneyTrapへのペイロードを検索
2018/7/17にクリティカルパッチアップデートが公開されたWebLogicServerの脆弱性であるCVE-2018-2893を例に検索してみます。
参考:2018年 7月 Oracle 製品のクリティカルパッチアップデートに関する注意喚起
CVE-2018-2893はT3プロトコルを利用した機能の脆弱性であり、T3プロトコルの通信のURL形式はt3://ip address:portであるため、t3://を検索ワードにして検索したいと思います。
まず、t3://を16進数文字列に変換します。
やり方は色々ありますが、今回はCyberChefを使います。
左のOperationからTo HexをドラッグしてRecipeにドロップします。
DelimiterはNoneを選択します。その後、Inputにt3://を入力します。

変換後の文字列である74333a2f2fが得られました。
次に、T-PotのKibanaを開き、Discover画面を開きます。
標準のフィルター機能ではLike検索ができないため、カスタムクエリを作成します。
Add a filterを選択、Edit Query DSLを選択し、以下を入力します。
{
"query": {
"bool": {
"must": [
{
"wildcard": {
"attack_connection.payload.data_hex": "*74333a2f2f*"
}
}
]
}
}
}
以下の画面になります。

Saveボタンを押下すると、検索結果が表示されました。
これらレコードは、ペイロードにt3://の文字列を含んでいるはずです。

2.2. HoneyTrapへのペイロードを表示
2.1.の検索結果のうち1件をサンプルに、attack_connection.payload.data_hexの値を16進数文字列から元に戻します。
74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a50553a74333a2f2f75732d6c2d627265656e733a373030310a0aをサンプルにします。
2.1と同じくCyberChefを使用します。
左のOperationからFrom Hexをドラッグして、Recipeにドロップします。
その後、Inputに上記の文字列を入力します。

以下の変換結果が得られました。
t3 12.2.1 AS:255 HL:19 MS:10000000 PU:t3://us-l-breens:7001
T3プロトコルの偵察行為のようです。
3. 方法2「自動で変換」
2の手順を毎回実施するのは少々つらいです。
よって、16進数文字列ではなく生のペイロードに対して検索および表示をできるように改造します。
3.1. Logstashの定義変更
以前、以下の記事で実施したように、LogstashのFiltersステージで変換します。
以下の通り、logstash.confに、rubyによる変換定義を追加します。
# Honeytrap
if [type] == "Honeytrap" {
date {
match => [ "timestamp", "ISO8601" ]
}
mutate {
rename => {
"[attack_connection][local_port]" => "dest_port"
"[attack_connection][local_ip]" => "dest_ip"
"[attack_connection][remote_port]" => "src_port"
"[attack_connection][remote_ip]" => "src_ip"
}
}
ruby {
code => "event.set('attack_connection.payload.data', [event.get('[attack_connection][payload][data_hex]')].pack('H*'))"
}
}
具体的な手順は以下の通りです。
# ディレクトリ移動
[root@massshoemaker:~]# cd /opt/tpot/docker/elk/logstash/
# 比較用にバックアップ
[root@massshoemaker:/opt/tpot/docker/elk/logstash]# cp -p dist/logstash.conf dist/logstash.conf.bak
# 定義変更。具体的な変更箇所はdiff結果を参照
[root@massshoemaker:/opt/tpot/docker/elk/logstash]# vi dist/logstash.conf
[root@massshoemaker:/opt/tpot/docker/elk/logstash]# diff -u dist/logstash.conf.bak dist/logstash.conf
--- dist/logstash.conf.bak 2018-06-30 23:49:05.780835483 +0900
+++ dist/logstash.conf 2018-07-26 21:40:09.998708396 +0900
@@ -226,6 +226,9 @@
"[attack_connection][remote_ip]" => "src_ip"
}
}
+ ruby {
+ code => "event.set('attack_connection.payload.data', [event.get('[attack_connection][payload][data_hex]')].pack('H*'))"
+ }
}
# Mailoney
3.2. Dockerイメージ更新、再起動
定義変更を反映させるため、LogstashのDockerイメージを更新します。
# 停止 [root@massshoemaker:/opt/tpot/docker/elk/logstash]# systemctl stop tpot # Dockerイメージ更新 [root@massshoemaker:/opt/tpot/docker/elk/logstash]# docker build -t dtagdevsec/logstash:1710 . Sending build context to Docker daemon 43.52 kB Step 1/6 : FROM alpine ---> 3fd9065eaf02 Step 2/6 : MAINTAINER MO ---> Using cache ---> 213ca7b23dda Step 3/6 : ADD dist/ /root/dist/ ---> 1b4d52ba9495 Removing intermediate container ba89d3fbe28a (snip) Removing intermediate container 43fd92fb83e4 Successfully built 67798a694b3f # 起動 [root@massshoemaker:/opt/tpot/docker/elk/logstash]# systemctl start tpot
3.3. 稼働確認
ncコマンドで適当なデータを送信してみます。なお、localhostを指定してもHoneyTrapは受け取ってくれないため、グローバルIPアドレスを指定しました。
[root@massshoemaker:~]# echo -n hogefuga | nc <IPアドレス> 57001
3.4. 表示確認
Kibanaで、稼働確認した際のリクエストを見てみます。

生のペイロードを確認できました!
3.5. 検索確認
新規項目であるattack_connection.payload.data項目はインデックスが張られていないため、まずはインデックスを張ります。Management -> Index Patterns -> 右上のRefresh field listボタンを押下するだけです。

その後、2.1の手順と同様に、Discover画面を開き、Add a filterを選択、Edit Query DSLを選択し、以下を入力します。
{
"query": {
"bool": {
"must": [
{
"wildcard": {
"attack_connection.payload.data": "*gefu*"
}
}
]
}
}
}

目的の文字列で検索できました!
4. まとめ
ハニーポットを運用していて、定期的に観察する以外に、明確な検索条件(例えば、exploitコードの一部分)をもって全ポートへの攻撃の着弾を確認したい場合、今回紹介した方法は有効かと思います。
まずは「手動で変換」の方法で観察を実施してみて、何度も行う必要がある場合は「自動で変換」を試してみるのはいかがでしょうか。