はじめに

「吠えなかった犬の推理」

という言葉があります。シャーロック・ホームズ『白銀号事件』にある有名なやりとり、

「その他何か私の注意すべきことはないでしょうか?」
「あの晩の犬の不思議な行動に御注意なさるといいでしょう」
「犬は全然何もしなかったはずですが」
「そこが不思議な行動だと申すのです」

から来た、「一見すると不自然ではない(何も起きていない)ことが、状況を踏まえて考えれば極めて不自然であること」という、ミステリの定理とも言えるロジック。

筆者は公開しているVPSで不審なエラーログ(攻撃の検知ログ)は毎日のように見ていますが、先日、エラーではなく通常のアクセスログに、極めて不審な(というか完全にアウトな)一行を発見しました。

今回は、そのログの正体と、その裏に隠された攻撃者の意図について解説します。

見つかった「不自然な1行」のログ

見つかったのは、以下のようなログです(※IPアドレスやホストなどの情報はダミーに無害化しています)。

203.0.113.45 - - [02/Jun/2026:05:23:14 +0900] "POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1" 404 3097 "-" "libredtail-http"

Webサイトの運用経験がある方なら、この1行を見ただけでいくつか異様な点に気づくかと思います。

  • 見覚えのない海外IPからのアクセス
  • /.%2e/.%2e/ という怪しげな文字列の連続
  • 通常のブラウザでは使われない libredtail-http というUser-Agent
  • そして、何より/bin/sh(OSのシェル)に対して「POST」リクエストを送っているという異常さ

幸い、ステータスコードは 404(Not Found) なので、攻撃はサーバー側で弾かれています。では、この攻撃者は一体何をやろうとしていたのでしょうか?

このログの正体:パストラバーサル攻撃(CVE-2021-41773)

このリクエストは、過去に広く報道された Apache HTTP Serverの脆弱性(CVE-2021-41773など) を狙った自動スキャン(攻撃)ツールによるものです。

URLに含まれる .%2e をURLデコードすると、親ディレクトリを指す .. になります。
攻撃者は、公開フォルダ(cgi-bin)から強制的に外へ飛び出し、サーバーのルートにあるOSの実行ファイル(/bin/sh:シェル)に直接アクセスしようとしていたのです。古典的ですが強力なパストラバーサル(ディレクトリトラバーサル)攻撃です。

なぜ「GET」ではなく「POST」なのか?

「情報を盗み見るだけなら GET なのでは?」と思いましたが、調べてみると攻撃者の意図が浮かび上がりました。

① サーバー上で「コマンドを実行」させるため(RCE)

攻撃者の最終目的は、ファイルを覗き見ることではなく、サーバーを乗っ取ることです。
POST リクエストの「ボディ(本文)」部分に、実行させたい悪意あるLinuxコマンド(マルウェアのダウンロード命令など)を乗せて送信するのが真の目的です。

② 痕跡(ログ)を隠すため

GET メソッドの場合、実行したいコマンドをURLの後ろ(クエリパラメータ)に付ける必要があります。しかし、それだとアクセスログのURL部分に攻撃コマンドが丸見えになってしまいます。

Webサーバーの標準ログ設定は「ヘッダー」しか記録せず、「ボディ」は記録しません(パスワードやカード情報などの機密情報が含まれるため)。
攻撃者はこれを利用し、「POST/bin/sh を叩こうとした」という最低限の事実だけをログに残し、肝心の悪意ある命令(ボディ)をログから隠蔽しているのです。

攻撃の背景にあった、巨大な暗号資産マイニングマルウェア

さらにこのログの User-Agent にある libredtail-http を調べると、明確な犯行の背景が浮かび上がってきました。

これは、感染したサーバーのパワーを勝手に使って暗号資産(仮想通貨)を強制採掘させるマルウェア「RedTail」の拡散ツールです。

もし、サーバーに脆弱性が存在し、この POST が実行(200 OK)されてしまっていた場合、以下のような身の毛もよだつシナリオが進行していました。

  • マルウェア(RedTail)の強制インストール:
    • バックドアが設置され、サーバーが完全に乗っ取られます。
  • CPU使用率が「100%」に張り付く:
    • 裏でマイニングツール(XMRig)が暴走し、サイトが激重になります。クラウドの場合は莫大な従量課金が請求されます。
  • 報酬の隠蔽(マイニングプロキシの中継):
    • 採掘データを直接プールに送らず、攻撃者が用意した中継サーバーを経由させる。これによりウォレットアドレス(足跡)を隠蔽し、リサーチ会社や捜査の手から逃れる工作まで行っています。
      次の攻撃の「踏み台」にされる:
    • 被害者であると同時に加害者になり得ます。世界中の他のサーバーへ向けて、同様の不審な POST リクエストを無差別に送り始めます。

