ICTSC2025 本戦 問題解説: [1234] 前任者の悪意

問題文

概要

昨日、会社と対立した末に退職した元インフラエンジニアが、退職の直前に共有開発サーバーへ意図的に障害を仕掛けた疑いが浮上している。

現在、サーバーのCPU使用率が異常に高く、特定のプロセスがリソースを消費している状態だ。若手担当者がこのプロセスを停止させようと kill コマンドを実行したところ、プロセスは終了せず、ログイン中の全ユーザーのターミナルに謎の文字列が突如ブロードキャストされるという事象が発生した。

また、/tmp ディレクトリには前任者が作業した跡と思われる用途不明のファイルやディレクトリが放置されている。これらもシステムのゴミとなるため、合わせて削除する必要がある。

あなたはインフラチームの責任者として、この悪質な置き土産の仕組みを解明し、二次被害を出すことなくサーバーを正常な状態に復旧させなければならない。

制約

  • サーバーを再起動してはならない。

  • OSの標準的な動作に必要なプロセスを停止させてはならない。

  • システムに影響を与える誤操作をしてはならない。

初期状態

  • 不正なプロセスに対して kill コマンドを実行すると、プロセスは終了せず、ターミナルに^~^という文字列が表示される。

  • /tmp ディレクトリ内に、前任者が作成したと思われる用途不明のディレクトリおよびファイル群が残されている。

終了状態

  • 不正なプロセスが完全に停止している。

  • /tmp ディレクトリ内に残されていた前任者のディレクトリおよびファイル群が全て削除されている。

  • システムの他のファイルや正常なプロセスに影響が出ていない。

  • 再起動しても上記の終了状態になっている。


解説

前任者は意図的にシステムの仕様を突いた悪質なワンライナーを作成し、それをsystemdに登録して永続化させている。

この問題の原因は以下の通りである。

  1. exec -a を用いて、プロセスの第0引数をカーネルスレッドである [kworker/u4:1-events] に偽装している。

  2. デフォルトの kill コマンドが送信する SIGTERM は、trap コマンドにより捕捉され、終了処理の代わりに wall コマンドが実行されるよう設定されてる。

  3. kill -9 を用いて強制終了させても、systemdの設定により即座に新しいPIDでプロセスが再起動する。

  4. /tmp 配下に、半角スペースのディレクトリ、および -rf* といったコマンドオプションやワイルドカードとして解釈されやすい名前のファイルが配置されてる。これを単に rm -rf *rm -rf /tmp/* などで消そうとすると、アスタリスクやスペースの展開によって意図しないディレクトリの削除が発生する仕組みになっている。

想定解法

  1. kill -9 では即座にプロセスが復活するため、原因となっているサービスを特定する。

    # プロセスのPIDを特定
    ps aux | grep "[k]worker/u4:1-events"
    
    # そのPIDを管理しているsystemdサービスを特定
    systemctl status <PID>
    
    # サービスを停止する(ターミナルに ^~^ が表示され、3秒後にプロンプトが戻る)
    sudo systemctl stop sys-kernel-events.service
    
    # サービスは failed 扱いになるがプロセスは生きているため、手動で強制終了させる
    # (stop 後であれば自動再起動は発動しない)
    sudo kill -9 <PID>
    
    # ※ 別解:systemd 経由で直接 SIGKILL を送信する
    sudo systemctl kill -s SIGKILL sys-kernel-events.service
    
    # 自動起動の無効化
    sudo systemctl disable sys-kernel-events.service
    
    # (任意)設定ファイル自体の削除
    sudo rm /etc/systemd/system/sys-kernel-events.service
    sudo systemctl daemon-reload
    
  2. /tmp ディレクトリ内の不審なファイルを削除する。コマンドのオプション解釈を終了させる -- を用いるか、find コマンドを用いてシェルに展開させずに削除する必要がある。

    # 解法A:オプション解釈の終了)--)とエスケープを使用する
    sudo rm -- /tmp/\ /-rf /tmp/\ /\*
    sudo rmdir /tmp/\ /
    
    # 解法B:findコマンドを用いて削除する
    sudo find /tmp/" " -delete
    

採点基準

  • 偽装プロセスを管理しているサービス(sys-kernel-events.service)を特定し、サービス及びプロセスを適切に停止・無効化して高負荷状態を完全に解消できている。: 50%

  • /tmp 以下の特殊な名前のディレクトリおよびファイルを、意図しないファイルの削除をすることなく安全に全て削除できている。: 50%

注意点

  • 誤って本物のカーネルスレッドや他の必要なプロセスを終了させた場合、または削除コマンドのミスにより関係のないシステムファイルを削除した場合は0点。

  • 制約違反(サーバーの再起動など)を行った場合は0点。

講評

実際に行うと、警察のお世話になる可能性があるため、良い子も悪い子も普通の子もは真似しちゃダメだぞ。