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

img

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.