文件上传讲义
- 格式:pdf
- 大小:3.22 MB
- 文档页数:42
文件上传文件上传漏洞简介文件上传漏洞的原理由于文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者向某个可通过Web 访问的目录上传恶意文件,并能够将这些文件传递给脚本解释器,就可以在远程服务器上执行恶意脚本。
文件上传流程A 客户端javascript 检测(通常为检测文件扩展名)B 服务端MIME 类型检测(检测Content-Type 内容)C 服务端目录路径检测(检测跟path 参数相关的内容)D 服务端文件扩展名检测(检测跟文件extension 相关的内容)E 服务端文件内容检测(检测内容是否合法或含有恶意代码)随后本文将对这些检测如何绕过进行详细的讲解。
任意文件上传漏洞实例以下代码会处理上传的文件,并将它们移到Web 根目录下的一个目录中。
攻击者可以将任意的PHP源文件上传到该程序中,并随后从服务器中请求这些文件,会在远程服务即使程序将上传的文件存储在一个无法通过Web 访问的目录中,攻击者仍然有可能通过向服务器环境引入恶意内容来发动其他攻击。
如果程序容易出现文件包含漏洞,那么攻击者就可能上传带恶意内容的文件,并利用另一种漏洞促使程序读取或执行该文件,形成“二次攻击”。
客户端检测绕过(javascript检测)通常一个文件以HTTP协议进行上传时,将以POST请求发送至web服务器,web服务器接收到请求并同意后,用户与web服务器建立连接,并传输数据。
客户端javascript检测的概念当客户端选中要上传的文件点击上传的时候,在没有向服务端发送任何数据信息,就对本地文件进行检测是否是允许上传的类型的这种方式称之为客户端本地javascript检测。
先配置本地代理,然后打开http反向代理工具burp suite。
打开文件上传漏洞演示脚本的HTTP地址,选择上传文件当点击“上传”,Burp里没有收到任何数据,便弹出一个警告框修改上传文件名为*.jpg/gif等可以上传的格式,选择上传。
上传后,在POST包里面文件名字段的值是one.jpg。
将filename=“one.jpg”改为filename=“one.php”,forward上传。
通过上传一句话,成功获得网站webshell,然后用菜刀连接。
客户端代码:<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(stIndexOf("."));//alert(ext_name);//alert(ext_name + "|");//判断上传文件类型是否允许上传if (allow_ext.indexOf(ext_name + "|") == -1) {var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;alert(errMsg);服务端检测(MIME 类型检测)MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。
多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
MIME类型检测的概念所谓MIME类型检测实际上就是客户端在上传文件到服务端的时候,服务端对客户端上传的文件的Content-Type类型进行检测,如果是白名单所允许的,则可以正常上传,否则上传失败。
首先上传one.php进行上传测试上传出错,推测服务端可能检测了文件类型MIME。
重新截取上传数据包,修改Content-Type,然后forward上传。
上传成功,菜刀连接。
可以看到,我们成功绕过了服务端的MIME检测,像这种服务端检测HTTP包的Con tent-Type都可以用这种类似的方法来绕过。
客户端代码:服务端代码:<?php//文件上传漏洞演示脚本之MIME验证$uploaddir = 'uploads/';if (isset($_POST['submit'])) {if (file_exists($uploaddir)) {if (($_FILES['upfile']['type'] == 'image/gif') || ($_FILES['upfile']['type'] == 'image/jpeg') ||($_FILES['upfile']['type'] == 'image/png') || ($_FILES['upfile']['type'] == 'image/bmp')) {if (move_uploaded_file($_FILES['upfile']['tmp_name'], $uploaddir . '/' . $_FILES['upfile']['name'])) {echo '文件上传成功,保存于:' . $uploaddir . $_FILES['upfile']['name'] . "\n";}} else {echo '文件类型不正确,请重新上传!' . "\n";}} else {exit($uploaddir . '文件夹不存在,请手工创建!');}//print_r($_FILES);}?>服务器检测绕过(目录路径检测)上传目录路径检测的概念目录路径检测一般就是检测上传的路径是否合法,一旦程序员在写程序的时候对文件的上传路径过滤不严格就很有可能产生0x00上传截断漏洞。
假设文件的上传路径为:http://xx.xx.xx.xx/upfiles/cimer.php.gif,通过抓包截断将cimer.php 后面的.换成0x00,当上传的时候,当文件系统读到0x00的时候,会认为文件已经结束,从而将cimer.php.gif中的内容写入到cimer.php,从而达到攻击目的。
漏洞成因:因为对目录路径的检测不够严谨而导致,我们可以用0x00 截断进行上传攻击。
首先开启burp suite代理截断,然后浏览上传。
修改one.php.gif为one.php gif。
修改one.php.gif为one.php0x00(十六进制)gif 。
成功上传文件。
客户端代码:服务器检测绕过(文件扩展名检测)上传服务端文件扩展名检测概念当客户端将文件提交到服务端的时候,服务端会根据自己设定的黑白名单对客户端提交上来的文件进行判断,如果上传的文件名是黑名单里面所限制的,则不予上传,否则正常上传。
直接上传one.php文件进行测试服务端返回错误,限制.php文件类型直接上传将one.php改为one.php.abc进行上传。
成功上传且菜刀连接成功。
客户端代码:<?php//文件上传漏洞演示脚本之服务端扩展名验证$uploaddir = 'uploads/';if (isset($_POST['submit'])) {if (file_exists($uploaddir)) {$deny_ext = array('.asp', '.php', '.aspx', '.jsp');//echo strrchr($_FILES['upfile']['name'], '.');$file_ext = strrchr($_FILES['upfile']['name'], '.');//echo $file_ext;if (!in_array($file_ext, $deny_ext)) {if (move_uploaded_file($_FILES['upfile']['tmp_name'], $uploaddir . '/' . $_FILES['upfile']['name'])) {echo '文件上传成功,保存于:' . $uploaddir . $_FILES['upfile']['name'] . "\n";}} else {echo '此文件不允许上传' . "\n";}} else {服务端检查绕过(文件内容检测)文件内容检测的概念一般文件内容的检测使用getimagesize()函数检测,会判断文件是否是一个有效的图片文件,如果是,则允许上传,否则的话,不允许上传。
上传一个没有gif文件头的.gif文件进行测试上传出错,由此推测服务端可能对上传的文件内容进行了检测。
用burp suite进行代理,然后选择图片马进行上传。
PHP_pass.gif图片马上传成功。
将文件名改回PHP_pass.gif.php,然后重新上传。
成功上传,菜刀连接,成功获得网站webshell。
客户端代码://文件上传漏洞演示脚本之内容验证$uploaddir = 'uploads/';if (isset($_POST['submit'])) {if (file_exists($uploaddir)) {//print_r($_FILES);$file_name = $_FILES['upfile']['tmp_name'];print_r(getimagesize($file_name));$allow_ext = array('image/png', 'image/gif', 'image/jpeg', 'image/bmp');$img_arr = getimagesize($file_name);//print_r($img_arr);$file_ext = $img_arr['mime'];if (in_array($file_ext, $allow_ext)) {if (move_uploaded_file($_FILES['upfile']['tmp_name'], $uploaddir . '/' . $_FILES['upfile']['name'])) {echo '文件上传成功,保存于:' . $uploaddir . $_FILES['upfile']['name'] . "\n";}} else {echo '此文件不允许上传' . "\n";}} else {exit($uploaddir . '文件夹不存在,请手工创建!');}//print_r($_FILES);}?>文件上传攻击文件名大小写绕过用AsP、pHp之类的文件名绕过黑名单检测,对配置不严格的服务器很有效。