LINE(電話)とSMS認証の話

以前当ブログでは、LINE電話の問題をネタにしてエイプリルフール記事を書きました。
その際LINEをモデルとした『通話アプリL』にて認証SMSをマルウェア経由で盗まれるシナリオを書きました。

『通話アプリL』登録時に藤田口关さんのスマホで認証SMSを受け取り、不正アプリがそのSMS内容を犯人に転送&隠蔽して『通話アプリL』の登録を完了していた。
http://d.hatena.ne.jp/pochi-p/20140401#p1

上記は架空の悪用シナリオですが、実際にそんな事が可能かどうかピンと来ない人もいるでしょう。*1 という訳で…

SMS転送&隠蔽するマルウェアを作ってみたよ!

自分でマルウェアを作って動作確認してみました。
最初このブログに実際に動くプログラムをUpしようかと当初思ってましたが、不正指令電磁的記録の「配布」や、犯罪要件となる「作成」になる恐れがある*2為要点の解説と画面キャプチャだけ掲載する事にしました。


マルウェア作成のポイントはこれだけです。

  • SMS受信のブロードキャストを受けるReceiverを用意。priorityの指定を最高値に。
  • 特定条件下でSMSを隠蔽&転送。他アプリに対してSMSを隠蔽する際はBroadcastReceiver#abortBroadcast()を呼ぶだけ。
  • Receiverで受け取ったSMSを転送する処理するは別途Serviceで実装。(IntentServiceでもOK)
  • 別途コントロールするWEBアプリを用意。

部分的にソースを抜粋すると以下の様な感じです。
AndroidManifest.xmlの抜粋

<receiver android:name="SmsYokodoriReceiver">
    <intent-filter android:priority="2147483647">
        <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver>

SmsYokodoriReceiver.javaの抜粋

Bundle bundle = intent.getExtras();
Object messages[] = (Object[]) bundle.get("pdus");
// 略
Intent serviceIntent = new Intent(context.getApplicationContext(), SmsTensouService.class);
serviceIntent.putExtra("pdus", messages);
context.startService(serviceIntent);
abortBroadcast(); // ブロードキャストを破棄する。「アプリのみんなにはナイショだよ!」

