0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第二回 練習問題#2 writeup ハッキング・ラボの作り方(完全版)-

0
Posted at

P438〜の練習問題02-1、02-2、02-3のWriteupです。

02-1

省略

02-2

(1)

Drupageddonとは、Drupal 7 コアに存在した重大な SQLインジェクション脆弱性です。
SQLインジェクションってのは、超簡単に言えばデータベースを操作できるコマンドを普通の入力に混ぜて送ると、データベースが操作できちゃう。見ちゃいけない情報が見れちゃう。みたいなやつです。
SQLインジェクション自体は昔からありますし、数ある攻撃手法の中で一番有名(たぶん)だといえるくらい有名。
対策も簡単。
プレースホルダーを使ったり、入力値を検証したりORMを使ったり...いろんな対策方法があります。
Drupageddonはプレースホルダーの展開処理に不備があったようです。

このDrupageddonの何がヤバいかっていうとその影響範囲。
特別な権限なしに攻撃者は任意のSQL文を実行でき、データベースの読み取り・改ざんはもちろん、管理者アカウントの作成や、最終的には任意のPHPコード実行(RCE)までつなげることができました。

Drupalセキュリティチームは、パッチ公開からわずか7時間以内に自動化された攻撃が観測されたと警告を出しました。そのため「パッチを当てていないサイトは、たとえ後から更新しても、既に侵害されている前提で対応すべき」という異例の勧告(バックドアの有無を確認し、必要ならサイトを完全に再構築すること)が出され、これが大きな話題になりました。

7時間ルールってやつですね。

(2)

runコマンドを実行する前に、wiresharkを開いて、パケットを観察できるようにしましょう。

手順1:Wiresharkの表示フィルタでノイズを削る

キャプチャ全体にはARP(IPからMACアドレスを引くための名前解決)や、TCP[SYN]/[ACK]単体のような、通信の中身を持たないパケットが大量に混ざります。まずはアプリケーション層のリクエストだけに絞り込みます。

image.png

何もしなかったらパケットがいっぱいで見にくい。

image.png

今回のキャプチャからは

  • POST /?q=user/login HTTP/1.1 (長さ3405バイト)
  • POST /?q=user/login HTTP/1.1 (長さ440バイト)

の2件のHTTPリクエストが残るはずです。ARPやTCPハンドシェイクは「通信を成立させるための準備」であって攻撃の中身ではないので、肝心なのはここだけ。

手順2:TCP会話(コネクション)の単位で数える

次に、メニューの統計(Statistics)→ 会話(Conversations)→ TCPタブを開くと、このキャプチャ内で何本のTCPコネクションが張られたかが一覧できます。今回のキャプチャでは次の3本が確認できるはずです。
image.png

コネクション 送信元ポート 宛先ポート 役割
34573 80 1回目のPOST(3405バイト)を送るための接続
36267 80 2回目のPOST(440バイト)を送るための接続
47596 4444 Meterpreterのリバースシェル通信

3つめはポート番号が今までと毛色が違い、宛先が80番ではなく4444番です。Metasploit側のshow optionsを見るとLPORT 4444(ペイロードのリスンポート)となっており、これが一致します。

手順3:中身を確認する(Follow HTTP Stream / TCP Stream)

各パケットを右クリック→「Follow」→「HTTP Stream」(または「TCP Stream」)を選ぶと、リクエストの生データが読めます。

1回目のPOST(3405バイト、コネクション①)
image.png

SQLインジェクションを使い、Drupalのフォームキャッシュ(cache_formテーブル)に悪意あるシリアライズ済みPHPペイロードを書き込むリクエストです。データ量が大きいのは、注入するSQL文+シリアライズされたペイロード分のデータを一度に送り込んでいるためです。

2回目のPOST(440バイト、コネクション②)
image.png

1回目より明らかに小さいリクエストです。これは、①で仕込んだ「毒入りのフォームキャッシュ」を実際に呼び出させるためのトリガーにあたります。

③のポート4444の通信

image.png

ここでPHPコードの実行に成功した対象サーバーが、Metasploitのペイロード(Meterpreterステージャ)の指示通り、攻撃者のLHOST:LPORT(192.168.56.101:4444)に向けて自分から接続しにいく通信です。

