web-dev-qa-db-ja.com

変数をNULLまたは0または-1に初期化することは、セキュリティの観点から悪い習慣ですか?

リバースエンジニアリングに対するアプリケーションの防御について少し学習しようとしています。ある記事で、変数をNULLまたは0または-1に初期化することは、アプリケーションで一般的なパスワードを使用するのと同じくらい安全(対RE)であると読みました。つまり、RNGを使用してランダムデータを生成し、それを最初に新しい宣言された変数に「格納」する必要があるということです。他のアプローチは、XOR演算子を使用することです。残念ながら、私はこの記事をブックマークするのを忘れており、それを全部読む時間はありませんでした。

問題は-変数を初期化するときにランダムデータやXOR演算子を使用すると、リバースエンジニアリングに対するアプリケーションの防御に追加されるというのは本当でしょうか。

編集:私の質問は十分に明確ではなかったようです。私が求めているのはどちらが優れているか(またはまったく違いがない)です

  • _int variable = 0;_

または

  • int variable = random(seed);

質問のために、random(seed)が実際に真のランダム性であると仮定しましょう。

XOR演算子について。私が言ったように私は記事を部分的に読んだだけです。私は2つの段落を見ました。1つは「乱数ジェネレータの使用」のような名前で、もう1つは「XORを使用した変数の初期化」です。 XORはどのように使用されているのかは不明であり、誰かがそれについてもっと知っている場合に注意を引くためにここで言及するだけです。

8
StupidOne

あなたは2つのセキュリティ対策方針を混合しているようです:リバースエンジニアリングに対するコードの保護と攻撃に対するアプリケーションの保護。これらの目的はしばしば矛盾します。リバースエンジニアリングに対する保護はコードの複雑さを増し、特定の状況でコードが予期しない動作をするため、コードが攻撃に対して脆弱になる可能性が高くなります。

適例:変数をランダムな値に初期化する場合、メモリブロックが初期化されていないことをリバースエンジニアリングするときを理解するのはより困難です。一方、RNGの呼び出しをトレースすると、変数が初期化されている場所が表示されます。したがって、変数をランダムな値に初期化するメリットはありません。

セキュリティに関しては、変数をランダムな値に初期化するのはよくありません。ゼロははるかに安全です。変数が初期化されずに使用されていることが判明した場合、ゼロの方が害が少ないことがよくあります。値が0であると想定されていないかどうかを再確認し、それがポインターである場合、クリーンクラッシュにつながります。初めて逆参照されます。逆に、ランダムな値は、予期しない動作、潜在的なセキュリティホールにつながります。

リバースエンジニアリングからの保護は非常にコストがかかります(デバッグはプログラミングよりも難しく、難読化では2倍になるため)、価値があることは非常にまれです。難読化に労力を費やす必要があると判断した場合は、おそらくその難しさを過小評価しています。とにかく難読化することを選択した場合、変数をランダムな値に初期化することは、静的または動的な分析でランダムな値が使用されていないことが簡単にわかるため、あまり有用な手法ではありません。難読化では、計算を実行するためにランダムな値を使用する必要がありますが、最終的な結果は値に依存しません。

securityの観点からは、変数をNULL、0、またはその他の安全で再現可能な値に初期化することをお勧めします。

多くのプログラミング言語では、ローカル変数の初期化が強制されるか、エンジンが初期化されていないデータの読み取りをフラットに拒否します。 can初期化されていない変数を読み取って、RAMその場所に残ったもののコピーを取得する言語でも、 "ランダム"であると期待することはできません。これは、アプリケーションが以前に行ったことに応じて、常に同じ値を含む傾向があります。実際、Cでは、ローカル変数はスタックから、および/またはCPUレジスターにキャッシュされ、これらはアプリケーション全体で常に再利用されるリソースです。

あなたが読んだ記事が推奨ローカル変数を初期化しない場合、それからそれらを読み取る場合、andはこれが「ランダムさ」をもたらすと期待し、これは記事は、多くの理由で、火棒に焼かれなければならない:

  • 初期化されていないデータを読み取ることは、明らかに仕様違反です。 Cプログラミング言語標準では、これは「未定義の動作」と呼ばれ、アプリケーションのクラッシュや、さらに悪いことに、サイレントメモリ破損など、問題のある結果をもたらす可能性があります。

  • この種類のランダム性は、話す価値のある「ランダム性」の概念によって、notは良いものになります。

  • 再現可能な動作はgoodです。ローカル変数から再現不可能な値を取得しようとすることにより、この記事はコードをデバッグ不可能にすることを促進します。これは血まみれの愚かなこととしてのみ記述できます。特にセキュリティのために。これにより、長年にわたって検出が困難なセキュリティホールの存在がほぼ保証されます。

ランダム性が必要な場合は、OSが提供するものを使用してください。 /dev/urandom。それは、あらゆる観点から見ると、無作為の神々を平穏にするための不合理な自家製の儀式よりも比類のないものです。


編集: @TerryChiaが指摘するように、あなたの質問は次のようになるかもしれませんforcing PRNGからの変数(ローカルまたは非ローカル)のランダムな初期化ではなく、デフォルト値をそのままにします(もちろんisはデフォルト値です;多くのプログラミング言語では、ローカル変数にはデフォルト値がありません)。その文脈で「XOR」と呼んでいるものは不明確です。

その場合、意味のある値を変数に格納する前に上記の変数を読み取らないこともできます。その場合、最初に含まれていた変数はまったく関係ありません。コードの動作には影響しません。またはdo変数を読み取って、これらの多かれ少なかれランダムな値を取得し、アプリケーションコードを再現不可能にして、上記で説明した問題を引き起こします。つまり、コードのデバッグが難しくなり、実際の脆弱性の確率と密度が増加します。

10
Thomas Pornin

変数を初期化すると、一貫した動作が提供されます。それ自体が十分にランダムなRNGを使用する必要があります。ランダム出力をそのメモリ位置にあるものとXORすると、現実的には何のメリットもありません。

値のランダム性を高めるためにこのようなソリューションに依存することは、通常は推奨されません。

しかし、あなたがしないように注意してください それらを修正することで物事を壊す

2
tylerl