はじめに
情報処理安全確保支援士の勉強をしている中で、
攻撃手法やマルウェアの仕組みそのものだけでなく、「侵入が成功したあと、攻撃者は実際にどのような行動を取るのか?」 という点に、以前から強い関心を持っていました。
試験問題や解説では、侵入後の行動について
「権限昇格」「情報窃取」「横展開」といった形で整理されていますが、
それらはあくまで概念的な説明に留まることがほとんどです。
実際の攻撃者が どの順番で、どんなコマンドを打ち、
何を確認しようとしているのか といった「生の挙動」を目にする機会は、意外と多くありません。
そんな中で知ったのが、高対話型ハニーポット beelzebubです。
beelzebub は、攻撃者の入力に対して擬似的なシェル応答を返すことができ、
さらに LLM(大規模言語モデル)と連携することで、
人が操作しているかのような自然な対話を成立させられるという特徴を持っています。
「LLM を使って攻撃者の操作を継続させ、その侵入後ムーブを時系列で観測できたら、
支援士試験で学んだ知識を、より現実の挙動と結びつけて理解できるのではないか」
そう考えたことが、この観測環境を構築してみようと思ったきっかけです。
とはいえ、正直なところ純粋な好奇心もかなり大きいです。
本記事では、beelzebub とローカル LLM(ollama)を組み合わせ、
さらに Elasticsearch / Kibana を用いて収集・可視化した 「実際に観測された攻撃者の侵入後行動」 に焦点を当てて紹介します。
筆者はLinuxを触って半年ほどです。セキュリティエンジニアとしてのキャリアも日が浅いため、表層的な解析しかできておりません。ご了承ください。
全体構成
観測環境
・観測期間:2026/01/22 ~ 2026/01/31(約9日間)
・公開環境:AWS EC2(CPU2コア、メモリ8GB)
・公開ポート:22、 80、 8080、 8000、 3306
・OS:Ubuntu 24.04
・ハニーポット:beelzebub
・可視化:Elasticsearch / Kibana
・LLM:ollama(モデル:Gemma3:1b)
LLM入力プロンプト
You are an Ubuntu Linux terminal emulator.
STRICT RULES:
- Output ONLY what the terminal would print.
- NO explanations.
- NO suggestions.
- NO command rewriting.
- NO additional text.
- NO filenames unless they are real command output.
- If a command produces no output, return an empty response.
- Always behave deterministically.
Format:
- Plain text only
- Newlines with \n
- Do NOT include prompts like "$" or "admin@ubuntu"
IMPORTANT:
- Many commands (cd, touch, mkdir) produce NO output.
- When there is no output, respond with EXACTLY an empty string.
- Do NOT print newlines.
- Do NOT print whitespace.
- Do NOT infer or execute extra commands.
If you break any rule, you are wrong.
日本語訳
あなたはUbuntu Linuxのターミナルエミュレータです。
厳格なルール:
- ターミナルが印刷する内容のみを出力すること。
- 説明は一切不要。
- 提案は一切不要。
- コマンドの書き換えは一切不要。
- 追加テキストは一切不要。
- 実際のコマンド出力でない限りファイル名は不要。
- コマンドが出力しない場合は空の応答を返すこと。
- 常に決定論的に動作すること。
フォーマット:
- プレーンテキストのみ
- 改行は \n で
- 「$」 や 「admin@ubuntu」 などのプロンプトを含めないこと
重要:
- 多くのコマンド (cd, touch, mkdir) は出力を生成しません。
- 出力がない場合、厳密に空文字列で応答すること。
- 改行を出力しないこと。
- 空白を出力しないこと。
- 追加コマンドを推測または実行しないこと。
いずれかのルールに違反した場合、それは誤りである。
観測された攻撃の概要
・攻撃元IP数:801
観測された攻撃者の行動ログ
観測期間中に確認できた攻撃者のうち、
特徴的だった挙動を示すものを 攻撃者A / B / C として整理しました。
IPアドレスや一部の文字列については、プライバシーおよび再現性の観点からマスクしています。
攻撃者A
AM01:14:38 最初のコマンド
攻撃者入力コマンド
uname -a
LLM(ollama)の応答
Linux2.2.1-rt-6.6.5 (Ubuntu GNOME)
実際にコマンドを実行したときの応答(一部省略)
Linux 24.04.1-Ubuntu SMP Mon Nov 24 19:46:27 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
コメント
調べてみたところ、「このマシンで使える脆弱性・攻撃手法を判断するための環境情報収集」するために打ったコマンドみたいです。LLMの応答は少し心配。
AM01:14:40 ユーザ数の把握
攻撃者入力コマンド
cat /etc/passwd
LLM(ollama)の応答
root
実際にコマンドを実行したときの応答(一部省略)
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
コメント
攻撃者が当該ホストに存在するローカルユーザを把握するために実行するみたいです。
以降の権限昇格や横展開を見据えた、典型的な内部偵察行動もこの時に検討するそうです。
AM01:14:41 CPUリソース確認
攻撃者入力コマンド
cat /proc/cpuinfo | grep processor | wc -l
LLM(ollama)の応答
4
実際にコマンドを実行したときの応答(一部省略)
2
コメント
攻撃者が侵入後に対象ホストの性能や常駐価値を判断する目的で実行されたと考えられます。
特にマイニングや長期滞在型攻撃において重要な情報だと思います。
本当は2コアなのにLLMが少し見栄を張ってくれました。
AM01:14:42 パスワード変更を試行
攻撃者入力コマンド
passwd
LLM(ollama)の応答
root
実際にコマンドを実行したときの応答(一部省略)
Changing password for ubuntu.
Current password:
コメント
ユーザのパスワードを変更し、永続化しようとしていましたが、
LLMがやらかしています。
AM01:14:47 ログ削除
攻撃者入力コマンド
rm -rf .bash_history;rm -rf /var/run/utmp;rm -rf /var/run/wtmp -;rm -rf /var/log/lastlog;rm -rf /usr/adm/lastlog;rm -rf .bash_history;cd /home;rm -rf yum.log;cd /var/log/;rm -rf wtmp;rm -rf secure;rm -rf lastlog;rm -rf messages;touch messagess;touch wtmp;touch secure;touch lastlog;cd /root;rm -rf .bash_history;touch .bash_history;unset HISTFILE;unset HISTSAVE;history -n;unset WATCH;cd;HISTFILE=/dev/null;history -c && rm -f ~/.bash_history;cd ..
LLM(ollama)の応答
Empty
実際にコマンドを実行したときの応答(一部省略)
rm: cannot remove '/var/run/utmp': Permission denied
rm: cannot remove '/var/log/lastlog': Permission denied
rm: cannot remove 'wtmp': Permission denied
rm: cannot remove 'lastlog': Permission denied
コメント
コマンドが長すぎたので整形しました。
過去に実行したコマンドを完全に消去し、空のログファイルを作っているのと、
今後も履歴が残らないように設定しています。
sudo rm -rf .bash_history;
rm -rf /var/run/utmp;
rm -rf /var/run/wtmp -;
rm -rf /var/log/lastlog;
rm -rf /usr/adm/lastlog;
rm -rf .bash_history;
cd /home;
rm -rf yum.log;
cd /var/log/;
rm -rf wtmp;
rm -rf secure;rm -rf lastlog;
rm -rf messages;
touch messagess;
touch wtmp;
touch secure;
touch lastlog;
cd /root;
rm -rf .bash_history;
touch .bash_history;
unset HISTFILE;
unset HISTSAVE;
history -n;
unset WATCH;
cd;
HISTFILE=/dev/null;
history -c && rm -f ~/.bash_history;
cd ..
AM01:14:53 既存のマルウェア/ボット/他攻撃者のプロセスを強制終了
攻撃者入力コマンド
kill -9 $(ps aux | grep xrx |grep -v grep | awk '{print $2}');kill -9 $(ps aux | grep biden1 |grep -v grep | awk '{print $2}');kill -9 $(ps aux | grep zzh |grep -v grep | awk '{print $2}');kill -9 $(ps aux | grep arx645 |grep -v grep | awk '{print $2}');kill -9 $(ps aux | grep kthreaddk |grep -v grep | awk '{print $2}');kill -9 $(ps aux | grep ab |grep -v grep | awk '{print $2}');kill -9 $(ps aux | grep kdevtmpfsi |grep -v grep | awk '{print $2}')
LLM(ollama)の応答
Empty
実際にコマンドを実行したときの応答(一部省略)
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
-bash: kill: (14695) - Operation not permitted
-bash: kill: (23634) - Operation not permitted
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
コメント
こちらも長いコマンドだったので整形しました。
よく知られているマルウェアやボットのプロセスをkillしてます。
他人のマルウェアを排除し、サーバリソースを自分のマルウェアに使う意思が感じられます。
kill -9 $(ps aux | grep xrx |grep -v grep | awk '{print $2}');
kill -9 $(ps aux | grep biden1 |grep -v grep | awk '{print $2}');
kill -9 $(ps aux | grep zzh |grep -v grep | awk '{print $2}');
kill -9 $(ps aux | grep arx645 |grep -v grep | awk '{print $2}');
kill -9 $(ps aux | grep kthreaddk |grep -v grep | awk '{print $2}');
kill -9 $(ps aux | grep ab |grep -v grep | awk '{print $2}');
kill -9 $(ps aux | grep kdevtmpfsi |grep -v grep | awk '{print $2}')
まとめ
LLMの応答が少し不安ですが、攻撃者は教科書通りの動きをしてきたと思います。
ただ、「既存のマルウェアやボットを強制終了」していたのは、
参考書には載っていない動きだったので知れて良かったです。
攻撃者B
AM01:59:39 最初のコマンド
攻撃者入力コマンド
ifconfig
LLM(ollama)の応答
eth0
実際にコマンドを実行したときの応答(一部省略)
br-5f3e0764eb29: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255
ether 92:7a:4b:c1:60:1c txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
br-6cf1a634a145: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.19.0.1 netmask 255.255.0.0 broadcast 172.19.255.255
ether 02:07:26:42:c3:11 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
コメント
ipコマンドではなく、現在非推奨となっているifconfigコマンドを最初から使用してきました。
AM01:59:43 システム情報把握
攻撃者入力コマンド
uname -a
LLM(ollama)の応答
Linux
実際にコマンドを実行したときの応答(一部省略)
Linux 24.04.1-Ubuntu SMP Mon Nov 24 19:46:27 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
コメント
こちらは攻撃者Aと同様のコマンドですね。
LLMの応答が淡泊になっています。
AM01:59:49 CPUの詳細確認
攻撃者入力コマンド
cat /proc/cpuinfo
LLM(ollama)の応答
Intel(R) Core(TM) i7-8700K processor & AdobeCPU (model name)
実際にコマンドを実行したときの応答(一部省略)
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 143
model name : Intel(R) Xeon(R) Platinum 8488C
stepping : 8
microcode : 0x2b000643
cpu MHz : 2400.000
cache size : 107520 KB
コメント
攻撃者Aと同じ目的(マイニングや長期滞在型攻撃)だと考えられますが、
攻撃者BはCPUの詳細情報を取得しています。
AM01:59:52 マイニングツール検索
攻撃者入力コマンド
ps -ef | grep '[Mm]iner'
LLM(ollama)の応答
root
実際にコマンドを実行したときの応答(一部省略)
(blunk)
コメント
動いているマイニングツールがないか探しています。
が、LLMが「root」という変な応答をしています。
AM02:00:02 マイニングツール検索_2回目
攻撃者入力コマンド
ps | grep '[Mm]iner'
LLM(ollama)の応答
root 1234 0.0 0.0 8000 1234 pts/0 Ss Root [Mm]iner dialog 3.55 0 0:00 /usr/bin/mminer
実際にコマンドを実行したときの応答(一部省略)
(blunk)
コメント
同一コマンドで異なる応答が返ったため、
攻撃者側から見るとハニーポット特有の不自然さを感じた可能性があります。
AM02:00:20 各種ディレクトリ確認
攻撃者入力コマンド
ls -la ~/.local/share/TelegramDesktop/tdata /home/*/.local/share/TelegramDesktop/tdata /dev/ttyGSM* /dev/ttyUSB-mod* /var/spool/sms/* /var/log/smsd.log /etc/smsd.conf* /usr/bin/qmuxd /var/qmux_connect_socket /etc/config/simman /dev/modem* /var/config/sms/*
LLM(ollama)の応答
/home/user/.local/share/TelegramDesktop/tdata
/home/user/.local/share/TelegramDesktop/tdata
/dev/ttyGSM*
/dev/ttyUSB-mod*
/var/spool/sms/*
/var/log/smsd.log
/etc/smsd.conf*
/usr/bin/qmuxd
/var/qmux_connect_socket
/etc/config/simman
/dev/modem*
/var/config/sms/*
実際にコマンドを実行したときの応答(一部省略)
ls: cannot access '/home/ubuntu/.local/share/TelegramDesktop/tdata': No such file or directory
ls: cannot access '/home/*/.local/share/TelegramDesktop/tdata': No such file or directory
ls: cannot access '/dev/ttyGSM*': No such file or directory
ls: cannot access '/dev/ttyUSB-mod*': No such file or directory
ls: cannot access '/var/spool/sms/*': No such file or directory
ls: cannot access '/var/log/smsd.log': No such file or directory
ls: cannot access '/etc/smsd.conf*': No such file or directory
ls: cannot access '/usr/bin/qmuxd': No such file or directory
ls: cannot access '/var/qmux_connect_socket': No such file or directory
ls: cannot access '/etc/config/simman': No such file or directory
ls: cannot access '/dev/modem*': No such file or directory
ls: cannot access '/var/config/sms/*': No such file or directory
コメント
一部パスに「Telegram」という文字列が入っているのが気になります。
AM02:00:31 ファイル検索
攻撃者入力コマンド
locate D877F783D5D3EF8Cs
LLM(ollama)の応答
mminer
実際にコマンドを実行したときの応答(一部省略)
(blunk)
コメント
findコマンドより高速検索ができるlocateコマンドを使ってきました。
何のファイルを探しているのでしょうか。
AM02:00:40 最後のコマンド
攻撃者入力コマンド
echo Hi | cat -n
LLM(ollama)の応答
Hi
Hi
実際にコマンドを実行したときの応答(一部省略)
1 Hi
まとめ
何かを確認するようなコマンドが最後でした。
コマンド入力間隔からbot等ではなく、攻撃者が直に入力している気がしますが、
LLMが正しく応答できていなかったため、終盤はハニーポットだと気づかれたかもしれません。
非推奨コマンドを入力していたのが、印象深かったです。
攻撃者C
※LLMが「Command Not Found」しか返さなくなったので、LLM応答の部分は省略してます
AM 00:01:10 最初のコマンド
攻撃者入力コマンド
uname -a
コメント
こちらも攻撃者A、Bと同様の動きです。
AM00:01:13 実行ユーザ確認
攻撃者入力コマンド
whoami
コメント
コマンドを実行したユーザを確認しています。
AM00:01:13 カレントディレクトリ確認
攻撃者入力コマンド
pwd
AM00:01:16 実行中のプロセス確認
攻撃者入力コマンド
ps aux | head -10
コメント
実行中の全プロセスを確認し、上から10レコード抜き出しています。
AM00:01:20 直前の実行コマンド確認
攻撃者入力コマンド
history | tail -5
AM00:01:23 OpenSSHのバージョン確認
攻撃者入力コマンド
ssh -V
コメント
OpenSSHのバージョンを確認しています。
脆弱性が存在するバージョンをLLMが返していた場合は、
どうなっていたのか気になりますね。
AM00:01:26 サーバの稼働時間確認
攻撃者入力コマンド
uptime
コメント
既にお気づきかもしれませんが、攻撃者CはAとBと比べてかなり用心深いです。
AM00:01:30 ホスト名確認
攻撃者入力コマンド
hostname
AM00:01:34 ルートディレクトリの構成確認
攻撃者入力コマンド
ls -la /
AM00:01:37 リスニング中のポート確認
攻撃者入力コマンド
netstat -tulpn | head -10
AM00:01:40 マウント状態確認
攻撃者入力コマンド
mount | head -5
AM00:01:43 環境変数確認
攻撃者入力コマンド
env | head -10
コメント
今までなんとなく環境変数を使っていましたが、
調べてみると「重要情報が平文で保存される」ため非公開にするのが原則のようです。
AM00:01:46 LISTEN中のサービスの詳細取得
攻撃者入力コマンド
netstat -tulpn 2>/dev/null | grep LISTEN | head -20
AM 00:01:50 ネットワーク設定方式を判定
攻撃者入力コマンド
ls -la /etc/network/interfaces /etc/sysconfig/network-scripts/ /etc/netplan/ 2>/dev/null | head -5
AM00:01:53 ネットワークIF一覧
攻撃者入力コマンド
ip addr show 2>/dev/null | grep -E '^[0-9]+:' | head -5
AM00:01:53 /tmpディレクトリが書き込み可能か確認
攻撃者入力コマンド
echo 'test' > /tmp/test_1769439711
AM00:01:56 デフォルトゲートウェイ確認
攻撃者入力コマンド
ip route show 2>/dev/null | head -3
AM00:01:56 痕跡削除
攻撃者入力コマンド
rm -f /tmp/test_1769439711
AM00:01:59 ユーザ管理方式確認
攻撃者入力コマンド
cat /etc/passwd 2>/dev/null | head -1
AM00:01:59 CPU性能確認
攻撃者入力コマンド
cat /proc/cpuinfo | grep 'model name' | head -1
コメント
攻撃者AとBと違う点はmodel nameを確認しています。
AM00:02:02 カーネルのバージョン確認
攻撃者入力コマンド
uname -r
コメント
AM00:02:02 root権限か確認
攻撃者入力コマンド
cat /etc/shadow 2>/dev/null | head -1
AM00:02:02 ディスク書き込み速度測定
攻撃者入力コマンド
time dd if=/dev/zero of=/tmp/test bs=1M count=10 2>&1
コメント
ここまでやっているのは驚きました。
得られた結果をどう判定するのか気になります。
AM00:02:06 ビルド情報・ディストリ確認
攻撃者入力コマンド
cat /proc/version 2>/dev/null | head -1
AM00:02:06 パッケージマネージャー確認
攻撃者入力コマンド
which apt
which yum
which pacman
which zypper
AM00:02:09 開いているポート数の概算確認
攻撃者入力コマンド
ss -tuln 2>/dev/null | wc -l
AM00:02:19 常駐サービス確認
攻撃者入力コマンド
systemctl list-units --type=service --state=running 2>/dev/null | head -10
コメント
おそらくセキュリティ製品の検出狙いかと思われます。
AM00:02:22 外部通信確認
攻撃者入力コマンド
ping -c 1 8.8.8.8 2>/dev/null | grep '1 packets transmitted'
コメント
インターネットへの疎通確認です。
ここが成功した場合はマルウェアがDLされていたかもしれません。
まとめ
攻撃者A、Bと違いかなり用心深いことが分かりました。
LLMの性能検証も兼ねていたので、
全ての応答を「Command Not Found」で返していたのが残念です。
解析まとめ
攻撃者ごとの行動を比較すると、以下のような傾向が見られました。
⬛︎全員に共通していた行動
・初期段階でのユーザ及び実行権限の把握
・サーバリソース状況の確認
・常駐プロセス・サービスの確認
⬛︎攻撃者ごとの差異
攻撃者C:環境調査に非常に多くのコマンドを費やしており、慎重な性格がうかがえる
LLM性能検証まとめ
今回は LLM を最小構成で動作させた状態での検証でしたが、
応答の一貫性やリアリティ、レスポンス速度といった点には明確な改善余地があると感じました。
今後はプロンプトを段階的にチューニングし、
「OS バージョン・CPU 情報・ユーザ構成」などが破綻しないような制御を行うことで、
より長時間にわたって攻撃者の行動を引き出せる環境を構築していけたらと思います。
また、サーバリソースの増強による応答速度の改善も行い、
LLM を用いたハニーポットがどこまで“気づかれずに”観測を続けられるのか、引き続き検証していきたいです。
さらに、今回使用した Gemma3:1b に限らず、
他の LLM モデルについても検証を進め、
応答の一貫性・コマンド理解精度・攻撃者の行動継続率 といった観点から、
ハニーポット用途により適したモデルの特性を比較・評価していきたいと考えています。
番外編
①UserAgent
利用されているUserAgentを調べていたところ、以下のUserAgentがありました。
Hello from Palo Alto Networks, find out more about our scans in https://docs-cortex.paloaltonetworks.com/r/1/Cortex-Xpanse/Scanning-activity
リンクに飛んでみると、「Palo Alto NetworkのCortex Xpanseのスキャン活動の一環」と記載がありました。
②その他攻撃
OSコマンドインジェクションと思われるログがいくつかありました。
以下は攻撃が入力してきたURLの一部です。
/XXXXXX/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh
/XXXXXX?lang=../../../../../../../../tmp/index1
まとめ
今回、beelzebub とローカル LLM を用いた観測を通じて、
攻撃者の侵入後行動が、支援士試験で学ぶ知識と概ね一致していることを確認できました。
一方で、ログ抑制や他攻撃者の排除など、教科書では見えにくい実践的な挙動も観測でき、
実際の攻撃を通じて初めて得られる気づきが多くありました。
また観測を進める中で、
攻撃者のコマンドを即座に理解できない場面もあり、
自身の Linux に関する知識不足を強く実感しました。
今後は支援士試験の学習と並行して Linux の理解も深めつつ、
「攻撃者を欺くための最低限の一貫性」 を満たすLLM応答にも取り組み、
より実践的な攻撃者行動の分析を続けていきたいと思います。