まとめ
「3段階の通信で構成されている」という構造で捉えて説明するのが答えなんでしょうか(わからん)
「ツール側のログとパケットキャプチャを両方見て、片方だけでは分からない意味を補い合う」というのが、この狙いだと思います。

(3)

  1. SQLiで書き換えたパスワード(または既知のadmin/dragon)で管理画面にログイン
  2. 「PHP filter」モジュールを有効化する(Drupal 7標準機能、デフォルトでは無効なことが多い)
  3. 新しいコンテンツ(ページ)を作成し、本文の入力形式を「PHP code」にして、リバースシェルのPHPコードを書く
  4. 攻撃側でリスナー(nc)を待ち受けておく
  5. 作成したページを閲覧(アクセス)した瞬間にPHPコードがサーバー側で実行され、シェルが返ってくる

02-3

(1)

echo '<?php system("cat /etc/passwd");?>' > malicious

ポイントとしては、シングルクォーテーション ’ で囲むこと
内容に<> " " が含まれています。もしダブルクオートで囲んでしまうと、シェルは中の`"cat /etc/passwd"`部分を「文字列の終わり」と誤解して構文が壊れてしまいます。またクォートなしで書くと、`<`や`>がリダイレクト演算子として解釈されたり、ダブルクォートの対応がずれたりして意図通りの中身になりません。 シングルクォートで囲む最大のメリットは、**中に書いた文字がほぼすべてそのままリテラルとして扱われる**ことです(例外は'自身のみ)。<`や`>"`はシングルクォートの中では特別な意味を持たず、ただの文字として保存されます。

(2)

まず実際に試す手順は次の通りです。

bash

mv malicious malicious.php   # もしくは新規に同内容でmalicious.phpを作成
python3 -m http.server 8000

ブラウザでhttp://localhost:8000/malicious.phpにアクセスすると、/etc/passwdの中身が画面に表示されるのではなく、malicious.phpというファイル自体をダウンロードしようとするダイアログが出てきます。

理由は、python3 -m http.serverが「ただの静的ファイル配信サーバー」であり、PHPを解釈・実行する機能を一切持っていないからです。

PHP対応のWebサーバー(Apache+mod_phpやNginx+php-fpm)はリクエストされたファイルの拡張子が.phpだと分かると、そのファイルの中身をPHPインタプリタに渡して実行し、実行結果(今回ならcat /etc/passwdの出力を含むHTML)をレスポンスとして返します。

一方、Pythonのhttp.server.phpという拡張子を特別扱いする仕組みを持っていません。リクエストされたファイルを中身を一切解釈せず、そのままバイト列としてクライアントに返すだけです。つまりmalicious.phpにアクセスすると、サーバーは<?php system("cat /etc/passwd");?>というPHPのソースコードの文字列そのものを返してきます(実行はされません)。

ではなぜ「テキストとして表示」ではなく「ダウンロードしようとする」のかというと、これはHTTPレスポンスのContent-Typeヘッダーが関係しています。http.serverは、返すファイルのContent-Typeを拡張子から推測する仕組み(Python標準ライブラリのmimetypesモジュール)を使っています。しかしmimetypesのデフォルトの対応表には、そもそも.html.txt.css.jpgのような一般的なWeb向け拡張子は登録されていますが、.phpはプログラミング言語のソースコード用の拡張子であり、Web標準のコンテンツタイプとしては登録されていません。対応する型が見つからない場合、http.serverは既定値であるapplication/octet-stream(「中身不明のバイナリデータ」を意味する汎用MIMEタイプ)を返します。

ブラウザはContent-Type: application/octet-streamを受け取ると、「これはブラウザ内で表示できる種類のコンテンツではない」と判断し、画面に表示する代わりにファイルとして保存するかどうかをユーザーに確認するダイアログを出します。これが「ダウンロードを試みる挙動」の正体でしょう。

この違いはLFIやRFIを使う上で重要で、攻撃者がpython3 -m http.serverのような簡易サーバーで悪意あるPHPファイルを配信しても、それ自体は実行されず、あくまで「素材」を配っているだけ。

実際にコードが実行されるのは、脆弱なターゲット側のアプリケーションが、そのファイルをincluderequire(あるいはLFIの脆弱性経由)で自分のPHP実行環境に取り込んだときです。つまり「配信するサーバー」と「実行するサーバー」が別物である、という構造を、この設問は体感させようとしているのだと思います。

(3)(4)

省略
できないなら多分写し間違いでしょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?