Hello there, ('ω')ノ
興味深いアカウントの乗っ取りを。
脆弱性:
IDOR
アカウントの乗っ取り
弱い暗号化
パスワードリセットの欠陥
記事:
https://infosecwriteups.com/an-interesting-account-takeover-3a33f42d609d
IDORと弱い暗号化により、完全なアカウントの乗っ取りが発生して。
多くのアカウント乗っ取りについて読んでいると。
トークンを盗むために「X-Forwarded-Host」ヘッダを使用していて。
今回のバグは「パスワードリセット」機能に存在し。
ユーザからの1回の操作なしで完全なアカウントの乗っ取りを可能にして。
これは、IDOR、少しの暗号化、および多くのディレクトリファジングの組合せで。
仮に「example.com」と呼ぶことに。
まず、通常のパスワードリセットがどのように機能するかを確認することに。
1.ユーザは「example.com/php/login_or_password_forgotten」にアクセスし。
プロファイルIDと名前を入力してパスワードのリセットを要求して。
2.プロファイルIDと名前が検証され、「STATE」パラメータが生成されて。
STATE=eJxdkN1OwzAMhd8lDzA1XffT9GpMDE2gdmKTuIxM4paILilJJhBo747DfjRxlfhzYp9zGpHPBduaryiXzqN8wdeVhz1%2BOv8utxEiMsHFTxATwcJfWYEoEpgKppxtTZfIOJGSSG%2FQRmkGVgXBC8H4ZDYq8hHnfMSnZaL0r3cKekwFTUUrH%2B7SnXT0YLsDdP9aRxo1E6y96hrAR4ueVY3Iy1v1i81abk7Ny8loIWkjKQcLe1bVNDrPBHuDIHuEYGwnyUf0oCKrXkWWhFPfo3KdNd%2Bob6k0FiOt34cLJTvy4wD9FZANCVp7DCFtO4vfPS%2Fq7WK5Wze13DWP93WyOM4FgxJn7VgrBS2fTzVqzDLFVY4cs2Le6vSuTMmESL5P0RT8bHrjXWt68j0M8sl1xjZ%2BAyFQSHrlfOdidJbyO%2F4CvKKcYg%3D%3D55840ad4a2f32819aa5da2cf48288290
3.この後、パスワードリセットリンクがユーザ登録メールに送信されて。
https://example.com/php/login_or_password_forgotten?k=789c0dc8610a80200c06d0bbec049bc9d26f870921834192a4ffa2bbd7fbf90a029e810c9adeea98a5753287a844e16555b1016150bfafc3cfbaf94eff2450e494
4.これで、ユーザはリンクをクリックした後にダッシュボードに移動して。
パスワードを変更できて。
「?k」パラメータは少し疑わしいように見えたので。
すぐにコピーしてCyberChefに貼り付け。
暗号化された文字列かどうかを確認すると。
それは暗号化された+圧縮された文字列で。
https://gchq.github.io/CyberChef/
最初にZlibでdeflateされ、次にdeflateされた文字列が16進数を使用して。
暗号化されたので。
トークン: “789c0dc8610a80200c06d0bbec049bc9d26f870921834192a4ffa2bbd7fbf90a029e810c9adeea98a5753287a844e16555b1016150bfafc3cfbaf94eff2450e494a2e640f67ebc89137aade927d25a020ab2535ab4b5c9dc4fd1"
復号化:
“a:2:{s:9:”timestamp”;i:1614104013;s:10:”profile_id”;s:8:”40884692";}”
復号化された文字列は、2つの重要な変数「profile_id」と「timestamp」で。
構成されて。
すぐに2番目のアカウントのトークンを偽造し。
それを使用してパスワードを変更して。
偽造トークン: 789c0dc8510a85201005d0bdcc0ac6f25da6eb62427806034992fe457bb7df93b9f0e9dc28c36be923d726c919107ec0aa40ea0c4a69f775f85976ffcb2746891a610693f44ebe171387
しかし、完全に間違っていてリンクが無効で。
それから、元のトークンと偽造されたトークンの長さが異なることに気付くことに。
元のトークンと偽造されたトークンには32文字の違いがあって。
サーバがその32文字の代わりにジャンク値を受け入れなかったため。
これは大きな問題で。
両方のトークンが同じ値に復号化されていて。
“a:2:{s:9:”timestamp”;i:1614104013;s:10:”profile_id”;s:8:”40884692";}”
Zlib圧縮についてもっと検索し始めて。
そして、BC89137Aを取得した後にAdler-32_Checksum()関数を使用すると。
ZlibにADLER32チェックサムが含まれていることがわかって。
このチェックサムが元のトークンに存在することに注意して。
Zlibでは、このチェックサム以降は。
すべて圧縮ストリームの一部ではないため無視されて。
これが、長さが異なっていても両方のトークンが同じ結果をもたらす理由で。
そのため、現在の課題は32ビット文字列を見つけることで。
トークン関連の作業はすべてクライアント側で行われていたので。
JSファイルで何かを見つけることができて。
JSファイルを調べた後、エンドポイント「/php/user」が見つかって。
ディレクトリをブルートフォース攻撃することにし。
最終的にエンドポイント「https://example.com/php/user/example/」を見つけて。
このエンドポイントには「Transction_Token」という名前の文字列があって。
まとめ:
ページが更新されるたびに「Transaction _Token」が変更されるため。
この攻撃は正確である必要があったので。
全体を自動化するためのPythonスクリプトを作成して。
2番目のアカウントのトークンを生成し、それを使用してパスワードを変更して。
重要なポイント:
トークンがある場合、それがクラックされる可能性があって。
JSファイルにはWebアプリの動作に関する非常に重要な情報が含まれているため。
手動でJSファイルを1回読んで。
Best regards, (^^ゞ