Skip to Content
新しいバージョン 12 を公開しました 🎉
Obfuscator改ざん検出

改ざん検出

改ざん検出は、ソフトウェアアプリケーションの整合性とセキュリティを確保するうえで重要な要素です。.NET においては、Babel Obfuscator が改ざんを検出する強力なツールの 1 つです。Babel の改ざん検出機能を利用すると、開発者はアプリケーションに保護レイヤーを追加し、改ざんの試みに対してカスタムロジックを実行できます。

アセンブリが署名されている場合、.NET Framework はアプリケーションが改ざんされたかどうかをすでに検出できます。Babel Obfuscator はこれをさらに一歩進め、追加の保護手段を提供します。Babel の改ざん検出機能を有効にすると、難読化されたアセンブリは、自身が改ざんされているかどうかを検証できるようになります。改ざんされていた場合は、アプリケーションを終了するか、アセンブリ内のカスタムメソッドを呼び出して、より制御された形で改ざんに対処できます。

モバイルの .NET MAUI ターゲットでは、バージョン 12 以降、デスクトップのイメージハッシュの代わりに、パッケージの整合性チェックによって改ざん検出が提供されます。Android では APK 署名のチェック(Android(MAUI)のパッケージの整合性を参照)、iOS ではバンドル ID とプロビジョニングプロファイルのチェック(iOS(MAUI)のパッケージの整合性を参照)です。デスクトップターゲットでは、このチェックはメモリに読み込まれたイメージのハッシュを計算するため、単一ファイル、トリミング、AOT で公開されたアプリでは機能しません。そうした公開に対して改ざん検出が要求されると、Babel は警告を出力します。

改ざん検出の設定

Babel で改ざん検出を有効にするのは簡単です。コマンドラインで対応するスイッチを追加するか、Babel タスクでプロジェクトファイルに TamperingDetection 属性を含めます。

コマンドライン

babel myapp.exe --tamperingdetection

MSBuild の Babel タスク

<PropertyGroup> <TamperingDetection>true</TamperingDetection> </PropertyGroup> <Babel TamperingDetection="$(TamperingDetection)" />

改ざん検出を有効にすると、難読化されたアセンブリは実行時に改ざんを自動的にチェックします。アセンブリが改ざんされていた場合、アプリケーションは終了します。

デスクトップターゲット(.NET Framework と、CoreCLR で動作する .NET)では、メモリに読み込まれたイメージのハッシュを計算し、難読化時にアセンブリに埋め込まれたハッシュと比較することでチェックします。この手法では、アセンブリがメモリマップされたイメージとして存在している必要があるため、単一ファイル、トリミング、AOT で公開されたアプリケーションには適用されません。そうした公開に対して改ざん検出を要求すると、Babel はチェックが機能しないことを警告します。

Android(MAUI)のパッケージの整合性 Ultimate

前述のメモリ内イメージのハッシュは、Android では使用できません。アプリケーションは MonoVM 上で動作し、マネージドアセンブリは Windows の PE イメージとして読み込まれるのではなく、APK の中にパッケージ化されるためです。バージョン 12 以降、Babel は .NET for Android(MAUI)ターゲット向けに、APK 署名の整合性に基づく同等の保護を提供します。

net*-android アセンブリで改ざん検出を有効にすると、Babel は実行時チェックを挿入します。このチェックは、実行中の APK の署名に使われた証明書を読み取り、難読化時にピン留めした 1 つ以上の信頼された署名者のフィンガープリントと比較します。アプリケーションが別のキーで再署名または再パッケージ化されると(改変したアプリを再配布する典型的な方法です)、フィンガープリントが一致しなくなり、改ざんへの対応が実行されます。つまり、アプリケーションが終了するか、カスタムハンドラーが呼び出されます(改ざん検出時のカスタムアクションを参照)。このチェックは、マネージドイメージではなくオペレーティングシステムのパッケージ署名を調べるため、トリミングや 事前(AOT)コンパイルでも引き続き機能します。

署名証明書のピン留め

Babel は、アセンブリだけからは署名証明書を知ることができません。署名証明書は、後で APK に署名するときに適用されるためです。そのため、想定する証明書の SHA-256 フィンガープリントを --trustedsigner オプションでピン留めします。このオプションは繰り返し指定できるので、複数の証明書(たとえば、アップロードキーと Google Play のアプリ署名キー)をピン留めできます。

babel MyApp.dll --tamperingdetection --trustedsigner 2924C53EE9C511E9F26E0720FD8151064F7621681667D7AB1899E551CDB25104

MSBuild タスクでは次のようにします。

<PropertyGroup> <TamperingDetection>true</TamperingDetection> <TrustedSigner>2924C53EE9C511E9F26E0720FD8151064F7621681667D7AB1899E551CDB25104</TrustedSigner> </PropertyGroup> <Babel TamperingDetection="$(TamperingDetection)" TrustedSigner="$(TrustedSigner)" />

