jarvisoj phpinfo writeup及注入的变量详解 这题目是关于php session反序列化的题目,参考了许多大神的writeup,但是注入点没有详细的讲解,因此自己想写一篇witeup
题目探索 首先打开题目页面直接获得源码:
// An highlighted block
mdzz = 'phpinfo();
';
}
function __destruct()
{
eval($this->mdzz);
}
}
if(isset($_GET['phpinfo']))
{
$m = new OowoO();
}
else
{
highlight_string(file_get_contents('index.php'));
}
?>
当new一个实例对象,会给属性mdzz赋值成phpinfo; 当销毁一个实例对象,会执行eval函数,说明我们需要得到一个实例对象,并且我们可以控制mdzz的值,再让它销毁,从而执行eval函数。
传入参数phpinfo,得到对方的配置图,
文章图片
结合ini_set(‘session.serialize_handler’, ‘php’); 配置中php_serialize的俩个值不同,php是当前脚本的配置,php_serialize是全局配置,是php.ini中设置的,可知该问题是php session反序列化问题。如果网站不同的php文件的写入Session的序列化方式与读取Session的反序列化方式不同,就可能导致漏洞的产生
各个配置的解释
配置 | 解释 |
---|---|
session.upload_progress.enabled | 是否启用上传进度报告(默认on),开启后会在上传文件时,将一个表示进度的数据结构传入$_SESSION |
session.upload_progress.cleanup | 是否在上传完成后及时删除进度数据(默认on,本题需要是off ) |
session.upload_progress.prefix | 默认是upload_progress_ |
session.upload_progress.name | 默认是PHP_SESSION_UPLOAD_PROGRESS |
session.serialize_handler | 对session进行序列化or反序列化的处理器:php、php_serialize(php>5.5.4)、php_binary |
session.save_handler | files表示session保存到会话文件中 |
配置 | 解释 |
---|---|
php | 对$_SESSION的每个元素对象单独调用serialize(),存储在文件。每个元素存储格式:键名+|+ serialize($_SESSION[‘key’]) |
php_serialize | serialize($_SESSION)返回的字符串存储在会话文件中 |
php_binary | 对$_SESSION的每个元素对象单独调用serialize(),存储在文件。存储规则:键名的长度对应的ASCII值+键名+serialize($_SESSION[‘key’])。 |
进度数据将存储在$_SESSION[ini_get(“session.upload_progress.prefix”).$_POST[ini_get(“session.upload_progress.name”)]]
如图:upload_progress_是session.upload_progress.prefix的值,
laruence是$_POST[ini_get(“session.upload_progress.name”)]的值。
文章图片
注入实例的实现 【jarvisoj phpinfo writeup及注入的变量详解】由phpinfo()页面继续可知,session.upload_progress.enabled为On
文章图片
且session.upload_progress.cleanup是off, 这两个配置决定了该上传进程的数据结构能保存在会话文件中。
自己写一个html文件实现 上传文件
抓包如图
文章图片
必须有上传一个参数,名是PHP_SESSION_UPLOAD_PROGRESS,值可以任意,
http报文中的filename的值对应$_SESSION[‘upload_progress_laruence’][‘files’][0][‘name’]
http报文中的name的值对应
$_SESSION[‘upload_progress_laruence’][‘files’][0][‘filed_name’]
这两处都可以实现攻击。
###具体过程的猜想:
上传文件时,记录上传进度数据到$_SESSION[‘upload_progress_laruence’],以php.ini中的session.serialize_handler指定的序列化方式保存在会话文件,
当对filename进行构造payload:
filname="|O:5:\“OowoO\”:1:{s:4:\“mdzz\”; s:20:\“var_dump($_SESSION); \”; }"
filname的字符串内容中的双引号必须加上\进行转义,否则会和filename=后的双引号闭合。
文章图片
下图,是在本地搭建环境下,查看会话文件的保存内容
文章图片
选中的字符串是filename的值,选中的字符串的后面的字符串在被php方式反序列化时,会被忽略。
但是当访问php文件时,且该文件带有ini_set(‘session.serialize_handler’, ‘php’); php文件将以该方式反序列化session文件中保存的数据,从而产生了OowoO类的实例,因为不是new产生的实例,不会执行__construct函数。php文件执行完后,销毁对象时,执行__destruct函数。
该php文件执行结束后,session又以php方式序列化保存$_SESSION。如图
文章图片
竖线后的字符会被反序列化成为实例对象,竖线前的字符作为SESSION数组中OowoO实例的key,
构造payload的方法:filename=”|serialize(OowoW实例对象)” (注:字符串内容中的双引号要加上\)
payload注入点二
其实不一定要在filename处写payload,只要使上传进度的数据中field_name的值是payload,也是可以实现的,field_name对应http报文中的name。尝试对name写入payload
文章图片
返回结果,表明执行了var_dump();
文章图片
最后,修改payload,使mdzz的值是print_r(scandir(dirname(FILE)));
文章图片
查出当前目录的文件
使mdzz=
print_r(file_get_contents("/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php"));
查出flag
文章图片
转载请注明出处
参考资料
https://www.cnblogs.com/sijidou/p/10455646.html
https://blog.csdn.net/wy_97/article/details/78430690
推荐阅读
- 解护网杯一道web(EasyChallenge)
- ctf|ctf-htctf-misc
- C++|一些关于程序内存布局的问题
- QCTF 2018xman夏令营选拔赛
- 第一届桂林电子科技大学绿盟杯CTF大赛 wp
- Capture the flag
- CTF|BUUOJ [2019红帽杯]easyRE
- Buuctf -web wp汇总(二)
- #|CTF-网络信息安全攻防学习平台(脚本关)
- ctf