目录
php反序列化
Phar反序列化概要
phar文件的结构:
原生类序列化
Session反序列化
Session反序列化的特殊利用
什么是反序列化?
序列化就是将一个对象转换成字符串。字符串包括 属性名 属性值 属性类型和该对象对应的类名。反序列化则相反将字符串重新恢复成对象
serialize() 序列化
unserialize() 反序列化
漏洞原理:
PHP将所有以__ (两个下划线)开头的类方法保留为魔术方法。所以在定义类方法时,除了上述魔术方法,建议不要以__为前缀。
常见的魔术方法:
PHP类中的特殊属性
序列化为了能把整个类对象的各种信息完完整整的压缩,格式化,也会将属性的权限序列化进去。但不同类型的属性会有不同的格式
1. Public 权限
可以内部调用,实例调用等
2. Private权限 ( test flag)反序列化时会多两个空字节00==>可以传递%00test%00flag进行反序列化
被private修饰的只能是同一个类的可以访问
3. Protected权限 ( * test)同样多了两个空字节==>%00*%00test进行反序列化
对继承的类开放,没继承的类不开放
除了unserialize()来利用反序列化漏洞之外,还可以利用phar文件以序列化的形式存储用户自定义的meta-data这一特性,扩大php反序列化漏洞的攻击面。该方法在文件系统函数(file__exists()、 is__dir()等)参数可控的情况下,配合phar://伪协议,可以不依赖unserialize()直接进行反序列化操作。
来自Secarma的安全研究员Sam Thomas发现了-种新的漏洞利用方式,可以在不使用php函数unserialize()的前提下,引起严重的php对象注入漏洞。这个新的攻击方式被他公开在了美国的BlackHat会议演讲上,演讲主题为:”不为人所知的php反序列化漏洞”。它可以使攻击者将相关漏洞的严重程度升级为远程代码执行。我们在RIPS代码分析引擎中添加了对这种新型攻击的检测。
因此可以构造一个恶意的phar包,使得代码能够被反序列化,在使用phar://协议读取文件时,文件会被机械成为phar,解析过程种会触发php_var_unserialize()函数对meta-data的操作,造成反序列化
什么是Phar文件?
在软件中,PHAR (PHP归档) 文件是一种打包格式,通过将许多PHP代码文件和其他资源(例如图像,样式表等)捆绑到一个归档文件中来实现应用程序和库的分发。php通过用户定义和内置的“流包装器”实现复杂的文件处理功能。内置包装器可用于文件系统函数,如(fopen(),copy(,file_exists()和filesize()。 phar://就是一 种内置的流包装器。
php中一些常见的流包装器如下:
file:// -访问本地文件系统,在用文件系统函数时默认就使用该包装器
大http:// -访问HTTP(s) 网址
ftp:// -访问FTP(s) URLS
php:// -访问各个输入/输出流(I/O streams)
zlib:// -压缩流
data:// -数据(RFC 2397)
glob:// -查找匹配的文件路径模式
phar:// -PHP归档
ssh2:// -Secure Shell 2
rar:// -RAR
ogg:// -音频流
expect:// -处理交互式的流
Phar文件都包含以下几个部分
php.ini中的phar.readonly选项设置为off
startBuffering();
$phar->setStub(" "); //设置stub
//$phar -> setStub('GIF89a'.''); //增加gif头,绕过gif检测
$o = new TestObject();
$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "
test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
实际在文件上传的时候,如果存在利用条件,可以将生成的phar.phar文件后缀更改为phar.gif上传
php一大部分文件系统函数在通过phar://伪协议解析phar文件时,都会将meta-data进行反序列化受影响函数的链接
Phar反序列化漏洞的利用条件:
SessionHandler::open()
当$flag=ZipArchive:OVERWRITE时,就会将$filename的文件删除
open('1.txt', ZipArchive:OVERWRITE)
?>
public SoapClient::SoapClient ( mixed $wsdI [, array $options ] )
第一个参数是用来指明是否是wsdl模式,如果为null,那就是非wsdl模式,反序列化的时候会对第二个参数指明的url进行soap请求。
SOAP是webService三要素(SOAP 、WSDL(WebServicesDescriptionl anguage)、
UDDI(UniversalDescriptionDiscovery. andIntegration))之一
WSDL用来描述如何访问具体的接口
UDDI用来管理,分发,查询webService
SOAP(简单对象访问协议)是连接或Web服务或客户端和Web服务之间的接口。
webService相当于HTTP + XML
PHP中的session保存:PHP.ini有以下配置项用于控制session有关的设置:
session.save_path="D:lxampp\tmp" 表明所有的session文件都是存储在xampp/tmp下
session.save_handler = files 表明session是以文件的方式来进行存储的
session.auto start=0 表明默认不启动session
session.serialize_handler= php 表明session的默认序列话引擎使用的是php序列化引擎
设置session为$_ SESSION["name"] = "Threezh1";时。不同的引擎保存的session文件内容如下:
php:
name|s:8:"Threezh1";
存储方式是,键名+竖线+经过serialize()函数序列处理的值
php.binary:
names:8:"Threezh1";
存储方式是,键名的长度对应的ASCII字符+键名+经过serialize()函数序列化处理的值
php.serialize(php>5.5.4):
a:1:{s:4:"name' ;:8:"Threezh1";}
存储方式是经过serialize()函 数序列化处理的值
当PHP中sessionupload progress enabled打开时,php会记录上传文件的进度,在上传时会将其信息保存在$_SESSION中。
上传文件进度的报告就会以写入到session文件中,所以我们可以设置-一个与session.upload progress.name同名的变量(默认名为PHP_SESSION_UPLOAD_PROGRESS),PHP检测到这种同名请求会在$_SESSION中添加一条数据。我们就可以控制这个数据内容为我们的恶意payload。
mdzz = 'phpinfo();';
}
function __destruct()
{
eval($this->mdzz);
}
}
if(isset($_GET['phpinfo']))
{
$m = new OowoO();
}
else
{
highlight_string(file_get_contents('index.php'));
}
?>
exp.php
mdzz = "print_r(scandir(__dir__));";
echo serialize($a);
//生成序列化payload
?>