SQL Injection 개념

황씨·2022년 1월 16일
1

이미지 출처 : Cloudflare

SQL 인젝션 (SQL Injection)

SQL 인젝션은 웹 애플리케이션을 이용하고 있는 데이터베이스에 SQL을 부정하게 실행하는 공격 방식이다.
SQL Injection은 OWASP TOP 10 목록의 3위를 차지하고 있을만큼 대중적이고 치명적인 기법이다.

OWASP(The Open Web Application Security Project)란? 오픈소스 웹 애플리케이션 보안 프로젝트이다. 주로 웹에 관한 정보노출, 악성 파일 및 스크립트, 보안 취약점 등을 연구한다.

SQL 인젝션에 의해 받을 수 있는 영향

  • 데이터베이스 내의 데티어 부정 열람이나 변조
  • 인증 회피
  • 데이터베이스 서버를 경유한 프로그램 실행

SQL 인젝션으로 인한 국내 피해 사례

  1. 여기어때 해킹 사건

    이용자명과 휴대전화 번호는 물론 숙박 이용정보 등이 빠져 나갔으며 어플 이용자에게 협박성 문자를 전송한 사건
    https://www.joongang.co.kr/article/21628794#home

  2. 뽐뿌 해킹 사례

    해킹범이 SQL Injection 취약점을 이용하여 약 196만 명의 개인정보가 유출된 사건

SQL 인젝션의 종류와 공격 방법

1. Error Based SQL Injection

가장 많이 쓰이는 SQL Injection 공격 방법이다.
WHERE 절 이후가 동적 쿼리로 되어 있다고 가정했을 때

SELECT * FROM MEMBER WHERE id = 'honggd' AND password = '12341234'

사용자의 입력 값에 ' or 1=1 --(주석)을 추가하면 항상 참인 쿼리가 되기 때문에 비밀번호의 유효성을 검증하지 않고 로그인 할 수 있다.

해커 입력값 : abcd' OR 1=1 --

SELECT * FROM MEMBER WHERE id = 'honggd' AND password = 'abcd' OR 1=1 --

2. Union Based SQL Injection

2개 이상의 쿼리를 요청하여 결과를 얻어내는 UNION 연산자를 이용한 공격 방법이다.

UNION 연산자를 사용하기 위해서는 2개의 테이블이 동일한 필드 개수를 가져야 하기 때문에 사전 공격을 통해 해당 정보를 알아낼 필요가 있다.

⇒ 에러 페이지를 통해 정보를 알아낼 수 있다.

해커 입력값 : honggd’ UNION SELECT cardNo, password FROM card_log --'

SELECT name, age FROM member WHERE id = 'honggd' UNION SELECT cardNo, password FROM card_log -- '

3. Blind Based SQL Injection

3-1. Boolean Based SQL

DB에서 데이터를 얻어내는 앞의 방법들과 다르게 쿼리 결과의 참, 거짓만으로 값을 유추해낼 수 있는 방법이다.

동적 쿼리 뒤에 1=1 (반드시 참), 1=2(반드시 거짓) 조건을 붙인 후 Return 되는 출력 값을 알아내서 DB 정보와 버전 등을 알아낼 수 있다.

⇒ 수백 수천번의 시도를 해야 하기 때문에 보통 자동화 프로그램을 이용하여 시도한다.

검색어에 honggd’ and ‘1’ = ‘1 을 입력했을 때 참이 리턴된다면 취약점이 존재하는 것이다.

해커 입력값 : honggd' AND 1=1

SELECT id FROM MEMBER WHERE id = 'honggd' AND 1=1

3-2. Time Based SQL

참, 거짓의 응답 결과가 같을 떄 시간을 지연시키는 쿼리를 주입하여 시간 차이로 참, 거짓 여부를 판단할 수 있다.

  • 해당 쿼리에서 응답이 5초 뒤에 이루어지면 참
  • 바로 이루어지면 거짓이다

해커 입력값 : honggd' AND sleep(5)

SELECT id FROM MEMBER WHERE id = 'honggd' AND sleep(5)

SQL Injection을 방어하는 방법

  • DB 계정의 권한을 제한한다.
  • 쿼리 스트링을 사용하지 않고 PreparedStatement, SqlCommand 등을 이용한다.
  • 가능한 한 동적 쿼리를 지양한다.
  • 클라이언트 측 뿐만아니라 서버 측에서도 사용자 입력 값에 주석, DB 연산자가 있는지 유효성 검사를 한다.
  • 데이터베이스의 에러 메세지를 사용자 화면에 보여주지 않는다.
profile
그냥 기록하기

0개의 댓글