しばらくの間、bin2hex() を作成するという興味深いリクエストが PHP に対してオープンされました。これにより、メーリング リスト上でいくつかの興味深い議論が生まれました (そして、私は -X と返信することもありました)。 PHP はリモート タイミング攻撃についてかなり詳しく扱っていますが、文字列の比較についても説明しています。他のタイプの時限攻撃について話したいと思います。
リモートタイミング攻撃とは何ですか?
次のコードがあると仮定しましょう:
function containsTheLetterC($string) { for ($i = 0; $i < strlen($string); $i++) { if ($string[$i] == "c") { return true; } sleep(1); } return false;}var_dump(containsTheLetterC($_GET['query']));
それが何をするかは簡単にわかるはずです。 URL からクエリ パラメータを取得し、それを逐語的に調べて、それが小文字の c であるかどうかを確認します。そうすれば戻ってきます。そうでない場合は、1 秒間スリープします。
それでは、文字列 ?query=abcdef を渡したとしましょう。チェックには 2 秒かかると予想されます。
さて、どの文字を探せばよいのかわからないと想像してみましょう。 「c」が私たちの知らない別の値であると想像してみましょう。その手紙が何であるかを調べる方法がわかりますか?
簡単です。文字列「abcdefghijklmnopqrstuvwxyzABCDEFGHIJ....」を作成して渡します。その後、戻るまでにかかる時間を計算できます。そうすれば、どのキャラクターが違うのかが分かります!
これが時限攻撃の基本です。
しかし、現実の世界にはそのようなコードはありません。実際の例を見てみましょう:
$secret = "thisismykey";if ($_GET['secret'] !== $secret) { die("Not Allowed!");}
何が起こっているのかを理解するには、PHP のソース コードから is_identical_function を確認する必要があります。この関数を見ると、結果が次によって定義されていることがわかります:
case IS_STRING: if (Z_STR_P(op1) == Z_STR_P(op2)) { ZVAL_BOOL(result, 1); } else { ZVAL_BOOL(result, (Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && (!memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)))); } break;
両方の変数が同じ場合の if 変数 (主な要件は $secret === $secret であるため)。私たちの場合、これは不可能なので、else ブロックを確認する必要があります。
Z_STRLEN_P(op1) == Z_STRLEN_P(op2)
つまり、文字列の長さが一致しない場合は、すぐに戻ります。
これは、文字列の長さが同じであれば、より多くの作業を実行できることを意味します。
さまざまな長さで実行にかかった時間を計測すると、次のようになります:
長さ | タイムラン1 | タイムラン2 | タイムラン3 | 平均時間 |
---|---|---|---|---|
7 | 0.01241 | 0.01152 | 0.01191 | 0.01194 |
8 | 0.01151 | 0.01212 | 0.01189 | 0.01184 |
9 | 0.01114 | 0.01251 | 0.01175 | 0.01180 |
10 | 0.01212 | 0.01171 | 0.01120 | 0.01197 |
11 | 0.01210 | 0.01231 | 0.01216 | 0.01219 |
12 | 0.01121 | 0.01211 | 0.01194 | 0.01175 |
13 | 0.01142 | 0.01174 | 0.01251 | 0.01189 |
14 | 0.01251 | 0.01121 | 0.01141 | 0.01171 |
如果您忽略平均列,您会注意到似乎没有多少模式。这些数字都在彼此的原因之内。
但是,如果您平均进行多次跑步,您就会注意到一种模式。你会注意到长度11需要更长的时间(略),然后是其他长度。
这个例子非常夸张。但它说明了这一点。它已经显示了可以使用约49000(所以49000次尝试,而不是在上述实施例3)的样品大小远程检测的差异在时间缩短到约15纳秒。
但是,我们发现了这个长度。那不会给我们太多的收入......但第二部分呢?那怎么样memcmp(...)?
如果我们看的执行memcmp()::
int memcmp(const void *s1, const void *s2, size_t n){ unsigned char u1, u2; for ( ; n-- ; s1++, s2++) { u1 = * (unsigned char *) s1; u2 = * (unsigned char *) s2; if ( u1 != u2) { return (u1-u2); } } return 0;}
等一下!这返回两个字符串之间的第一个区别!
所以一旦我们确定了字符串的长度,我们可以尝试不同的字符串开始检测差异:
axxxxxxxxxxbxxxxxxxxxxcxxxxxxxxxxdxxxxxxxxxx...yxxxxxxxxxxzxxxxxxxxxx
并通过相同的技术,发现与“txxxxxxxxxx”的差异比其他时间略长。
为什么?
让我们看看在memcmp中一步一步发生的事情。
-
首先,它查看每个字符串的第一个字符。
如果第一个字符不同,请立即返回。
-
接下来,看看每个字符串的第二个字符。
如果它们不同,立即返回。
等等。
因此"axxxxxxxxxx",它只执行第一步(因为我们正在比较的字符串"thisismykey")。但是"txxxxxxxxxx",第一步和第二步相匹配。所以它做更多的工作,因此需要更长的时间。
所以一旦你看到了,你知道t是第一个字符。
那么这只是一个重复这个过程的问题:
taxxxxxxxxxtbxxxxxxxxxtcxxxxxxxxxtdxxxxxxxxx...tyxxxxxxxxxtzxxxxxxxxx
为每个角色做到这一点,你就完成了。你已经成功推断出一个秘密!
防止比较攻击
所以这是一个基本的比较攻击。==并且===在PHP中都容易受到攻击。
有两种基本的防御方法。
首先是手动比较两个字符串,并且总是比较每个字符(这是我以前的博客文章中的函数:
/** * A timing safe equals comparison * * @param string $safe The internal (safe) value to be checked * @param string $user The user submitted (unsafe) value * * @return boolean True if the two strings are identical. */function timingSafeEquals($safe, $user) { $safeLen = strlen($safe); $userLen = strlen($user); if ($userLen != $safeLen) { return false; } $result = 0; for ($i = 0; $i < $userLen; $i++) { $result |= (ord($safe[$i]) ^ ord($user[$i])); } // They are only identical strings if $result is exactly 0... return $result === 0;}
第二个是使用内置的PHP hash_equals() function。这是在5.6中添加的,与上面的代码做同样的事情。
注:一般情况下,它是不是能够防止长度泄漏。所以可以泄漏这个长度。重要的部分是它不会泄漏关于两个字符串的差异的信息。
其他类型的计时攻击 - 索引查找
那就是比较。这是相当好的覆盖。但是让我们来谈谈索引查找:
如果您有一个数组(或字符串),并且使用秘密信息作为索引(键),则可能会泄漏有关该键的信息。
为了理解为什么,我们需要了解一下CPU如何处理内存。
通常,CPU具有固定宽度的寄存器。把这些想象成小变量。在现代处理器上,这些寄存器可能是64位(8字节)宽。这意味着CPU可以在一次处理的最大变量是8个字节。(注意:这是不正确的,因为大多数处理器都有基于向量的操作,例如SIMD,它允许它与更多的数据交互。对于这个讨论来说,尽管这并不重要)。
那么当你想读一个长度为16字节的字符串时会发生什么呢?
那么,CPU需要加载它块。根据操作的不同,它可能一次加载8个字节的字符串,并且一次对它操作8个字节。或者更常见的是,它一次处理一个字节。
所以这意味着它需要从某处获取字符串的其余部分。这个“某处”是主存(RAM)。但记忆非常缓慢。像真的很慢。大约100ns。这是我们的15纳秒阈值。
而且由于主内存非常慢,所以CPU在CPU本身上只有很少的内存空间来充当缓存。实际上,它们通常有两种类型的缓存。它们具有特定于每个核心(每个核心都有自己的L1高速缓存)的L1高速缓存,也是特定于核心的L2高速缓存,以及经常在单个芯片上的所有核心之间共享的L3高速缓存。为什么3层?由于速度:
メモリタイプ | サイズ | 潜在 |
---|---|---|
32KB | 0.5ナノ秒 | |
25 6KB | 2.5 ns | |
4- 16MB | 10-20ナノ秒 | |
たくさん | 60 - 100ナノ秒 |
以上がPHPセキュリティサンプルの共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

PHPSESSIONの障害の理由には、構成エラー、Cookieの問題、セッションの有効期限が含まれます。 1。構成エラー:正しいセッションをチェックして設定します。save_path。 2.Cookieの問題:Cookieが正しく設定されていることを確認してください。 3.セッションの有効期限:セッションを調整してください。GC_MAXLIFETIME値はセッション時間を延長します。

PHPでセッションの問題をデバッグする方法は次のとおりです。1。セッションが正しく開始されるかどうかを確認します。 2.セッションIDの配信を確認します。 3.セッションデータのストレージと読み取りを確認します。 4.サーバーの構成を確認します。セッションIDとデータを出力し、セッションファイルのコンテンツを表示するなど、セッション関連の問題を効果的に診断して解決できます。

session_start()への複数の呼び出しにより、警告メッセージと可能なデータ上書きが行われます。 1)PHPは警告を発し、セッションが開始されたことを促します。 2)セッションデータの予期しない上書きを引き起こす可能性があります。 3)session_status()を使用してセッションステータスを確認して、繰り返しの呼び出しを避けます。

