沉于思考,默默学习!

你不能预知明天,但你可以利用今天。你不能样样顺利,但你可以事事尽力!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  63 随笔 :: 0 文章 :: 712 评论 :: 0 引用

我们通过前篇:web上存漏洞及原理分析、防范方法 学习,已经知道后端获取服务器变量,很多来自客户端传入的。跟普通的get,post没有什么不同。下面我们看看,常见出现漏洞代码。

1、检测文件类型,并且用用户上存文件名保存

if(isset($_FILES['img']))
{
    $file = save_file($_FILES['img']);
	if($file===false) exit('上存失败!');
	
	echo "上存成功!",$file;
}

function check_file($img)
{
	///读取文件
	if($img['error']>0) return false;
	
	$tmpfile = $img['tmp_name'];
	$filename = $img['name'];
	
	
	///读取文件扩展名
	$len=strrpos($filename,".");
	if($len===false) return false;
	
	//得到扩展名
	$ext = strtolower(substr($filename,$len+1));
	if(!in_array($ext,array('jpg','jpeg','png'))) return false;
	return true;
}

function save_file($img)
{
	if(!check_file($img)) return false;
	
	//格式检测ok,准备移动数据
	$filename = $img['name'];
	$newfile = "upload/" .$filename;
	if(!move_uploaded_file($img["tmp_name"],$newfile)) return false;
	
	return $newfile;

}
?>

以上代码,对输入类型也做了判断,看了没有问题。但是问题,确恰恰出现在对获取的用户名变量检测上面。直接获取传入用户名,然后存为文件。 有朋友会说:这些文件名都是我电脑里面存在的,文件名格式都受限于操作系统对文件名定义。 但是,需要注意是,对于$_FILES里面获取变量,是直接来自http request请求。它跟普通获取其它get,post变量一样。 因此,别有用心的人,往往会自己模拟浏览器,给服务器发送一个特殊文件名。然后,让存文件时候,能够正常保存为自己格式。

前些年,”\0” 在字符串中,保存为文件,会自动截断后面内容。 如:$filename 构造为:”a.php\0.jpg” ,我们想想,将会变成怎么样?

$newfile = “upload/a.php\0.jpg” 因为,对扩展名验证,最右边”.”后面字符是jpg ,是允许图片格式。 但是,我们一以该文件名,保存。 发现磁盘会在upload目录下面生成a.php ,\0后面所有字符,被自动截断。

该漏洞,风靡一时。当时几乎大多数上存网站都有漏洞。一时,很多平台关闭了上存。其实,根本原因就在此。我们拿到文件名,自己作为最终生成文件名保存了。  好的方法,是自己随机生成文件名+读取扩展名 。这样可以组织输入特殊字符,在进行文件保存时候,被抛弃或截断了。

php4时代这个漏洞可以利用,到php5时代,生成的变量文件名值中,会自动过滤掉”\0” ,这样无论用户构造怎么样的特殊”\0”用户名,都会被截断。 但是 ,目前这类漏洞,在asp,jsp 等站点。还经常有出现。老版本的php站点也会经常出现。

 

好了,今天先到这里,后面还有2种其它常见方法,后面给出!欢迎交流!

作者:chengmo  QQ:8292669 
原文网址:http://blog.chacuo.net/136.html 
订阅保持关注:http://blog.chacuo.net/feed 
本文版权归作者所有,欢迎转载,请务必添加原文链接。

posted on 2013-06-03 09:08 程默 阅读(...) 评论(...) 编辑 收藏