Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
hka-seminar-log4shell — Log4Shell脆弱性(CVE-2021-44228)の実用的なデモンストレーション | Kitploit
ツール/GitHubGitHub/fabioeletto/hka-seminar-log4shell
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト学習と教育ラボと実践
GitHubfabioeletto/hka-seminar-log4shell

hka-seminar-log4shell

Log4Shell脆弱性(CVE-2021-44228)の実用的なデモンストレーション

リポジトリを見る
11年前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

セミナー論文 - Log4Shell脆弱性デモンストレーション (CVE-2021-44228)

セキュリティに関する注意事項

このリポジトリは、セキュリティ関連のセミナー論文の一環として、教育およびデモンストレーション目的のみに使用されます。本コードを本番環境や明示的な許可なしにシステムに対して使用しないでください。この構成は、ロギング、名前解決、クラスの動的ローディングといった一見無害な機能が組み合わさると、どのように複雑な脆弱性が生じるかを示し、セキュリティ意識を高めることを目的としています。

目次

  • 1. プロジェクト概要

    • 1.1 セミナー論文の目的
    • 1.2 デモンストレーションの概要
  • 2. Log4Shellとは?

  • 3. 技術コンポーネントの詳細

    • 3.1 Log4j - 動作原理
    • 3.2 JNDI - ルックアップメカニズム
    • 3.3 LDAP - 構成と役割
    • 3.4 Log4Shellの一般的な流れ
  • 4. プロジェクト構成とセットアップ

    • 4.1 ディレクトリ構成
    • 4.2 前提条件
    • 4.3 セットアップ
  • 5. プロジェクトのデモ

  • 6. 対策

  • 7. 結論

  • 8. 参考文献

1. プロジェクト概要

1.1 セミナー論文の目的

本セミナー論文の目的は、2021年12月に公表され、近年最も深刻な脆弱性の一つと評価されたLog4Shellセキュリティホール(CVE-2021-44228)に関する深い理解を提供することです。本論文では、理論的な基礎を説明するだけでなく、脆弱性の実践的なデモンストレーションも行います。

1.2 デモンストレーションの概要

Log4Shellセキュリティホールを実践的に示すために、このリポジトリでは完全な攻撃の流れを再現可能な、隔離されたコンテナ環境を構築しました。デモンストレーションは3つの中心的なコンポーネントに基づいています。

  • vulnerable-app: Log4j 2.14.1を搭載した意図的に脆弱なSpring Bootアプリケーションです。HTTPリクエストのUser-Agentヘッダーをログに記録し、攻撃者がこれを操作して脆弱性を悪用できます。
  • ldap-server: 攻撃者の制御下にあるLDAPサーバーとして機能する、有名なツール_marshalsec_のフォークです。このサーバーは、後で実行される悪意のあるJavaクラスへの参照を提供します。
  • payload-server: 悪意のあるJavaクラス(Exploit.class)を配信する単純なHTTPサーバーです。LDAPサーバーと同様に、このサーバーも攻撃者の制御下にあります。

注意: セットアップとデモンストレーションの実行に関する詳細は、4. プロジェクト構成とセットアップと5. プロジェクトのデモのセクションを参照してください。

2. Log4Shellとは?

Log4Shellは、JavaライブラリLog4jにおけるCVE-2021-44228という識別番号を持つ深刻なセキュリティ脆弱性の名前です。これにより、攻撃者は最小限の労力でリモートサーバー上で任意のコードを実行(リモートコード実行、RCE)することが可能になります。

この脆弱性はLog4jの2.0から2.14.1までのバージョンに影響し、多くのセキュリティ当局(ドイツ連邦情報セキュリティ庁(BSI)など)によって最高リスクレベルに分類されるほど深刻です。

Log4Shellが特に危険な理由は以下の通りです。

  • Log4jは非常に広く普及しています。ゲームサーバーからエンタープライズアプリケーションに至るまで利用されています。
  • 認証が不要であり、匿名の外部攻撃者であれば誰でも潜在的に被害をもたらす可能性があります。
  • 攻撃ベクトルは些細であり、多くの場合、操作された文字列をアプリケーションに送信するだけで済みます。
  • この脆弱性を悪用するためのLog4jの機能は、デフォルトで有効になっています。

