函数
move_uploaded_file
move_uploaded_file ( string $filename , string $destination ) : bool
$filename 上传的文件的文件名。
$destination 移动文件到这个位置。
本函数检查并确保由 filename 指定的文件是合法的上传文件(即通过 PHP 的 HTTP POST
上传机制所上传的)。如果文件合法,则将其移动为由 destination 指定的文件。
move_uploaded_file—>传送门1
move_uploaded_file—>传送门2
文件上传漏洞
文件上传漏洞是最早的漏洞,也是最容易理解的漏洞,代码都写再文件里面执行,如果能吧文件上传到管理员或者应用程序不想让你上传的目录,那就存在文件上传漏洞。挖洞经验
文件上传中的上传点都是调用一个上传类,上传函数为move_uploaded_file()
而文件上传又只有这一个函数,所以文件上传在代码审计的时候,最快的方式就是去搜索 move_uploaded_file()函数
几个文件上传漏洞代码分析
未过滤或本地过滤
move_uploaded_file($_FILES["file"]["tmp_name"],$FILES["file"]["name"])
move_uploaded_file函数直接吧上传的临时文件copy到新文件
黑名单扩展名过滤
PHPCMSv9限制
1. 限制扩展名不够全
上传文件格式不可预测的性质导致了可能有漏鱼之网扩展名不同的WebServer 默认有不同的可以解析的下面的验证就有了漏鱼之网,并没过滤cdx,存在绕过
$savefile = preg_replace("/(php|php3|php4|jsp|exe|dll|asp|cer|asa|shtml|shtm |aspx|asax|cgi|fcgi|p1)(\.|$)/i","_\\1\\2",$savefile);
2. 限制扩展名的方式有文件
function getExt($filename){return substr($filename,strripos($filename,'.'+1));$disallowed_types =array("php","asp","aspx");//获取文件扩展名$FilenameExt = strtolower(getExt($_FILES["file"]["name"]));#判断是否在允许的扩展名里面if(in_array($FilenameExt,$disallowed_types)){die("disallowe type");}else{$filename = time().".".$FilenameExt;move_uploaded_file($_FILES["file"]["tmp_name"],"upload/".$FileName);}
这段diamond的问题在获取文件扩展名与验证扩展名。如果我们上传文件名 的时候为 " 1.php",注意后面有一个空格,则这里$FilenameEXT的值为"php空格",后面有一个空格,这时候inarray(FilenameExt,FilenameExt,FilenameExt,disallowed_types) 是返回false,最终成功上传文件
文件头content-type验证绕过
只要在文件头中加上GIF89a后上传,则通过,这是因为程序用了一先不可靠的函数去判断是不是图片文件,比如getmagesize()函数找一段段存在该漏洞的代码 可以看到就验证了contet-type类,我们抓包修改为该类型也许就绕过了$type = $_Files['img']['type'];if(($type == "image/pjpeg") || ($type == "image/jpg") || ($type == "image/jpeg") || ($type == "image/gif") || ($type == "image/bmp") || ($type == "image/png") || ($type == "image/x-png"){//uploading}
条件竞争上传
传送门—>条件竞争
FUZZ文件上传
传输门—>在该文章实验七
还有更多绕过姿势,该文章只是讲一下上传代码分析基本思路