Many times while conducting a pentest, I need to script something up to make my life easier or to quickly test an attack idea or vector. Recently I came across an interesting command injection vector on a web application sitting on a client’s internet-facing estate. There was a page, running in Java, that allowed me to type arbitrary commands into a form, and have it execute them. While developer-provided webshells are always nice, there were a few caveats. The page was expecting directory listing style output, which was then parsed and reformatted. If the output didn’t match this parsing, no output to me. Additionally, there was no egress. ICMP, and all TCP/UDP ports including DNS were blocked outbound.
I was still able to leverage the command injection to compromise not just the server, but the entire infrastructure it was running on. After the dust settled, the critical report was made, and the vulnerability was closed, I thought the entire attack path was kind of fun, and decided to share how I went about it.
Enumeration
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 52
8080/tcp open http-proxy syn-ack ttl 52
We only have a couple ports, let’s start with port 8080:
We have a default tomcat installation. We can start using scanners to find any jsp files:
Foothold
We have a “test.jsp” page we can look into, it appears to be a page for running commands:
We can run any command using this however we can only see the output of “ls” commands. We also know this box has a firewall blocking most of our communications. I tried checking /etc to see what firewalls we could have:
We saw that SSH is running, we can attempt to run commands using it. Checking /home, we see a user called bill:
User own
We’ll try disable the firewall using ssh:
Let’s try run a reverse shell:
We can capture the reverse shell using netcat:
Root own
Bill to root is very easy, if we check sudo -l, we see we can run everything as admin:
We just “sudo su” and get root.