文件上传
文件上传漏洞
如果对文件上传路径变量过滤不严,并且对用户上传的文件后缀以及文件类型限制不严,攻击者可通过 Web 访问的目录上传任意文件,包括网站后门文件(webshell),进而远程控制网站服务器。
webshell
就是以asp、php、jsp或者cgi等网页文件形式存在的一种代码执行环境
使用方法简单,只需上传一个代码文件,通过网址访问,便可进行很多日常操作
解题步骤
1、判断题目利用的漏洞方式为读取、写入、还是执行,如果不能立刻确定就由低到高一次挖掘。(先找文件读取、再找文件写入、再找命令执行)先确定出最终要拿到的权限方向
2、判断漏洞的大概类型即考点,实现漏洞利用
3、寻找敏感数据
网站检测机制与防护手段
通常检查文件后缀,分为两种
白名单过滤
只允许上传它指定的文件后缀,这种过滤在没有其他漏洞辅助的情况下几乎不可能绕过
黑名单过滤
就是不允许上传它指定的文件后缀
一些绕过
双写绕过
原理:服务端对黑名单中的内容进行处理 ,将⿊名单的字符串替换为空 ,且仅处理一次,比如说使用str_replace()函数,所以可以通过双写后缀绕过。
比如黑名单有php,上传一个a.php文件,经过服务器端检测后会将其更改为a.文件
绕过方法就是写成a.pphphp,经过服务器端检测后中间的pphphp中间的php被替换为空,最终文件名会变成a.php上传到服务器
a.php=>a.pphphp
黑名单后缀绕过
后缀替换
| 文件拓展名 | 等价拓展名 |
|---|---|
| php | phtml、php2、php3、php4、php5、phps |
| aspx | ashx、asmx、ascx |
| asp | asa、cer、cdx |
| jsp | jspx、jspf、jspa、jsw、jsv、jtml |
%00截断
php版本<5.3.4
原理:无论是0x00、%00、/00,最终被解析后都是:chr(0)
chr()是一个函数,这个函数是用来返回参数所对应的字符的,也就是说,参数是一个ASCII码,返回的值是一个字符,类型为string
00截断就是在后缀中插入一个空字符(不是空格)
例如在文件1.php.jpg中插入空字符变成:1.php.0x00.jpg中,解析后就会只剩下1.php
方法
1、bp抓包
2、在文件名插入一个空格
3、在HEX中找到空格应的16进制编码‘20’,把它改成00,就可以插入空字符
对文件内容检测的绕过
1、其他标签绕过
如果检测的是<?php ··· ?>这些标签可以用其他标签绕过
1 | |
或者(过滤php)
1 | |
或者
1 | |
2、脏数据绕过
适⽤于对⽂件⼤⼩没有限制的 有时候服务器可能为了追求效率,对上传的⽂件只检测部分内容或者特定部分的内容,这时候可以利⽤脏数据
生成脏数据的脚本
1 | |

3、敏感内容绕过(免杀马)
如果检测的是敏感内容
1 | |
用法
1 | |
4、替换大小写绕过
如:将Content-Disposition修改为content-Disposition
将form-data修改为Form-data
将Content-Type修改为content-Type
5、通过删减空格绕过
6、等效替换绕过
添加空格
原内容:
1 | |
修改后:
1 | |
boundary后面加入空格。
7、通过字符串拼接来绕过
用+拼接字符
1 | |
将form-data改为f+orm-data
将from-data改为form-d+ata
8、双文件上传绕过
9、HTTP header 属性值绕过
1 | |
我们通过替换form-data 为*来绕过
10、 修改编码绕过
使用UTF-16、Unicode、双URL编码等
11、HTTP header 属性名绕过
源码
1 | |
绕过
1 | |
删除掉ontent-Type: image/png只留下c,将.php加c后面即可,但是要注意额,双引号要跟着c.php”.
12、命令函数绕过
如果检测eval之类的,用assert或者其他
13、传参方式检测
若不允许POST,GET传参这类可以用Cookie之类的绕过
方法
1 | |
cGhwaW5mbygpOw==这是对phpinfo的base64编码
检查文件头
原理:每个类型的文件都会有不一样的开头和标识符,服务器端可能会检查这些标识符,从而判断上传的文件是否合法
| 格式 | 文件头 |
|---|---|
| JPEG(jpg) | FFD8FF |
| PNG(png) | 89504E47 |
| GIF(gif) | 47494638 |
| ZIP Archive(zip) | 504B0304 |
| RAR Archive(rar) | 52617221 |
| Wave(wav) | 57415645 |
| HTML(html) | 68746D6C3E |
| XML(xml) | 3C3F86D6C |
绕过方法
只要在上传的内容加入幻术头字节(可以用010,也可以制作图片马)
前端js绕过
禁用JS
直接在浏览器中禁用JS脚本,让JS脚本不发挥作用

f12+f1直接禁用js
禁用后直接可以上传.php后缀名文件
bp拦截抓包
上传允许的后缀名文件,bp抓包后修改后缀名

