s0

Phân tích lỗ hổng bảo mật Spring4Shell

1.Tổng quan

Ngày 29/3/2022, một bài twitter từ Trung Quốc nói về một lỗ hổng bảo mật của SpringCore Framework. Mặc dù đoạn hội thoại này đã bị xóa, nhưng các chuyên gia bảo mật đã lần theo dấu vết và tìm ra được một lỗi mới của SpringCore gọi là Spring4Shell (CVE-2022-22965). Đây là một lỗi khá nguy hiểm vì nó cho phép kẻ tấn công có thể RCE được máy chủ và thực hiện nhiều hành vi độc hại. Hiện nay POC của lỗ hổng này đã được công bố.

Quá trình tấn công

Điều kiện bị ảnh hưởng:

  • Sử dụng JDK 9 hoặc cao hơn
  • Sử dụng Apache Tomcat 9.0.60
  • Project được đóng gói thành file WAR
  • Sử dụng “spring-webmvc” hoặc “spring-webflux”
  • Tất cả phiên bản Spring trước 5.3.18 và trước 5.2.20 hoặc Spring boot trước 2.6.6

2.Phân tích lỗ hổng

2.1.  Nguồn gốc vấn đề

  • Trong java có một kiểu cấu trúc được gọi là POJO (Plain old Java object) để chỉ những object java bình thường, không có cấu trúc đặc biệt gì ngoài các thuộc tính, các getter and setter.

Cấu trúc bình thường của một class object

 

  • Đối với java Beans, để lấy hoặc thay đổi giá trị các thuộc tính của POJO, cần phải sử dụng các hàm set hoặc get có sẵn trong object.

Sử dụng get và set để điều khiển các thuộc tính trong object

  • Trong các class POJO, ngoài các thuộc tính do mình đặt ra thì còn có một thuộc tính nữa là object.class, bên trong class lại có rất nhiều thuộc tính khác (vd: ClassLoader).

Trong object còn có một thuộc tính ẩn là class, từ đó gọi được thuộc tính ClassLoader và nhiều thuộc tính khác

  • Và từ đây vấn đề sẽ xảy ra, hacker có thể kết tận dụng ClassLoader để truy cập object khác và thay đổi các thuộc tính quan trọng của nó. Nếu như các thuộc tính quan trọng (vd: các thuộc tính liên quan đến configure) mà bị thay đổi, thì hacker hoàn toàn có thể tải các đoạn mã độc hại lên máy nạn nhân.

2.2.  Phân tích lỗ hổng

  • Để khai thác lỗ hổng Spring4Shell, chúng ta cần gửi 1 payload có dạng như sau:

“class.module.classLoader.resources.context.parent.pipeline.first.pattern=<shell_payload>

 class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp

 class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT

 class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell

 class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=”

  • Khi nhận được payload trên, server sẽ mặc định hiểu là người dùng đang muốn thay đổi thuộc tính pattern, suffix, … của đối tượng module.classLoader.resources.context .parent.pipeline.first. Trong spring, đối tượng này ứng với lại đối tượng org.apache. catalina.valves.AccessLogValve.

  • Đối tượng apache.catalina.valves.AccessLogValve là một interface của AccessLog có chức năng generate access log. Trong interface này có các thuộc tính như pattern (định dạng dữ liệu), suffix (tên đuôi file log), directory (địa chỉ file log), prefix (tên file log). Khi thay đổi những thuộc tính này thì chức năng ghi log của server cũng bị ảnh hưởng.

Các thuộc tính của AccessLogValve

  • Sau khi payload được gửi, các thuộc tính directory, prefix, suffix, fileDateFormat, pattern sẽ bị thay đổi. Khi đó chức năng ghi access log bị ảnh hưởng, thay vì ghi log vào file log thì sẽ ghi lại nội dung của shell vào thư mục ROOT.

Các thuộc tính quan trọng đã bị thay đổi

Một file “log” mới đã được ghi lại ở thư mục ROOT

  • Vì chức năng ghi log đã bị ảnh hưởng nên các log mới sẽ không được apache tomcat ghi lại nữa.

Các log mới sẽ không được ghi lại nữa (cho đến khi khởi động lại apache tomcat)

  • Tuy trong spring core đã có kiểm tra ngăn chặn những truy cập độc hại đến các class object bằng cách kiểm tra tên, tuy nhiên công đoạn kiểm tra này hoàn toàn có thể bị bypass khi sử dụng payload trên.

Chặn những truy cập độc hại thông qua việc kiểm tra tên

Tên của các thuộc tính không phải là “ClassLoader” nên có thể bypass được đoạn code kiểm tra

  • Trong phiên bản 5.3.18, spring core đã cải tiến đoạn code kiểm tra, chỉ cho phép những properties có ký tự “name” ở bên trong.

So sánh đoạn code của spring 5.3.17 và 5.3.18

2.3.  Cách phát hiện

  • WebApp sử dụng JDK 9 trở lên
  • Project được đóng gói thành file war và triển khai trên tomcat

  • Sử dụng các annotation sau sẽ có khả năng bị lỗi:

@RequestMapping                    @PutMapping

@GetMapping                          @DeleteMapping

@PostMapping                         @PatchMapping

3.Ảnh hưởng và khắc phục

  • Spring4Shell là một lỗ hổng vô cùng nghiêm trọng, được đánh giá 9.8/10 điểm CVSS trên trang NVD. Nếu như bị khai thác, server hoàn toàn có thể bị up mã độc và chiếm quyền điều khiển bởi hacker.

  • Ở Việt Nam đã ghi nhận những trường hợp máy bị gửi request quét lỗ hổng spring4shell. Để phòng tránh những trường hợp đáng tiếc xảy ra, chúng ta cần sử dụng các biện pháp phòng tránh như:
    • Cập nhật Apache Tomcat lên phiên bản mới nhất
    • Sử dụng phiên bản Spring mới
    • Rà soát mã độc, phòng trường hợp máy tính đã bị tấn công
    • Sử dụng các công cụ bảo mật để phát hiện và chặn những request độc hại

4.Tài liệu tham khảo

https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities/

https://github.com/reznok/Spring4Shell-POC

https://snyk.io/blog/spring4shell-zero-day-rce-spring-framework-explained/

https://medium.com/geekculture/spring4shell-exploit-walkthrough-9843c0244b68

https://www.trendmicro.com/en_no/research/22/d/cve-2022-22965-analyzing-the-exploitation-of-spring4shell-vulner.html

Nguyễn Minh Hoàng

CyRadar Team