草庐IT

Log4j2 CVE-2021-44288 代码审计(底层调用链分析)

Tanya203 2023-03-28 原文

1、搭建本地环境

2、编写Demo

3、开启debug跟踪方法

3.1 跟进 error 方法 

3.2 跟进 logIfEnabled 方法

3.3 跟进 logMessage 方法

3.4 跟进 logMessageSafely 方法

3.5 跟进 logMessageTrackRecursion 方法

3.6 跟进 tryLogMessage 方法

3.7 跟进 log 方法

3.8 跟进 log 方法

3.9 跟进 log 方法

3.9 跟进 processLogEvent 方法

3.10 跟进 callAppenders 方法

3.11 跟进

3.12 跟进 callAppenderPreventRecursion 方法

3.13 跟进 callAppender0 方法

3.14 跟进 tryCallAppender 方法

3.15 跟进 append 方法

3.16 跟进 tryAppend 方法

3.17 跟进 directEncodeEvent 方法

3.18 跟进 encode 方法

3.19 跟进 toText 方法

3.20 跟进 toSerializable 序列化 方法

3.21 跟进 format 方法

3.22 跟进 format 方法

3.23 跟进 replace 方法(进入 if 判断前,做了格式判断,需要满足 "${" 开头才进入 )

3.24 跟进 substitute 方法

3.25 跟进 resolveVariable 方法

3.26 跟进 lookup 方法

3.27 跟进 lookup 方法

