土日の勉強ノート

AI、機械学習、最適化、Pythonなどについて、技術調査、技術書の理解した内容、ソフトウェア/ツール作成について書いていきます

徳丸本:セッション管理を理解してセッションID漏洩で成りすましを試す

ハッキング・ラボのつくりかた 完全版 仮想環境におけるハッカー体験学習」と「体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践」(通称:徳丸本)を参考に、セキュリティの勉強を進めています。

今回は、徳丸本の 3章の「Webセキュリティの基礎」について、実際にやっていきたいと思います。

それでは、やっていきます。

参考文献

今回から「独習PHP 第4版」を参考書に追加しました。徳丸本の用意してくれている実習環境では、PHP が使われています。私は PHP は初めてなのですが、C言語に似ていることもあり、独習PHP があれば、とりあえず違和感なく読み解けています。

独習PHP には、セッション管理のことや、セキュリティについても、多めに言及してくれていて、理解しやすかったです。数多くある技術書の中でも、独習シリーズは安心して使える本だと思います。

はじめに

「セキュリティ」の記事一覧です。良かったら参考にしてください。

セキュリティの記事一覧

徳丸本の環境構築については、以下の第9回でやりました。

daisuke20240310.hatenablog.com

また、徳丸本が用意してくれている、脆弱なアプリケーション Bad Todo の準備については、以下の第12回でやりました。今回は、この環境を使ってやっていきます。

daisuke20240310.hatenablog.com

Bad Todoのセッション管理を確認する

まず、Bad Todo にアクセスしたときのシーケンスについて、セッションに関するところを中心に、図にしてみました。

Bad Todo は、脆弱性を多く含むように作られているため、このシーケンスが普通というわけではないので、注意が必要です。

Bad Todoのログインからログアウトまで
Bad Todoのログインからログアウトまで

シーケンス図のソースコードも貼っておきます。

@startuml

title 徳丸本 Bad Todo

group トップページにアクセス (ログイン前)
    Client -> Server: GET /todo/
    Server -> Client: 200 OK
    note left
        index.phpにtodolist.phpが書かれている
    end note
    
    Client -> Server: GET /todo/todolist.php
    Server -> Client: 200 OK (Set-Cookie: TODOSESSID=emce6a5kg99aurb263obo7fd82; path=/)
    note left
        この時、クライアントにCookieが保存される
    end note
end

group ログインをクリック (ログイン前)
    Client -> Server: GET /todo/login.php?url=todolist.php&TODOSESSID=emce6a5kg99aurb263obo7fd82
    note right
        セッションIDがURLに埋め込まれている
        (.user.iniでURL自動埋め込みの設定になっているため)
    end note
    Server -> Client: 200 OK
end

group ユーザIDとパスワードを入力してログインボタンをクリック
    Client -> Server: POST /todo/logindo.php?
    note left
        メッセージボディの内容
        TODOSESSID=emce6a5kg99aurb263obo7fd82&userid=daisuke
        &pwd=useruser&url=todolist.php
    end note
    Server -> Client: 302 Moved Temporarily
    note right
        一覧ページにリダイレクトしてる
        Set-Cookie: USER=O%3A4%3A%22User%22%3A3%3A%7Bs%3A8
        %3A%22%00User%00id%22%3Bs%3A1%3A%223%22%3Bs%3A12%3A
        %22%00User%00userid%22%3Bs%3A7%3A%22daisuke%22
        %3Bs%3A11%3A%22%00User%00super%22%3Bs%3A1%3A
        %220%22%3B%7D; path=/
    end note
    
    Client -> Server: GET /todo/todolist.php?TODOSESSID=emce6a5kg99aurb263obo7fd82
    Server -> Client: 200 OK
end

group ログアウトボタンをクリック
    Client -> Server: GET /todo/logout.php?TODOSESSID=emce6a5kg99aurb263obo7fd82
    note left
        Cookie: USER=O%3A4%3A%22User%22%3A3%3A%7Bs%3A8
        %3A%22%00User%00id%22%3Bs%3A1%3A%223%22%3Bs%3A12%3A
        %22%00User%00userid%22%3Bs%3A7%3A%22daisuke%22
        %3Bs%3A11%3A%22%00User%00super%22%3Bs%3A1%3A
        %220%22%3B%7D; path=/
    end note
    Server -> Client: 200 OK
    note right
        Set-Cookie: TODOSESSID=deleted;expires=Mon, 14-Aug-2023 05:48:22 GMT; path=/
        Set-Cookie: USER=deleted; expires=Mon, 14-Aug-2023 05:48:22 GMT; path=/
    end note
