この記事はLINE Advent Calendar 2016の16記事目です。 こんにちは、LINEエンジニアの愛甲健二です。所属は「セキュリティ室」の「Application Security Team」というところで、主にリリース前のGames/Appsの診断を行っている、いわゆる一般的なセキュリティエンジニアです。今日はUnityに関するセキュリティ視点の入門記事を書きたいと思います。 はじめに そもそも「Games/Appsのセキュリティ診断って具体的に何をするのか」という話ですが、基本的にはアプリの解析と、通信プロコトルの解析/診断をメインに行います。 アプリの解析にはいくつかのツールを使うのですが、まず.dexを分析するためにJava Decompilerを使います。有名なものにJD-GUIがあります。ただ、デコンパイルに失敗するメソッドがあったりするので、そのときはsmali(AndroidのJavaVM実装)を直接読みます(smali)。smaliはApktoolを使って.apkを展開するとファイルが作成されます。コード分析においてはJava、ARM、そしてIL(Intermediate Language)が読めればほぼ問題ないので、それぞれJD-GUI、IDA、JustDecompile辺りを使います。これらは後ほど改めて解説します。 またゲームサーバとのHTTPS通信も確認したいため商用のBurp Suiteを使います。MITMについてはこの記事では触れませんが、「[Unity/C#]WWW/HttpWebRequestにおける中間者攻撃の危険性を考慮した通信プログラムまとめ」という記事が対策も含め詳細に解説されています。あとは一般のメモリチートツール/自作ツールを使って簡単にcheckしたり、メモリをdumpして内容を確認する、また私はあまり使いませんが、Xposed、Frida、Cydia Substrateを使い、動的に動作を検証することもあります。 ゲームにおけるセキュリティリスクは大きく2つあり、ひとつは「悪意あるユーザーがゲームプレイを(大幅に)簡略化できるもの」もうひとつは「悪意あるユーザーが他ユーザーに被害を与えられるもの」です。 前者は、他プレイヤーに直接的には被害を与えないが、ゲームプレイを大幅に簡略化できるもので、例えば「アイテムやコインを無限に入手できる」「スタミナを一瞬で回復できる」「botによりゲームプレイを自動化し、プレイしなくても強くなれる」といったものが挙げられます。こちらは、アプリを解析されるといずれ実現される、いわゆる対策不可能問題ですが、最悪サーバ側で各ユーザーのプレイログをベースに異常検知(bot/cheat/abusing検知)を行えばアカウントを凍結できます。 後者は「他ユーザーの持つアイテムを自由に売ることができる」「PlayerIDを差し替えることで他ユーザーの認証を突破できる」「他ユーザーの個人情報を(ゲームプロトコルを通して)入手できる」といった例が挙げられます。ゲームの通信は大抵は独自に暗号化されているため、Black-boxによる診断だと、まずアプリの解析を行い、通信プロトコルを分析した上ではじめて調査ができます。当たり前ですが、こちらの方が脆弱性としてはCriticalです。 最近だとほとんどのゲームはUnityもしくはCocos2d-xで作られているため、これらGame Engineの仕組みを理解し、アプリ(ゲーム)を解析し、その上でサーバ側の脆弱性を調査するのがGame Security診断の業務となります。今回はその中でもUnityに関係する部分に限定して解説したいと思います。 Unity Unityは有名な「Game Engine」のひとつで、最近はAndroid/iOS向けの、いわゆるスマートフォンゲームによく利用されています。マルチプラットフォームに対応しており、Android/iOSはもちろん、その他のスマートフォン、PC、各種ゲーム機用の実行ファイルを出力でき、様々な開発シーンで使われているGame Engineです。今回はAndroid/iOSに限定した(どちらかというとメインはAndroidで、iOSは補足的に説明する感じの)話になりますが、Unityについてセキュリティ視点で書きたいと思います。 またセキュリティ視点なのでプログラミングやゲームの作り方についてはまったく触れません。内容はUnityの仕組みに関する初歩的なもので、主にMono(IL)、IL2CPP辺りに興味がある方を対象としています。 Game Securityはわりとマイナーな技術分野ですが、少しでも興味を持ってもらえたら幸いです。 Mono Monoは.NET Framework互換環境を提供するオープンソースソフトウェアのひとつです。Unityはこれを用いてマルチプラットフォームを実現しています(mono-project)。Unityアプリは、IL(Intermediate Language)と呼ばれる中間言語を実行ファイル内に持ち、実行時に機械語へ変換、実行します。ILにはCIL(Common Intermediate Language)、MSIL(Microsoft Intermediate Language)がありますが、この辺はあまり本筋と関係ないため説明は省きます(Common Language Infrastructure (CLI) Partitions I to VI)。 ゲーム開発者が書いたコードは中間言語であるILとして実行ファイル内に保持されているため、まずはそれを確認します。 UnityのAsset Storeから、Survival ShooterというUnityを学ぶためのチュートリアルゲーム「Survival Shooter tutorial」をUnityへImportします。これをAndroid向けにビルドしてapkファイルを作成します。apkファイルを展開し、\assets\bin\Data\Managed以下を見ると、Assembly-CSharp.dllファイルがあります(iOSだとNightmares.app\Data\Managed以下にあります)。この中にゲームのコードが入っています。 ゲーム本体となる*.dllは.NETのDLLファイルであるため、.NET用のdecompilerでILに戻せます。decompilerには有名なもので、ILSpy、JustDecompileがあります。ILを編集するためにReflexilも必要です。JustDecompileならば、起動後Plugins -> Plugins Managerを選択し、Assembly EditorをダウンロードすればPluginとして組み込まれます。 Assembly-CSharp.dllをJustDecompileで開き、ReflexilでPlayerHealthのTakeDamageメソッドの先頭Instructionをretに変更します。 .method public hidebysig instance void TakeDamage ( int32 amount ) cil managed { IL_0000: ldarg.0 # 変更: ldarg.0 -> ret IL_0001: ldc.i4.1 IL_0002: stfld bool CompleteProject.PlayerHealth::damaged IL_0007: ldarg.0 IL_0008: dup これによりTakeDamageメソッドは何も実行せずにcall元に処理を返します。TakeDamageはPlayerのダメージを計算、反映する処理なので、変更したAssembly-CSharp.dllをapkの中に戻してre-pack/re-signすれば、Playerがダメージを受けない状態でゲームを続けられます。 IL2CPP IL2CPPはその名の通り、ILをCPPに変換するツール(オプション)です。UnityのBuild SettingsからPlayer Settings -> Other Settings -> Configuration -> Scripting Backendで設定できます。IL2CPPに関する詳細はAN INTRODUCTION TO IL2CPP INTERNALSを参照してください。 IL2CPPでビルドしていた場合*.dllはなく、代わりにlibil2cpp.so内にゲームコードが存在します(iOSの場合はMach-O実行ファイルに含まれます)。この場合プロセッサに対応した機械語になるため、解析には有料の逆アセンブラであるIDAがよく使われます。 IL2CPPを使った場合、メソッド名、参照文字列は\assets\bin\Data\Managed\Metadata\global-metadata.dat内に置かれており、libil2cpp.soから動的に読み込まれます。そのためIDAでsoファイルを開いただけではメソッド名、参照文字列は見えません。よって構造体、オフセットをベースにこれらを復元する(名前付け)するIDA Script(unity_metadata_loader)を使います(Demo)。unity_metadata_loaderはオープンソースなので、詳細が知りたい方はコードを読んでみてください。作者の資料も公開されています(Mobile Game Security)。 Androidの場合はlibil2cpp.soを、iOSの場合はMach-O実行ファイルをIDAで開いて上記Scriptを実行します。 さきほどと同様にSurvival Shooter (…)
↧