署名証明書の SHA-256 フィンガープリントは、keytool(キーストアから)または apksigner(ビルドして署名した APK から)で取得できます。

keytool -list -v -keystore my-release.keystore -alias my-alias | grep -i SHA256 # or, from a signed APK: apksigner verify --print-certs MyApp.apk | grep -i 'SHA-256'

区切りのコロンは取り除いてください。--trustedsigner に渡す値は、64 文字の 16 進文字列です。

信頼された署名者をピン留めせずに Android ターゲットで改ざん検出を有効にすると、Babel は警告を出力し、パッケージが署名されていることだけを検証する弱いチェックにフォールバックします。実効性のある保護のために、必ずリリース証明書のフィンガープリントを指定して --trustedsigner(TrustedSigner)を渡してください。

iOS(MAUI)のパッケージの整合性 Ultimate

.NET for iOS(MAUI)では、マネージドコードは完全に AOT コンパイルされ、ハッシュを計算できるメモリマップされた PE イメージが存在しないため、デスクトップの手法は使用できません。バージョン 12 以降、Babel は net*-ios ターゲット向けにパッケージの識別情報のチェックを提供します。難読化されたアプリは実行時に、自身のバンドル ID と、プロビジョニングされたビルドから実行している場合は Apple チーム ID を、難読化時にピン留めした値と照合して検証します。どちらかが一致しなくなると(たとえば、アプリが再パッケージ化されたり、別の開発者 ID で再署名されたりした後)、改ざんへの対応が実行されます(アプリケーションが終了するか、カスタムハンドラーが呼び出されます)。このチェックは、プロセスの開始時にモジュール初期化子から実行され、完全な AOT でも機能します。

バンドル ID とチーム ID のピン留め

想定する値を --trustedbundle オプションと --trustedteam オプションでピン留めします。

babel MyApp.dll --tamperingdetection --trustedbundle com.mycompany.myapp --trustedteam ABCDE12345

MSBuild タスクでは次のようにします。

<PropertyGroup> <TamperingDetection>true</TamperingDetection> <TrustedBundle>com.mycompany.myapp</TrustedBundle> <TrustedTeam>ABCDE12345</TrustedTeam> </PropertyGroup> <Babel TamperingDetection="$(TamperingDetection)" TrustedBundle="$(TrustedBundle)" TrustedTeam="$(TrustedTeam)" />
  • --trustedbundle は、アプリの CFBundleIdentifier(Info.plist に記載)です。
  • --trustedteam は、10 文字の Apple チーム ID です(Apple Developer ポータルの「Membership」と、署名証明書の ID 名で確認できます。例:Apple Development: You (ABCDE12345))。

それぞれのピン留めは任意で、個別にチェックされます。バンドル ID、チーム ID、またはその両方をピン留めできます。

チーム ID のチェックは、アプリに埋め込まれたプロビジョニングプロファイル(embedded.mobileprovision)を読み取ります。このプロファイルは、開発用、アドホック、エンタープライズの各ビルドに含まれています。iOS シミュレーターでは利用できず(チェックはスキップされます)、App Store 向けビルドからは取り除かれます(Apple が再署名するため)。そのため、App Store で配布する場合は、バンドル ID のピン留めを使用してください。どちらの値もピン留めせずに iOS ターゲットで改ざん検出を有効にすると、Babel は警告を出力し、整合性チェックを実行しません。

改ざん検出時のカスタムアクション

改ざんの試みへの対応をカスタマイズするには、アセンブリ内に専用のメソッドを定義します。[Obfuscation] 属性を使って「on tampering detected method」機能を適用すると、改ざんイベントを処理するカスタムメソッドを指定できます。これにより、開発者は独自のロジックを実装し、改ざんが検出されたときに適切なアクションを実行できます。たとえば、隠しフラグを設定する、誤った結果を生成する、改ざんの影響を抑えるための特定の対抗策を実行する、といったことができます。デスクトップのイメージチェックにも、Android と iOS のパッケージの整合性チェックにも同じハンドラーが使われるため、1 つのメソッドですべてのターゲットに対応できます。

class CustomTampering { public static bool HasBeenTampered { get; internal set; } [Obfuscation(Feature = "on tampering detected method")] static void OnTamperingDetected() { HasBeenTampered = true; } }

このコードは、改ざん検出を処理する基本的な実装です。

HasBeenTampered が true に設定されている場合、改ざんが検出されたことを意味します。推奨される使い方は、改ざんが検出されたときに特定のアクションやコードを実行することです。

if (CustomTampering.HasBeenTampered) { // Tampering detected: Implement appropriate security measures or handle the // situation accordingly. // Examples include logging the incident, notifying system administrators, // disabling critical functionality or terminating the application. }

まとめると、Babel Obfuscator の改ざん検出機能を利用することで、開発者は .NET アプリケーションのセキュリティを大きく高められます。改ざんの試みを検出して対応できるため、ソフトウェアを不正な変更から守り、データの整合性を維持し、機密情報を保護できます。

Last updated on