文件上传漏洞全面渗透姿势
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
0x00 文件上传场景
(本文档只做技术交流)
文件上传的场景真的随处可见不加防范小心容易造成漏洞造成信息泄露甚至更为严重的灾难。
比如某博客网站评论编辑模块右上角就有支持上传图片的功能提交带有恶意字符串的图片后就直接可以显示在评论中了如图
再次声明大家在自己的搭建的环境里面测试不要给别人造成麻烦哈。
文件上传漏洞是进行渗透是比较常见好利用的漏洞利用它能够直接上传webshell进行连接是比较常见的攻击方式。针对文件上传场景检测和绕过进行了全面姿势总结。
0x01 渗透姿势全面分析
针对一个文件上传场景首先判断是客户端JS校验还是服务器校验判断依据上传非法文件返回结果是否很快
1.客户端JavaScript检测
如果上传非法文件返回结果很快或者F12打开开发者模式上传非法文件发现没有网络请求但是被拦截了很有可能就是客户端进行了JS校验检测。这种前端采用JS限制上传类型和大小的方式
<script type="text/javascript">
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;
}
}
</script>
很是鸡肋绕过思路1.直接本地禁用JS不让其做检测 2.抓包修改文件后缀名类型绕过检测限制
2.服务器后端检测
服务器后端检测有较多方式普遍分为文件类型检测文件头类型文件扩展名名单检测文件内容检测接下来进行简要分析。
a.文件类型检测
此类检测防护主要是从content-type进行检测检验请求中content-type是否符合可接受的上传类型(如"image/gif","image/png","image/jpeg")
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name'];
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
绕过思路抓包将content-type改为可接受图片形式即可绕过
b.文件头类型检测
上个文件类型是检测content-type,比较好伪造这个则是使用getimagesize()函数来获取文件的MIME类型通过文件头进行判断文件类型
if(file_exists($filename)){
$info = getimagesize($filename);
文件头就是文件特定的标志如二进制PE文件的4D5Abmp文件的424Dzip文件的504B0304各种常见文件的文件头类型大家可以查找了解一下常见图片文件头如下
gif GIF89a
jpg,jpeg: FF D8 FF
png: 89 50 4E 47 0D 0A
绕过思路针对这种上传木马恶意文件时先使用编辑工具在数据最前面添加图片的文件头进行伪造即可绕过
c.文件扩展名检测
这种类型有基于黑名单检测和白名单检测。通常基于黑名单是很不安全的黑名单机制只拦截名单中出现的扩展后缀名其余默认放行。这就取决于名单中的扩展后缀名覆盖能力范围了很难把所有的考虑全面就很容易造成漏洞。
黑名单绕过思路可以从服务器的解析特性进行分析如特殊可解析后缀php3,php7,phtml,jspx等 如特殊的解析方式陌生后缀名带换行后缀名双后缀名等解析差异造成的漏洞。 还可以从混淆方面出发后缀名大小写点绕过空格绕过以及上传.htaccess配置控制文件权限和::$DATA数据流的使用
基于白名单相对于黑名单就安全很多了要求只能是特定扩展名的文件才能够上传。
白名单绕过思路MIME绕过修改文件类型为白名单可接受的类型以及%000x00截断绕过这种场景针对save_path可控。
00截断原理其实很巧妙利用场景是文件保存路径可控这样一来我们上传的文件符合白名单就行真正动手的地方在文件保存路径出可以放上自己的webshell文件然后在webshell文件后面添加%00,或0x00再加一些字符这样一来系统在解析碰到00就会截断后面字符就不起作用只剩下前面的webshell文件名就可以在url中进行访问了。%00和0x00的使用区别在于提交get请求时是%00,会进行url自动解码动作然后进入验证函数。0x00则是post请求直接进入验证函数。
d.文件内容检测
比较厉害的防护检测就是针对内容做检测这种防护能力比较强但也不是不能绕过。自始至终攻防都是在对抗中螺旋演进的。
这种检测防护基本都是从webshell具有的代表性敏感字符?或者危险敏感函数。
绕过思路从特殊敏感字符开始进行Fuzz测试探测webshell中有多少必要的字符存在被替换如果构成webshell执行的字符
被替换得较多剩下未过滤的字符的难以支撑webshell执行可以换个角度利用系统调用脚本语言如<script language='php'>system('ls');<script>。
还有一种更强的基于内容检测机制对上传的图片进行二次渲染参考代码如下
//判断文件后缀与类型合法才进行上传操作
if(($fileext == "jpg") && ($filetype=="image/jpeg")){
if(move_uploaded_file($tmpname,$target_path)){
//使用上传的图片生成新的图片
$im = imagecreatefromjpeg($target_path);
if($im == false){
$msg = "该文件不是jpg格式的图片";
@unlink($target_path);
}else{
//给新图片指定文件名
srand(time());
$newfilename = strval(rand()).".jpg";
//显示二次渲染后的图片使用用户上传图片生成的新图片
$img_path = UPLOAD_PATH.'/'.$newfilename;
imagejpeg($im,$img_path);
@unlink($target_path);
$is_upload = true;
}
} else {
$msg = "上传出错";
}
主要就是后端调用了PHP的GD库利用imagecreatefromjpeg()函数提取了文件中的图片数据然后再重新渲染这样图片中插入的恶意代码就会被过滤掉了经过测试发现,不管是直接修改文件头制作图片马还是利用copy命令制作的图片马都无法避免其中的一句话被过滤掉。