只验证MIME类型: 代码中验证了上传的MIME类型,绕过方式使用Burp抓包,将上传的一句话小马*.PHP
中的Content-Type:application/PHP
,修改成Content-Type: image/png
然后上传.
<?PHP
header("Content-type: text/html;charset=utf-8");
define("UPLOAD_PATH","./");
if(isset($_POST['submit']))
{
if(file_exists(UPLOAD_PATH))
{
// 判断 content-type 的类型,如果是image/png则通过
if($_FILES['upload_file']['type'] == 'image/png')
{
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name'];
if (move_uploaded_file($temp_file,$img_path))
echo "上传完成.";
else
echo "上传出错.";
}
}
}
?>
<body>
<form enctype="multipart/form-data" method="post">
<input class="input_file" type="file" name="upload_file">
<input class="button" type="submit" name="submit" value="上传">
</form>
</body>
白名单的绕过: 白名单就是允许上传某种类型的文件,该方式比较安全,抓包上传PHP后门,然后将文件名改为.jpg即可上传成功,但是有时候上传后的文件会失效无法拿到Shell.
<?PHP
header("Content-type: text/html;charset=utf-8");
define("UPLOAD_PATH","./");
if(isset($_POST['submit']))
{
if(file_exists(UPLOAD_PATH))
{
$allow_ext = array(".jpg",".png",".jpeg");
$file_name = trim($_FILES['upload_file']['name']); // 取出文件名
$file_ext = strrchr($file_name,'.');
$file_ext = str_ireplace('::$DATA','',$file_ext); //去除字符串::$DATA
$file_ext = strtolower($file_ext); // 转换为小写
$file_ext = trim($file_ext); // 首尾去空
if(in_array($file_ext,$allow_ext))
{
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path))
echo "上传完成: {$img_path} <br>";
else
echo "上传失败 <br>";
}
}
}
?>
<body>
<form enctype="multipart/form-data" method="post">
<input class="input_file" type="file" name="upload_file">
<input class="button" type="submit" name="submit" value="上传">
</form>
</body>
白名单验证文件头: 本关主要是允许jpg/png/gif这三种文件的传输,且代码中检测了文件头的2字节内容,我们只需要将文件的头两个字节修改为图片的格式就可以绕过.
通常JPEG/JPG: FF D8 | PNG:89 50 | GIF:47 49
以JPEG为例,我们在一句话木马的开头添加两个11也就是二进制的3131,然后将.PHP修改为.jpg,使用Brup抓包发送到Repeater模块,将HEX编码3131
改为FFD8
点Send后成功上传JPG.
<?PHP
header("Content-type: text/html;charset=utf-8");
define("UPLOAD_PATH","./");
function getReailFileType($filename)
{
$file = fopen($filename,"rb");
$bin = fread($file,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;
}
if(isset($_POST['submit']))
{
if(file_exists(UPLOAD_PATH))
{
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_type = getReailFileType($temp_file);
if($file_type == 'unkNown')
{
echo "上传失败 <br>";
}else
{
$img_path = UPLOAD_PATH."/".rand(10,99).date("YmdHis").".".$file_type;
if(move_uploaded_file($temp_file,$img_path))
echo "上传完成 <br>";
}
}
}
?>
<body>
<form enctype="multipart/form-data" method="post">
<input class="input_file" type="file" name="upload_file">
<input class="button" type="submit" name="submit" value="上传">
</form>
</body>
绕过检测文件头: 这种方式是通过文件头部起始位置进行匹配的从而判断是否上传,我们可以通过在上传文件前面追加合法的文件头进行绕过,例如在文件开头部位加上GIF89a<?PHP PHPinfo();?>
即可完成绕过,或者如果是\xffxd8\xff
我们需要在文件开头先写上%ff%d8%ff<?PHP PHPinfo(); ?>
然后,选择特殊字符,右击CONVERT->URL->URL-Decode
编码后释放.
<?PHP
header("Content-type: text/html;charset=utf-8");
define("UPLOAD_PATH","./");
function getReailFileType($filename)
{
$fh = fopen($filename,"rb");
if($fh)
{
$bytes = fread($fh,6);
fclose($fh);
if(substr($bytes,3) == "\xff\xd8\xff" or substr($bytes,3)=="\x3f\x3f\x3f"){
return "image/jpeg";
}
if($bytes == "\x89PNG\x0d\x0a"){
return "image/png";
}
if($bytes == "GIF87a" or $bytes == "GIF89a"){
return "image/gif";
}
}
return 'unkNown';
}
if(isset($_POST['submit']))
{
if(file_exists(UPLOAD_PATH))
{
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_type = getReailFileType($temp_file);
echo "状态: {$file_type} ";
if($file_type == 'unkNown')
{
echo "上传失败 <br>";
}else
{
$file_name = $_FILES['upload_file']['name'];
$img_path = UPLOAD_PATH . "/" . $file_name;
if(move_uploaded_file($temp_file,$img_path))
echo "上传 {$img_path} 完成 <br>";
}
}
}
?>
<body>
<form enctype="multipart/form-data" method="post">
<input class="input_file" type="file" name="upload_file">
<input class="button" type="submit" name="submit" value="上传">
</form>
</body>
图像检测绕过: 通过使用图像函数,检测文件是否为图像,如需上传则需要保持图像的完整性,所以无法通过追加文件头的方式绕过,需要制作图片木马上传.
针对这种上传方式的绕过我们可以将图片与fig文件合并在一起copy /b pic.gif+shell.PHP 1.PHP
上传即可绕过.
<?PHP
header("Content-type: text/html;charset=utf-8");
define("UPLOAD_PATH","./");
function getReailFileType($filename)
{
// 检查是否为图像
if(@getimagesize($filename))
{
if(@imagecreatefromgif($filename)){
return "image/gif";
}
if(@imagecreatefrompng($filename)){
return "image/png";
}
if(@imagecreatefromjpeg($filename)){
return "image/jpeg";
}
}
return 'unkNown';
}
if(isset($_POST['submit']))
{
if(file_exists(UPLOAD_PATH))
{
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_type = getReailFileType($temp_file);
echo "状态: {$file_type} ";
if($file_type == 'unkNown')
{
echo "上传失败 <br>";
}else
{
$file_name = $_FILES['upload_file']['name'];
$img_path = UPLOAD_PATH . "/" . $file_name;
if(move_uploaded_file($temp_file,$img_path))
echo "上传 {$img_path} 完成 <br>";
}
}
}
?>
<body>
<form enctype="multipart/form-data" method="post">
<input class="input_file" type="file" name="upload_file">
<input class="button" type="submit" name="submit" value="上传">
</form>
</body>
上传之目录穿越:
<?PHP
// upload/dir/loop/
header("Content-type: text/html;charset=utf-8");
if(isset($_POST['submit']))
{
$uploaddir = "upload/" . $_POST['UPLOAD_DIR'] . "/";
var_dump($uploaddir);
if(file_exists($uploaddir))
{
if(move_uploaded_file($_FILE['upfile']['tmp_name'],$uploaddir . "/" . $_FILE['upfile']['name']))
echo "文件上传完成: " . $uploaddir . $_FILE['upfile']['name'] . "\n";
else
echo "上传失败.";
}
else
{
echo "文件目录不存在: /upload/file/";
}
}
?>
<body>
<script type="text/javascript">
function checkFile()
{
var file = document.getElementsByName('upfile')[0].value;
if(file == null || file=="")
return false;
}
</script>
<form action enctype="multipart/form-data" method="post" name="upload">
<input type="hidden" name="MAX_FILE_SIZE" value="204800">
<input type="hidden" name="UPLOAD_DIR" value="file">
选择文件:
<input type="file" name="upfile">
<input type="submit" name="submit" value="上传">
</form>
</body>
上传条件竞争: 这里是条件竞争,先将文件上传到服务器,然后判断文件后缀是否在白名单里,如果在则重命名,否则删除,因此我们可以上传1.PHP只需要在它删除之前访问即可,可以利用burp的intruder模块不断上传,然后我们不断的访问刷新该地址即可
<?PHP
header("Content-type: text/html;charset=utf-8");
define("UPLOAD_PATH","./");
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);
echo "上传完成. <br>";
}else
{
unlink($upload_file);
echo "上传失败. <br>";
}
}
}
?>
<body>
<form enctype="multipart/form-data" method="post">
<input class="input_file" type="file" name="upload_file">
<input class="button" type="submit" name="submit" value="上传">
</form>
</body>
文件上传: 通过判断文件Content-Type
来拒绝非图片文件上传,并且验证文件后缀,基于黑名单验证,一般会使用白名单验证。
<html>
<body>
<form enctype="multipart/form-data" method="post">
<input class="input_file" type="file" name="upload_file">
<input class="button" type="submit" name="submit" value="上传图片">
</form>
</body>
</html>
<?PHP
define("UPLOAD_PATH","./tmp");
$is_upload = false;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
# 判断文件MIME (Content-Type: image/jpeg) 参数,该参数是可以伪造的!
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png')) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name'];
# 下面则是采用黑名单验证机制,用于验证文件后缀不在这些列表中的文件
$deny_ext = array(".PHP",".PHP",".PHP",".PHP",".html",".htm",".htaccess",".ini");
$file_name = $_FILES['upload_file']['name']; # 取出文件的名字
$file_suffix = strrchr($file_name,'.'); # 取出FileName的后缀 .jpg
$file_suffix = strtolower($file_suffix); # 强制将后缀转换为小写
$file_suffix = trim($file_suffix); # 首尾去空
if (!in_array($file_suffix,$deny_ext)){
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
echo "上传图片成功: " . $img_path . "<br>";
} else {
$is_upload = false;
echo "上传图片失败!" . "<br>";
}
}
}
}
}
?>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。