安全-Pass14之文件头绕过(upload-labs)
Posted 小狐狸FM
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安全-Pass14之文件头绕过(upload-labs)相关的知识,希望对你有一定的参考价值。
前言
- 前面13关的笔记已经对
php
的源码分析过了,之后的关卡代码类似,就不再一步步分析了php
即Hypertext Preprocessor
超文本预处理器,多用于web
后端- BUUCTF的upload-labs在线靶场和本地的靶场有点差别,如果用文章的方法没法绕过时,注意看一下源码是否一致
相关介绍
其他介绍
一、题目
php
后端代码
function getReailFileType($filename){
$file = fopen($filename, "rb");
$bin = fread($file, 2); //只读2字节
fclose($file);
$strInfo = @unpack("C2chars", $bin);
$typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
$fileType = '';
switch($typeCode){
case 255216:
$fileType = 'jpg';
break;
case 13780:
$fileType = 'png';
break;
case 7173:
$fileType = 'gif';
break;
default:
$fileType = 'unknown';
}
return $fileType;
}
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_type = getReailFileType($temp_file);
if($file_type == 'unknown'){
$msg = "文件未知,上传失败!";
}else{
$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = "上传出错!";
}
}
}
二、WriteUp
[1]. 函数介绍
getReailFileType
是靶场自己设置的函数
@
是错误控制运算符,在函数前面添加@
符号表示屏蔽错误提示
PHP函数 | 介绍 |
---|---|
date(格式) | 以固定的时间格式获取当前系统的时间 |
fopen(文件路径,模式) | 以指定的模式打开文件,返回文件指针 |
fread(文件指针,字节个数) | 获取文件中指定字节个数的内容 |
fclose(文件指针) | 关闭一个文件指针 |
intval(变量) | 获取变量的整数值 |
move_uploaded_file(文件路径,文件夹路径) | 将文件移动到指定文件夹下 |
rand(数字1,数字2) | 从数字1到数字2的范围内生成随机数,两个数字都有包含在内 |
@unpack(模式,二进制数据) | 以指定模式,从二进制字符串对数据进行解包 |
[2]. 源码审计
创建
upload.php
和show.php
文件,将题目中重要的代码贴进去,show.php
用于显示变量的内容
<form enctype="multipart/form-data" method="post" action="show.php">
<p>上传图片</p>
<input class="input_file" type="file" name="upload_file"/>
<input class="button" type="submit" name="submit" value="提交"/>
</form>
<?php
$filename = $_FILES['upload_file']['tmp_name'];
$file = fopen($filename, "rb");
$bin = fread($file, 2); //只读2字节
fclose($file);
$strInfo = @unpack("C2chars",$bin);
$typeCode = intval($strInfo["chars1"].$strInfo["chars2"]);
echo $filename;//显示上传的路径
echo "<br>";
echo $bin;//显示文本前两个字节内容
echo "<br>";
echo $strInfo;//数组
echo "<br>";
echo $strInfo["chars1"];//第一个字节
echo "<br>";
echo $strInfo["chars2"];//第二个字节
echo "<br>";
echo $typeCode;//显示前两个字节的十六进制数
?>
- 使用
winhex
或010editor
创建一个文件,在ascii
位置任意输入内容- 1 byte(字节) = 8 bit(比特)
1 hex(十六进制) = 4 bit(比特)
再上传文件,测试
php
代码中各个变量的内容
变量$filename
被赋值成了上传文件的tmp_name
临时保存路径,这个值每上传一次都会变化,不会影响最终结果
变量 | 值 |
---|---|
$filename | C:\\Windows\\php95C6.tmp |
$bin | ni |
$strInfo | Array |
$strInfo[“chars1”] | 110 |
$strInfo[“chars2”] | 105 |
$typeCode | 110105 |
110
和105
分别是字符n
和i
的ASCII
码值
所以我们需要绕过的话就只需要修改前两个字节(前四位十六进制数)的内容
字符 | ASCII | 十六进制数 |
---|---|---|
n | 110 | 6E |
i | 105 | 69 |
在
getReailFileType
函数中有一个switch
用来判断文件的前两个字节的内容
如果文本的前两个字节不为255216
、13780
或7173
时,函数返回的变量值就是unknown
[3]. 绕过
使用
winhex
或010editor
创建一个十六进制文件,先将前两个字节替换成下方图片类型对应的十六进制数
十进制 | 十六进制 | 类型 |
---|---|---|
255 216 | FF D8 | jpg |
137 80 | 89 50 | png |
71 73 | 47 49 | gif |
再添加一句话木马进去
成功绕过限制上传了木马文件,因为图片马需要结合文件包含的漏洞才能连接shell,所以能够绕过限制上传完整的木马文件就达成了目的
以上是关于安全-Pass14之文件头绕过(upload-labs)的主要内容,如果未能解决你的问题,请参考以下文章
安全-Pass07之黑名单空格绕过(upload-labs)
安全-Pass10之黑名单点空点绕过(upload-labs)