upload-labs靶场通关详解:第12-13关
目录
第12关:get00截断
一、分析源代码
二、解题思路
三、解题步骤
第13关:post00截断
一、分析源代码
二、解题思路
三、解题步骤
第12关:get00截断
一、分析源代码
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$ext_arr = array('jpg','png','gif');$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);if(in_array($file_ext,$ext_arr)){$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = '上传出错!';}} else{$msg = "只允许上传.jpg|.png|.gif类型文件!";}
}
这一关开始变成了白名单验证,只允许上传jpg、png、gif这三种格式的文件。代码首先会对文件的扩展名进行验证,通过验证后将文件进行处理,修改文件名并存放到指定路径。
我们来看这行代码:
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
$img_path:是上传文件的目标保存路径。它由$_GET['save_path'](通过 URL 参数传递的保存目录)、随机数(rand(10, 99))、当前时间戳(date("YmdHis"))以及文件扩展名组合而成。这样做能保证文件名的唯一性。
上传的文件会被重命名保存在upload目录下。
二、解题思路
这一关用到的是00截断。在 C 语言和受其影响的编程语言(像 PHP)里,空字节(也就是\0,对应的 ASCII 码为 0)被用作字符串的结束符。当程序在处理包含空字节的字符串时,可能会错误地将空字节之后的内容忽略掉,把空字节前面的部分当作完整的字符串。
举个例子,攻击者上传一个名为shell.php%00.jpg的文件。这里的%00是 URL 编码后的空字节。当服务器处理这个文件名时:程序会提取扩展名,得到php%00.jpg。然而,由于空字节的存在,程序会错误地认为字符串在php之后就结束了,从而把扩展名识别为php。这样一来,文件就会被当作 PHP 文件执行,进而导致代码注入攻击。
00截断的利用条件:
1.上传路径可控;
2.配置文件php.ini中的magic_quotes_gpc = off。
注意:在 PHP 5.3.4 及以后的版本中,已经修复了00截断漏洞。
三、解题步骤
1.上传666.jpg,抓包,修改保存路径为xxx.php%00。
可以看到文件应该被命名为777.php�/1320250520193657.jpg,这个�就是00截断,在保存到服务器时,会被误以为到空字节就结束,所以文件被保存为777.php。
2.测试木马是否能被解析。
第13关:post00截断
一、分析源代码
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$ext_arr = array('jpg','png','gif');$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);if(in_array($file_ext,$ext_arr)){$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传失败";}} else {$msg = "只允许上传.jpg|.png|.gif类型文件!";}
}
通过代码可以发现这关和上一关的代码只修改了一个地方,就是get变成了post。
二、解题思路
我们知道get和post是http协议中两种常用的请求方法,get可以直接跟在url后面,而post会将参数放在请求体里面进行传输。
这一关的区别就在于,get方式中, 空字节的URL 编码是%00。而post方式中,服务器会直接处理原始 post数据,需要手动修改十六进制为00。
三、解题步骤
1.上传666.jpg,抓包,在请求体中找到文件保存路径,修改为“888.php,”。(,是为了方便下一步查找十六进制的位置)
2.编辑十六进制,这个“,”的十六进制就是2c,将2c改成00。
如下图:
2.文件上传成功,测试木马。