upload-labs
文件上传漏洞被利用需要两个前提条件:
1、文件能上传成功
2、攻击者能知道文件路径
凡是上传图片并显示的关卡,都有三种方式可以知道文件路径
1、最简单直接的,在没显示出来的图片上右键选择“复制图像链接”,可以得到文件的绝对路径
2、网页上右键选择“查看页面源代码”,源代码中显示文件的相对路径
3、如果是用burpsuite上传的文件,response报文中也会显示文件的相对路径。
Pass-01(前端验证)
方法1:
浏览器disable JS
firefox可以安装一个叫Script Switch的插件,安装成功之后,就是下图右上角小红框里那个图标,使其处在JS disabled状态,上传x.php。出现下图这样没加载成功的图片表示webshell已经上传成功。
到服务器上看看,上传成功的webshell在 upload-labs目录\upload 文件夹下
方法2:
bp抓包修改后缀
蚁剑连接即可看到文件已经上传
Pass-02(ContentType)
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) |
第二关主要是对MIME进行检查(ContentType),直接修改为上面的三种类型就可以
Pass-03(修改httpd.ini)
姿势一:
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA |
可以进行双写绕过::$DA::$DATATA
首先上传个1.php,发现页面提示是”不允许上传……后缀文件“,并且burpsuite有抓到包,初步判断,这关可能是后端文件后缀黑名单过滤。
payload写一些有可能被解析为php的文件后缀的字符,大小写绕过,双写绕过,一些利用操作系统特性(比如服务器是windows系统的话,结尾加点,加空格,加::$DATA,后缀某几个字母大写)
上图的文件后缀是正常的,是有用的,用webshell管理工具连接的时候,文件名写202304071406293829.php就行
姿势二:
修改httpd.ini配置文件,将.php3,,php5,,phtml
作为php文件
Pass-04(.htaccess)
姿势一:
把后缀改成png之后,可以上传成功。可以初步判断,本关不检查文件内容,检查点应该在Content-Type或者文件后缀,或者两者都有。
先看看Content-Type有无影响。把Content-Type从image/png改成application/octet-stream,发送之后,发现文件依然能上传成功,说明本关Content-Type无影响。
接下来判断一下文件后缀是黑名单过滤还是白名单过滤:
文件后缀改成.xxx,发送后发现文件上传成功,说明本关还是文件后缀黑名单过滤
HTTP EXP:将文件后缀名改为“点+空格+点”的格式,这样file_ext会变为空,成功绕过黑名单上传。Windows会自动删除文件名最后的点,最后变为2.php。
Content-Disposition: form-data; name="upload_file"; filename="2.php. ." |
姿势二:
上传.htaccess
文件(分布式配置文件),优先等级高于http.ini,它的作用范围是本目录和其子目录
修改配置文件http.ini,将none改为All,允许.htaccess文件生效
·htaccess文件内容
AddType application/x-httpd-php .png //.png文件当作php文件执行 |
访问.png文件即可
Pass-05(.user.ini)
主要源码
$is_upload = false; |
姿势一:
和Pass-04一样,代码中只过滤了一次点,删除了空格和::$DATA,将文件后缀改为小写,黑名单等,使用Pass-04的方法绕过即可。但黑名单中屏蔽了.htaccess文件。
HTTP EXP:文件名改为“2.php. . ”。
姿势二:
利用.user.ini
文件,优先级高于php.ini
生效条件:上传目录里必须有php文件,serverAPI要是CGI/FastCGI (phpinfo可以进行查看)
Server API | CGI/FastCGI |
---|
内容
auto_prepend_file=info.png //php文件包含info.png |
Pass-6(大小写绕过windows下)
与上一关比较,少了一个将后缀转小写的操作
$file_ext = strtolower($file_ext); //转换为小写 |
因为windows系统对将.Php
转变成.php
,导致代码执行成功
Pass-7(空格绕过windows下)
少了一个首尾去空的函数
$file_ext = trim($file_ext); //首尾去空 |
直接在后缀后面加一个空格就行,因为windows系统特性会将文件后面空格删掉
抓包加空格
Pass-8(点绕过windows下)
少了一个deldot函数
$file_name = deldot($file_name);//删除文件名末尾的点 |
那我们可以在后缀加上点,就能绕过,操作同上
Pass-9(::$DATAwindows下)
在window的时候如果文件名+"::$DATA"
会把::$DATA
之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA
之前的文件名,他的目的就是不检查后缀名
目录里有一个1.txt文件
echo 456>1.txt:2.txt |
原1.txt的内容是不受影响的
我们在文件名加上::$DATA
,上传就行
Pass-10(点空格点绕过windows下)
看了源码,发现这些函数只验证一次,例如删除文件末尾的点
点空格点为什么能绕过?
有一个文件1.php. .
首先deldot函数会去掉末尾的一个点,变成1.php.
strrchr函数取的后缀是.
,然后去掉后面的.
,后缀就剩一个.了(不在黑名单中)
最后上传文件名是1.php.
Pass-11(双写绕过)
源码变了,但依旧是黑名单
$file_name = str_ireplace($deny_ext,"", $file_name); //文件名里有黑名单的后缀就会被替换成空 |
构造一个文件名1.pphphp
,它是从左到右序列替换的,替换后变成1.php
Pass-12(%00截断)
源码变了
$is_upload = false; |
save_path是一个可控变量,用%00进行截断,使用条件:
php版本小于5.3.4 |
上传.png图片
上传后url地址是这样的
我们访问1.php就行了
Pass-13(0x00绕过)
同样save_path是可控的,这个是post请求
在文件名后面随便加个字符,将它的hex编码改成00
访问同上
Pass-14(图片🐎)
准备php文件(里面是一句话木马),和一张普通图片
copy 13.jpg /b + 13.php webshell.jpg |
上传图片后,利用文件包含漏洞进行执行
Pass-15(图片🐎)
$info = getimagesize($filename); |
getimagesize()是PHP中用于获取图像的大小和格式的函数。它可以返回一个包含图像的宽度、高度、类型和MIME类型的数组
getimagesize()的基本语法如下:
$size = getimagesize($filename);
其中,$filename是要获取信息的图像文件的路径。该函数返回一个数组$size,数组元素如下:
$size[0]: 图像的宽度
$size[1]: 图像的高度
$size[2]: 图像的类型
$size[3]: 图像的MIME类型
$size[bits]: 图像的位深度
$size[channels]: 图像的通道数
$size[mime]: 图像的MIME类型
Array |
该值有如下常量:
IMAGETYPE_GIF: GIF格式
IMAGETYPE_JPEG: JPEG格式
IMAGETYPE_PNG: PNG格式
上面的3就代表是png格式的图片
同样图片马绕过
Pass-16(exif_imagetype)
//需要开启php_exif模块 |
上传包含一句话木马的图片,然后利用文件包含漏洞执行代码
Pass-17(二次渲染)
有二次渲染函数
imagecreatefromjpeg |
上传图片马之后,会将文件最后的php代码删掉
我们可以先上传图片马,然后用010和被渲染的图片进行对比,找到一样的部分(未被渲染的部分)
再上传就可以了
Pass-18(条件竞争)
unlink($upload_file); //文件类型不合规直接会被删除 |
我们可以多开几个线程,在还没删除之前就执行代码
抓包上传php文件,开两个爆破页面,一个写,一个读