PHP でのシリアル化は、PHP オブジェクトを文字列に変換する方法です。この文字列は、データベースに保存したり、別の関数に渡したりするなど、さまざまな方法で使用できます。 PHP ドキュメントによると、これは、型や構造を失わずに PHP 値を渡すときに便利です。しかし、私はこれまでそのような問題に直面したことがありません。もしかしたら見えていないかもしれません。
<?php $test = new User(); $test->name = "Denzyl"; echo serialize($test); /// Output: O:4:"User":1:{s:4:"name";s:6:"Denzyl";}
それでは、文字列をダイジェストしてみましょう。 o は Object を表し、次の数字はオブジェクト名の長さです。 2 つの文字 s は、文字列と文字列の名前の長さを表します。
文字列を PHP に変換し直す必要がある場合は、unserialize 関数を呼び出し、文字列をパラメータとして渡します。
オブジェクトをシリアル化するときに、2 つのメソッドが自動的に呼び出されます。 __serialize() と __sleep()。これにより、クラス作成者はオブジェクトを文字列に変換する前に何かを行うことができます。
それはまさに要点です。ただし、ここでは文字列のシリアル化を解除することに焦点を当てましょう。これは、文字列を、後で PHP コードの実行時に使用できる実際の PHP オブジェクトに変換することを意味します。
<?php $string = 'O:8:"User":1:{s:4:"name";s:6:"Denzyl";}'; echo unserialize($string)->name; /// Output: Denzyl
同じ機能がシリアル化解除にも適用されます。ただし、今回は 2 つのメソッドは __unserialize() と __wakeup() です。
知らずに unserialize を使用すると、リモートでコードが実行される可能性があります。だからこそ、彼らは入力を決して信用してはいけないと言います。
あなたが怠け者で、ランダムな入力を信頼し、シリアル化されたオブジェクトに連結して、
ができるとします。
オブジェクト内の値を変更します。ドーン、ハッキングされる可能性があります。
<?php $username = $_GET['username']; $serialized = 'O:8:"User":1:{s:4:"name";s:6:"' . $username . '";}';
このようなものに対するエクスプロイトの書き方については説明しません。一部のツールではペイロードを自動的に生成できるため、自分自身をスクリプトキディと呼ぶことができます (私たちは皆、どこかから始まります)。私が知っているのは PHPGGC です。
エクスプロイトを理解するには、OWASP の記事を参照してください。
これまで知らなかった場合は、脆弱性に関する残りの OWASP 記事もお読みください
エクスプロイトの書き方をまだ説明していないことはわかっています。インターネット上の記事よりも優れた仕事はできないと思います。しかし、これであなたはこれを知ったので、自分で調べることができます。
なぜこれを使用したいのですか?分かりません。私はシリアライズ/アンシリアライズを使用して問題を解決する機会があるほどプログラミングを長くしていない(約15年)。
私の解決策は抜本的すぎます。答えは簡単です。私の PHP プロジェクトでは使用しないでください。
開発者がプロジェクトに含めたいと考えているもの。この記事を書いている時点では、
を停止するルールを作成中です。
人々が unserialize を使用しないようにすることで、次のリリースの準備が整うはずです。プロジェクトをフォローすると通知が届きます
さらにルールを書くことにしました。
以上がPHP でオブジェクトをアンシリアライズすることが悪い考えであるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。