对上传文件的类型、内容没有进行严格的过滤、检查或是过滤检查被绕过,使得攻击者可以通过上传木马获取服务器的webshell权限,因此文件上传漏洞所造成的危害都是毁灭性的。
5.解析漏洞:
- Apache:
对文件的解析是从右向左的,若文件名不可识别,则继续向左进行判断解析,例如:xx.php.owf.rar,由于apache不认识owf和rar所以将其视作php文件进行解析执行。- Nginx:
Nginx<0.8.3畸形解析漏洞: Fast-CGI开启状况下,访问以下网址,服务器将其作为php解析并执行: http://xxx/xxx/xx.jpg/.php- IIS:
IIS 5.x/6.0解析漏洞:
目录解析:在网站名下建立文件夹名称中带有asp、asa、cer、cdx等可执行脚本文件后缀为后缀的文件夹,其目录下的扩展名文件都可被IIS当做可执行文件执行,例如:http://xxx/xxx/xx.asp/xx.jpg(图马)
文件解析:IIS6.0中,分号后面不被解析,http://xxx/xxx/xx.asp;xx.jpg–》被当做xx.asp解析并执行
IIS7.0/IIS7.5畸形解析漏洞: 同Nginx
尝试抓包,抓不到说明是前端验证:
客户端Js检查
首先查看源码,找到js中的验证方法,将其重写为true
checkFile=function(){return true;}
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;
}
}
//isset判断变量是否存在,有无提交submit参数
if (isset($_POST['submit'])) {
//判断路径是否存在
if (file_exists(UPLOAD_PATH)) {
/*uploadfile就是上传文件
$_FILES['upload_file']['type']文件中包含多种属性,包括文件名以及文件类型,这里的uploadfile就是文件名,type就是Content-Type的内容,放在一起代表上传目录的类型。
*/
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
/*无条件上传到临时目录中,web是不可访问的,名字可能也是随机的。
*/
$temp_file = $_FILES['upload_file']['tmp_name'];
upload_PATH是图片存储地址,web可访问的最终目录upload/上传文件的文件名
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']
//将上传文件进行移动,从temp移动到img_path中
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '文件类型不正确,请重新上传!';
}
} else {
$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
}
}
所以只是对文件类型进行校验–》抓包修改Content-Type内容即可。
代码分析
$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']);//trim去掉末尾空格
文件名去掉点
$file_name = deldot($file_name);//删除文件名末尾的点
取后缀
$file_ext = strrchr($file_name, '.');//用某一个字符(点)分割另一个字符串(filename),分割结果(点及点后面的内容)取后缀名
后缀b
$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—》php3,成功。
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini");
$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(虽然不知道是什么,但是这一步应该是在后缀中删除了::$DATA)
//::$DATA,NTFS文件流,是NTFS文件的属性,代表的是文件本身
$file_ext = trim($file_ext); //收尾去空
if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.$file_name;
//upload是web可访问的路径
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
黑名单很全,各个判别都有,可以考虑Apache解析漏洞:
利用一个apache不能解析的文件如“app”文件,先上传一个.app格式的文件后再上传.htaccess文件,其内容为:
SetHandler application/x-httpd-php
其含义是告诉apache“app”为后缀的文件使用php的方式解析。
成功
利用Ajax,这里缺少环境,跳过。
与4类似,但缺少大小写要求strtolower($file_ext)
----》大小写绕过,注意黑名单中有pHp限制,所以使用PHp。
缺少空格判断,但是后缀中的空格会被系统删掉,所以通过抓包修改后缀名+空格。
然后转发,成功。
缺少点的判断,可以设计一个带有.的后缀名进行绕过
$file_name = deldot($file_name);//删除文件名末尾的点
缺少删除字符串代码:
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
抓包在后缀名后面加上::$DATA
,生成的图片的链接中再将字符串删除,即可得到页面。
::$DATA是NTFS文件流,
此题与pass-04代码一致,可以将其看作是第四题的第二种解法,利用代码的逻辑漏洞进行绕过。
$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(虽然不知道是什么,但是这一步应该是在后缀中删除了::$DATA)
//::$DATA,NTFS文件流,是NTFS文件的属性,代表的是文件本身
$file_ext = trim($file_ext); //收尾去空
其中,这里先执行首尾删除空格-删除末尾点-以点作为分隔-转换为小写-去除文件流-首尾删除空格,利用此在后缀处添加(点空格点)进行绕过,经过过滤后的后缀名带点,绕过黑名单php后缀。
加载图片url时,需要把后缀后面的点去掉。成功:
见到替换方法想到双写绕过
$file_name = str_ireplace($deny_ext,"", $file_name);
//str_ireplace()函数的作用就是将黑名单中的后缀直接替换为空,见此函数可通过双写绕过
抓包,修改后缀双写:p php hp
ph php p不可以
成功:
$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);
//substr(待裁剪字符串,从哪开始)裁剪字符
//strrpos(从这个字符串里找,找这个字符串)获取一个字符串在另一个字符串里的位置
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_GET['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类型文件!";
}
}
这里的路径拼接中使用了Get来获取,其输出结果应该是…/upload/23xxxx.jpg,则可进行注入截断…/upload/12.php%00,因为是对url里的内容进行截断,所以使用url编码截断:%00的方式。
通过Burp抓包修改有两处,其一为截断处,其二是对上传文件的后缀进行修改为白名单后缀,共同达到绕过白名单的目的。
将图片链接后面的内容删除,加载成功。
12题用的是GET方法,13题是POST方法,换汤不换药,但是在post中的截断不是在url中显示,因此其不需要url编码。可在php后加h,在Hex模块内找到70 68 70 68,将最后的68改为00,达到截断的目的。
成功
检查图片的方式是查看图片的exif信息,是指除了图像之外的信息
这三问都可以用这个方法:
shift+右键打开当前页面命令窗口:copy /b pte.jpg+15.php picshell.php
过滤函数:imagecreatefromjpeg/gif/png,是进行重新渲染的函数,gif最好插,用gif来做。
白名单中提供三种格式:此处进行改包选择gif格式,抓包,然后在内容部分的中间偏后位置添加木马shell,再转发,可以看到改包前后的图片出现变化。
利用顺序验证的问题:条件竞争漏洞+Burp爆破访问
1.出问题的地方在于其先move再验证,利用其move之后及验证失败删除生成木马包(gen.php)的时间差来快速访问生成木马包。
2.抓取上传gen包
3.打开另一个链接,访问gen包并抓取。
4.将两个包发送到intruder中同样的更改爆破方式:clear all符号,选择没有payloads–3000次—20线程—同时快速开始爆破
在结果中找到一个与其他不同的包,发现这个包访问成功
成功后即可访问18.php包,成功:
Apache解析漏洞+条件竞争
array(
".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
".html", ".xml", ".tiff", ".jpeg", ".png" );
利用白名单中后缀名“7z”Apache很有可能不认识–Apache解析从右向左进行,不认识就会向左找认识的后缀进行解析。来构建gen.php.7z文件。
查看源码知道其流程为:
检查后缀名—>移动文件—>重命名
所以在它检查完文件名到重命名的过程可以利用条件竞争漏洞快速访问gen.php.7z.
方法同上:
访问成功,然后查看19.php文件。这里访问的链接不需要填upload不然会找不到。
$file_ext = pathinfo($file_name,PATHINFO_EXTENSION);
if(!in_array($file_ext,$deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' .$file_name;
这里使用的是黑名单,看代码可知其进行文件路径的拼接,所以采用截断的方式将rename的文件名注释掉。Hex00
将url文件名后边的jpg删掉得到:
$file = explode('.', strtolower($file));
//使用explode函数来将文件名用“.”来分割成数组
// $file = explode('.', 'aaa.bbb.ccc');
得到数组 ['aaa','bbb','ccc']
$file_name = reset($file) . '.' . $file[count($file) - 1];
//取文件数组的头【0】和总数组长度-1【len-1】位置的内容,通过构造数组来进行文件名称的绕过