【干货】PHP文件上传测试使用的表单表单的代码
优采云 发布时间: 2021-08-13 18:07【干货】PHP文件上传测试使用的表单表单的代码
前言 文件上传漏洞是我们平时渗透过程中经常用到的漏洞。使用文件上传,我们可以直接获取webshell,这是一种非常直接的测试方法。写这个文章主要是总结常见的文件上传检测绕过,练习写文件上传PHP代码。
用于以下上传测试的 HTML 表单代码为:
File Upload
选择文件:
1.1 前端 JavaScript 检测
前端一般使用js来限制我们的上传类型和文件大小。这里以upload-labs Pass-01的源码为例:
function checkFile() {
var file = document.getElementsByName('upload_file')[0].value;
if (file == null || file == "") {
alert("请选择要上传的文件!");
return false;
}
//定义允许上传的文件类型
var allow_ext = ".jpg|.png|.gif";
//提取上传文件的类型
var ext_name = file.substring(file.lastIndexOf("."));
//判断上传文件类型是否允许上传
if (allow_ext.indexOf(ext_name + "|") == -1) {
var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
alert(errMsg);
return false;
}}
对于前端检测,我们可以抓包修改文件类型,或者禁用JavaScript。总之,只有前端限制很不安全,很容易绕过。
2.1 后端检测文件类型
2.1.1 检查内容类型
后端代码大致如下:
如何绕过:
抓包并将content-type改为图片格式(即image/png等),上传成功
2.1.2 检查文件头以确定文件类型
后端代码大致如下:
虽然此时检查了文件类型,但是getimagesize()函数是用来获取文件的MIME类型的。这时候检测的不是数据包中的content-type,而是图片的文件头,常见的图片文件头如下:
gif(GIF89a) : 47 49 46 38 39 61
jpg、jpeg : FF D8 FF
png : 89 50 4E 47 0D 0A
如何绕过:
上传PHP文件时,可以使用winhex、010editor等十六进制处理工具,在数据顶部添加图片的文件头,从而绕过检测
2.2 后端检测文件扩展名2.2.1 黑名单检测
后端代码大致如下:
众所周知,使用黑名单是非常不安全的。很多网站会使用扩展黑名单来限制上传文件的类型,有的甚至判断时不使用strtolower()处理,从而造成漏洞
如何绕过:
使用一些特殊的扩展绕过(比如PHP可以用php3、php4、php5等代替)
当后端比较没有大小写转换时,用例混淆(如PHP改PHP等)绕过
2.2.2 白名单检测
一般代码如下,与黑名单检测区别不大:
这时候如果我们要上传一段PHP的话,PHP的语言标签里面是什么?将被替换! , 这样的语句不能执行
如何绕过:
主要是根据实际过滤的字符来判断。难写的话可能没办法(一般不会,因为还考虑到图片上传)
比如过滤问号,我们可以用这样的句子。具体方法要看实际代码过滤了哪些字符。
3.1解析漏洞及其他漏洞3.1.1 IIS解析漏洞
IIS6.0
IIS6.0中有两个非常重要的asp解析漏洞:
假设有一个名为“xxx.asp”的目录,这个目录下的所有文件都会被解析为asp文件
假设上传名为“test.asp;xxx.jpg”的文件,该文件将被解析为asp文件
IIS7.5
这其实不是IIS的漏洞。它实际上是一个PHP解析漏洞。利用该漏洞的条件是服务器在php.ini中将cgi.fix_pathinfo的值设置为1
然后当我们访问服务器上的任何文件时(例如:/a.jpg),当我们在URL后面添加时。 PHP(即:),那么文件a.jpg会被解析为PHP文件
3.1.2 Apache 解析漏洞
使用低版本apache扩展解析功能
在了解这个解析漏洞之前,我们首先要了解apache和PHP的三种组合:
3.1.3 被截断
这个多用于截断路径,使用条件是:
以upload-labs的Pass-12为例,源码如下:
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}
因为白名单限制了上传文件的类型,所以我们不能在文件名中做文章。但最终move_uploaded_file()的目标目录是可控的。我们可以把POST中传入的save_path改成../upload/shell.php,这样后面的内容就会被截断,导致任意文件上传
还要注意是url编码。 POST传递参数时,应使用burpsuite进行url解码,或者修改hex值为00;而用GET传递参数的时候,因为浏览器会做一次url解码,所以直接传递就好了。
3.1.4 使用。 htaccess 解析
.htaccess 文件(或“分布式配置文件”),全称是 Hypertext Access。提供更改目录配置的方法,
即把一个收录一个或多个指令的文件放在一个特定的文档目录中,
对这个目录及其所有子目录进行操作。作为用户,可以使用的命令是有限的。管理员可以通过 Apache 的 AllowOverride 指令进行设置。
使用。 htaccess 条件:Apache 中配置了 AllowOverride All
.htaccess文件可以配置为根据指定的文件类型解析特定的文件,可以通过以下两种方式进行配置:
SetHandler application/x-httpd-php
这个使用正则匹配,只要名为test的文件就会被解析为PHP文件
AddType 应用程序/x-httpd-php .jpg
第二种是将所有.jpg文件解析为PHP文件
所以如果可以的话。如果htaccess上传到服务器,那么上传的文件可以根据自己设置的规则进行解析,绕过上传过滤
/MKMg8y9ByhhZ1IquAqKusRI(自动识别二维码)