NHN Cloud Meetup 編集部
TOAST AppGuardとAndroidコードのセキュリティ強化に向けた効果的な改善方法
2020.01.20
1,471
セキュリティ開発ライフサイクル(Security Development Lifecycle)の段階別の保護対策について、活用できる技術を紹介します。
コード改ざんの脅威
ご存知のように、コードのセキュリティは、Androidの開発作業で非常に重要な要素です。しかし、アプリ開発の初期段階から、コードのセキュリティに対して、あまり考慮されていないのも事実です。今回は、このような部分を効果的に向上できる様々な方法を紹介したいと思います。
Androidのモバイルアプリは、次のようなソースコードの露出と改ざんのセキュリティ脅威を保有しています。
1.逆コンパイル(Decompile)
コンパイルされたAndroidのコード(DEX)は、単純な逆コンパイルツール(Apktool、JADXなど)から原本と似たJavaのソースコード形式に簡単に戻すことができます。逆コンパイルされたソースコードを利用して、プログラムロジックの検索や分析が可能であり、重要なデータを容易に取得することができます。
例えば、認証に使用されたキー値や露出してはいけないバックグラウンドの管理サーバーのアドレスなど、重要なデータが流出してしまう危険性があります。
2.デバッグ(Debugging)
GDB、IDA、JDBなどの動的デバッグツールを利用して、実行時にアプリデータとロジックを動的に抽出し、修正することができます。重要関数のパラメータとリターン値を取得して、ログ情報をもとにハードコーディングされた対称暗号化や、CBCモードの固定IVを取得して、暗号化された重要なデータ(認証、決済、個人情報など)の復号化が可能です。
3.リパッケージ(Repackaging)
APKファイルは、逆コンパイルからアプリ内の重要ロジックを修正し、改ざんされたAPKファイルとしてリパッケージや配布が簡単に行えます。セキュリティネットワーク通信(HTTPS、SSH)でサーバーと暗号化通信をしても、元のコードを変更して容易に解読することができます。NHNでも自社サービスのAndroidアプリに不正広告のSDKが挿入され、改ざんされたアプリがマーケットに流通してしまった事例があります。
セキュリティ開発ライフサイクル(Security Development Lifecycle)
コードのセキュリティを効果的に向上させるには、下図のようにアプリの開発ライフサイクルのすべての過程において、様々な方法でセキュリティリスクを削減し、ソフトウェア的なセキュリティリスクを最小限に抑える必要があります。また、上記のようなコード改ざんの脅威に備えるために、TOAST AppGuardをアプリビルド時に自動適用できるように、開発プロセスのリリース段階に統合することが必要です。
1.開発段階(Development)
開発者は、Androidアプリの開発段階で、次のようなセキュリティ項目を理解し、それらの適用方法についても検討する必要があります。
■セキュリティキーボード
重要な入力には、不正コードによるキーロギングを防止するため、セキュリティキーボードを有効にする必要があります。
■暗号復号化
ハードコーディングされたキー、ローカルセグメンテーション暗号化の保存を避け、ホワイトボックス暗号方式の使用を検討します。
■通信セキュリティ
中間者攻撃(man-in-the-middle attack)、証明書の脆弱性診断(weak check)などによって、通信プロトコル解析後にクラッキングされるため、通信データの暗号化とチェックサム等の認証の有効性チェックが必要です。
■データ検証
署名の確認、検証済JNI(Java Native Interface)の読み込み、ネットワークの段階でAPKファイルが改ざんされていないか、などのチェックが必要です。
■ログ漏洩防止
デバッグログを残さないこと、またログメッセージはJava難読化の適用を検討する必要があります。
■機密データ流出
プレーンテキストで機密データを保存することを避け、ローカルストレージデバイス(SharedPreferences、SQLiteなど)の暗号化を考慮する必要があります。
■重要ロジックの開発
重要ロジックは、JNI層での実装を推奨します。コード難読化と組み合わせると、分析の難易度を向上させることができます。
開発やテスト段階では、セキュリティリスクにかかるコストが低く、配布/運用段階ではセキュリティリスクに関するコストが高いため、開発者は開発段階からコードのセキュリティ性を確保する重要性を認識しましょう。
2.テスト段階(Test)
テスト段階では、ソフトウェアの欠陥だけでなく、自動化された脆弱性診断ツールを活用して、セキュリティホールについても継続的にコードの修正と補完を行う必要があります。
脆弱性診断(Vulnerability Scan)
脆弱性診断におけるブラックボックステストは一般的な方法の1つで、既存のテストプロセスでも簡単に統合できます。自動化された脆弱性診断ツールを使って、脆弱性の詳細情報、脆弱なコードライン、危険水準、修正提案などを取得することができます。
Android APKのみアップロードすれば自動的に脆弱性診断をしてくれるモバイルアプリのセキュリティテストフレームワーク「Mobile Security Framework」は優れたツールと言えるでしょう。
3.リリース段階(Release)
Androidアプリは、配布前にコードの強化、難読化、その他の技術を使用してAPKファイル内のコードが解読されにくいように強化しなければなりません。攻撃しきい値とリバースエンジニアリングにかける時間を増やすことが必要です。コード強化の技術としては、代表的なものに、ソースコードのパッキング(DEX暗号化、SO強化)と難読化(DEX、C/C++)があります。
コードパッキング
1. DEX暗号化
DEXファイルにはコンパイルされたコードが入っています。ハッカーはリバースエンジニアリングを使ってDEXファイルからJARファイル、またはJavaクラスファイルを作成することができるため、当該DEXファイルの暗号化を行うことで原本コードを保護します。
2. SO強化
SOファイルは共有オブジェクトライブラリ(Shared Objects library)の略で、C/C++の言語を用いて開発された動的ライブラリです。SO強化はELFファイルの内部コード(C.C++)にカスタムパッキング(実行圧縮+暗号化)を行います。容易に分析可能なシンボル情報を難読化することで、リバースエンジニアリングによってコードが分析されないように防御します。
コード難読化
1. DEX難読化
DEX難読化は、ソースコード内の文字列を暗号化し、ネイティブ(Native)で復号化する必要があります。また、ProGuardのようなツールを活用して、変数、メソッド、クラスの名前を識別しづらくしなければなりません。DexGuardやARXANなどの商用ソリューションは、関数の呼び出しを再構築して、攻撃者に対して分析を妨害し、分析所要時間や分析難易度の増加させ、パターン検出や類似比較を迂回させるために主に使用されます。
2. C/C++コード難読化
C/C++の難読化はObfuscator-LLVMツールを使用して効率的に適用できます。
このツールは、主に次のような機能を備えています。
■制御フローの偽造とマージ : if、while、for、doのような制御文をソースコードの機能を変更することなく、条件分岐(switch)選択文に変換する
■インライン代替 : 複数の場所から呼び出される主要な関数に代わって、実際の関数の本体に置き換える
■文字列の暗号化 : 文字列定数を暗号化して、実行時にその文字列をネイティブで復号化する
■表現変換 : +、&、| 演算子を同じ結果を返す関数に置き換える
4.運用段階(Operation)
運用段階では、改ざんアプリ、ハッキングツールが流通するブラックマーケットや、ハッキング関連のコミュニティを監視する必要があります。ハッキングの兆候を事前に検知して攻撃パターンを把握し、収集したセキュリティログなどを活用するなどして、様々な方法で対応する必要があります。
要約
以下のように、アプリサービス開発時にセキュアコーディングの要件を検討し、配布前の段階での脆弱性診断、コード強化、ネットワーク通信層の整合性チェックなどを考慮し、事前にさらされる可能性があるセキュリティの脆弱性を最小限に抑えましょう。またリリース段階では、アプリ保護の技術を適用してコードを保護し、安全なモバイルサービスが提供できるように対応しましょう。
セキュリティ開発ライフサイクル | 開発者 | セキュリティサポート |
---|---|---|
開発 | セキュアコーディングの適用 | 開発段階のセキュリティレビュー セキュリティ開発ガイド |
テスト | コードの脆弱性診断(選択) コードの脆弱性とセキュリティ脅威の除去 |
コードの脆弱性診断 セキュリティ脆弱性診断 |
リリース | コードを強化するパッキングおよび難読化(AppGuard)の適用 | コード保護技術の提供、ガイド |
運営 | ログデータの分析 | 著作権侵害チャネルの監視 ログデータの分析 |