Skip navigation

Monthly Archives: July 2012

The jsp backdoor I mentioned in the last post inspired me to do a little playing around with php backdoors. PHP backdoors range from incredibly simple to extremely elaborate, and can either be independent .php scripts uploaded to a vulnerable server, or inserted directly into a page. The interfaces for some of these shells are quite distinctive, and I thought, surely some of these shells have to have been indexed by search spiders?

Google provides a search API, but it is fairly limited in the number of searches you can perform per day. It only returns a couple results at a time, meaning you have to perform several requests to get a decent number of results per search. The API is also deprecated, so they reserve the right to turn it off at any time.

The shell I’m focusing on for now is the WSO Shell (Web Shell by Orb). Like many shells, it includes a set of server stats along with the command line. A google search for the string of terms “uname user php hdd cwd WSO” currently returns about 12,700 results. The results from the first page are divided into two groups:

  • People asking for help with their compromised servers
  • Websites with the shell interface bang in the middle (bingo!)

I whipped up a pretty shaky python script to do the heavy lifting:

#!/usr/bin/env python

import sys
import httplib
import json


WSOShell = '/search?btnG=1&pws=0&q=uname%20user%20php%20hdd%20cwd%20WSO'

def usage():
	print "Usage:"
	print "./ [mode]"
	print "Modes: --easy, --hard"

def get_json_results(start):
	conn = httplib.HTTPConnection('')
	response = conn.getresponse()
	json_data = json.load(response)
	results = json_data['responseData']['results']
	for i in range(len(results)):
		print "| " + results[i]['titleNoFormatting']
		print "| - " + results[i]['unescapedUrl']

	if(len(sys.argv) > 1):
		if sys.argv[1] == '--easy':
			print "Scraping small result set from json api."
			print "| Results --------------------------------------"
			for i in range(10):
			print "|-----------------------------------------------"
		elif sys.argv[1] == '--hard':
			print "Scraping bigger result set from search."
				#Room for expansion here
except IOError, e: 
	if hasattr(e, 'code'): # HTTPError 
		print 'http error code: ', e.code 
	elif hasattr(e, 'reason'): # URLError 
		print "can't connect, reason: ", e.reason 

… and along comes the stream of nicely formatted results.

Extensions to make:

  • Bypass limits/risks of API by making a scraper for regular google search results
  • Add more search strings for other types of shell
  • Tunnel requests through assorted proxies to avoid IPs getting blocked for too many searches
  • Store results in database for easy storage
  • Disclaimer: I didn’t go on any of these sites. Verification of the shell’s presence was performed by checking the preview screenshot Google supplies with the search results. The most responsible use of the information presented here would be to warn website owners that their machines have been compromised.


While browsing Twitter, I saw a link to a startup going by the name of HackAServer. In their own words, “HackaServer is an online marketplace between PenTesters and companies with a IT&C infrastructure that requires pentesting, and aims to lower the costs and deliver the best quality to price ratio for manual penetration tests using crowdsourcing.”

Upon closer inspection, it appears that companies or individuals looking to get their product given a good going over can attach their server(s) to HackAServer’s VPN, kick back while freelance pen-testers break things and write reports, then pay according to HackAServer’s pricing system for the most promising looking report. I see no mention as to how much of this bounty goes to the hard working pen tester. At any rate, it looked interesting enough to warrant signing up for an account.

Access to the machines of paying customers is not immediately accessible to new members. New members first have to prove themselves in the Training Ground, finding vulnerabilities on the sample targets and filing out a report to prove that they’re at least partially skilled. The first on the list of targets? Our good friend Metasploitable. There’s not much to Metasploitable, but it’s a good way to people to cut their teeth on various tools and techniques.

If you’ve ever had a go at it, from here on in will be of little interest to you.

I scanned the host with nmap, and here’s what I learned:

