ホームページ バックエンド開発 PHPチュートリアル PHPのデシリアライゼーション・アンシリアライズの小さな機能

PHPのデシリアライゼーション・アンシリアライズの小さな機能

Jun 13, 2016 pm 12:30 PM
case data false goto return

PHP unserialize の小さな機能

WordPress のシーケンス解除の脆弱性は最近非常に有名になっていますが、具体的な脆弱性については分析しません: http://drops.wooyun.org/papers/596,?
英語の原文も読むことができます: http://vagosec.org/2013/09/wordpress-php-object-injection/。 ?

wp の公式 Web サイトにパッチがあります。パッチを回避しようとしましたが、成功したと思ったら、自分が甘かったことがわかり、wp のパッチを回避できませんでした。ですが、unserialize の小さな機能を発見したので共有したいと思います。?

1. Unserialize() 関数関連のソースコード: ?

if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);?<br style="margin: 0px; padding: 0px;">????????yych = *YYCURSOR;?<br style="margin: 0px; padding: 0px;">????????switch (yych) {?<br style="margin: 0px; padding: 0px;">????????case 'C':?<br style="margin: 0px; padding: 0px;">????????case 'O':????????goto yy13;?<br style="margin: 0px; padding: 0px;">????????case 'N':????????goto yy5;?<br style="margin: 0px; padding: 0px;">????????case 'R':????????goto yy2;?<br style="margin: 0px; padding: 0px;">????????case 'S':????????goto yy10;?<br style="margin: 0px; padding: 0px;">????????case 'a':????????goto yy11;?<br style="margin: 0px; padding: 0px;">????????case 'b':????????goto yy6;?<br style="margin: 0px; padding: 0px;">????????case 'd':????????goto yy8;?<br style="margin: 0px; padding: 0px;">????????case 'i':????????goto yy7;?<br style="margin: 0px; padding: 0px;">????????case 'o':????????goto yy12;?<br style="margin: 0px; padding: 0px;">????????case 'r':????????goto yy4;?<br style="margin: 0px; padding: 0px;">????????case 's':????????goto yy9;?<br style="margin: 0px; padding: 0px;">????????case '}':????????goto yy14;?<br style="margin: 0px; padding: 0px;">????????default:????????goto yy16;?<br style="margin: 0px; padding: 0px;">????????}

上記のコードは判定ですシーケンス文字列の処理メソッド (シーケンス文字列 O:4:"test":1:{s:1:"a";s:3:"aaa";} など) このシーケンス文字列を処理するには、まず最初のstring The Character is O, then case 'O':??goto yy13?

yy13:?<br style="margin: 0px; padding: 0px;">????????yych = *(YYMARKER = YYCURSOR);?<br style="margin: 0px; padding: 0px;">????????if (yych == ':') goto yy17;?<br style="margin: 0px; padding: 0px;">????????goto yy3;

上記のコードからわかるように、ポインターは移動します2 番目の文字を指す 1 ビットを使用して、その文字が次であるかどうかを判断し、次に yy17?