実際の原因は、Lookupと呼ばれる機能を通じて、ログメッセージに動的コンテンツをロードできるLog4jの機能にあります。JNDI(Java Naming and Directory Interface) およびLDAP(Lightweight Directory Access Protocol) プロトコルと組み合わせることで、リモートの悪意のあるJavaクラスをロードして実行することが可能になります。

この脆弱性の発見と公開により、世界中でセキュリティ対応の波が引き起こされました。多くのシステムが直ちにパッチ適用またはシャットダウンを余儀なくされました。その後、さらに関連する脆弱性(例:CVE-2021-45046)が明らかになり、この問題がいかに深刻かつ危険であったかを示しています。

以下では、脆弱性をより深く理解するために、関連する技術とその相互作用について詳しく説明します。

3. 技術コンポーネントの詳細

3.1 Log4j - 動作原理

Log4jは、Apacheによって作成されたJavaアプリケーションにおけるイベントを記録するためのライブラリです。ロギングはソフトウェア開発において、システムの監視やエラー分析を行うための中心的なツールです。Log4jはJavaエコシステムで最も有名で広く使われているロギングフレームワークの一つであり、小規模なアプリケーションから大規模なエンタープライズシステムまで使用されています。

なぜロギングが必要か?

プログラムの実行中には、例えば以下のようなイベントが発生します。

  • ユーザーリクエスト
  • 内部状態の変更
  • エラーメッセージ

これらのイベントはログとして文書化され、通常はコンソールへのテキスト出力、ファイル、またはネットワークプロトコルを介した中央ログサーバーへの出力として記録されます。適切なロギングにより、アプリケーションがいつ何を行ったかを追跡できます。

Log4jが提供するもの

Log4jは、ログメッセージの生成と処理のための柔軟で高度に設定可能なインフラストラクチャを提供します。中心的な機能には以下が含まれます。

  • ログレベル: 重要度の段階(例:DEBUG、INFO、WARN、ERROR)があり、ログの詳細度を制御できます。
  • Appender: ログ出力をさまざまな送信先(例:コンソール、ファイル、リモートサーバー)に送ることができます。
  • レイアウト: レイアウトを使用して、ログメッセージの形式(例:タイムスタンプ、スレッド、メッセージ)を定義できます。

セミナー論文に関連するその他の機能、特にプレースホルダー機能とLookup機能については、後のセクションで扱います。

簡単な例```java

import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;

public class Example { private static final Logger logger = LogManager.getLogger();

public static void main(String[] args) {
    logger.info("Starte Anwendung...");
}

}

この簡単な例では、Loggerインスタンスが作成されるか、既に存在する場合は取得されます。その後、`INFO`レベルのログメッセージが出力されます。Log4jは設定に基づいてメッセージのフォーマットと出力を処理します。設定の例は次のようになります:```xml
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

この設定は、Datum Uhrzeit Log-Level Loggername - Nachricht の形式でログメッセージをコンソールに出力するアペンダーを定義します。このアペンダーはルートロガーに割り当てられ、INFO レベル以上のすべてのログメッセージを処理します。

出力は次のようになります:``` 2023-10-01 12:00:00 INFO Example - Starte Anwendung...

それでは、Log4Shell脆弱性に最も関連するLog4jの具体的な機能について説明します。

#### ログメッセージ内のプレースホルダ

Log4jの特に便利な機能の1つは、ログメッセージ内の**プレースホルダ**のサポートです。これにより、動的なコンテンツを実行時にログ出力に挿入できます:```java
String username = "Alice";
logger.info("Benutzer angemeldet: {}", username);

実行時に、{} は変数 username の実際の値に置き換えられます。 これにより次の出力が得られます:```text "Benutzer angemeldet: Alice"

#### 動的式(ルックアップ)

単純なプレースホルダーの他に、Log4jではログメッセージ内でより複雑な式を直接解決する機能も提供しています。この機能は**ルックアップ**と呼ばれ、実行時に値を動的に挿入できます(例:環境変数、システム情報、設定値など)。

そのような動的式の例:

- `${env:HOME}` - 環境変数 `HOME` の値を返します。Linux / macOS では、例えば `/home/username` となります。
- `${docker:...}` - アプリケーションが実行されている Docker コンテナに関する情報を提供する可能性があります。
- `${jndi:...}` - 内部または外部リソースをロードするために JNDI ルックアップを実行します。

次のセクションでは、JNDI 機能が Log4Shell 脆弱性において中心的な役割を果たすため、より詳しく見ていきます。

### 3.2 JNDI - ルックアップメカニズム

**JNDI** は _Java Naming and Directory Interface_ の略で、**名前およびディレクトリサービス**にアクセスするための標準化された Java API です。JNDI を使用すると、Java アプリケーションはリソースを技術的なパスではなく、シンボリック名で参照できます。

JNDI の古典的な使用例はデータベース接続の検索であり、ここで見られるように:```java
public class JndiExample {
    public static void main(String[] args) throws Exception {
        InitialContext ctx = new InitialContext();
        Datasource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/myDB");
        // Datenbankverbindung verwenden
    }
}

