SQL 인젝션

김민성·2023년 3월 6일

DataBase

목록 보기
3/8

정의

웹 사이트의 보안상 허점을 이용해 특정 SQL쿼리문을 전송하여 공격자가 원하는 데이터베이스의 중요한 정보를 가져오는 해킹 기법

  • 클라이언트가 입력한 데이터를 제대로 필터링하지 못하는 경우에 발생
  • 공격의 쉬운 난이도에 비해 피해가 상당하기 때문에 보안 위협 1순위로 불릴만큼 중요한 기법

공격 종류 및 방법

Error based SQL injection

: 논리적 에러를 이용한 SQL injection (가장 많이 쓰임)

1. 입력값에 대한 검증이 없음
2. OR 1 = 1— 라는 구문을 넣어 WHERE 절을 모두 참으로 만들고 뒤 구문을 주석처리함
3. 로그인에 성공하게 됨

Union based SQL injection

Union : 두 쿼리문에 대한 결과를 통합하여 하나의 테이블로 보여주는 명령어

Union injection을 성공하기 위한 조건

  • Union하는 두 테이블의 컬럼 수 동일
  • Union하는 두 테이블의 데이터 형 동일
  1. 입력값을 title과 contents 칼럼의 데이터랑 비교하여 비슷한 글자가 있는 값 출력
    1. 입력값에 대한 검증이 없음
  2. 사용자의 id와 패스워드를 요청하는 쿼리문
  3. 인젝션 성공하면 사용자의 개인정보가 board 와 함께 보여짐

Blind SQL Injection

Boolean Based SQL

단순히 참과 거짓의 정보만 알 수 있을 때

→ 로그인 폼에 SQL injection이 가능하다고 할 때, 서버가 응답하는 로그인 성공/실패 메시지를 이용하여 DB의 테이블 정보 등 추출 가능

1. 로그인 폼
2. 임의 아이디 ‘abc123’로 injection구문 주입
1. MySQL에서 테이블 명을 조회하는 구문
2. limit 으로 하나의 테이블만 조회
3. SUBSTR로 첫 글자만 조회
4. ASCII를 통해 아스키 값으로 변환
3. ex. 테이블 명이 User라면 U가 아스키 값으로 바뀌고 뒤의 100과 비교
1. 거짓이라면 로그인 실패, 참이 될 때까지(로그인 될 때까지) 시도

Time Based SQL

서버로부터 특정한 응답 대신 참 혹은 거짓의 응답을 통해 데이터베이스의 정보를 유추하는 기법

MySQL 기준으로 SLEEP 과 BENCHMARK 함수 사용

: 현재 사용하고 있는 데이터베이스의 길이를 알아내는 방법

  1. 로그인 폼
  2. 임의 아이디 ‘abc123’으로 injection구문 주입
    1. LENGTH : 문자열 길이 / DATABASE : 데이터베이스 이름
    2. LENGTH(DATABASE())=1 이 참이면 SLEEP(2)(2초 동안 지연) 작동하므로 1값을 바꿔가면서 데이터베이스의 길이를 알아낼 수 있음

+) BENCHMARK, WAIT구문도 있는데 봐도 이해가 안 됐음(창명센세 부탁)

Stored Procedure SQL Injection

: 저장된 프로시저에서의 SQL injection

저장 프로시저 : 쿼리들을 모아 하나의 함수처럼 사용하기 위한 것

공격에 사용되는 대표적인 저장 프로시저 : MS-SQL에 있는 xp_cmdshell (윈도우 명령어로 사용)

공격자가 시스템 권한을 획득해야 하므로 공격난이도가 높으나 공격에 성공한다면 서버에 직접적인 피해를 입힐 수 있는 공격

Mass SQL Injection

: 다량의 SQL Injection

기존 SQL injection과 달리 한 번의 공격으로 다량의 데이터베이스가 조작되는 것

보통 데이터베이스 값을 변조하여 데이터베이스에 악성스크립트를 삽입하고, 사용자들이 변조된 사이트에 접속 시 좀비PC로 감염되게 함

대응방안

입력 값에 대한 검증

  • 서버단에서 화이트리스트 기반으로 검증 → 블랙리스트 기반으로 검증 시 많은 차단 리스트를 등록해야 하고, 하나라도 빠지면 공격 성공
  • 공백으로 치환하는 방법 → 취약한 방법 → 공격자가 SE(SELECT)LECT 라고 입력 시, SELECT라는 키워드가 됨 → 공백 대신 공격 키워드와 의미 없는 단어로 치환되어야 함

Prepared Statement 구문 사용

preparedStatement는 (parse : 구문 분석 → bind : 치환 → execute : 실행 → fetch : 인출) 4가지 단계

  • 이중 parse 부분을 컴파일한 채로 캐시에 저장하고 데이터가 bind될 때까지 대기
  • 이후 fetch부분까지 실행이 완료
  • sql을 재사용 할 때 parse를 다시 실행하지 않고 캐시에 저장되어있는 부분 사용해 나머지 3단계만 실행
  • sql이 반복적 일 때 효율적이다.

바인딩 된 데이터는 SQL문법이 아닌 내부의 인터프리터나 컴파일 언어로 처리

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

parse부분에서 이미 쿼리의 문법적인 처리 부분이 수행됨

바인딩 단계에서 입력된 부분은 쿼리로 인식하지 않음

→ sql injection에 좋다.

Error Message 노출 금지

공격자가 SQL injection을 위해서는 데이터베이스 정보가 필요함

→ 에러 발생 시 따로 처리를 하지 않았다면 에러가 발생한 쿼리문과 함께 에러에 관한 내용 반환

→ 테이블명 및 컬럼명, 쿼리문 노출 가능성

→ 에러 페이지 or 메시지 박스 띄우도록 해야 함

웹 방화벽 사용

웹 방화벽 : 웹 공격에 특화되어 있는 방화벽

  • 소프트웨어 형 : 서버 내에 직접 설치
  • 하드웨어 형 : 네트워크 상에서 서버 앞 단에 하드웨어 장비로 구성
  • 프록시 형 : DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법

공격 범위

  • bypass
  • data access
  • content change
  • db delete

0개의 댓글