Idea
Hi! Is it possible to run an interactive shell session using only java servlets or Spring MVC controllers? The idea was to write someting like php-findsock-shell using Java.
Implementation
Implementation for spring MVC controller can be found in my gist repo here
Usage
Add the controller to your application and connect using netcat:
nc localhost 8080
POST /shell HTTP/1.1
Host: localhost
Content-Length: 2147483647
Accept-Encoding: identity
Transfer-Encoding: identity
Details
It’s possible to interact with HttpServletRequest using javax.servlet.AsyncContext:
Java
final ServletOutputStream socketOut = asyncContext.getResponse().getOutputStream();
final ServletInputStream socketIn = asyncContext.getRequest().getInputStream();
Imagine, that we are sending very long POST request and server can interact with each sent line in runtime.
Problem 1 - chunked encoding
By default servlet will send chunked response and the corresponding header for async streams:
Transfer-Encoding: chunked
This’ll cause a mess in our interactive shell. To get rid of this - let’s explicitly set content length for our response:
Java
response.setContentLength(Integer.MAX_VALUE);
Problem 2 - connection timeout
By default Tomcat sets 20 seconds as a connection timeout for our servlets (connectionTimeout in server.xml), so if we won’t send any commands more than 20 seconds - our web shell will die. I didn’t find any suitable way to bypass this limitation from java code for the current servlet (or controller). If you know such a hint - welcome to comments.