风炫安全web安全学习第三十六节课 15种上传漏洞讲解(一)javascript
文件上传漏洞能够说是平常渗透测试用得最多的一个漏洞,由于用它得到服务器权限最快最直接。可是想真正把这个漏洞利用好却不那么容易,其中有不少技巧,也有不少须要掌握的知识。俗话说,知己知彼方能百战不殆,所以想要研究怎么防御漏洞,就要了解怎么去利用。php
网站web应用都有一些文件上传功能,好比文档、图片、头像、视频上传,当上传功能的实现代码没有严格校验上传文件的后缀和文件类型,此时攻击者就能够上传一个webshell到一个web可访问的目录上,并将恶意文件传递给PHP解释器去执行,以后就能够在服务器上执行恶意代码,进行数据库执行、服务器文件管理,服务器命令执行等恶意操做。
根据网站使用及可解析的程序脚本不一样,此处能够上传的恶意脚本能够是PHP、ASP、JSP文件,也能够是篡改后缀后的这几类脚本。html
WebShell 就是以 asp、php、jsp 或者 cgi 等网页文件形式存在的一种命令执行环境,也能够将其称之为 一种网页后门。攻击者在入侵了一个网站后,一般会将这些 asp 或 php 后门文件与网站服务器 web 目录 下正常的网页文件混在一块儿,而后使用浏览器来访问这些后门,获得一个命令执行环境,以达到控制网站服务器的目的(能够上传下载或者修改文件,操做数据库,执行任意命令等)。前端
$_FILES['file']['name'] 客户端文件名称 $_FILES['file']['type'] 文件的MIME类型 $_FILES['file']['size'] 文件大小 单位字节 $_FILES['file']['tmp_name'] 文件被上传后再服务器端临时文件名,能够在php.ini中指定
要注意的是在文件上传结束后,默认的被储存在临时文件夹中,这时必须把他从临时目录中删除或移动到其余地方,不然,脚本运行完毕后,自动删除临时文件,可使用copy或者move_uploaded_file
两个函数java
MIME类型格式: 类别/子类别;参数 Content-Type: [type]/[subtype]; parametergit
MIME主类别: text:用于标准化地表示的文本信息,文本消息能够是多种字符集和或者多种格式的;github
Multipart:用于链接消息体的多个部分构成一个消息,这些部分能够是不一样类型的数据;web
Application:用于传输应用程序数据或者二进制数据;shell
Message:用于包装一个E-mail消息;数据库
Image:用于传输静态图片数据;
Audio:用于传输音频或者音声数据;
Video:用于传输动态影像数据,能够是与音频编辑在一块儿的视频数据格式。
一、客户端javascript校验(通常只校验后缀名)
二、服务端校验
三、文件头content-type字段校验(image/gif)
四、后缀名黑名单校验
五、文件内容头校验(GIF89a)
六、后缀名白名单校验
七、自定义正则校验
八、WAF设备校验(根据不一样的WAF产品而定)
这次咱们用的靶场是:upload-labs: https://github.com/c0ny1/upload-labs
这个漏洞已通过时,几乎不会再出此类漏洞
WebDAV是一种基于 HTTP 1.1协议的通讯协议.它扩展了HTTP 1.1,在GET、POST、HEAD等几个HTTP标准方法之外添加了一些新的方法。使应用程序可直接对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还能够支持文件的版本控制。当WebDAV开启PUT,MOVE,COPY,DELETE方法时,攻击者就能够向服务器上传危险脚本文件。
此时可使用OPTIONS探测服务器支持的http方法,若是支持PUT,就进行上传脚本文件,在经过MOVE或COPY方法更名。当开启DELETE时还能够删除文件
<?php //文件上传漏洞演示脚本之js验证 $uploaddir = 'uploads/'; if (isset($_POST['submit'])) { if (file_exists($uploaddir)) { if (move_uploaded_file($_FILES['upfile']['tmp_name'], $uploaddir . '/' . $_FILES['upfile']['name'])) { echo '文件上传成功,保存于:' . $uploaddir . $_FILES['upfile']['name'] . "\n"; } } else { exit($uploaddir . '文件夹不存在,请手工建立!'); } //print_r($_FILES); } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html;charset=gbk"/> <meta http-equiv="content-language" content="zh-CN"/> <title>文件上传漏洞演示脚本--JS验证明例</title> <script type="text/javascript"> function checkFile() { var file = document.getElementsByName('upfile')[0].value; if (file == null || file == "") { alert("你尚未选择任何文件,不能上传!"); return false; } //定义容许上传的文件类型 var allow_ext = ".jpg|.jpeg|.png|.gif|.bmp|"; //提取上传文件的类型 var ext_name = file.substring(file.lastIndexOf(".")); //alert(ext_name); //alert(ext_name + "|"); //判断上传文件类型是否容许上传 if (allow_ext.indexOf(ext_name + "|") == -1) { var errMsg = "该文件不容许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name; alert(errMsg); return false; } } </script> <body> <h3>文件上传漏洞演示脚本--JS验证明例</h3> <form action="" method="post" enctype="multipart/form-data" name="upload" onsubmit="return checkFile()"> <input type="hidden" name="MAX_FILE_SIZE" value="204800"/> 请选择要上传的文件:<input type="file" name="upfile"/> <input type="submit" name="submit" value="上传"/> </form> </body> </html>
绕过方式
去掉前端的提交时候的验证checkFile
函数既可
演示地址:Pass-01/index.php
MIME type的缩写为(Multipurpose Internet Mail Extensions)表明互联网媒体类型(Internet media type),MIME使用一个简单的字符串组成,最初是为了标识邮件Email附件的类型,在html文件中可使用content-type属性表示,描述了文件类型的互联网标准。
?php if($_FILE['userfile']['type'] != "image/gif"){ //检测content-type echo "sorry,we only allow uploading GIF images"; exit; } else { echo "Upload success!"; } ?>
以上是一个简单的服务器上传验证代码,只要content-type符合image/gif就容许上传
绕过方式
使用Burp截取上传数据包,修改Content-Type的值,改成image/gif便可成功绕过上传webshell
演示地址:Pass-02/index.php
使用黑名单,禁止上传.asp,.aspx,.php,.jsp
结尾的文件。
$is_upload = false; $msg = null; if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array('.asp','.aspx','.php','.jsp'); $file_name = trim($_FILES['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //收尾去空 if(!in_array($file_ext, $deny_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)) { $is_upload = true; } else { $msg = '上传出错!'; } } else { $msg = '不容许上传.asp,.aspx,.php,.jsp后缀文件!'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工建立!'; } }
绕过方式
使用特殊文件.php,.phtml、php二、php三、php五、phtml、pht
。来突破上传,在特定状况下一样也能够解析
演示地址:Pass-03/index.php
参考
http://blog.evalshell.com/2020/12/20/风炫安全web安全学习第三十六节课-15种上传漏洞讲解/