PHPでのセッションライフサイクルの構成は、session.gc_maxlifetimeとsession.cookie_lifetimeを設定することで達成できます。 1)session.gc_maxlifetimeサーバー側のセッションデータのサバイバル時間を制御します。 0に設定すると、ブラウザが閉じているとCookieが期限切れになります。

データベースストレージセッションを使用することの主な利点には、持続性、スケーラビリティ、セキュリティが含まれます。 1。永続性:サーバーが再起動しても、セッションデータは変更されないままになります。 2。スケーラビリティ:分散システムに適用され、セッションデータが複数のサーバー間で同期されるようにします。 3。セキュリティ:データベースは、機密情報を保護するための暗号化されたストレージを提供します。

PHPでのカスタムセッション処理の実装は、SessionHandlerInterfaceインターフェイスを実装することで実行できます。具体的な手順には、次のものが含まれます。1)CussentsessionHandlerなどのSessionHandlerInterfaceを実装するクラスの作成。 2)セッションデータのライフサイクルとストレージ方法を定義するためのインターフェイス(オープン、クローズ、読み取り、書き込み、破壊、GCなど)の書き換え方法。 3)PHPスクリプトでカスタムセッションプロセッサを登録し、セッションを開始します。これにより、データをMySQLやRedisなどのメディアに保存して、パフォーマンス、セキュリティ、スケーラビリティを改善できます。

SessionIDは、ユーザーセッションのステータスを追跡するためにWebアプリケーションで使用されるメカニズムです。 1.ユーザーとサーバー間の複数のインタラクション中にユーザーのID情報を維持するために使用されるランダムに生成された文字列です。 2。サーバーは、ユーザーの複数のリクエストでこれらの要求を識別および関連付けるのに役立つCookieまたはURLパラメーターを介してクライアントに生成および送信します。 3.生成は通常、ランダムアルゴリズムを使用して、一意性と予測不可能性を確保します。 4.実際の開発では、Redisなどのメモリ内データベースを使用してセッションデータを保存してパフォーマンスとセキュリティを改善できます。

APIなどのステートレス環境でのセッションの管理は、JWTまたはCookieを使用して達成できます。 1。JWTは、無国籍とスケーラビリティに適していますが、ビッグデータに関してはサイズが大きいです。 2.cookiesはより伝統的で実装が簡単ですが、セキュリティを確保するために慎重に構成する必要があります。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

ホットトピック









