为什么说 %00
过气了呢……
因为需要满足以下条件:
1. php版本小于5.3.4
2. php的magic\_quotes\_gpc为OFF状态
截断的核心,就是 chr(0)
这个字符
先说一下这个字符,这个字符不为空 (Null)
,也不是空字符 ("")
,更不是空格。
当程序在输出含有 chr(0)
变量时
chr(0)
后面的数据会被停止,换句话说,就是误把它当成结束符,后面的数据直接忽略,这就导致漏洞产生
<?php
$file = $_GET\['file'\].'PNG';
$contents = file\_get\_contents($file);
file\_put\_contents('put.txt', $contents);
?>
利用方式:
http://localhost/FileGetContents.php?file=password%00
此时可以看到当前目录 put.txt
是上面 password
中的内容。
原理很简单, %00
截断了后面的 .PNG
<html>
<body>
<h2>test</h2>
<form action="" method="post" enctype="multipart/form-data">
<label>文件:</label>
<input type="file" name = "file" >
<input type="submit" value="submit" name = "upload">
</form>
</body>
</html>
<?php
error_reporting(0);
if(isset($_POST\['upload'\]))
{
$ext_arr = array('flv','swf','mp3','mp4','3gp','zip','rar','gif','jpg','png','bmp');
$file_ext = substr($_FILES\['file'\]\['name'\],strrpos($_FILES\['file'\]\['name'\],".")+1);
if(in_array($file_ext,$ext_arr))
{
$tempFile = $_FILES\['file'\]\['tmp_name'\];
// 这句话的$_REQUEST\['jieduan'\]造成可以利用截断上传
$targetPath = $_SERVER\['DOCUMENT_ROOT'\].$_REQUEST\['jieduan'\].rand(10, 99).date("YmdHis").".".$file_ext;
if(move\_uploaded\_file($tempFile,$targetPath))
{
echo '上传成功'.'<br>';
echo '路径:'.$targetPath;
}
else
{
echo("上传失败");
}
}
else
{
echo("上传失败");
}
}
?>
问题就出在:
$targetPath = $_SERVER['DOCUMENT_ROOT'].$_REQUEST['jieduan'].rand(10, 99).date("YmdHis").".".$file_ext;
这里的 $_REQUEST['jieduan']
存在截断
可以上传文件名如下 sky.php%00.jpg
在 $_REQUEST['jieduan']
中, %00截断
了后面的代码
带入后就成了
targetPath=targetPath = \_SERVER\['DOCUMENT\_ROOT'\].sky.php;
再经过 move\_uploaded\_file(tempFile,tempFile,targetPath)
就成功传入了php恶意文件