继续学习文件上传骚操作 skrskr

pass-09

$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",".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_PATH . '/' . $_FILES['upload_file']['name'])) {    
                $img_path = UPLOAD_PATH . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

源码发现黑名单机制将该过滤的都过滤了.可是过滤仅过滤了一次.
假如构造 test.php. . //点+空格+点
首先第一步删掉了文件末尾的点 test.php. //点+空格
然后第二步删掉了末尾的空格 test.php. //点
从而绕过了对文件名的处理.
前由此前八关也可以利用这种方式绕过构造.可这种利用方式如果没有拿到源码的情况下,构造这样的payload我想还是不太容易的,所以对这样的文件名处理还是有一定的防御能力

pass-10

$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 . '文件夹不存在,请手工创建!';
    }
}

同样是黑名单机制但是,这次不同的是当发现黑名单里的字符串时,它采取的是替换为空
构造test.pphphp
str_ireplace(find,replace,string,count)该函数对大小写不敏感。

同时对大小写敏感的是str_replace(find,replace,string,count)

作用是将string中的find替换成relpace,count计数替换了几次。

如果find和replace都是数组的话,replace若多于find,则多余部分无视,若少,则空串替换。

pass-11

$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类型文件!";
    }
}

不知道什么原因上传失败,查了别人的payload也还是失败.先留着

pass-12

$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 = $_POST['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类型文件!";
    }
}

12和11其实是同类型 都是由于上传路径可控可以利用%00截断构造php结尾的文件.
11题是get型直接在url后面添加%00就可以达到效果,
12题是post型需要利用burp在发包的时候以16进制的方式修改
例如 test.php .jpg //中间有个空格
​ 空格对应的16进制是20利用burp修改成00便可以达到目的

%00截断有这么2种利用状况
在url中加入%00,如http://xxxx/filename.php%00.jpg
在burpsuite的16进制编辑工具将”filename.php .jpg”[带空格的]中间的空格由20改成00

url中的%00[只要是这种%xx]的形式,Webserver会把它当作十六进制处理,然后把16进制的hex自动翻译成ascii码值“NULL”,实现了截断Burpsuite中16进制编辑器将空格20改成了00,跟上面一样的变成Asccii的null。

pass-13

从此关开始php文件不能直接执行,需要配合其他漏洞才能利用.在源码上的表现,就是文件后缀被写死,一定是gif,jpg,png
​ function getReailFileType($filename){
$file = fopen($filename, “rb”);
$bin = fread($file, 2); //只读2字节
fclose($file);
$strInfo = @unpack(“C2chars”, $bin);
$typeCode = intval($strInfo[‘chars1’].$strInfo[‘chars2’]);
$fileType = ‘’;
switch($typeCode){
case 255216:
$fileType = ‘jpg’;
break;
case 13780:
$fileType = ‘png’;
break;
case 7173:
$fileType = ‘gif’;
break;
default:
$fileType = ‘unknown’;
}
return $fileType;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);

    if($file_type == 'unknown'){
        $msg = "文件未知,上传失败!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        }
        else{
            $msg = "上传失败";
        }
    }
}

pass-13只是读取文件头两个字节, 也就是文件头了, 于是可以用 copy 命令去生成一个图片马
​ copy test.jpg /b + test.php /a shell.jpg

pass-14
​ $image_type = exif_imagetype($filename);

pass-15
​ $info = getimagesize($filename);
$ext = image_type_to_extension($info[2]);

pass-16

16题进行层层检查,毫无可能上传一个php文件.即使是插入了php代码的图片马也会被二次渲染一定几率破坏掉.虽然有机会绕过,但是在没有类似文件包含这样的漏洞执行php代码,这个漏洞并不能被利用.
要实现上传正常的图片与二次渲染的图片进行对比,在相同数据部分插入php代码 //这种骚操作暂时还不会

总结

1.对文件名的处理是必要且有效的,进过滤一次特殊字符可能达不到预期的防御效果
2.上传路径和文件名可控会存在一定问题
3.写死文件后缀可以防止恶意文件的getshell.像菜刀链接的文件就得是php,asp这些动态文件
4.当文件名被写死时,需要寻找例如文件包含漏洞来触发图片马内的php代码达到getshell