上記のような記述が出来ればOKなので、作成難易度はEASYだと思います。(というかすでにそういうマルウェアって沢山出てます *3
WEBアプリ側もPHPでGET/POSTパラメーター取ってsqlite3読み書きしてhtmlかjsonの出力するだけです。


SMS転送&隠蔽するマルウェアを動かしてみるよ!

まずはマルウェアのインストールです。こちらは電話番号(=SMS宛先)を勝手に使われる被害者側のスマホに入れます。
内容は「電池長持ち!」とかの名前にして小さく注意書きに「個人の感想であり、効果には個人差があります」と書いておけば何人かは騙されるでしょう。*4

マルウェアの使用する権限です。
大手アプリベンダーのお陰でどんな権限も黙認してインストールさせるのが(分からない人にとっての)常識とされてしまってるので、これくらいの権限も気にならないでしょう


インストール後のマルウェア起動画面。


マルウェアは既に裏で外部のサーバーにSIMの国情報、電話番号、そしてLINEのインストール状況を送信してます。(LINEの項目が0になってるのは未使用ユーザーという事です)


まだこの段階ではSMSをSMSを隠蔽&転送しません。管理サーバーにて『攻撃対象に設定』されていて、現在時刻が『攻撃予定時間帯』のみ隠蔽&転送を行います。*5
という訳でさっそく外部サーバーで乗っ取りの為の設定を行います。実行フラグと犯行予定時刻をセットします。


では攻撃予定時間帯にあわせて犯人側のスマホのLINEを初期設定します。「新規登録」をタップ。


マルウェアで支配したスマホの電話番号を入れます。


「同意して番号認証」をタップ。


マルウェア入りの被害者側端末はTwitterアプリを使用中です。


犯人のスマホで「確認」を押すことで、LINE社からSMSが指定の番号に送られます。ポチっとな。


マルウェア入りの端末には特に何も表示されません…。


SMSアプリで受信BOXを見てもLINE社からのものは記録されていません。


しかしSMSは既に犯人の用意したサーバーに転送されています。


これで犯人は他人のスマホの電話番号で、まんまとSMS認証を通過してしまいました!


ここまではDIGNO S(KYL21)に用意されてたau製SMSアプリ「SMS(com.kddi.android.cmail)」を利用した流れです。
せっかくなのでSMS送受信機能が追加されたGoogleハングアウト(旧Google Talk)でどうなるか確認してみましょう。
まずハングアウトの設定でSMSの機能をONにしましょう。


「SMSをONにする」にチェックを付けたらもうOKです。


先程と同じ流れでLINEの番号認証を行うと…。


SMSは今回も取得出来ました。


…がしかし、ハングアウトでは受信通知が表示され、SMSがしっかり端末に記録されています。


何だかハングアウトさんお手柄な感じですね!

この違いは(以前のバージョンは分かりませんが)ハングアウト側でSMS受信用Receiverのpriorityを最高まで設定していたからです。

<receiver
    android:name="com.google.android.apps.babel.sms.SmsReceiver"
    android:permission="android.permission.BROADCAST_SMS"
    android:enabled="false">
    <intent-filter
        android:priority="2147483647">
        <action
            android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver>

au製SMSアプリではそのpriority設定はありませんね。

<receiver
    android:name=".service.SmsPrivilegeReceiver"
    android:permission="android.permission.BROADCAST_SMS">
    <intent-filter>
        <action
            android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver>

ついでにドコモ端末(T-01D ICSアップデート済み)のSMS受信を確認したところ、デフォルトのアプリ「メッセージ(com.android.mms)」はpriority設定が100になっていました。(こちらでもマルウェアによるSMS隠蔽&転送に成功しています)

<receiver
    android:name=".transaction.PrivilegedSmsReceiver"
    android:permission="android.permission.BROADCAST_SMS">
    <intent-filter
        android:priority="100">
        <action
            android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver>

ADKにある仮想マシンもドコモ端末のと同じパッケージ名&同じpriority設定だったような気がします。最近のは全然チェックしてませんが。(つまりうろ覚え)

私も詳細には確認してませんが、「sendOrderedBroadCastが投げられて、同じpriorityのintent-filterがあった場合、到着する順番は保証されない」となっています。どうも実感としては先にインストールされたアプリの方が優先されているみたいですね。とりあえずテストに使ったDIGNO Sではハングアウトが先にインストールされており、SMSの受信順序も「ハングアウト→電池長持ち(マルウェア)」となっていました。その為マルウェア隠蔽工作が失敗になった訳ですね。
マルウェア側の対策としては同じpriorityのアプリが存在しないかチェックするとか、マルウェアの隠蔽機能をOnにした上でSMSを間違いメール的な感じ*6で送ってみて反応が無い(≒ユーザーに認識されてない)場合だけ悪用対象にする等が考えられます。


あ、もちろんLINEのユーザー設定は最後まで行えています。今後使う気は全く無いのでアンインストールしましたが。*7


権限削ったり、(主にプライバシー関連の)設定のデフォルト値がマトモになったりしたら評価が変わる可能性はあるんですけどねぇ…。


テストした各アプリのバージョンは下記の通りです。バージョン情報等の取得にはAPK signature checkerのタブ区切りテキスト出力機能を使いました。*8

PackageLabel PackageName versionName versionCode System
LINE jp.naver.line.android 4.5.0 200 Download
LINE jp.naver.line.android 4.5.3 203 Download
SMS com.kddi.android.cmail 04.10.10 15046 System
ハングアウト com.google.android.talk 2.1.311 (1231142-30) 21311130 Download
メッセージ com.android.mms 4.0.3-f11tri.20140423.160445 15 System


機種やソフトウェアバージョンによって動作は変わってくると思いますが、実使用されてる端末のそれなりの数はSMS隠蔽し放題という前提で良いと思います。
現状のSMS認証の実態は所詮この程度なのです。

SMS認証の是非と今後

作成してみたマルウェアによって、SMS認証を他人のスマホを踏み台にして行える事が分かりました。
ではSMS認証は認証として使い物にならないという事になるのでしょうか?


これについては「それなりに使える」という認識で問題で良いかと思います。上記のマルウェアのお話は、あくまで非合法な方法だからです。


「1人のユーザーが複数アカウントを(簡単に)作らせない」といった程度の利用方法であれば、SMS認証はそれなりに使い物になるでしょう。
しかし「SMS認証さえ使えば(携帯電話使用者の)本人確認が確実に出来る」といった解釈は駄目です。4月時点のLINE電話のなりすまし問題は、そのような誤った解釈から生まれたモノかと思います。


要はSMS認証を「ほどほどに使える」ものとして扱い、「ほどほどに使う」ならOKという話です。
例えるなら「ログイン状態を保持するCookie」のように「ログイン中としてそこそこの機能は提供するけど、ユーザー設定変更や決済処理では必ずパスワード入力を必須とする(=Cookieだけでは許可を与えない)」くらいなら全然問題にはならないでしょう。
問題になるのは「過剰なアクセス権限をSMS認証に与える」場合です。だから4月のLINE電話のように「SMS認証が通ったから、通ったアプリ/アカウントに『その電話番号の使用権』を与える」等は使い方を間違えているんですね。

それはさておき

公式キャリアは是非とも標準SMSアプリの改修してください! 「セキュリティパッチが最新OS用しかなくて旧OSに当てるの難しい!」とかいうレベルでなくて、単にxmlをちょちょいと変更してビルドするだけで出来る事なので。テストも不要だしサクっと終わりますよ。
まあもしかしたら最新機種では既に問題解決されてて、順次旧機種用のアップデートを配信準備されてるのかもしれませんけども。

LINE電話の今後

現在のLINE電話では、SMS認証した電話番号とアプリ稼働中の端末のSIM情報を比較し、不一致であれば電話番号は非通知となりました。
これで上記の悪用シナリオを実行しても、他人の電話番号でLINE電話は使えません。
しかしLINE電話の苦労はこれからが本番です。


今後は「LINE電話プロトコルを話す互換アプリ」の排除を頑張り続けなければいけないのです。
SIMのチェック等はスマホ端末上のLINEアプリが行います。逆に言えば「SIMのチェック等がOKだったふりをする互換アプリ」がLINE電話を行えば、結局他人の電話番号でLINE電話を発信する事は未だに可能なのです。
純正LINEアプリはスマホ上にある為、プログラム本体は常に解析される立場にあります。
プログラム本体をガチガチに難読化(&一部のロジックをサーバーから受信してスクリプト的に実行など)していても、通信内容を解析されて互換アプリを作られる恐れもあります。例えSSLで通信してようが、Netagent社の「Counter SSL Proxy」の様な製品で解析される可能性があります。*9 *10
そういう訳でLINE社の苦労は今後も絶えません。是非ともセキュリティ会社はLINEにバンバン営業かけてみてください。もし(セキュリティ会社の)営業に乗ってこないのであれば、逆にLINEに出入りする技術者をヘッドハンティングすると優秀なセキュリティ技術者がGET出来るかもしれませんね! *11


……まあauソフトバンクが「ドコモと同じように海外の電話番号通知を華麗にスルー」すればLINE電話の番号通知なんてほぼオワコン化しますけどね。:p

*1:約1ヶ月でLINE電話の仕様は変更されましたが、その間に実際にこれが悪用されたかどうかは分かりません。

*2: 参考 http://takagi-hiromitsu.jp/diary/20061022.html

*3: モバイルマルウェアを用い2要素認証のコードを盗む手口に注意 http://www.itmedia.co.jp/enterprise/articles/1404/18/news045.html http://securityblog.jp/news/20140428.html ユーザーを騙してSMSマルウェアをインストールさせるベトナム語のアダルトアプリ http://ascii.jp/elem/000/000/863/863130/ Android.FakeLookout テクニカルノート | シマンテック 日本 http://www.symantec.com/ja/jp/security_response/writeup.jsp?docid=2012-101919-2128-99&tabid=2

*4:だって公式キャリアやセキュリティ会社が(以下略)

*5:時間帯だけでなく、SMSの送信者電話番号や本文の内容で転送&隠蔽する対象を絞る事も可能です。ちなみにLINEの番号認証SMSの送信元番号って一意では無いみたいです。

*6:「山田です。元気ですか! 久しぶりに会いたいです!」とかよくある名前で馬鹿可愛い感じを醸し出せば愛され系キャラの扱いとして普通反応があるのではないでしょうか?

*7:私にとっては「(思考)実験素材として面白いが、実用する気にはなれない」という点で、Winnyと似た位置づけとなってますね。

*8:宣伝してあげたから何かください id:popokann さん

*9:純正アプリにて通信先のSSL証明書をチェックする等の対策も実装出来ますが、そのチェック部分を潰した改造版アプリがあればやはりSSL通信でも解析はされうるかと思います。純正SSLプロトコルを使わずにSQLのUNION→ONION化でCounter SSL Proxyのような製品を回避する事も可能でしょうが、今度はLINE社のサーバー設備に色々制限も出てくるかと思います。

*10:Netagent様、御社サイトを見たところアフィリエイトプログラムの様なものが存在しませんでした。当エントリの影響でもし売上が増えたりしたら何か(以下略)

*11:もしかしたら今後LINE社が「スマホアプリ版n●rotect的なの作りました!」って商売を始める事もあるかも!?