最初に、JNDIを使用した名前解決のエントリポイントとなるInitialContextが作成されます。次に、lookupメソッドを使用してリソースを検索します。この場合は、シンボリック名java:/comp/env/jdbc/myDBを持つデータソース(DataSource)です。

JNDIの利点は何ですか?

  • アプリケーションとインフラストラクチャの分離: 構成はコードにハードコードする必要がなく、サーバー上で集中管理できます。
  • 再利用性と移植性: アプリケーションはコードを変更することなく、複数の環境(例:開発、テスト、本番)で簡単に実行できます。各環境の構成ファイルを調整するだけで済みます。
  • 柔軟性: JNDIはプロトコルに依存せず、単にインターフェースを提供し、実際の通信はバックグラウンドでいわゆる_Service Provider_が担当します。これにより、JNDIはLDAPだけでなく、RMI、DNS、CORBAなど様々なサービスにアクセスできます。

JNDIの構造

JNDI Aufbau

JavaアプリケーションはJNDIのプロトコルに依存しないインターフェースを使用します。これにはlookupメソッドを持つInitialContextなどのクラスが含まれます。APIはLDAP、DNSなどを使用する場合でも常に同じです。Naming Managerは仲介役として機能し、実際の通信を担当する適切な_Service Provider_を選択します。JNDI SPI(Service Provider Interface)は、さまざまなプロトコルに対してJNDI機能を実装するクラスのコレクションです。この場合、関連するService ProviderはLDAPです。

次のセクションでは、Service Provider LDAPを詳しく見ていきます。

3.3 LDAP - 構造と役割

LDAPは_Lightweight Directory Access Protocol_の略で、いわゆるディレクトリサービスへのアクセスを可能にする標準化されたネットワークプロトコルです。元々はX.500の軽量な代替として開発され、今日では多くの企業ネットワーク、特に中央集権的なユーザーおよび権限管理において標準となっています。

ディレクトリサービスとは?

ディレクトリサービスは、情報を階層形式で保存する構造化データベースです。リレーショナルデータベースとは異なり、ディレクトリは次の特性を持ちます。

  • 読み取り指向である
  • 強く階層的に構成されている(ファイルシステムのように)
  • IDや構成データへの高速アクセスに最適化されている

LDAPディレクトリの構造

LDAP Baum

画像でわかるように、LDAPディレクトリはツリー状の構造で編成されています。ルートレベルには**Domain Components (dc)があります。その下には、Usersなどのさらに細かい区分を表すOrganizational Units (ou)が存在します。個々のユーザーやオブジェクトには、特定のエントリを識別し、さまざまな属性を含むことができるCommon Names (cn)**があります。

意味:

  • dn: Distinguished Name
  • dc: Domain Component
  • ou: Organizational Unit
  • cn: Common Name

ここで、LDAPがどのように呼び出されるか、そしてLog4Shell脆弱性においてどのような役割を果たすかを見てみましょう。

LDAPはどのように呼び出されるか?

LDAPでは、外部クラスへの参照を保存することもでき、必要に応じて後からロードすることができます。これはjavaClassNameやjavaCodeBaseなどの特別な属性を使用して行われます。これらの属性は、JavaクラスをロードするURLを参照できます。

例えば、次のURLを使用して、Javaクラスを参照するオブジェクトをクエリできます:``` ldap://ldap-server:1389/Exploit

![LDAP Eintrag](https://assets.kitploit.com/production/public/readmes/25332/c60420b9b33a1189fd949bcf725f4ca7c3d4bdcd25f03cd50b715ceac5f95d24.png)
ツールをダウンロード