ガイド:コード難読化リバースエンジニアリング
公開: 2021-11-17コードの難読化の図は、アプリケーションのハッキングを防ぐための最も一般的なアプリケーションセキュリティアプローチの1つです。 これは、世界中のセキュリティスペシャリストによって最も頻繁に提案されているAppSecの取り組みの1つであり、アプリケーションの最小限のセキュリティ要件を処理することがよくあります。 この戦略は、ハッキングの試みに対する主要な防御メカニズムとして頻繁に使用され、コードインジェクション、リバースエンジニアリング、顧客やアプリケーションユーザーの個人情報の改ざんなどの一般的な脅威から保護します。
コードの難読化?
実行可能ファイルをわかりにくく、理解しにくく、実用的でなくなったように難読化する方法は、コードの難読化として知られています。 ソースコードは、実行はもちろんのこと、第三者が理解しにくく、把握しにくい程度に難読化されています。 エンドユーザーのUIまたはコードの意図された出力は、あいまいさの影響を受けません。 これは、ソフトウェアの実行可能コードにアクセスできる潜在的なハッカーがコードを役に立たないようにするための予防措置にすぎません。
コードを難読化する必要があるのはなぜですか?
コードの難読化は、個人的な利益のためのハッキング可能性の点で重大な欠点があるオープンソースソフトウェアにとって特に重要です。 開発者は、プログラムのリバースエンジニアリングを困難にすることで、製品の知的財産がセキュリティリスク、不正アクセス、およびアプリケーションの欠陥の発見から保護されることを保証します。
使用される不明瞭な手法の種類に関係なく、このアプローチは危険なソースコードを制限し、さまざまなレベルのプログラムセキュリティを保証します。 時間、コスト、およびリソースの理由はすべて、逆コンパイルされたコードが判読不能になるため、コードが難読化されたときにコードを放棄することを支持します。
コード難読化の手法
難読化はさまざまなレベルで機能します。セマンティック/語彙コード構造レベルまたはデータ構造/制御フローレベルで実装できます。 難読化の戦略も、コードのアクションによって異なります。 本質的に、セキュリティチームは、開発チームと協力して、コードで使用する難読化の種類を決定します。
難読化の名前を変更する必要があります。
このアプローチでは、変数に紛らわしい名前を付ける必要があるため、変数を利用する実際の目的は巧妙に隠されています。 メソッドと変数の名前がさまざまな表記法と数値に変更されているため、逆コンパイラーは制御フローを理解するのに苦労しています。 この難読化方法は、Java、.NET、およびAndroidプラットフォームのアプリケーションコードを偽装するために一般的に使用されます。 これは、アプリケーションの保護レイヤーを提供するためにソースコードを直接対象としているため、レイアウトの難読化として分類されます。
データの難読化
この方法は、コードで使用されるデータ構造に焦点を合わせているため、ハッカーがプログラムの真の目標にアクセスすることはできません。 これには、ソフトウェアがデータをメモリに保存する方法と、そのデータを処理して最終的な結果を生成する方法を変更する必要がある場合があります。 この手順は、さまざまな方法で実行できます。
1.集約の難読化
この結果、ソフトウェアへのデータの保存方法が変わります。 たとえば、配列は複数のサブ配列に分割され、プログラム全体で参照できる場合があります。
2.データストレージの難読化
これは、データがメモリに格納される方法に影響を与えます。 たとえば、開発者は、ローカル変数ストレージとグローバル変数ストレージをシャッフルして、変数の動作の本質をわかりにくくすることができます。
3.オンデマンドで難読化を取得する
このアプローチでは、プログラム/コードスニペットの機能を変更せずにデータの順序を変更します。 開発者は、変数参照のインスタンスごとに呼び出される個別のモジュールを作成することでこれを実現します。
4.文字列の暗号化
この手法では、読み取り可能なすべての文字列が暗号化されるため、コードが判読できなくなります。 ソフトウェアを実行するときは、実行時に復号化する必要があります。
5.制御/コードフローの難読化
プログラムの目標を設定するには、コードベースのある部分から別の部分に制御を送信する方法が重要です。 このフローをわかりにくくすることは、ゲームのフローを混乱させる最も有益な方法であることがよくあります。 この難読化戦略は、コードが特定のパスをたどる方法と理由をハッカーが理解するのを困難にすることで、ハッカーを寄せ付けません。
ランダムで予期しないステートメント、および実行されることのない不要なcase-switchステートメント(デッドコード)を含めることは、この難読化戦略を実現するための最も一般的な方法の1つです。 これらのアサーションには、標的となるハッカーを困惑させる以外の機能はありません。 条件付きプログラム指向の場合、プログラム実行ステートメントのシーケンスのこの変更は非常に役立ちます。

難読化がデバッグされています。
デバッグ情報は、ソースコードを逆コンパイルおよび再コンパイルすることにより、プログラムフローと欠陥に関する重要な情報を判別するのに役立つことがよくあります。 IDや行番号を変更したり、デバッグデータへのアクセスを完全にオフにしたりして、このような識別データを非表示にすることが重要です。
難読化に対処する必要があります。
特にCやC++のようなメモリセーフでない言語では、メモリプログラミングの間違いが攻撃で広まっています。 セキュリティ上の欠陥は、制御されていないアレイアクセスなどのエラーによって引き起こされることがよくあります。 コードの仮想アドレスとプログラムのデータは、変換されたコードが実行されるたびにランダム化されるため、アドレスの難読化アプローチではリバースエンジニアリングが困難になります。 その結果、メモリエラー攻撃の大部分は非決定論的であり、成功する可能性は非常に低くなります。
パーソナライズされたコーディング
開発者はこのアプローチを使用してカスタムアルゴリズムで文字列を暗号化し、元のコードを復元するためのデコーダー関数を提供します。
実行時に渡される引数
実行時にパラメータを期待するようにプログラムを変更することが可能です。 変数をデコードするには、ユーザーはコードと復号化キーの両方を持っている必要があります。
さまざまなセキュリティの脅威からアプリケーションを保護するための階層化された防御方法を開発するために、セキュリティチームは同時に複数の技術を展開することを選択する場合があります。
結論
要約すると、誤った方向性だけでは、高度なセキュリティ上の懸念に対処するには効果がありません。 aiソフトウェアの可用性とハッカーのスキルのために、コードの難読化を解除することはより困難ですが、それは不可能ではありません。 結果として、暗号化はすべてのソフトウェアセキュリティの懸念に対する万能薬ではありません。
開発チームは、セキュリティの必要性、プログラムの性質、およびパフォーマンスベンチマークに応じて、さまざまなコード難読化アプローチを使用して、信頼できない環境でコードを保護する場合があります。 これらは、各アプローチの長所と短所を考慮しながら実行する必要があります。 暗号化、RASP、データ保持規制などの他のAppSecイニシアチブは、この戦略によってサポートされる必要があります。 AppSealingのようなRASPソリューションと組み合わせると、今日のセキュリティ上の懸念に対する強力な解毒剤になります。