공격 프로세스

  1. 취약점 분석
    1. 에러 유/무 확인
    2. 취약점 유/무 확인
    3. 조건 구문 완성
  2. 환경 분석
    1. DBMS 파악
    2. 공격 적합성 검토
  3. 공격 기법 선택
    1. Error based
    2. Blind based
    3. Union based
    4. Out of Band
  4. 공격 검증
  5. 데이터 조회 및 탈취
    1. 기본 정보 목록화
    2. 메타 데이터 목록화
    3. 데이터 목록화

1. DBMS 파악

DBMS 별로 사용하는 함수 명이 다르다. 공격 대상의 DBMS를 파악한 뒤, 대상에 맞는 함수를 사용해야 한다.

각 DBMS에 맞는 데이터 사전(메타데이터)을 사용해야 한다.

파악 방법

  • 에러 출력: DBMS 이름을 포함한 에러 출력, 각 DBMS의 에러 코드
  • 연결 연산자
    • Oracle, Tibero, PostgreSQL: ||
    • MSSQL: +
    • MySQL: 공백(%20)
  • 함수
    • Oracle: sysdate(), substr(), length()
    • MSSQL: getdate(), substring(), len()
    • MySQL: now(), mid(), concat(), length()
  • 더미 테이블
    • Oracle과 MySQL은 dual이라는 더미테이블 존재
    • MSSQL은 dual 테이블 없음 → select 0001 A 사용
?idx=192
?idx=(select 192 from dual)
id=test' and 1=(select 1 from dual) --
id=test' and 1=(select 1 from sysibm.sysdummy) --
?idx=192+and+'test'='te'%2b'st'
-- +는 공백, %2b는 +를 의미해 MSSQL인 것 파악 가능

2. 공격 적합성 검토

  1. DBMS 에러 출력 유/무 파악
  2. DB 데이터 웹 페이지 출력 유/무 파악

3. 공격 기법 선택

선택 기준

  1. 적합성
  2. 속도

DB 데이터가 웹 페이지에 출력되면서 DBMS 에러 내용도 출력되면 속도를 기준으로 공격 방식을 선택한다.

순차적 레코드 출력 방법

MySQL

select id from members limit 0, 3;

limit의 첫번째 인자는 인덱스, 두번째 인자는 size이다. 순차적 레코드 출력을 위해 size는 항상 1로 고정한다. 첫번째 인자만 변경하며 인덱스는 0부터 시작한다.

순차적 레코드 출력이 필요없을 때

기본 키를 사용하는 테이블은 limit, rownum 같은 문법이 불필요하다.

select * from members limit 0,1;       -- 순차적 레코드 사용
select * from members where idx=1;     -- 기본키 컬럼 사용

메타 데이터

데이터에 대한 데이터로, 자료 그 자체가 아닌 자료의 속성을 설명하는 데이터이다.

공격자의 메타 데이터 접근 방법

순차적 접근

  1. 메타데이터 목록화 (데이터베이스 → 테이블 → 컬럼)
  2. 데이터 목록화

비 순차적 접근

  1. 원하는 개체 탐색 후 대상 개체 정보 목록화
  2. 데이터 목록화

DBMS 데이터 사전

DBMS데이터 사전
MySQLinformation_schema.schemata, information_schema.tables, information_schema.columns
MSSQLsysdatabases, sysobjects, syscolumns, sys.databases, sys.objects, sys.columns
Oracleall_tables, all_tab_columns

MySQL 메타데이터 목록화

-- 데이터베이스 목록화
select schema_name from information_schema.schemata;
 
-- 테이블 목록화
select table_name from information_schema.tables where table_schema='DB NAME';
 
-- 컬럼 목록화
select column_name from information_schema.columns where table_name='TABLE NAME';
 
-- 데이터 목록화
select [조회할 컬럼] from db_name.table_name;

취약점 점검 방법론

취약점 분석 프로세스는 크게 분석공격으로 나누어진다.

  • 분석: ① 에러 유/무 확인 → ② 취약점 유/무 확인 → ③ 조건 구문 완성
  • 공격: ① 인증 우회 → ② 데이터 조회 → ③ 시스템 명령어 실행

에러 유/무 확인

SQL 질의를 통해 DBMS 에러 유/무 확인 시 획득 가능한 정보:

  1. 웹 애플리케이션이 사용하는 DBMS 종류 파악
  2. 에러를 통해 소스코드 노출
  3. 경로 노출

데이터 타입: 문자형

연결 연산자(||, +, 공백)를 통해 문자와 문자를 연결하는 방식으로 SQL 삽입 여부를 확인한다.

  • || → Oracle DBMS
  • + → MSSQL DBMS
  • 공백 → MySQL

데이터 타입: 숫자형

산술연산자를 이용하여 취약점 유무를 판단한다.

CASE When 구문으로 취약점 유무 탐지

SELECT * FROM EMPLOYEE order by (case when 1=2 then empId else name end)
-- 조건이 1=2(거짓)이면 order by name 컬럼 주입

연결 연산자와 Case when 구문

MSSQL

SELECT * FROM EMPLOYEE where name like '%Da'+(case when 1=2 then 'v' else 'n' end)+'e%';

MySQL

MySQL은 문자열 연결 연산자와 case when 구문을 직접 함께 사용할 수 없다. concat 함수를 사용해야 한다.

select * from board where id='' or concat('t',case when length(database())=5 then 'es' else 1/0 end, 't')='test';

Oracle

SELECT * FROM EMPLOYEE where name like '%Da'||(case when 1=1 then 'v' ELSE 'n' end)||'e%';

검색 메뉴 취약점 분석

예상 쿼리:

select idx, title, write, date from board where title like '';

조회 가능한 쿼리

' and 1=1 -- -  →  모든 글 조회 가능

이 쿼리는 서버 측에 select * from board where title like '%' and 1=1 -- - 참이 되는 쿼리로 반영된다.

조건 구문 완성 방법

  1. In-line query: select * from board where title like '%test%' and 1=1 and '1%' and '1%'
  2. Terminating query: select * from board where title like '%test%' and 1=1 -- -

게시판 정렬 기능 취약점

컬럼 이름은 order by 절 뒤에 삽입되므로, Prepared Statement로 방어할 수 없다.

-- 올바른 삽입 방법 (컬럼명 없이 case when만)
order by (case when 1=1 then title else name end)
 
-- 잘못된 방법 (에러 발생)
order by title case when 1=1 then title else name end

컬럼, 테이블 이름이 쿼리에 삽입되는 경우 화이트리스트로 방어해야 한다.


관련 노트:

sqli webhacking web-hacking