什么是文件上传?
就是将客户端资源,通过网络传递到服务器端。??
为什么使用文件上传?
就是因为数据比较大,我们必须通过文件上传才可以完成将数据保存到服务器端操作.
文件上传对渗透测试的意义
文件上传属于获取Getshell的一种方法,属于最常规获取webshell的方法,所以寻找上传点比进入后台还重要,如果前台上传点你直接上传上去一个一句话木马,整个站你就拿下来了。
文件上传需要做信息收集吗?
当然需要信息收集,信息收集中对web容器和用的动态语言和动态语言版本对文件上传非常有用,一个ASP的站,你传一个PHP的马,如果说没有特殊设置,那么这个马是不可能执行(但是有些情况下,他设置了解析,也是可以解析的)然后web容器也会存在一些解析漏洞,如iis6.0畸形解析、CGI解析漏洞
文件上传是不是只会检测后缀?
并不是,有些文件上传还会去检测文件内容。
黑名单和白名单哪个安全
相对而言,白名单更安全一点
如果只能上传图片,这个上传点是不是没用?
并不是,好歹你还是有文件上传上去的,如果网站存在本地包含或者解析漏洞,你传上去的图片马就可以大放光彩了。
只是windows有::$DATA吗?
是的呀
windows忽略大小写,linux?
Linux并不会忽略大小写,比如访问一个网站,将URL里面文件夹得名字改一个小写字母为大写,如果正常访问那一般是windows,如果访问出现问题一般是linux(快速检测不一定准)
双写绕过常见吗
双写绕过并不是特别常见,但是也是遇到过,你上传得文件得文件名就可以看出来能否双写绕过
没有源码怎么测试文件上传漏洞?
因为大多数情况下,都不会有目标站点的源码。所以黑盒怎么测试妮?先传一个正常图片,然后看看这个地方上传是否有用,然后再传一个jpg后缀的图片马,看看对内容会不会检测,然后再尝试改包,看看是不是前端验证,然后尝试下看看是黑名单还是白名单机制,然后最后尝试条件竞争。
.htaccess文件绕过这个常见吗?
虽然这个默认不是开启的,但是开启了伪静态的网站都会开启,所以遇到伪静态可以直接尝试,不过没用遇到也是可以尝试的,也许管理员开启了妮~多尝试
后缀大小写绕过可能存在吗?
当然可能啦,老的ASP站比较容易遇到
文件后缀(空和点)绕过适用于什么环境?
仅仅用于windows
00截断和%00截断有区别吗?
没有任何区别,%00 仅仅是00的URL编码而已
00截断有限制条件吗?
高版本php不存在,5.4.45以上似乎就没有了
有没有把图片打成base64保存到数据库的操作?
有这个操作,但是这样会让数据库超级大,而且感觉影响了数据库的性能
条件竞争实战可行性?
实战是可以行的,之前遇到过一个非法网站,然后他就存在条件竞争(不过一般5分钟没跑出来就放弃把)
IIs6.0畸形解析漏洞(一)怎么利用?
Asa cer 这个很明显是绕过黑名单机制的
IIs6.0畸形解析漏洞(二)怎么利用?
这里是绕过白名单机制的,利用;进行绕过
IIs6.0畸形解析漏洞(三)怎么利用?
当你拥有建立文件夹且可以命名的时候利用
IIS6.0感觉很老呀现在还多吗?
ASP的站大部分都是这个版本,也有些IIS6.0修复了解析漏洞,也不用太执着
我图片马做了,但是上传上去连接不了怎么办?
你先看看你的图片马是不是太大了,图片马大了会影响执行,所以我建议使用小图片做图片马,我自己真的用的图片马,都是QQ表情,一个图片才10kb.第二个要检测的就是看看图片马是否正常运行,建议在本地先试试
动态脚本语言不同,他们的一句话木马可以通用吗?
当然不可以啦,难道你觉得英语和中文还有日语可以通用吗?每个动态脚本语言都有自己的一句话木马,函数可能连名字都是差不多的,但是语句肯定不一样(百度查一查就有了)
服务端检测几个常见的手段:
检查Content-Type (内容类型) ??
检查后缀 ?(检查后缀是主流) ?? ?
检查文件头
任意文件上传 => 一句话木马 ?1.php (一句话木马) 后端代码 ?? ?1、能否上传上去 ?? ?2、能否解析(你传的文件被当做后端脚本处理) ?? ?3、你要能访问得到你上传的文件(路径 只有在根目录里面的文件才能访问到) ?
先来看看第一题
upload-labs
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;
}
}
看代码只能上传.jpg .png .gif的文件
那就把1.php的文件重命名为1.jpg,然后上传抓包,改后缀再发送
?
Burp抓包看响应源码
看到js是单独写出来的,那直接把它删了再发送,就可以上传任意文件了
Pass-02:(Content-Type方式绕过)
upload-labs
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;
}
}
?既然是检查文件类型,拿出我们的图片马,WEB容器是根据后缀来识别格式的,我只要上传的文件后缀是.php就行
同Pass-01的方法一
Pass-03:黑名单绕过
前面讲到过黑名单绕过机制不靠谱,很明显这个过滤不严谨, php中,如果默认状态下.php3,.php4,.php5,.phtml 都是会被解析为php的
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$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)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR. '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR .'/'. $_FILES['upload_file']['name'];
$is_upload = true;
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
将1.php改为phtml
?上传成功
?
前端检测就是没有检测
Pass-04: .htaccess文件绕过
htaccess是什么?
全称是Hypertext Access(超文本入口) ?
.htaccess文件也被成为分布式配置文件,提供了针对目录改变配置的方法,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。
.htaccess功能:
文件夹密码保护、用户自定义重定向、自定义404页面、扩展名伪静态化、禁止特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表 很可惜,这么一个强大的功能默认是不开启的 Apache (有伪静态的都可以试试)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".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");
$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)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . $_FILES['upload_file']['name'];
$is_upload = true;
}
} else {
$msg = '此文件不允许上传!';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
?
?
Pass-05:大小写绕过 ?? ?
我们可以通过大小写去绕过。WEB容器除非非常老的版本,不然都不区分大小写
windows的文件和系统不区分大小写
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".htaccess");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空
if (!in_array($file_ext, $deny_ext)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . '/' . $file_name;
$is_upload = true;
}
} else {
$msg = '此文件不允许上传';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
?
?
Pass-06:文件后缀(空)绕过
在文件名后面留一个空格,然后上传上去后空格会被自动的省略,但是看源码可知道,源码中黑名单中没有过滤空值,那么php和php ,当然是不一样的
Windows是不允许后面有空格的
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".htaccess");
$file_name = $_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
if (!in_array($file_ext, $deny_ext)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . '/' . $file_name;
$is_upload = true;
}
} else {
$msg = '此文件不允许上传';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
所以单纯的改文件后缀是行不通的,那就抓包去改
?
在这里悄悄的填一个空格~
然后放包看结果
成功~
?
?
?
Pass-07: 文件后缀(点)绕过
windows有一个特性,会自动去掉后缀名最后的.
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".htaccess");
$file_name = trim($_FILES['upload_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)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . '/' . $file_name;
$is_upload = true;
}
} else {
$msg = '此文件不允许上传';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
那么还是老样子,抓包去改
?加完后缀点后,放包
?
?
Pass-08: ? ?::$DATA(Windows文件流绕过)?
(这里利用到了NTFS交换数据流(ADS),ADS是NTFS磁盘格式的一个特性,在NTFS文件系统下,每个文件都可以存在多个数据流。通俗的理解,就是其它文件可以“寄宿”在某个文件身上,而在资源管理器中却只能看到宿主文件,找不到寄宿文件。)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".htaccess");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = trim($file_ext); //首尾去空
if (!in_array($file_ext, $deny_ext)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . '/' . $file_name;
$is_upload = true;
}
} else {
$msg = '此文件不允许上传';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
上传 1.php文件,用BURP抓包
得到:
?改为:
?
Pass-09:构造文件后缀绕过
$file_ext = strrchr($file_name, '.'); 是检测末尾最后是否是. ?(很明显是为了防御双写.)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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",".htaccess");
$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)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . '/' . $file_name;
$is_upload = true;
}
} else {
$msg = '此文件不允许上传';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
看了看代码结构,使用双后缀试一试
?
?
Pass-10:双写绕过
仔细看源码发现 ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?这里的意思就是讲检测到的危险字符替换为空,php被替换为空是空,那么pphphp被替换为空就会变为php,不就达到了绕过
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = str_ireplace($deny_ext,"", $file_name);
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $file_name)) {
$img_path = $UPLOAD_ADDR . '/' .$file_name;
$is_upload = true;
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
所以,将文件后缀改为.pphphp? 然后上传
?
总算搞完这前几个了。咱就说一天一更吧
?
|