Deserialize to memshell in Spring

Ở bài này mình sẽ note về leo memshell thông qua deserialize trong Spring

1. Preface

Trước khi đi vào thì mình note một xíu về JDK version. Các phiên bản Spring Framework 5.x trở đi thì Spring yêu cầu JDK8+, từ Spring Framework 6.x trở đi sẽ yêu cầu tối thiểu là JDK17 trở lên. Do đó ta sẽ có bảng sau:

JDK8+
JDK17+

Spring Boot 2.x

Spring Boot 3.x

SpringMVC 4.x

SpringMVC 6.x

Spring MVC 5.x

2. Deser2memshell trong Spring với JDK8

A. SpringMVC 4.x

Dựng môi trường demo

Tạo một project SpringMVC như bài trước nhưng lần này mình dùng JDK8 với SpringMVC 4.x

Thêm path deser

Mình sẽ exploit bằng chain CC3 nên ta import thêm commons-collections-3.2.1

Exploit

Vì trong Spring thì ta có thể get trực tiếp ApplicationContext để triển khai memshell, không giống như trong Tomcat phải tìm cách gọi được HttpServletRequest trong quá trình Runtime. Do đó việc exploit có phần đơn giản hơn nhiều

Mình sẽ dùng code gen payload CC3 như bài trước. Tuy nhiên sẽ chỉnh sửa class exploit lại 1 chút để load memshell như sau

Nguyên nhân ta có thêm một constructor nhận String a nữa là vì trong quá trình exploit chain CC3 thì constructor của ExploitDeser2Mem được gọi. Payload inject memshell được thực thi, mà payload triển khai memshell cũng tạo instance của ExploitDeser2Mem -> cũng gọi đến constructor. Điều này tạo ra vòng loop vô tận làm quăng lỗi overflow, do đó ta cần thêm constructor thứ 2.

Ta sẽ có payload gen ra như sau

Tiến hành inject

Kết quả

B. SpringBoot 2.x

Dựng môi trường demo

Tạo một project SpringBoot như bài trước nhưng lần này mình dùng JDK8 với SpringBoot 2.x

Mình dùng phiên bản 2.7.6, nếu dùng verion trước 2.6 thì modify payload lại xíu như mình đề cập bài trước.

Cuối cùng thêm path để deser cũng như trên

Exploit

Mình sẽ có class exploit như sau

Ta sẽ có payload gen ra như sau

Tiến hành inject

Kết quả

3. Deser2memshell trong Spring với JDK17

Do bản JDK cao đã strict việc deser nên mình tạm để trống phần này 🙌

4. Refer

Last updated