yy17:?<br style="margin: 0px; padding: 0px;">???????yych = * YYCURSOR; に進みます。 ?<br style="margin: 0px; padding: 0px;">??? ????if (yybm[0 yych] & 128) {?<br style="margin: 0px; padding: 0px;">????????????goto yy20;?<br style="margin: 0px; padding: 0px;">??? ????<br style="margin: 0px; padding: 0px;">??????if (yych == ' ') goto yy19;?<br style="margin: 0px; padding: 0px;"><br style="margin: 0px; padding: 0px;">....?<br style="margin: 0px; padding: 0px;"><br style="margin: 0px; padding: 0px;">yy19:?<br style="margin: 0px; padding: 0px;"> ???? ???yych = * YYCURSOR;?<br style="margin: 0px; padding: 0px;">?????????if (yybm[0 yych] & 128) {?<br style="margin: 0px; padding: 0px;">????????? goto yy20;?<br style="margin: 0px; padding: 0px;">?????????}?<br style="margin: 0px; padding: 0px;">??????goto yy18;

より 上記からわかるようにコードの場合はポインタが移動し、文字が数字の場合は yy20 に進み、 ' ' の場合は yy19 に進み、次の文字が数字の場合は yy20 に進みます。 yy18 に移動するだけではありません。yy18 はシーケンス処理を直接終了します。yy20 はオブジェクト シーケンスの処理であるため、上記からわかるように:?

O: 4:"テスト":1:{s:1:"a";s:3:"aaa" ;} ?<code style="margin: 0px auto; padding: 4px 8px; display: block; font-family: 'Lucida Console', 'Courier New', Courier, mono, monospace; font-size: 12px; color: #333333; background-color: #f8f8f8; border: 1px solid #cccccc; line-height: 18px; overflow: auto; white-space: normal;">O: 4:"test":1:{s:1:"a";s:3:"aaa";}?<br style="margin: 0px; padding: 0px;">O:4:"test":1:{s:1:"a";s:3:"aaa";}O:4:"test":1:{s:1:"a";s:3:"aaa";}

<🎜> はすべて逆シリアル化できますアンシリアライズしても結果は同じです。?

2. 実際のテスト: ?

<?php?<br style="margin: 0px; padding: 0px;">var_dump(unserialize('O: 4:"test":1:{s:1:"a";s:3:"aaa";}'));?<br style="margin: 0px; padding: 0px;">var_dump(unserialize('O:4:"test":1:{s:1:"a";s:3:"aaa";}'));?<br style="margin: 0px; padding: 0px;">?>

出力: ?

object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(4) "test" ["a"]=> string(3) "aaa" }?<br style="margin: 0px; padding: 0px;">object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(4) "test" ["a"]=> string(3) "aaa" }

実際には、もう 1 つの ' ' で処理できるオブジェクトの型だけでなく、他の型も処理できます。具体的なテストについてはあまり説明しません。?

3.我们看下wp的补丁:?

