PHP反序列化原生类利用

前言

之前对反序列化原生类进行过总结,但可能总结的方面不同,在ctf用到的很少,所以这里在对ctf常用原生类进行一次总结。

原生类

php中内置很多原生的类,在CTF中常以echo new $a($b);这种形式出现,当看到这种关键字眼时,就要考虑本题是不是需要原生类利用了。

先看下都有什么内置原生类


$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反序列化原生类利用_第1张图片

目录遍历类

测试代码


$a = $_GET['a'];
$b = $_GET['b'];
echo new $a($b);
?>

DirectoryIterator

这个类会创建一个指定目录的迭代器,当遇到echo输出时会触发Directorylterator中的__toString()方法,输出指定目录里面经过排序之后的第一个文件名。

可以结合glob协议使用
在这里插入图片描述

FilesystemIterator

该类继承于Directorylterator,所以在用法上基本也是一样的。
PHP反序列化原生类利用_第2张图片

GlobIterator

通过类名也不难看出,这是个自带glob协议的类,所以调用时就不必再加上glob://
PHP反序列化原生类利用_第3张图片

文件读取类

SplFileObject

当用文件目录遍历到了敏感文件时,可以用SplFileObject类,同样通过echo触发SplFileObject中的__toString()方法。(该类不支持通配符,所以必须先获取到完整文件名称才行)
在这里插入图片描述
除此之外其实SplFileObject类,只能读取文件的第一行内容,如果想要全部读取就需要用到foreach函数,但若题目中没有给出foreach函数的话,就要用伪协议读取文件的内容

http://127.0.0.1/1.php?a=SplFileObject&b=php://filter/read=convert.base64-encode/resource=flag

PHP反序列化原生类利用_第4张图片
例题:极客大挑战-SoEzUnser

报错类

Error/Exception 触发XSS

Error/Exception中也有个__toString()方法,能将我们输入的xss内容输出
PHP反序列化原生类利用_第5张图片
例题:[BJDCTF 2nd]xss之光

Error/Exception 绕过哈希比较

测试代码


$a = new Error("payload",1);$b = new Error("payload",2);
echo $a;
echo "
"
; echo $b; echo "
"
; if($a != $b) { echo "a!=b"; } echo "
"
; if(md5($a) === md5($b)) { echo "md5相等"."
"
; } if(sha1($a)=== sha1($b)){ echo "sha1相等"; }

当变量a,b同时触发__toString()方法时,虽对象不同,但执行__toString()方法后,返回结果相同
PHP反序列化原生类利用_第6张图片
这里需要注意 a , a, a,b赋值时,必须要在同一行上,因为执行__toString()方法时会返回行号

例题:[2020 极客大挑战]Greatphp

命令执行

若代码是这种有eval的形式,则可以进行命令执行


$a = $_GET['a'];
$b = $_GET['b'];
eval("echo new $a($b());");
?>

PHP反序列化原生类利用_第7张图片
这里就不仅限于Error和Exception了,基本上所有的原生类都可以

例题:ctfshow web110

其它类

ReflectionMethod 获取类方法的相关信息

想起了去年的国赛,第一次遇到这种类型的题[2021 CISCN]easy_source

可以结合getDocComment() 方法,用它来获取类中各个函数注释内容


class Sentiment{
    /** flag{asdasd} */
    public function a(){
    }
}
$a = $_GET['a'];
$b = $_GET['b'];
$c= $_GET['c'];
$d=new $a($b,$c);
var_dump($d->getDocComment());
?>

在这里插入图片描述

ZipArchive 文件操作

可以通过本类执行一些文件操作,在CTF可以用来删除waf

常用类方法

ZipArchive::addEmptyDir:添加一个新的文件目录
ZipArchive::addFile:将文件添加到指定zip压缩包中
ZipArchive::addFromString:添加新的文件同时将内容添加进去
ZipArchive::close:关闭ziparchive
ZipArchive::extractTo:将压缩包解压
ZipArchive::open:打开一个zip压缩包
ZipArchive::deleteIndex:删除压缩包中的某一个文件,如:deleteIndex(0)代表删除第一个文件
ZipArchive::deleteName:删除压缩包中的某一个文件名称,同时也将文件删除

实例代码


$zip = new ZipArchive;
$zip->open('web.zip', ZipArchive::CREATE)
?>

第一个参数:要打开的压缩包文件

第二个参数:

ZIPARCHIVE::OVERWRITE总是创建一个新的文件,如果指定的zip文件存在,则会覆盖掉。

ZIPARCHIVE::CREATE如果指定的zip文件不存在,则新建一个。

ZIPARCHIVE::EXCL如果指定的zip文件存在,则会报错。

ZIPARCHIVE::CHECKCONS对指定的zip执行其他一致性测试。

之后会在当前目录创建个web.zip,但可能由于环境原因没有打出来

其他命令可以参考:php利用ZipArchive类操作文件的实例_php技巧_脚本之家 (jb51.net)

例题:NepCTF2021 梦里花开牡丹亭

魔法方法

SQLite3

除了原生类外还有一个魔法方法SQLite3也可以使用,基于__construct()方法,可以在指定目录下创建文件需要将php这两项前的;去除
PHP反序列化原生类利用_第8张图片

http://127.0.0.1/1.php?a=SQLite3&b=f:/2.txt

执行后在f盘创建了一个2.txt空文件

你可能感兴趣的:(php,CTF,php,web安全,安全)