PHP建站技术分享-从入门到精通_各类知识收集PHP建站技术分享-从入门到精通_各类知识收集PHP建站技术分享-从入门到精通_各类知识收集

QQ:420220301 微信/手机:150-3210-7690
当前位置:首页 > 工作总结

PHP教程:你不知道的文件上传漏洞php代码分析

管理员 2025-02-26
工作总结
6

《PHP教程:你不知道的文件上传漏洞php代码分析》要点:
本文介绍了PHP教程:你不知道的文件上传漏洞php代码分析,希望对您有用。如果有疑问,可以联系我们。
 

漏洞描述PHP实例

开发中文件上传功能很常见,作为开发者,在完成功能的基础上我们一般也要做好安全防护.
文件处理一般包含两项功能,用户上传和展示文件,如上传头像.PHP实例

文件上传攻击示例
PHP实例

upload.phpPHP实例

<?php$uploaddir = 'uploads/'; $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)){ echo "File is valid, and was successfully uploaded.n";} else { echo "File uploading failed.n";}?>

upload.htmlPHP实例

<form name="upload" action="upload1.php" method="POST" ENCTYPE="multipart/formdata">Select the file to upload: <input type="file" name="userfile"><input type="submit" name="upload" value="upload"></form>

上述代码未经过任何验证,恶意用户可以上传php文件,代码如下PHP实例

<?php eval($_GET['command']);?>
PHP实例

恶意用户可以通过访问 如http://server/uploads/shell.php?command=phpinfo(); 来执行远程命令PHP实例

Content-type验证PHP实例

upload.phpPHP实例

<?phpif($_FILES['userfile']['type'] != "image/gif") {//获取Http请求头信息中ContentType echo "Sorry, we only allow uploading GIF images"; exit;}$uploaddir = 'uploads/';$uploadfile = $uploaddir.basename($_FILES['userfile']['name']);if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)){ echo "File is valid, and was successfully uploaded.n";} else { echo "File uploading failed.n";}?>

该方式是通过Http请求头信息进行验证,可通过修改Content-type ==> image/jpg绕过验证,可以通过脚本或BurpSuite、fiddle修改
如下
Content-Disposition: form-data; name="userfile"; filename="shell.php"
Content-Type: image/gifPHP实例

图片类型验证
PHP实例

该方法通过读取文件头中文件类型信息,获取文件类型PHP实例

备注:如JPEG/JPG文件头标识为FFD8PHP实例

PHP教程:你不知道的文件上传漏洞php代码分析PHP实例

upload.phpPHP实例

<?php$imageinfo = getimagesize($_FILES['userfile']['tmp_name']);if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg') { echo "Sorry, we only accept GIF and JPEG imagesn"; exit;}$uploaddir = 'uploads/';$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)){ echo "File is valid, and was successfully uploaded.n";} else { echo "File uploading failed.n";}?>

可以通过图片添加注释来绕过此验证.
如添加注释<?php phpinfo(); ?>,保存图片后将其扩展名改为php,则可成功上传.
上传成功后访问该文件则可看到如下显示PHP实例

PHP教程:你不知道的文件上传漏洞php代码分析PHP实例

文件扩展名验证PHP实例

 通过黑名单或白名单对文件扩展名进行过滤,如下代码PHP实例

upload.phpPHP实例

<?php$blacklist = array(".php", ".phtml", ".php3", ".php4");foreach ($blacklist as $item) {if(preg_match("/$item$/i", $_FILES['userfile']['name'])) { echo "We do not allow uploading PHP filesn"; exit;}}$uploaddir = 'uploads/';$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)){ echo "File is valid, and was successfully uploaded.n";} else { echo "File uploading failed.n";}?>

当黑名单不全,构造特殊文件名可以绕过扩展名验证PHP实例

直接访问上传的文件
PHP实例

将上传文件保存在非web root下其他文件夹下,可以防止用户通过路径直接访问到文件.
upload.phpPHP实例

<?php$uploaddir = 'd:/uploads/';$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {  echo "File is valid, and was successfully uploaded.n";} else {  echo "File uploading failed.n";}?>

用户不可以直接通过http://localhost/uploads/ 来访问文件,必须通过view.php来访问
view.phpPHP实例

<?php$uploaddir = 'd:/uploads/';$name = $_GET['name'];readfile($uploaddir.$name);?>

查看文件代码未验证文件名,用户可以通过例如http://localhost/view.php?name=..//php/upload.php,查看指定的文件PHP实例

解决漏洞示例PHP实例

upload.phpPHP实例

<?phprequire_once 'DB.php';$uploaddir = 'D:/uploads/'; $uploadfile = tempnam($uploaddir, "upload_");if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {  $db =& DB::connect("mysql://username:password@localhost/database");  if(PEAR::isError($db)) {    unlink($uploadfile);    die "Error connecting to the database";  }  $res = $db->query("INSERT INTO uploads SET name=?, original_name=?,mime_type=?",      array(basename($uploadfile,basename($_FILES['userfile']['name']),$_FILES['userfile']['type']));  if(PEAR::isError($res)) {    unlink($uploadfile);    die "Error saving data to the database. The file was not uploaded";  }  $id = $db->getOne('SELECT LAST_INSERT_ID() FROM uploads');  echo "File is valid, and was successfully uploaded. You can view it <a href="view.php?id=$id">here</a>n";} else {  echo "File uploading failed.n";}?>

view.phpPHP实例

<?phprequire_once 'DB.php';$uploaddir = 'D:/uploads/';$id = $_GET['id'];if(!is_numeric($id)) {  die("File id must be numeric");}$db =& DB::connect("mysql://root@localhost/db");if(PEAR::isError($db)) {  die("Error connecting to the database");}$file = $db->getRow('SELECT name, mime_type FROM uploads WHERE id=?',array($id), DB_FETCHMODE_ASSOC);if(PEAR::isError($file)) {  die("Error fetching data from the database");}if(is_null($file) || count($file)==0) {  die("File not found");}header("Content-Type: " . $file['mime_type']);readfile($uploaddir.$file['name']);?>

上述代码文件名随机更改,文件被存储在web root之外,用户通过id在数据库中查询文件名,读取文件,可以有效的阻止上述漏洞发生PHP实例

总结PHP实例

通过以上示例分析,可总结一下几点PHP实例

1.文件名修改,不使用用户上传的文件名PHP实例

2.用户不可以通过上传路径直接访问文件PHP实例

3.文件查看采用数据库获取文件名,从而在相应文件服务器读取文件PHP实例

4.文件上传限制文件大小,个人上传数量等PHP实例



希望以上内容对你有所帮助!如果还有其他问题,请随时提问。 各类知识收集 拥有多年CMS企业建站经验,对 iCMS, LeCMS, ClassCMS, Fastadmin, PbootCMS, PHPCMS, 易优CMS, YzmCMS, 讯睿CMS, 极致CMS, Wordpress, HkCMS, YznCMS, WellCMS, ThinkCMF, 等各类cms的相互转化,程序开发,网站制作,bug修复,程序杀毒,插件定制都可以提供最佳解决方案。

相关推荐

扫码关注

qrcode

QQ交谈

回顶部