Starting Nmap 5.21 ( ) at 2012-07-23 17:10 CEST
NSE: Loaded 36 scripts for scanning.
Initiating Ping Scan at 17:10
Scanning [8 ports]
Completed Ping Scan at 17:10, 0.04s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 17:10
Completed Parallel DNS resolution of 1 host. at 17:10, 0.03s elapsed
Initiating SYN Stealth Scan at 17:10
Scanning [1000 ports]
Discovered open port 53/tcp on
Discovered open port 139/tcp on
Discovered open port 80/tcp on
Discovered open port 3306/tcp on
Discovered open port 445/tcp on
Discovered open port 23/tcp on
Discovered open port 21/tcp on
Discovered open port 25/tcp on
Discovered open port 22/tcp on
Discovered open port 5432/tcp on
Discovered open port 8009/tcp on
Discovered open port 8180/tcp on
Completed SYN Stealth Scan at 17:10, 0.95s elapsed (1000 total ports)
Initiating Service scan at 17:10
Scanning 12 services on
Completed Service scan at 17:10, 31.16s elapsed (12 services on 1 host)
Initiating OS detection (try #1) against
Retrying OS detection (try #2) against
Retrying OS detection (try #3) against
Retrying OS detection (try #4) against
Retrying OS detection (try #5) against
Initiating Traceroute at 17:10
Completed Traceroute at 17:10, 0.03s elapsed
Initiating Parallel DNS resolution of 2 hosts. at 17:10
Completed Parallel DNS resolution of 2 hosts. at 17:10, 0.01s elapsed
NSE: Script scanning
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 17:11
Completed NSE at 17:11, 32.28s elapsed
NSE: Script Scanning completed.
Nmap scan report for
Host is up (0.032s latency).
Not shown: 988 closed ports
21/tcp   open  ftp         ProFTPD 1.3.1
22/tcp   open  ssh         OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0)
| ssh-hostkey: 1024 60:0f:cf:e1:c0:5f:6a:74:d6:90:24:fa:c4:d5:6c:cd (DSA)
|_2048 56:56:24:0f:21:1d:de:a7:2b:ae:61:b1:24:3d:e8:f3 (RSA)
23/tcp   open  telnet      Linux telnetd
25/tcp   open  smtp        Postfix smtpd
|_smtp-commands: EHLO metasploitable.localdomain, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN
53/tcp   open  domain      ISC BIND 9.4.2
80/tcp   open  http        Apache httpd 2.2.8 ((Ubuntu) PHP/5.2.4-2ubuntu5.10 with Suhosin-Patch)
|_html-title: Site doesn't have a title (text/html).
139/tcp  open  netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)
445/tcp  open  netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)
3306/tcp open  mysql       MySQL 5.0.51a-3ubuntu5
| mysql-info: Protocol: 10
| Version: 5.0.51a-3ubuntu5
| Thread ID: 14
| Some Capabilities: Connect with DB, Compress, SSL, Transactions, Secure Connection
| Status: Autocommit
|_Salt: 9QlM{C|fjd6}5.'t:b\*
5432/tcp open  postgresql  PostgreSQL DB
8009/tcp open  ajp13?
8180/tcp open  http        Apache Tomcat/Coyote JSP engine 1.1
No exact OS matches for host (If you know what OS is running on it, see ).
TCP/IP fingerprint:

Uptime guess: 2.043 days (since Sat Jul 21 16:10:00 2012)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=197 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: Host:  metasploitable.localdomain; OSs: Unix, Linux

Host script results:
| smb-os-discovery:  
|   OS: Unix (Samba 3.0.20-Debian)
|   Name: WORKGROUP\Unknown
|_  System time: 2012-07-23 17:11:07 UTC-4

TRACEROUTE (using port 199/tcp)
1   30.46 ms
2   31.07 ms

Read data files from: /usr/share/nmap
OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 79.30 seconds
           Raw packets sent: 1113 (52.750KB) | Rcvd: 1084 (47.018KB)

We can see this machine is broadcasting a lot of information about itself. I felt like pounding on Apache Tomcat, so I pointed my browser at to see what I could see. The standard Apache Tomcat homepage, with a handy link to the (password protected) management panel. Consulting google, I found that the default username and password for Apache Tomcat was tomcat/tomcat. Fortunately, (or not so, considering this machine is set up to be deliberately vulnerable) these credentials allowed access to the control panel. From here, the Apache Tomcat world was my oyster. Along with being able to modify the user accounts of assorted Tomcat managers, I was able to deploy any java webapp of my choosing! I chose a backdoor shell, giving me much greater control of the system. Unfortunately though, Tomcat was running as an unprivileged user, tomcat55.

At least we can take a look around.

$ cat /etc/passwd
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
postgres:x:108:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
mysql:x:109:118:MySQL Server,,,:/var/lib/mysql:/bin/false
user:x:1001:1001:just a user,111,,:/home/user:/bin/bash

There’s us, at tomcat55, and a list of the other users. I’ve said as much as I want to say about Metasploitable, but I will say that strong passwords aren’t a common trait on this system, and many of these are easily brute-forcible.