Androidアプリの普及で解読・改ざんの懸念が浮上
- - PR -
Androidの普及に伴い、Javaソースコード難読化ツールへの注目が高まっている。Androidアプリをリバースエンジニアリングの悪用から守るためである。
Androidアプリは、Java言語によるソースコードを、実行環境であるDalvik仮想マシン用の中間コードに変換して配布する。
このような中間コードと仮想マシンを用いる実行環境には強力なメリットがある一方、ネイティブコード(機械語)に比べてリバースエンジニアリングが非常に容易であるという特性がある。中間コードからソースコードを復元する「逆コンパイラ(デコンパイラ)」と呼ぶツールがあるためだ。
- 究極の問題解析ツール、逆コンパイラJD-Eclipseとは (1/2) - @IT
- @IT:Java TIPS -- Eclipseで逆コンパイルを行う
- 無償の逆コンパイラ「ILSpy」を利用するには?[C#] − @IT
リバースエンジニアリングそれ自体は有用な技術だ。例えば、「AOP(アスペクト指向プログラミング)」や「DI(Dependency Injection、依存性注入)」といった新しいプログラミング技術は、中間コードを巧みに操作することで実現している。
しかし、中間コードは解読と操作が可能であるという性質には、悪用されるリスクが伴う。このリスクを大幅に減らしてくれるのが難読化ツールだ。
本稿では、難読化ツールとしてよく知られている「ProGuard」と、高機能な「DashO」を取り上げる。
ProGuardは、AndroidのSDKのビルドシステムに組み込まれており、誰でも無償で利用可能だ(参考:ProGuardの紹介記事、その1とその2)。すでにProGuardを利用中の開発者も数多い。
一方、「DashO」(「ダッシュオー」と読む)は機能が多い商用製品である。米PreEmptive Solutions社が開発し、エージーテックが国内販売する。PreEmptive社は.NET向け難読化ツール「Dotfuscator」を製品化しているが、この製品はVisual Studioに同梱されて広く使われているという実績を持つ。一方、Java向けの難読化ツールDashOも古くからある製品だが「ここ2年ほど」(エージーテック)で注目が高まっているという。Androidが台頭してきたためだ。
「中間コード+仮想マシン」のメリットとデメリット
公平を期すために、中間コードを仮想マシン上で実行するプログラム処理系にはどのようなメリットとデメリットがあるのか記しておく必要があるだろう。
ソフトウェアの歴史を俯瞰すれば、中間コードを用いる処理系は、大きな流れとして観測できる。古くは「Smalltalk-80」「UCSD Pascal」でも用いられていた。1990年代に登場したJavaテクノロジと.NETテクノロジでも採用されている。これらの処理系は、開発者が記述したソースコードを中間コードにコンパイルし、仮想マシン上で実行する。
このような中間コードによる実行環境には、2つの重要な特徴がある。
- ネイティブコードよりも実行ファイルのサイズが小さくなる
- 実行中のプログラムが異常な状態になっても、他のプログラムに悪影響を及ぼす可能性を削減できる(これは、アプリのバグによるOSのクラッシュや、悪意のあるプログラムの登場を防ぐ意味からも、重要だ)
サイズが小さくなり、しかもセキュリティ上も有利──これはインターネット上で配布するプログラムの実行形式として優れた特質といえる。JavaテクノロジやAndroid、そして.NETテクノロジで「中間コード+仮想マシン」による実行形式が取り入れられてるのは、このようなメリットがあるためだ。
一方、中間コードには弱点もある。
- 仮想マシン上の実行であるため、ネイティブコードに比べ処理性能が不利
- リバースエンジニアリングが、ネイティブコードに比べ容易
弱点には対処法がある。1の性能問題を解決する「JIT(Just-in-Time)」コンパイラには長い歴史があり、多大な開発投資が注ぎ込まれてきた。今のJavaやC#で処理性能が問題となる場合はめったに聞かない。Androidでは、Android OS 2.2以降でJITコンパイラを導入し、計算処理が多いアプリの処理性能が大きく改善された。
そして2の「リバースエンジニアリングの容易さ」を解決する道具建てが、今回取り上げる難読化ツールなのである。
Androidの普及で再び注目を浴びる難読化ツール
興味深いことに、Javaがエンタープライズ分野で広く使われるようになってから約10年という年月が経っているのにもかかわらず、Javaの難読化ツールはこれまであまり注目されていなかった。エンタープライズ分野でのJavaは、主にサーバサイドで使われていた。マシンルームの奥深く、ユーザーから直接アクセスできないアプリケーションサーバ上で実行するプログラムに対してリバースエンジニアリング悪用の可能性を考慮するユーザーは、ほとんどいなかったということだろう。
歴史をさかのぼれば、Java登場の初期段階(1995〜1997年ごろ)にはJavaアプレットの形態で本格的なOffice系アプリを作る試みもあった。この時期には、難読化ツールの必要性が議論されたこともある。
そして、ここ2年で急激に普及したAndroidアプリは、Android Marketなどで世界中の不特定多数のユーザーに公開されるという性格を持っている。スマートフォン製品にプリインストールするAndroidアプリもある。もし、端末プリインストールのアプリが、リバースエンジニアリングの悪用により改ざんされて配布されるような事態が起これば、メーカーの責任が問われるだろう。このような事情から、Javaプログラムのリバースエンジニアリング悪用の可能性に再び注目が集まるようになったのだ。
難読化ツールの目的は、リバースエンジニアリングの難易度を上げることで、「カジュアルハックを防ぐ」(エージーテック プロダクト&ブランズProduct Manager岩沢宏美氏)ことにある。一般論として、どのようなセキュリティ技術であっても、スキルが高いプログラマが、全力であるターゲットに攻撃を試みる場合には「絶対に安全」といい切ることはできない。
とはいえ、面白半分に企業のブランド価値を毀損するようなリバースエンジニアリングの悪用の可能性を大幅に減らすことができる。「悪用の難易度を大幅に高める」ことが、難読化ツールの価値なのである。鍵がかかっていないドアより、鍵がかかったドアの方が安全であることは、いうまでもない。
リバースエンジニアリング悪用のリスクを7つに分類
PreEmptive Solutions社のSebastian Holst氏の論文「Javaと.NET固有のセキュリティリスクの評価と管理」(Assessing and Managing Security Risks Unique to Java and .NET, ISSA Journal, Nov. 2009.)では、リバースエンジニアリングの悪用に基づくリスクを次のように分類している。
読んでいると恐ろしくなってくるかもしれないが、あくまでも悪用の可能性を列挙した記述であることに注意したい。
- 知的財産の侵害
ソースコードを解読し、そこに含まれる知的財産にアクセスされる可能性がある - 脆弱性の調査
ソースコードを解析することで、脆弱性をより発見しやすくなり、攻撃者がより強力な攻撃を仕掛ける可能性が高まる - ソーシャルエンジニアリング
リバースエンジニアリングにより利用者固有の個人情報を取得し(例えば、オンラインバンキングのアプリのバグを解析してログイン情報など重要な情報を盗み出し)、その情報を基に利用者をだまして別の犯罪行為を行う可能性がある - 著作権の侵害
例えば有料アプリのコードを解析して、不正に利用するなどの可能性がある - サービスレベル違反
- マルウェア
「めったにない」が、マルウェアによる攻撃の材料となる可能性がある - データ損失やプライバシー侵害
アプリのコードを解析することで、意図しない個人情報へのアクセスの可能性が高まる
リバースエンジニアリングを妨害する9つの手段
一方、リバースエンジニアリングを妨害するには、次のような手段がある。
- 名前の難読化
クラス名、メソッド名、変数名などソースコード中の「名前」を人間にとって読みにくいものに変換する。副次的に、コードのサイズを減らす効果もある。副作用として、リフレクションなどの機能が無効になってしまうため、そのような場合はコードを修正する必要がある
- 制御フローの難読化
意味がないループやGoto文を挿入するなどして、ソースコードをわざと難解にする。CPUサイクルが若干増加(=パフォーマンスが低下する)する副作用がある - 文字列暗号化による難読化
ログインプロンプト、SQLクエリなど、重要な情報を含む文字列を暗号化する。パフォーマンスが低下する副作用がある - 事前コンパイル
「AOT(Ahead-of-Time)コンパイラ」と呼ぶ技術を用いて中間コードではなくネイティブコードの形式で配布。副作用は、プラットフォーム独立ではなくなること - パッキング
中間コードを暗号化および圧縮 - セキュアな仮想マシンを利用
- コード署名
- 改ざん防御
コードにモジュールを埋め込み、アプリ実行時にパッケージ全体を見て、オリジナルの署名と相違がある場合には、ハッキングされた可能性があることを警告するメッセージを表示 - 使用状況のモニタリング
認証されないアプリ利用やインストールを検出
ツールの必要性・使い道を考える
難読化ツールProGuardが提供する機能は1の「名前の難読化」の範囲にフォーカスしている。一方、DashOは1に加えて、2「制御フローの難読化」、3「文字列暗号化による難読化」、7「コード署名」(Androidのビルドプロセスに署名に必要な情報を渡す。DashO自体はコードの署名を行わない)、8「改ざん防御」の機能を提供する。9「使用状況のモニタリング」の機能は、同社の別の製品「Runtime Intelligence Service」が提供している。
開発者は、開発サイクルの一部に難読化の工程を含める必要がある。また、上記2の「制御フローの難読化」などのテクニックは、性能やタイミングに厳しいアプリ(例えばゲームアプリ)に適用する場合には、テスト工程で性能を評価し、制御フロー難読化の程度などを調整する必要がある。
無償で利用できるProGuardでも、「カジュアルハック」を防ぐ効果は期待できる。個人開発者が無償で提供するアプリなどでは、ProGuardが提供する難読化機能で事足りる場合もあるだろう。その一方で、メーカー製端末プリインストールだったり、企業の「看板」となるアプリの場合には、より高度なリバースエンジニア対策が求められる場合も出てくるだろう。
商用製品のDashOは前述したように、より範囲が広い機能群を備える。このツールを指名して開発会社に使わせる発注主もいるという。一方、DashOは定価で最小構成79万円という価格設定なので、適用を見送る場合もあるという。有償ツールを適用するか否かは、開発プロジェクトの規模と、悪用された場合のインパクトを元に、個別に判断しているのが実情だろう。どのようなツールを選ぶにせよ、Androidが普及するほど、これら難読化ツールの出番も増えてきそうだ。
■ @IT関連記事
Androidアプリ開発テスト入門 日本Androidの会テスト部が、いままで培ってきたAndroidアプリ開発におけるのテストのノウハウを、実際のテストコード例とともに紹介していきます 「Smart & Social」フォーラム |
Android開発で泣かないための「テスト」の重要性 第1回Androidテスト祭りレポート その自由度の高さや多様性ゆえに、さまざまな課題を抱える、Androidアプリ開発の“テスト”に焦点を当てたイベントの模様を紹介します 「Smart & Social」フォーラム 2011/9/5 |
売れるスマホアプリを目指せ! テスト達人への道 安藤幸央のランダウン(56) iPhone/iPad・Androidアプリ開発にが重要な“使い心地”。しっかりとしたテストを経た高品質なアプリを作るためのポイントをまとめて紹介しよう 「Java Solution」フォーラム 2011/4/27 |
イチから始める! Androidセキュリティ Androidに潜む危険はマルウェアだけはありません。実はアプリの作り方にも注意が必要です。クウと一緒に学びましょう 「Security&Trust」フォーラム
|
Androidセキュリティの今、これから 爆発的な勢いで普及し始めたAndroid端末は、大きなポテンシャルを秘める一方で、セキュリティという課題にも直面しています。この連載では Androidアプリ開発者や一般ユーザー、ビジネスユーザーと、あらゆるユーザーを対象に、Androidのセキュリティについて解説していきます 「Security&Trust」フォーラム
|
Smart&Social フォーラム トップページへ |
- 夏休みの自由研究にマイコンボードで「電子サイコロ」を作ったり、音楽プログラミングをしたりしてみよう (2017/7/24)
子ども向け電子工作&プログラミング用マイコンボード「chibi:bit」の基本的な使い方を紹介する企画。夏休みの自由研究に「電子サイコロ」を作ったり、音楽プログラミングをしたりしてみよう - 子ども向け電子工作&プログラミング用マイコンボード「chibi:bit」の基本的な使い方 (2017/7/20)
子ども向け電子工作&プログラミング用マイコンボード「chibi:bit」の基本的な使い方を紹介する。夏休みの子どもの自由研究などに役立てつつ、プログラミングを始めるきっかけにしてみてはいかがだろうか - 3DゲームのAIをiOSのSceneKitとGameplayKitで作る基本 (2017/7/10)
3Dゲーム用のフレームワークSceneKitを使った簡単なアプリ制作を通して、3Dゲーム用の人工知能(AI)について学ぶ - UnityアプリをWebGL、UWP、Android、iOS用としてビルドしてみた (2017/6/27)
アプリをWebで実行できるように書き出す方法やWindows上でUWP、Android、iOS用などにビルドする方法について解説する【Windows 10、Unity 5.6に対応】
|
|