end

@enduml

Bad Todo のシーケンスについてですが、全般的には、セッションID を URL に埋め込んでいるところが目につきます。

HTTP はステートレスのプロトコルのため、状態を維持する(セッション)ためには、サーバ、クライアント間で、何らかのユニークな情報を共有しておく必要があります。

過去には、セッション管理として、hiddenパラメータでやりくりしていた時代もあったようですが、Cookie が使われるようになり、現在は、一時的な乱数値をセッションID として、実際のデータ(ユーザ名、パスワードなど)は、サーバで管理されるようになったようです。

重要なデータは通信上には出なくなりましたが、このセッションID が漏洩すると、このユーザに成りすますことが可能になります。

セッションIDが漏洩した場合を試す(セッションハイジャック)

少し実験してみます。

今、OWASP ZAP と Firefox の組み合わせで、Bad Todo にアクセスしています。

Bad Todo には、以前、準備したときに登録した非公開の Todo が 1件追加されて、計3件が登録されています。

Firefox で、Bad Todo にログインしている状態で、OWASP ZAP で HTTP のアクセスを確認します。リクエストヘッダに、Cookie の値があるのでコピーしておきます。

OWASP ZAPでCookieの値を取得
OWASP ZAPでCookieの値を取得

次に、上とは別に、Burp Suite と Chromium の組み合わせで起動します(攻撃者)。

ログインしていない状態で、Bad Todo にアクセスします。ゲストアカウントなので、先ほど登録した非公開の Todo は見えない状態です。

ゲストでBad Todoにアクセス
ゲストでBad Todoにアクセス

Burp Suite の intercept を ON にして、ブラウザをリロードします。

すると、Burp Suite の方で、GETリクエストを検知して、Bad Todo アプリにリクエストを送らずに止めてくれています。ここで、リクエストヘッダの Cookie を先ほどコピーしたものに置き換えます。

Cookieを改変する
Cookieを改変する

Forward をクリックして先に進めます。すると、非公開のはずの Todo が表示されていて、ゲストアカウントだったのが、登録済みのユーザでログインしたように表示されています。

Cookieを差し替えてBad Todoをアクセスしたところ
Cookieを差し替えてBad Todoをアクセスしたところ

セッションID が漏洩すると、ログインユーザに、なりすますことが出来てしまうという実験でした。

今回は手作業で Cookie を差し替えたので面倒に見えますが、通常は Python などのソースコードで攻撃を実現するため、Cookie を差し替え続けることが簡単に可能になります。

このため、ログインしたユーザと同じことが出来るので、Todo を削除したり、ログインユーザのパスワードを変更したり出来てしまいます(Bad Todo は、パスワード変更時に、古いパスワードを聞かれないため)。

Bad Todoの改善

Bad Todo を変更して、可能なら改善していきたいと思います。

wasbook には、SSH でログインできます。ファイル検索したところ、Bad Todo は、/var/www/html/todo で動作しているようです。

URLにセッションIDが埋め込まれないように対策する

まず、URL にセッションID が埋め込まれないように、PHP の設定ファイルで対策してみます。

設定ファイルは、/var/www/html/todo/.user.ini にありました。現状は、以下のようになっています。

1行目は、クッキーを使用する設定で、このままでいいです。

2行目は、セッションID の受け渡しにクッキーだけを使用する(URLに埋め込まない)設定で、ここは On に設定したいところです。

3行目は、クッキーからセッションID が取得できなかった場合に、ページ上の URL にセッションID が埋め込まれる設定です。こちらは Off に設定したいところです。

session.use_cookies=On
session.use_only_cookies=Off
session.use_trans_sid=On

というわけで、2行目と3行目を変更します。変更後は以下です。

session.use_cookies=On
session.use_only_cookies=On
session.use_trans_sid=Off

wasbook を再起動します。

対策が出来たかを確認する

再度、ログインからログアウトまでのシーケンスを確認しました。主な変更内容は赤字で示しています。

Bad Todoのログインからログアウトまで(改善後)
Bad Todoのログインからログアウトまで(改善後)

URL にセッションID が含まれなくなったことが確認できました。

おわりに

今回は、セッション管理について理解を深めました。セッションID が URL に埋め込まれているだけでは成りすますことは難しいですが、他の攻撃方法と合わせて行うことで、セッションID が漏洩してしまうケースがあります。

今回は、Burp Suite のロゴを使わせていただきました。ありがとうございます。

最後になりましたが、エンジニアグループのランキングに参加中です。

気楽にポチッとよろしくお願いいたします🙇

今回は以上です!

最後までお読みいただき、ありがとうございました。