ロボットで「私はロボットではありません」を突破してみる
ふと何気なくyoutubeを見ていたら以下の動画にたどり着いた。内容は「recaptcha v2」の 「私はロボットではありません」のセキュリティチェックがロボットにとって最も難しいと説明されていた。 いや、そんなわけあるか!しかもこの動画は"2021/04/13"に公開 …
ここ2年ほど スミッシング詐欺(=SMSフィッシング) のメッセージを何通か受けたことはないだろうか?Amazonとか銀行からSMSのメッセージが届き、そこにURLが書かれていてタップすると詐欺サイトに飛ばされるあれのことだ。まぁ普通に若い人はあんなバカな詐欺に引っかかるとは思えないけど、飛んでくること自体にイラついたりする。なぜ電話番号を知っているのか?って思うかもしれないが、なんでも、犯罪者はランダム(または連番で大量)でSMSを送信しているらしいから、たまたまあなたの携帯に届いてしまっているってことだ。
今回この詐欺師達の手口を分析して、反撃手段を考えてみたい。ジョーダン半分で楽しんでもらいたい。
URLを見てみて。“https:abnrno.com"って。いや、どこかに"amazon"くらい入れろよってくらいやる気なし。でもお年寄りとかはURLなんて見ずにポチるからどうでもいいんだろうね。そしてこのURLをタップした先が以下だ。
amazonのログイン画面やん!これにあなたの本当のamazonのアカウントを入力したら、個人情報が抜き取られるっていう詐欺ね。実際の本物のAmazonのログイン画面は以下で、見た目は少し違っている。
WHOISコマンドで見ても、所有者の情報は全く分からないようだ。分かるのはnamesilo.comというサービスで取得されているドメインってことくらい。
dig打ったら以下の情報が出た。
abnrno.com. 0 IN A 172.67.142.151
このIPを調べたらCloudFlareのサーバー所在地だった。当たり前だけど、このサイトやドメインの所有者の情報は割り出せない。まぁこんなので割り出せるなら警察も動いているだろうね。
次にこのフィッシングサイトのソースの一部を見てみる。
<form method="post" action="../checklogin.php">
<h1 class="common-div">ログイン</h1>
<div class="common-div">
<label>
Eメールまたは携帯電話番号
</label>
<input type="text" name="email" maxlength="128" required="required">
</div>
<div class="common-div" style="margin-top: 25px">
<input type="submit" class="submit-button" value="次へ進む">
</div>
<div class="common-div">
続行することで、 Amazonの
<a href="#">利用規約</a>
および
<a href="#">プライバシー規約</a>
に同意するものとみなされます。
</div>
<div class="common-div">
<a href="#">
お困りですか?
</a>
</div>
</form>
まず、メールアドレスを入力してsubmitすると、“checklogin.php"にpostされることがわかる。そして面白いのが、他のリンクである「利用規約」と「プライバシー規約」はリンク先が設定されていないので、押しても何も起こらないってこと。潔いね~。ログイン以外の操作は眼中になく、とにかくメールを入力してほしいってのが伝わってくる。あと、不思議なのは「Eメールまたは携帯電話番号」って書いているのに、inputタグのtypeはemailなんだよね。もし、本当にログインしようとしたおじいちゃんおばあちゃんが自分の電話番号を入れた場合、その情報を取得できたかもしれないのに。なぜこんな縛りを入れるのだろう。
そして次の画面は以下だった。
この画面のソースの一部はこれ。
<form method="post" action="../checklogin.php">
<h1 class="common-div">ログイン</h1>
<div class="common-div">
[email protected] <a href="index.php">変更</a>
</div>
<div class="common-div">
<label style="float:left">
パスワード
</label>
<a href="#" style="float:right">パスワードを忘れた場合</a>
<input type="password" name="pwd" maxlength="128" required="required">
</div>
<div class="common-div" style="margin-top: 25px">
<input type="submit" class="submit-button" value="ログイン">
</div>
<div class="common-div" style="font-size: 13px!important;">
<input style="width: 13px;height: 13px;float:left" type="checkbox" name="remember" value="1">
ログインしたままにする
<a href="#">詳細</a>
</div>
</form>
パスワードもまったく同じchecklogin.phpにpostする感じ。これに適当なパスワードを入力すると以下の画面に遷移する。
この画面のソースはもう張るまでもない。目的の情報の入力以外のすべてはハリボテでどのリンクも動作しない。てか「更新するまでアカウントにアクセスできません」って部分がかなりチープな見た目になっていた。
さらに次の画面がこれ。
キタコレ。お目当てのカード情報ですわ。ではクレカAPI実装でよく使うダミーカードを入力してみる。すると次の画面に。
これいろいろ調べてみたところ、画面上部に6つのカード会社のアイコンが表示されているくせに、一部のカード会社しか入力を受け付けていないようだった。てかこの先の「WEBサービスID」とか「パスワード」とかってよくわからんから、普通これ以上入力はされないと思う。てことはこの画面に到達している時点ですでにカード情報が取得されているってこと。(前の画面で入力したもの)
なお、前画面のカード情報が送信されるソースコードを発見したので張っておく。ちなみに現在、法律上、サービス事業者が運営するサーバーでカード情報を直接取得するのは違法行為のはず。なのでこの時点で違法行為なのだ。(すでに詐欺行為を働いているのでこれくらいへっちゃらだろうけど)
$.post("../checkcard.php", $("#cardinfo").serialize(),
function(result) {
if(result==="0"){
setTimeout(function() {
$(location).attr("href", "vbv.php")
},
100);
}else if(result==="3"){
setTimeout(function() {
$(location).attr("href", "cardInfo.php?debiterror=1")
},
100);
}else if(result==="2"){
setTimeout(function() {
$(location).attr("href", "cardInfo.php?cvv_error=1")
},
100);
}else{
setTimeout(function() {
$(location).attr("href", "cardInfo.php?error=1")
},
100);
}
})
ここまで調べてみてわかったことが何点かある。そしてこれはこのフィッシングサイトを作成した詐欺師側の弱点となりうる。
ここで一つの仮説を立ててみる。おそらく詐欺師はこのサイトで上記まで入力されて送信してきたカード情報を保存していると思われる。そのあと「セキュア認証」の画面が出てくるが、この認証は詐欺師にとって必要ではない。すでに送信されてきているカード情報が正しい情報である可能性が高いからだ。
とはいえ、本当に使用可能なカード情報かどうかを何らかの方法で確かめなければいけない。もしかしたら手動で入力して確かめているかも知れないし、クレカAPIでオーソリかけて確かめているかもしれない。
もし仮に、こちらから使用不能な同一でないカード情報を大量に送信することができれば、詐欺師さんも困るのではないだろうか?手動確認の場合は当然だが、クレカAPIの場合も大量に失敗オーソリが発生すると足がつきやすくなるのでは?
JSのソースで以下の箇所を発見した。最後trueがリターンされればサーバー上でもバリデーション通過できるようだ。
if (/[^0-9 \-]+/.test(a)) return !1;
var c, d, e = 0, f = 0, g = !1;
if (a = a.replace(/\D/g, ""), a.length < 13 || a.length > 19) return !1;
for (c = a.length - 1; c >= 0; c--) d = a.charAt(c), f = parseInt(d, 10), g && (f *= 2) > 9 && (f -= 9), e += f, g = !g;
return e % 10 === 0
詳しくは考えないでおくが、「6555555555554444」とかで通過する。一般的なカード支払API実装の時のダミー番号だけでなく、単に上記のバリデーションに通過するだけでOKなようだ。また、名前や有効期限、セキュリティコードも妥当性は最低限しか確認していない。つまりロジックで適当なカード情報を作り上げてバリデーションにも簡単に通過できそうである。
次にカード情報送信先エンドポイントに対して調査してみた。
で、いろいろいじってみるとcURLでPOSTできてしまった。以下は念のため一部は適当な値にしている箇所があるが、普通に成功レスポンスが返ってきた。
# cURLの例
curl -X POST -H "accept: */*" -H "accept-encoding: gzip, deflate, br" -H "cache-control: no-cache" -H "content-type: application/x-www-form-urlencoded; charset=UTF-8" -H "cookie: PHPSESSID=id" -H "origin: https://abnrno.com" -H "pragma: no-cache" -H "referer: https://abnrno.com/mobile/view/cardInfo.php" -H "sec-ch-ua: ' Not A;Brand';v='99', 'Chromium';v='96', 'Google Chrome';v='96'" -H "sec-ch-ua-mobile: ?1" -H "sec-ch-ua-platform: 'Android'" -H "sec-fetch-dest: empty" -H "sec-fetch-mode: cors" -H "sec-fetch-site: same-origin" -H "user-agent: Mozilla/5.0 (Linux; Android 10;) Hoge" -H "x-requested-with: XMLHttpRequest" -d "cardname=test&cardnum=1234123412341234&expyear=12&expmonth=2030&cvv=123" https://abnrno.com/mobile/checkcard.php
ちなみにSessionIDについてははじめの画面からの遷移データが必要であったとしても、非常に簡単にロボットで操作可能なサイト設計になっているのでイージーだ。参考
さぁ、でたらめの使用不可カード情報をプログラムで作成して、ボットでプレゼントすることはできそうだ。これは完全に迷惑行為だが、違法なフィッシングサイトのURLを勝手に送ってきたのはおたくの方ですよ。
まぁこの記事はシャレで書いているだけだから、特に何もしないよ。私は国家権力側でもないうえに被害者ですらないからね。ただふと考えてみて思ったけど、インターネット関連の詐欺側がいつも欲しいのは価値のある個人情報のはずだ。そして個人情報の妥当性を担保するのは誰であっても難しい。ということは妥当でない個人情報を大量にプレゼントすれば、膨大な情報の中から本当に騙されて送信してしまった個人情報が埋もれてしまい、それを見つけ出すのにコストがかかるのではないかと思ったわけ。そして情報を探し出すコストが詐欺による利益を上回れば、このようなフィッシング詐欺はなくなるのではないか。(知らんけど)
ふと何気なくyoutubeを見ていたら以下の動画にたどり着いた。内容は「recaptcha v2」の 「私はロボットではありません」のセキュリティチェックがロボットにとって最も難しいと説明されていた。 いや、そんなわけあるか!しかもこの動画は"2021/04/13"に公開 …
WPへの攻撃方法について書きましたが、WPサイトを構築する上での最低限のセキュリティ対策をおこなっていれば、前回記事のようなことにはならない。そこで最低限の対策を紹介。 ログイン情報は複雑に パスワードは覚えるものではない とにかくログインパスワードを複雑にしておけば、クラックするのが各段に難し …