MIME检查
一、什么是MIME
概念
媒体类型MIME,是一种标准,用来表示文档、文件或字节流的性质和格式
语法/通用结构type/subtype
由类型与子类型两个字符串中间用’/‘分隔而组成。
不允许空格存在
type表示可以被分多个子类的独立类别
subtype表示细分后的每个类型
MIME类型对大小写不敏感,但是传统写法都是小写
类型举例
1 | |
二、解决方法
bp抓包
将Content_Type,将application/octet-stream修改为image/jpeg或image/png即可上传
二次渲染
为了压缩图片对图片进行二次渲染,会删除图片中的恶意代码。在源码中使用imagecreatefromgif函数对图片进行二次生成
方法
1、制作图片马
2、将原图片上传, 下载渲染后的图片进行对比 (用010比较),搜索相同,在相同区域填写一句话木马或者恶意指令
$DATA绕过
原理:在 Windows 的 NTFS ⽂件系统⽀持⼀种叫做 Alternate Data Streams ( ADS ,备⽤数据流)的特性
- 什么是 ADS ?: ADS 允许⼀个⽂件包含多个 “ 数据流 ” 。你可以把它想象成⼀本书,主内容( $DATA 流)是 书的正⽂,但书还可以有附录、索引等额外的部分(其他数据流),它们都绑定在同⼀本书(⽂件名)上。
- 默认流:当⼀个⽂件被创建时,它的默认数据流就是 ::$DATA 。也就是说,你平常创建和编辑的 ⽂件,其完整名称实际上是 a.php::$DATA 。在⼤多数情况下,系统会⾃动隐藏 ::$DATA 部分。
- 特殊语法:在⽂件名后加上 a.php ::$DATA 是 NTFS 系统层⾯上的⼀个合法操作,⽤于指定要操作的是哪个数据流。
如果上传的⽂件名为 shell.php::$DATA ,服务器看到⽂件名末尾是⼀个⾮可执⾏⽂件,于是放⾏
当 Windows 系统接收到指令要创建⼀个名为shell.php ::$DATA ⽂件时,它会正确地将其识别为向shell.php ⽂件的默认数据流写⼊数据
所以就会在服务器上⽣成⼀个shell.php ⽂件 其内容和上传的内容相同
条件竞争
原理:利⽤服务器端 “ 检查⽂件 ” 和 “ 使⽤⽂件 ” 两个操作之间存在的⼀个微⼩的时间窗⼝,在这个极短的时间内,通过⾼并发请求,使⼀个恶意⽂件在被删除或被处理之前被执⾏
exp
1 | |
- ⽂件移动:代码先使⽤ move_uploaded_file 函数将上传的临时⽂件移动到⽬标⽬录,此时⽂件已经被放置在⽬ 标⽬录中,但还未进⾏⽂件类型检查
- 时间间隔:在⽂件移动完成后,代码才开始检查⽂件扩展名是否合法。在这个时间间隔内,攻击者可以利⽤多线 程或脚本快速地多次上传⽂件,并且在服务器进⾏⽂件类型检查之前,修改服务器上⽂件的扩展名或内容
- 绕过检查:如果攻击者在⽂件类型检查之前将⽂件扩展名修改为合法的扩展名,或者利⽤⽂件包含访问图⽚⻢等⽅式让服务器以恶意代码的形式执⾏⽂件,就可以绕过⽂件类型检查,实现恶意⽂件的上传和执⾏,所以可以利⽤ bp 的 Intruder 不断的发送请求,然后去访问上传的⽂件位置,可能会访问到
配置文件
.htaccess文件
利用条件:Apache环境下可利用
Apache中的一个配置文件,中间件是Apache才能用
可以实现 网页301重定向、自定义404错误页面,改变文件扩展名、允许/阻止特定的用户或者目录的访问,禁止目录列表,配置默认文档等功能
利用htaccess文件getshell
分析源码
如果对php,asp,jsp等进行过滤,大小写的方式也不行,但是可以上传.jpg文件,可是 .jpg只有解析成 php文件才能getshell
因此我们需要先上传 .htaccess 文件,然后再上传 .jpg文件
创建.htaccess文件
在本地(记事本就行)创建一个.htaccess文件
1 | |
这个代码是将题目要求的文件类型被解析为PHP文件
上传.htaccess文件
上传一句话木马
利用bp抓包上传一句话木马,这里要注意的是文件名称必须和.htaccess中的文件名相同
访问
获取绝对路径返回网站访问,可以蚁剑链接也可以用hackbar执行命令
.user.ini文件
利用条件:上传目录下必须有一个可执行的php文件
php.ini是 PHP 的一个全局配置文件,对整个 Web 服务器起作用,而.user.ini和.htaccess文件都可以看作是用户自定义的php.ini,其中.user.ini比.htaccess用的更广,不管是nginx、apache、IIS,只要是以fastcgi运行的 PHP 都可以用这个方法,但也有局限性,就是上传文件的目录下一定要有一个可执行的 PHP 文件
直接使用
如果黑名单没有限制.user.ini
先上传一个.user.ini文件,文件内容是包含一个1.txt
1 | |
然后上传123.txt
1 | |
然后访问index.php即可,POST传参输入命令
搭配协议使用
同样按上述步骤可以上传但不能解析时,就想到可以包含伪协议的,只要环境支持伪协议
1 | |
