http://web.jarvisoj.com:32784/
index.php
1 |
|
存在 phpinfo.php 文件,由此可知 session.upload_progress.enabled
为 On,session.serialize_handler
为 php_serialize
,与 index.php 页面所用的 PHP 存储引擎不同,存在反序列化攻击。session.upload_progress.name
为 PHP_SESSION_UPLOAD_PROGRESS
,可以本地创建 form.html,一个向 index.php 提交 POST 请求的表单文件,其中包括PHP_SESSION_UPLOAD_PROGRESS
变量。
form.html
1 | <form action="http://web.jarvisoj.com:32784/index.php" method="POST" enctype="multipart/form-data"> |
使用 bp 抓包,在 PHP_SESSION_UPLOAD_PROGRESS
的 value
值123后面添加 | 和序列化的字符串
查看根目录文件
查看根目录路径
读取 flag
利用条件: 存在文件包含,session
文件的路径已知,且文件中的内容可控。session
文件的路径可从 phpinfo
中得知,
或者进行猜测
1 | /var/lib/php/sessions/sess_PHPSESSIONID |
例子1:
session.php
1 |
|
include.php
1 |
|
往 session.php 传入一句话,写入 session
文件中
1 | session.php?s=phpinfo(); |
在 cookie
中 PHPSESSID
值为 k82hb2gbrj7daoncpogvlbrbcp
,即 session
存储的文件名为 sess_k82hb2gbrj7daoncpogvlbrbcp
,路径可以猜测一下,这里为 /var/lib/php/sessions/
include.php 文件包含 session
存储文件
1 | /include.php?i=/var/lib/php/sessions/sess_k82hb2gbrj7daoncpogvlbrbcp |
例子2:
XCTF2018-Final_bestphp
这里就取其中的小部分代码
bestphp.php
1 |
|
这里设置了 open_basedir
,限制了我们读取文件的范围,这里 session
文件是保存在 /var/lib/php/session/
下,不在读取的范围里,这里可以考虑修改一下 session
文件存储的位置。
session_start()
函数从 PHP7
开始增加了 options
参数,会覆盖 php.ini 中的配置。
利用 session_start
覆盖 php.ini 文件中的默认配置 session.save_path
的值,并写入
1 | http://192.168.1.101/bestphp.php/?function=session_start&save_path=/var/www/html |
成功包含 session 文件
其实这个操作也可以由 session_save_path()
函数来完成,但是这个函数传入的参数是个字符串,不适用于此题。
利用条件:知道所使用的 PHP session
存储引擎,以及 session
文件内容可控。
这里就以2020虎符杯-babyupload 为例
index.php
1 |
|
这是一个存在上传和下载文件的功能的文件,只有当$_SESSION['username'] ==='admin'
才能获取 flag
。 我们可以通过下载查看 session
文件所使用的存储引擎,然后通过相同的存储引擎伪造为 admin
,上传 session
文件 ,获取 flag
。
首先下载 session
文件,文件名为 sess_PHPSESSID
1 | http://192.168.100.16/index.php |
可知使用的是 php_binary
。
内容为:
1 | <0x08>usernames:5:"guest"; |
猜测我们只要上传一个 session
文件内容为:
1 | <0x08>usernames:5:"admin"; |
发现如果不上传 attr
参数,dir_path
会直接拼接上传的文件名+"_".hash_file("sha256",$_FILES['up_file']['tmp_name']);
如果把上传文件名设置为 sess
,并且不传递 attr
参数,就可以得到/var/babyctf/sess_XXXXXXXXX
,这就可以当成 session
文件。hash_file()
是根据文件内容得到的 hash
值
本地创建一个文件名为sess:
上传 sess 文件
计算 hash 值
文件名为 sess_432b8b09e30c4a75986b719d1312b63a69f1b833ab602c9ad5f0299d1d76a5a4
,尝试下载访问,如下可知已经上传成功。
现在就差 success.txt, 可以把 attr
参数设置为 success.txt
将 success.txt 变成一个目录,从而绕过了限制。
然后将 PHPSESSID
修改为432b8b09e30c4a75986b719d1312b63a69f1b833ab602c9ad5f0299d1d76a5a4
,就可以得到 flag
这里对 PHP session 常见的利用点进行一次汇总,当然肯定还有其他利用方式,等自己以后遇到再补充吧。
https://www.w3school.com.cn/php/php_sessions.asp
https://www.cnblogs.com/st-leslie/p/8016951.html
https://www.php.net/manual/zh/book.session.php
https://blog.spoock.com/2016/10/16/php-serialize-problem/
https://cloud.tencent.com/developer/article/1487037
https://zhuanlan.zhihu.com/p/90879209
Author: 哒琳
Permalink: http://blog.jieis.cn/2022/180b402f-c2f3-4ca4-a143-bcf860899c9d.html
Comments