黄色网站入口国产美女,精品国产欧美另类一区,国产一区二区美女自慰,日日摸夜夜添无码国产

選擇你喜歡的標(biāo)簽
我們會為你匹配適合你的網(wǎng)址導(dǎo)航

    確認(rèn) 跳過

    跳過將刪除所有初始化信息

    您的位置:0XUCN > 資訊 > 安全
    新聞分類

    log4j 漏洞一些特殊的利用方式

    安全 PRO 稿源:安全檔案 2021-12-11 19:52

    背景

    正愁本周沒主題可寫,結(jié)果兩天前就曝了一個核彈級的漏洞“l(fā)og4j RCE”,這兩天官方的修補方案也逐漸完善。所以本篇就拿 log4j 作為主題講一下我的幾個發(fā)現(xiàn)。

    RCE

    log4j RCE 原理已經(jīng)有挺多人發(fā)過了,本文不過多贅述。簡單說就是日志在打印時遇到 ${ 后 Interpolator 類按照 : 分割出第一部分作為 prefix 第二部分作為 key。通過 prefix 去找對應(yīng)的 lookup,再通過對應(yīng)的 lookup 實例調(diào)用 lookup 方法傳入 key 作為參數(shù)。

    log4j-core 自帶的 lookup 有很多實例,其中就包括了此次存在漏洞的 JndiLookup 實例。JndiLookup 則是直接把傳進來的 key 當(dāng)做 JNDI URL 用 InitialContext.lookup 去訪問,從而造成了 JNDI 代碼執(zhí)行漏洞。

    WAF bypass

    該漏洞曝光后各安全廠商也紛紛推出了解決方案,WAF、RASP、改源碼、改配置文件、更新到rc2等。

    在此次漏洞中最沒有防御效果的就是 WAF 了。有提出?${?、jndi、ldap、rmi?等關(guān)鍵詞規(guī)則的防護。但研究后發(fā)現(xiàn)都會存在被繞過問題。

    首先是 jndi、ldap 簡直太容易被繞過,只要用 lowerCase upperCase 就可以把關(guān)鍵詞分割開。

    如果是用了正則的話那還可以使用 upper 把 jnd? 轉(zhuǎn)成 jndi。

    注意:這里的??(\u0131)?不是?i(\x69)和I(\x49),經(jīng)過 toUpperCase 就會轉(zhuǎn)變成 I。從而繞過了 jndi 關(guān)鍵詞的攔截。

    再就是 ${ 關(guān)鍵詞的攔截了,雖然這個范圍有點大可能會產(chǎn)生一些誤報,但鑒于漏洞的嚴(yán)重性還是有很多人建議攔截 ${

    但這樣也未必能夠真正的解決,因為漏洞的觸發(fā)點是在打印日志的時候把可控內(nèi)容攜帶進去了。那么可控內(nèi)容從哪里來?

    Header、URL、鍵值對參數(shù)、JSON參數(shù)、XML參數(shù) ...

    現(xiàn)在隨著 JSON 數(shù)據(jù)格式的流行,很多系統(tǒng)都在使用 JSON 處理參數(shù),JSON 處理庫用的最多的就數(shù) Jackson和fastjson。

    而 Jackson 和 fastjson 又有 unicode 和 hex 的編碼特性。

    例如:

    {"key":"\u0024\u007b"}
    {"key":"\x24\u007b"}
    

    這樣就避開了數(shù)據(jù)包中有 ${ 的條件,所以 WAF 的防護規(guī)則還要多考慮幾種編碼。

    信息泄露

    sys、env 這兩個 lookup 的 payload 也在討論中被頻繁提起,實際上他們分別對應(yīng)的是?System.getProperty()?和?System.getenv(),能夠獲取一些環(huán)境變量和系統(tǒng)屬性。部分內(nèi)容是可以被攜帶在 dnslog 傳出去的。

    除了 sys、env 以外我還發(fā)現(xiàn) ResourceBundleLookup 也可以獲取敏感信息,但沒有看到有人討論 Bundle,所以重點講一下。

    public String lookup(final LogEvent event, final String key) {
        if (key == null) {
            return null;
        }
        final String[] keys = key.split(":");
        final int keyLen = keys.length;
        if (keyLen != 2) {
            LOGGER.warn(LOOKUP, "Bad ResourceBundle key format [{}]. Expected format is BundleName:KeyName.", key);
            return null;
        }
        final String bundleName = keys[0];
        final String bundleKey = keys[1];
        try {
            // The ResourceBundle class caches bundles, no need to cache here.
            return ResourceBundle.getBundle(bundleName).getString(bundleKey);
        } catch (final MissingResourceException e) {
            LOGGER.warn(LOOKUP, "Error looking up ResourceBundle [{}].", bundleName, e);
            return null;
        }
    }
    

    從代碼上來看就很好理解,把 key 按照 : 分割成兩份,第一個是 bundleName 獲取 ResourceBundle,第二個是 bundleKey 獲取 Properties Value

    ResourceBundle 在 Java 應(yīng)用開發(fā)中經(jīng)常被用來做國際化,網(wǎng)站通常會給一段表述的內(nèi)容翻譯成多種語言,比如中文簡體、中文繁體、英文。

    那開發(fā)者可能就會使用 ResourceBundle 來分別加載 classpath 下的 zh_CN.properties、en_US.properties。并按照唯一的 key 取出對應(yīng)的那段文字。例如:?zh_CN.properties

    LOGIN_SUCCESS=登錄成功
    

    那?ResourceBundle.getBundle("zh_CN").getString("LOGIN_SUCCESS")?獲取到的就是?登錄成功

    如果系統(tǒng)是 springboot 的話,它會有一個 application.properties 配置文件。里面存放著這個系統(tǒng)的各項配置,其中有可能就包含 redis、mysql 的配置項。當(dāng)然也不止 springboot,很多其他類型的系統(tǒng)也會寫一些類似 jdbc.properties 的文件來存放配置。

    這些 properties 文件都可以通過 ResourceBundle 來獲取到里面的配置項。所以在 log4j 中 Bundle 是比sys和env更嚴(yán)重的存在。

    在不出網(wǎng)的環(huán)境下可以通過 dnslog 的方式來外帶信息。

    除了dnslog以外還可以通過這兩種方法來獲取信息。

    ldap

    dns

    修復(fù)方案

    log4j 更新到最新版本

    0XU.CN

    [超站]友情鏈接:

    四季很好,只要有你,文娛排行榜:https://www.yaopaiming.com/
    關(guān)注數(shù)據(jù)與安全,洞悉企業(yè)級服務(wù)市場:https://www.ijiandao.com/

    圖庫
    公眾號 關(guān)注網(wǎng)絡(luò)尖刀微信公眾號
    隨時掌握互聯(lián)網(wǎng)精彩
    贊助鏈接