なぜ「犬は吠えなかった」のか?

筆者のVPSには、強力なWAFである ModSecurity を導入して不審な攻撃をシャットアウトしていますが、不思議なことに、今回この件に関するエラーログ(拒否ログ)は現れませんでした。

「攻撃が届いているのに、なぜWAFは吠えなかったのか?」

その理由は、以下の2つの可能性が考えられます。

1. 表面上は正しいドメイン名とヘッダを指定していた

筆者の環境では、ModSecurityで以下のようなカスタムルールを設けています。

# IPアドレス直打ちアクセス対策
SecRule REQUEST_HEADERS:Host "@rx ^[\d.]+(:\d+)?$" \
    "id:10001,\
    phase:1,\
    deny,\
    status:404,\
    log,\
    msg:'[CUSTOM RULE] Host header is a numeric IP address (incl port). Blocked immediately.',\
    tag:'application-attack',\
    tag:'PROTOCOL_VIOLATION/INVALID_HREQ'"

# Hostヘッダーが存在しない場合は即ブロック
SecRule &REQUEST_HEADERS:Host "@eq 0" \
    "id:10002,\
    phase:1,\
    deny,\
    status:404,\
    log,\
    msg:'[CUSTOM RULE] Missing Host Header. Blocked immediately.'"

「IPアドレス直打ち」や「Hostヘッダが無い」という、通常のWebブラウズではまず存在しないアクセスは、このルールで瞬殺(phase 1でブロック)されます。自動スキャナーの多くはこれで引っかかります。

この攻撃者は、筆者のサーバーの防御手段を見抜いていたのか、ご丁寧に正しいドメイン名をHostヘッダーに指定して、この網を通り抜けてきたと考えられます。

2. WAFが動く前に、Apacheのコア機能が処理を終わらせていた

もう一つの有力な可能性は、Apache自体の挙動です。
ModSecurityがURLの中身を深く精査(パース)するよりも前の段階で、Apacheのコア機能がURLのパスを処理した結果、「物理的にファイルが存在しない(404 Not Found)」と判断して処理を終了したパターンです。

エラー(拒否)ではなく、純粋に「そんなファイルは無いよ」として正常に(?)404を返したため、WAFの検知ログには残らなかった、というわけです。

Apacheにおいて、URLの文字列をデコードして物理的なファイルパスにマッピングする処理(ap_directory_walk)は、ModSecurityの phase:1(ヘッダー検査)と phase:2(ボディ検査)の間、あるいはその手前で行われます。

【Apacheの処理フロー】
1. リクエスト受信
2. ModSecurity (phase:1)  ← Hostヘッダーチェック(ドメインが正しいので通過!)
3. Apacheコア (パスの解決) ← 「/.%2e/」を解析しようとするが、そんなCGIは存在しない(404確定)
4. ModSecurity (phase:2)  ← 実行される前に、Apacheが「404」として即レスポンスを返して終了

つまり、攻撃者はドメインチェック(貴方のカスタムルール10001)を賢くすり抜けたものの、Apache自体のパス解決の壁に激突して、WAFが本格的に牙を剥く前に死んでいたわけです。

 3. 攻撃者が「POST」を選んだもう一つの邪悪な理由

それは「GETの文字数制限を回避するため」です。

RedTailのようなマルウェアは、侵入成功と同時に「Base64で難読化した巨大なシェルスクリプト」を送り込んできます。URLの末尾(GET)にこれを付けると、Apacheの最大URL長制限(LimitRequestLine:通常8KB)に引っかかり、コマンドが途中で切れて実行できません。 そのため、数万文字の「汚い攻撃コード」を確実に一発で流し込むために、ボディ制限が緩い POST を選択せざるを得ないのです。

まとめ:たまには「正常系のログ」も見ましょう

今回、攻撃の予兆に気づけたのは、「運良く」アクセスログを見ていた結果です。

自分の身やデータを守るため、そして自分が踏み台(加害者)にならないためにも、以下の基本を徹底しましょう。

  • Webサーバー(ApacheやNginxなど)を常に最新バージョンにアップデートしておく
  • 不要なCGI設定(cgi-binなど)は無効化・削除しておく
  • もはや必須となっているWAF(ModSecurityなど)の導入
  • クローラーや無駄なアクセスを拾わないログの整理

「エラーがない=安全」とは限らない。
攻撃があった兆候は、静かに普通のアクセスログにも現れる、というお話でした。