0
0

More than 1 year has passed since last update.

Log4Shellに脆弱な環境をSpring Bootでつくる

Posted at

勉強がてら、話題のLog4Shellに脆弱な環境を作ってみます。
Log4j2のバージョン2.14.0を使っていると簡単に脆弱な環境を作れました。すぐにバージョンアップしないと危険です!

脆弱性に対するSpring公式サイトの解説

題材

公式のGetting Started Guidesの中にあるBuilding a RESTful Web Serviceをベースにします。

image.png

  • GitHubからソースコードの取得

https://github.com/spring-guides/gs-rest-service/archive/main.zip
completeフォルダー内に完成したソースが含まれます。

│  build.gradle
│  gradlew
│  gradlew.bat
│  manifest.yml
│  mvnw
│  mvnw.cmd
│  pom.xml
│  settings.gradle
│
├─.mvn
│  └─wrapper
│          maven-wrapper.jar
│          maven-wrapper.properties
│
├─gradle
│  └─wrapper
│          gradle-wrapper.jar
│          gradle-wrapper.properties
│
└─src
    ├─main
    │  └─java
    │      └─com
    │          └─example
    │              └─restservice
    │                      Greeting.java
    │                      GreetingController.java
    │                      RestServiceApplication.java
    │
    └─test
        └─java
            └─com
                └─example
                    └─restservice
                            GreetingControllerTests.java

ログ出力にLog4J2を使うように修正

Log4j2を使うように変更します。バージョンは脆弱性のある2.14.0です。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.2</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>rest-service-complete</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>rest-service-complete</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
+       <log4j2.version>2.14.0</log4j2.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
+       <dependency>
+           <groupId>org.springframework.boot</groupId>
+           <artifactId>spring-boot-starter</artifactId>
+           <exclusions>
+               <exclusion>
+                   <groupId>org.springframework.boot</groupId>
+                   <artifactId>spring-boot-starter-logging</artifactId>
+               </exclusion>
+           </exclusions>
+       </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

HTTPリクエストのHTTPヘッダーをログ出力するように変更

GreetingController.java
package com.example.restservice;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


+ import java.util.Map;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ import org.springframework.web.bind.annotation.RequestHeader;


@RestController
public class GreetingController {


+   static protected Logger logger = LoggerFactory.getLogger(GreetingController.class);

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @GetMapping("/greeting")
-   public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
+   public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name,
+           @RequestHeader Map<String, String> headers) {
+
+       headers.forEach((key, value) -> {
+           logger.info(String.format("Header '%s' = %s", key, value));
+       });

        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    }
}

なんとこれだけで、脆弱です。

起動します。

./mvnw spring-boot:run

確認

トレンドマイクロさんが、チェックサイトを用意しているのを見つけましたので、これを使って確認してみます。

こんな感じで、サイトから直接リクエストを投げてチェックできます。
今回はlocalhostで起動しているので、右側のcURLスクリプトを生成して、実行します。

log4j-tester.trendmicro.com_(iPad) (1).png

結果はこんな感じで表示されます。

log4j-tester.trendmicro.com_(iPad).png

Log4J2の2.14.0を使っていると脆弱であることがわかります。
pom.xmlのバージョンを2.15.0にあげて再実行すると、脆弱性は検出されませんでした。

怖いですね。すぐにバージョンアップしましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0