(将传入的参数 jndi 和 rmi://192.168.3.175:8085/goqzKRmu 分离出来赋值给 name 和 prefix )

(StrLookupMap 中储存的 String,object 键值对,取出 JndiLookup 对象,并调用 jndiLookup 的 look 方法)

3.28 跟进 lookup 方法

3.29 跟进 lookup 方法

3.30 先跟进 getURLOrDefaultInitCtx 方法(重要调用)

3.30.1 跟进 getURLContext 方法

(此处将 rmi 协议抽取出来)

3.30.2 跟进 getURLObject 方法

3.30.3 跟进 getObjectInstance 方法

(先根据 scheme 属性的 rmi 参数 获取 rmiURLContextFactory 类,然后调用 rmiURLContextFactory 的 getObjectInstance 方法 )

3.30.4 getObjectInstance 返回值为 rmiURLcontext 对象

3.31 依次返回到 lookup 方法,因返回值为 rmiURLContext 对象,调用该对象的 lookup 方法

3.32 先跟进 getRootURLContext 方法

3.32.1 getRootURLContext 方法 返回一个 解析结果 ResolveResult 对象

3.33 getResolvedObj 方法返回解析对象,强转接口类,再调用 RegistryContext 类的 lookup 方法,继续跟进

3.34 继续跟进 decodeObject 方法(var2 这里应该是发起了连接,工具收到 RMI 请求)

执行 this.registry.lookup(var1.get(0)) 语句时收到 RMI 请求

3.35 关键方法 getObjectInstance 获取对象的实例,跟进该方法

( NamingManager 类是 java 原生类,只与 JDK 版本有关,当前 JDK 版本 8u112)

3.36 继续跟进 get Object Factory From Reference 方法(该方法 从引用获取对象工厂)

3.37  第一个 try catch 应该是本地加载,如果有内容则不进入if判断(未加载到 class,clas 属性还是等于 null)

执行到 clas = helper.loadClass(factoryName, codebase) 加载远程类成功,工具收到请求

计算器 弹出成功(工具写的恶意类 应该是放在 static 代码块中,类加载的时候就会执行 static 代码块,无需使用new创建对象)

(clas.newInstance() 此方法会通过构造方法创建对象)

(恶意代码可以写在 static 代码块中,也可以写在 构造方法 中)

4、log4j2 底层调用链

总结:会根据传入的值去解析成对应的对象

比如 java:os ,对应的是系统属性

 

有关Log4j2 CVE-2021-44288 代码审计(底层调用链分析)的更多相关文章

  1. ruby - 是否有 Log4J for Ruby 的等价物,Log4Ruby? - 2

    找了一圈也没找到。是否有Ruby的Log4X等价物?如果不是,那么处理所有调试语句的最佳方法是什么。我是Ruby的新手。谢谢! 最佳答案 Ruby带有一个内置的日志库,但是有log4r.内置库的一个简短示例:#!/usr/bin/envrubyrequire'logger'log=Logger.new('mylog.txt')log.debug"Hellolog" 关于ruby-是否有Log4JforRuby的等价物,Log4Ruby?,我们在StackOverflow上找到一个类似的问

  2. ruby - 如何使用 Ruby 将键盘和鼠标命令发送到底层操作系统? - 2

    是否有操作系统中立的方式让Ruby将键盘和鼠标事件发送到底层操作系统?(对我而言)一个明显的方法是使用Ruby/Java绑定(bind)并使用java.awt.Robot,但这看起来很愚蠢。 最佳答案 对于Mac:geminstallrb-appscript然后你可以用这样的脚本来测试它:require"rubygems"require"appscript"includeAppscriptapp("TextEdit").activateapp("SystemEvents").keystroke("LookMa,keystrokes!

  3. 中国民用飞机制造行业市场现状规模及发展战略规划报告2021-2027年 - 2

    中国民用飞机制造行业市场现状规模及发展战略规划报告2021-2027年详情内容请咨询鸿晟信合研究院!【全新修订】:2022年2月【撰写单位】:鸿晟信合研究研究【报告目录】第1章:中国民用飞机制造行业发展综述1.1民用飞机制造行业概述1.1.1民用飞机的概念1.1.2飞机制造的概念1.1.3民用飞机的分类1.2民机制造行业周期特性1.2.1影响行业周期的因素(1)GDP增速分析(2)运量增量分析(3)飞机更替分析(4)航空公司获利水平1.2.2行业现阶段周期分析1.2.3行业现阶段景气分析1.3民机制造信息化分析1.3.1信息化技术应用状况分析(1)MDO技术应用分析(2)供应链协同研发分析(3

  4. Salesforce低代码平台底层架构设计原理一:多租户与元数据驱动的概念 - 2

    先自我介绍一下哈,本人拥有17年的IT服务经验。从2011年开始从事Salesforce项目咨询与实施工作。最近几年呢,我一直都在研发一些自己的产品,同时也给一些大厂提供一些咨询服务。所以我自认为对Salesforce平台的产品与功能,以及其底层的架构与设计思想还是研究得比较深的。我打算分几期的篇幅,来具体探讨一下这个平台底层架构的设计原理,其中我也会加入自己的一些思考。因为Salesforce的架构是十几年之前做的,现在的环境以及各种新技术与框架已经发生了比较大的变化。为了方便理解,我简化了一些比较复杂的概念,只保留了最核心的概念与原理。说起低代码平台,我觉得首先要讲两个原理:一个是多租户,

  5. javascript - 在不修改底层对象的情况下使用 Lo-Dash 合并 - 2

    如何在不修改obj的情况下使用lodash_.merge(obj,source)?我只想返回合并计算的值,但我想保持原始对象完好无损。我认为这个问题适用于大多数lodash函数,但到目前为止我还没有找到解决方案。 最佳答案 只需提供一个空对象作为目标(mergesupportsmorethanonesourcevalue):varresult=_.merge({},obj,source); 关于javascript-在不修改底层对象的情况下使用Lo-Dash合并,我们在StackOver

  6. javascript - 在 jquery UI 中检测单选/复选框 'checked' 状态。底层按钮不更新 - 2

    我正在使用jQueryUIbuttonwidget在我需要验证某些单选/复选框元素的表单中。根据提供的链接中的演示-Their(theoriginalelements)associatedlabelisstyledtoappearasthebutton,whiletheunderlyinginputisupdatedonclick.即使您检查我提供的示例页面,底层按钮元素也不会更新任何内容。注意-默认选中示例中中间的单选按钮。我正在使用以下代码来检测按钮状态-奇怪的是它总是正确的(我认为它是错误的)。$el=$("#someCheckbox");if($el.attr('checked

  7. javascript - CasperJS 是否提供对底层 PhantomJS 对象的引用? - 2

    我正在从PhantomJS迁移脚本至CasperJS,并且想知道Casper是否提供了对它在幕后使用的Phantom对象的任何引用。Phantom提供了一些Casper没有的功能(例如injectJs)。为了完整起见,这里是所有Phantom'sobjects:webpagesystemfswebserverchild_process通过查看casper对象的属性,我确实找到了对webpage对象的引用(casper.page),所以我特别用例被处理。我想无论如何我都会发布这个问题,以防其他人需要访问系统、fs、网络服务器或child_process。 最佳

  8. [2021] 完美解决Unable to find image ‘hello-world:latest‘ locally 问题 - 2

    安装Docker出现的问题相信大家查询了很多的回答里面都是需要修改阿里镜像源,但是修改之后却无用。这是因为阿里那个源对于每个人来说都需要专属源。详细的内容可以参考菜鸟教程里的回答:菜鸟教程更换镜像源接下来就简单的完成这个这个更换源的操作(当时花了接近3小时,害):1.首先创建deamon.json文件用来保存源vim/etc/docker/daemon.json2.添加稳定而且不经常变动的镜像源,这里选择中科大的源{"registry-mirrors":["https://docker.mirrors.ustc.edu.cn/"]}当然也可以选择其他的源:网易:https://hub-mirr

  9. go - 在 Go 中查找结构的底层匿名字段类型 - 2

    我有这两个结构:typeCustomTimestruct{time.Time}typeEventsstruct{TimestampCustomTime}当我反射(reflect)Events.Timestamp的字段时,我得到CustomTime;我怎样才能得到实际的底层类型time.Time? 最佳答案 这是一个goplayground示例,展示了如何访问匿名字段。https://play.golang.org/p/yQULMVaQK0基本上,一旦您获得了结构的值,您就应该能够从字段0中获取时间值

  10. arrays - 如何判断 append 是否创建了一个新的底层数组 - 2

    是否可以判断append内置函数是否创建了一个新的底层数组? 最佳答案 当然,比较前后容量:before:=cap(myArray)myArray=append(myArray,newValue)after:=cap(myArray)fmt.Printf("before:%d,after:%d",before,after)更好的问题是,您为什么需要这样做?您的代码真的不应该关心是否创建了新的支持数组。Playground演示:https://play.golang.org/p/G_ZfrLfEpWb

随机推荐