function is_serialized( $data, $strict = true ) {?<br style="margin: 0px; padding: 0px;">?????????// 文字列でない場合はシリアル化されません?<br style="margin: 0px; padding: 0px;">???????if ( ! is_string( $data ) )?<br style="margin: 0px; padding: 0px;">? ?????????????return false;?<br style="margin: 0px; padding: 0px;">?????????$data = トリム( $data );?<br style="margin: 0px; padding: 0px;">??????? ? if ( 'N;' == $data )?<br style="margin: 0px; padding: 0px;">???????????????return true;?<br style="margin: 0px; padding: 0px;">?????????$length = strlen ( $data );?<br style="margin: 0px; padding: 0px;">?????????if ( $length ???????????????return false;?<br style="margin: 0px; padding: 0px;">?????????if ( ':' !== $data[1] )?<br style="margin: 0px; padding: 0px;">???????????????return false;?<br style="margin: 0px; padding: 0px;">?????????if ( $strict ) {//output?<br style="margin: 0px; padding: 0px;">???????????????$lastc = $data[ $length - 1 ]; ?<br style="margin: 0px; padding: 0px;">??????????????????if ( ';' !== $lastc && '}' !== $lastc )?<br style="margin: 0px; padding: 0px;">?????? ????????????????return false;?<br style="margin: 0px; padding: 0px;">??????????} else {//input?<br style="margin: 0px; padding: 0px;">??????? ???????$semicolon = strpos( $data, ';' );?<br style="margin: 0px; padding: 0px;">???????????????$brace???? = strpos( $data, '}' );?<br style="margin: 0px; padding: 0px;">??????????????????// どちらか ; ?<br style="margin: 0px; padding: 0px;">???????????????if ( false === $semicolon && false === $brace )?<br style="margin: 0px; padding: 0px;">????? ???????????????????return false;?<br style="margin: 0px; padding: 0px;">??????????????????// ただし、どちらも最初の X 文字。?<br style="margin: 0px; padding: 0px;">??????????????????if ( false !== $semicolon && $semicolon ??????? ????????????????return false;?<br style="margin: 0px; padding: 0px;">???????????????if ( false !== $brace && $中括弧 ?????????????????????return false;?<br style="margin: 0px; padding: 0px;">?????????}? <br style="margin: 0px; padding: 0px;">?????????$token = $data[0];?<br style="margin: 0px; padding: 0px;">?????????switch ( $token ) {?<br style="margin: 0px; padding: 0px;">???????? ??????????case 's' :?<br style="margin: 0px; padding: 0px;">?????????????????????if ( $strict ) {?<br style="margin: 0px; padding: 0px;">?????????????????????????????????if ( '"' !== $data[ $length - 2 ] ) ?<br style="margin: 0px; padding: 0px;">????????????????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????????????????????} elseif ( false === strpos( $data, '"' ) ) {?<br style="margin: 0px; padding: 0px;">??? ????????????????????????????return false;?<br style="margin: 0px; padding: 0px;">??????????????? ??????????}?<br style="margin: 0px; padding: 0px;">???????????????ケース 'a' :?<br style="margin: 0px; padding: 0px;">????????? ????case 'O' :?<br style="margin: 0px; padding: 0px;">?????????????????????エコー "a";?<br style="margin: 0px; padding: 0px;">?? ???????????????????return (bool) preg_match( "/^{$token}:[0-9] :/s", $data ); ?<br style="margin: 0px; padding: 0px;">??????????????????ケース 'b' :?<br style="margin: 0px; padding: 0px;">??????????????????ケース 'i' : ?<br style="margin: 0px; padding: 0px;">??????????????????ケース 'd' :?<br style="margin: 0px; padding: 0px;">????????????????????? ???$end = $strict ? '$' : '';?<br style="margin: 0px; padding: 0px;">?????????????????????return (bool) preg_match( "/^{$token}:[ 0-9.E-] ;$end/", $data );?<br style="margin: 0px; padding: 0px;">?????????}?<br style="margin: 0px; padding: 0px;">?????????return false;?<br style="margin: 0px; padding: 0px;">}
パッチ内?

return (bool) preg_match( "/^{$token}:[0-9] :/s", $data );<code style="margin: 0px auto; padding: 4px 8px; display: block; font-family: 'Lucida Console', 'Courier New', Courier, mono, monospace; font-size: 12px; color: #333333; background-color: #f8f8f8; border: 1px solid #cccccc; line-height: 18px; overflow: auto; white-space: normal;">return (bool) preg_match( "/^{$token}:[0-9] :/s", $data );

「 」をもう 1 つ追加できますバイパス、この方法でシーケンス値をデータベースに書き込みましたが、データベースから抽出されたデータは、再度検証するときにバイパスできません。個人的には、このパッチはデータベースに出入りするデータに変更を加えることができませんでした。データの内外の変更に焦点を当てる必要がなくなりました。 ?

4. 概要?
wp パッチはバイパスされませんが、unserialize() のこの小さな機能は多くの開発者によって無視される可能性があり、その結果、プログラムにはセキュリティ上の欠陥があります。 ?
上記の分析に誤りがある場合は、指摘するメッセージを残してください。 ?

5. 参考?
《WordPress < 3.6.1 PHP オブジェクトインジェクション》?
http:/ /vagosec.org/2013/09/wordpress-php-object-injection/?
《var_unserializer.c ソースコード》?
https://github. com /php/php-src/blob/73cd2e0ab14d804c6bf0b689490bdd4fd6e969b1/ext/standard/var_unserializer.c?
"PHP 文字列のシリアル化と逆シリアル化の間の一貫性のない構文解析によって引き起こされるセキュリティ上の危険"?
http://zone.wooyun.org/content/1664

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

C言語のreturnの使い方を詳しく解説 C言語のreturnの使い方を詳しく解説 Oct 07, 2023 am 10:58 AM

C 言語における return の使い方は、 1. 戻り値の型が void の関数については、return 文を使用して関数の実行を早期に終了することができます; 2. 戻り値の型が void ではない関数については、 return ステートメントは、関数の実行を終了するためのものです。結果は呼び出し元に返されます。 3. 関数の実行を早期に終了します。関数内で return ステートメントを使用して、関数の実行を早期に終了することもできます。関数が値を返さない場合。

Javaのreturn文とfinally文の実行順序は何ですか? Javaのreturn文とfinally文の実行順序は何ですか? Apr 25, 2023 pm 07:55 PM

ソースコード: publicclassReturnFinallyDemo{publicstaticvoidmain(String[]args){System.out.println(case1());}publicstaticintcase1(){intx;try{x=1;returnx;}finally{x=3;}}}#出力 上記のコードの出力は、単純に次のように結論付けることができます:finally の前に return が実行されます。バイトコード レベルで何が起こるかを見てみましょう。以下は、case1 メソッドのバイトコードの一部をインターセプトし、ソース コードを比較して、各命令の意味に注釈を付けます。

C言語のgoto文の意味は何ですか? C言語のgoto文の意味は何ですか? Dec 22, 2022 pm 06:00 PM

C 言語では、goto ステートメントは無条件転送ステートメントと呼ばれ、同じ関数内のラベル付きステートメントに無条件で制御を移すことができます。構文は「goto label;...label:statement;」で、label は次のとおりです。 C 以外のすべて C プログラムの goto ステートメントの前後に設定できるキーワード以外のプレーンテキスト。

HMD Skyline に新しいカラーオプションと公式磁気ケースが追加されました HMD Skyline に新しいカラーオプションと公式磁気ケースが追加されました Aug 23, 2024 am 07:04 AM

HMD Skyline (Amazon で $499 で入手可能) が先月発売されたとき、ネオン ピンクとツイスト ブラックの 2 色で発売されました。これらに、ブルー トパーズと呼ばれる 3 番目の色が加わりました。 HMD Global は、ph の公式ケースも発表しました。

Go言語でgotoを使う方法 Go言語でgotoを使う方法 Nov 23, 2022 pm 06:40 PM

Go 言語では、goto ステートメントはプログラム内の指定された行に無条件にジャンプするために使用され、ラベルを使用してコード間を無条件にジャンプします。 goto の後にはラベルが続きます。このラベルの意味は、Go プログラムにコードのどの行を次に実行するかを指示することです。構文は "goto label;... ...label:expression;" です。 goto は、元のコードの実行順序を破り、指定された行に直接ジャンプしてコードを実行します。goto ステートメントは通常、条件ステートメントと組み合わせて使用​​され、条件付き転送、ループの形成、ループからの抜け出しなどの機能を実装するために使用できます。身体。

Vue3 はセットアップ構文シュガーをどのように使用して return の書き込みを拒否しますか Vue3 はセットアップ構文シュガーをどのように使用して return の書き込みを拒否しますか May 12, 2023 pm 06:34 PM

Vue3.2 セットアップ構文シュガーは、単一ファイル コンポーネント (SFC) で結合された API を使用して、Vue3.0 の面倒なセットアップを解決するコンパイル時構文シュガーです。宣言された変数、関数、インポートによって導入されたコンテンツは、インポートによって公開されます。使用上の問題点 1. 宣言した変数、関数、import で導入した内容を使用中に return する必要はなく、糖衣構文を使用することができます。 // 導入した内容をインポート import{getToday }from'./utils'//variable constmsg='Hello !'//function func

スイッチケース判定変数 スイッチケース判定変数 Feb 19, 2024 am 08:04 AM

Switchcase では、変数を決定するための特定のコード例が必要です。プログラミングでは、さまざまな変数値に基づいてさまざまな操作を実行する必要があることがよくあります。 switchcase ステートメントは、変数の値に基づいて実行するコードのさまざまなブロックを選択できる便利な構造です。以下は、switchcase ステートメントを使用して変数のさまざまな値を決定する方法を示す具体的なコード例です。 #includeintmain(){

JavaScript関数の戻り値とreturn文の詳しい解説 JavaScript関数の戻り値とreturn文の詳しい解説 Aug 04, 2022 am 09:46 AM

JavaScript 関数は、外部と対話するための 2 つのインターフェースを提供し、パラメータは外部情報を受け取る入り口として機能し、戻り値は演算結果を外部にフィードバックする出口として機能します。次の記事では、JavaScript 関数の戻り値を理解し、return ステートメントの使用法を簡単に分析します。

See all articles