Skip to content

SQL Injection #

Find similar titles

2회 업데이트 됨.

Edit
  • 최초 작성자
  • 최근 업데이트
    jmchoi

SQL Injection #

SQL Injection 이란? #

  • SQL 인젝션, SQL 삽입이라고도 불리며, 응용 프로그램 보안상의 허점을 의도적으로 이용해, 악의적인 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위이다.
  • SQL Injection은 주로 사용자가 입력한 데이터를 제대로 필터링, 이스케이핑하지 못했을 때 발생한다.
  • 이러한 Injection 계열의 취약점들은 테스트를 통해 발견하기는 힘들지만, 스캐닝툴이나 코드 검증 절차를 거치면 보통 쉽게 발견되기 때문에 탐지하기는 쉬운 편이다.
  • Injection 공격은 OWASP(The Open Web Application Security Project) TOP 10중 첫 번째에 속해 있으며, 공격이 비교적 쉬운 편이고 공격에 성공하면 큰 피해를 줄 수 있어 보안에 각별한 주의가 필요하다.
  • 실제로, 2017년 3월에 일어난 여기어때의 대규모 개인정보 유출 사건도 SQL Injection으로 인해 발생했다.

SQL Injection 공격 종류 및 방법 #

1. Error based SQL Injection #

  • 논리적 에러를 이용한 SQL Injection
  • SQL 공격 기법은 여러 가지가 있는데 논리적 에러를 이용한 SQL Injection은 가장 많이 쓰이고, 대중적인 공격 방법이다.
  • [로그인 공격 예시]

    • 공격 대상

      SELECT * FROM Users WHERE id = 'insilicogen' AND password = 'insilicogen!';
      
    • 공격 예시 : 로그인 창의 ID 부분에 'OR 1 = 1 --를 입력한다.

      SELECT * FROM Users WHERE id = '' OR 1=1 -- ' AND password = 'insilicogen!';
      
    • 공격 과정
      1) WHERE 절에 있는 싱글 쿼터를 닫아주게 되고,
      2) OR 1 = 1로 모두 참을 만들어 준 후
      3) --를 이용해 그 뒤의 모든 쿼리문을 주석처리 한다.

    • 결과
      Users 테이블에 있는 모든 정보를 조회하게 됨으로써 가장 먼저 만들어진 계정으로 로그인에 성공하게 된다.
      보통은 관리자 계정을 맨 처음 만들기 때문에 관리자 계정에 로그인 할 수 있게 된다.
      이렇게 관리자 계정을 탈취한 공격자는 관리자의 권한을 이용해 또 다른 2차 피해를 발생시킬 수 있게 되는 것이다.

2. UNION based SQL Injection #

  • UNION 명령어를 이용한 SQL Injection
  • SQL에서 UNION 키워드는 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드이다.
  • 정상적인 쿼리문에 UNION 키워드를 사용하여 인젝션에 성공하면, 원하는 쿼리문을 실행할 수 있게 된다.
  • UNION Injection을 성공하기 위해서는 두 가지의 조건이 있다.
    1) UNION 하는 두 테이블의 컬럼 수가 같아야 한다.
    2) UNION 하는 두 테이블의 데이터 타입이 같아야 한다.
  • 또한, ORDER BY 절이나 HAVING을 이용한 오류 메시지를 통해 컬럼의 수를 유추할 수도 있다.
  • [게시글 조회 공격 예시]

    • 공격 대상

      SELECT * FROM notice WHERE title LIKE '%INPUT%' OR contents '%INPUT%';
      
    • 공격 예시 : 검색 창에 'UNION SELECT null, id, pwsd FROM User를 -- 입력한다.

      SELECT * FROM notice WHERE title LIKE '% ' UNION SELECT null,id,pwsd FROM Users -- INPUT%' OR contents '%INPUT%';
      
    • 공격 과정
      1) 입력값을 title과 contents 컬럼의 데이터랑 비교한 뒤 비슷한 글자가 있는 게시글을 출력한다.
      2) 여기서 입력값으로 UNION 함께 컬럼 수를 맞춰서 SELECT 구문을 넣어주게 되면 두 쿼리문이 합쳐서 하나의 테이블로 보여지게 된다.
      3) 사용자의 id와 pwsd를 요청하는 쿼리문을 함께 입력한다.

    • 결과 : 인젝션이 성공하게 되면, 사용자의 개인정보가 게시글과 함께 화면에 보여지게 된다.

3. Blind SQL Injection (1) #

  • Boolean based SQL Injection
  • 에러가 발생하지 않는 사이트에서 데이터베이스로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓의 정보만 알 수 있을 때 사용하는 공격 방법이다.
  • 서버가 응답하는 성공과 실패 여부를 이용하여 DB의 테이블 정보 등을 추출할 수 있다.
  • 최근에는 에러 메시지를 출력하지 않는 웹 서버를 구축하고 있어 주로 사용하는 방법이다.
  • [Boolean 기반 공격 예시]

    • 공격 대상

      SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2';
      
    • 공격 예시

      SELECT * FROM Users WHERE id = 'abc123' and ASCII(SUBSTR((SELECT name FROM information_schema.tables WHERE table_type='base table' limit 0,1),1,1)) > 100 (로그인이 될 때까지 시도) -- INPUT1' AND password = 'INPUT2'
      
    • 공격 과정
      1) 인젝션이 가능한 로그인 폼을 통하여 악의적인 사용자는 임의로 가입한 abc123 이라는 아이디와 함께 구문을 주입한다.
      2) 해당 구문은 테이블 명을 조회하는 구문으로 limit 키워드를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫 글자만 조회한다.
      3) ASCII를 통해 값이 변환되고
      4) 만약, 조회되는 테이블 명이 Users 라면 'U' 자가 ascii 값으로 변환되어 테이블이 조회된다.
      5) 거짓이면 로그인 실패가 될 것이고, 참(로그인)이 될 때까지 뒤의 100이라는 숫자를 변경해 가면서 비교하게 된다.

    • 결과 : 공격자는 이 프로세스를 자동화 스크립트를 통하여 단기간 내에 테이블 명을 알아낼 수 있게 된다.

4. Blind SQL Injection (2) #

  • Time based SQL Injection
  • Time Based SQL Injection도 마찬가지로 서버로부터 특정한 응답 대신에 참 혹은 거짓의 응답을 통해서 데이터베이스의 정보를 유추하는 공격 방법이다.
  • 사용되는 SQL 문 : SLEEP, BENCHMARK (MySQL 기준)
  • Time based SQL Injection의 궁극적 목표는 DB 구조를 파악하기 위함이다.
  • [Time 기반 공격 예시]

    • 공격 대상

      SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2'
      
    • 공격 예시 : 현재 사용하고 있는 데이터베이스의 길이를 알아내기

      SELECT * FROM Users WHERE id = 'abc123' OR (LENGTH(DATABASE())=1 (SLEEP 할 때까지 시도) AND SLEEP(2)) -- INPUT1' AND password = 'INPUT2'
      
    • 공격 과정
      1) 로그인 폼에 주입이 되었으며 임의로 abc123 이라는 계정을 생성한 후, 공격 구문을 주입한다.
      2) 여기서 LENGTH 함수는 문자열의 길이를 반환하고, DATABASE()를 사용해 데이터베이스의 이름을 반환합니다.
      3) 주입된 구문에서, LENGTH(DATABASE()) = 1 가 참이면 SLEEP(2) 가 동작하고, 거짓이면 동작하지 않는다.

    • 결과 : 이를 통해서 숫자 1 부분을 조작하여 데이터베이스의 길이를 알아낼 수 있습니다. 만약, SLEEP 단어가 치환 처리되었을 경우, 'BENCHMARK'나 'WAIT' 함수를 사용할 수 있습니다.

5. Stored Procedure based SQL Injection #

  • 저장 프로시저에서의 SQL Injection
  • 저장 프로시저(Stored Procedure) : 편의를 위해 일련의 쿼리들을 모아 하나의 함수처럼 모아둔 것
  • 대표적으로, MS SQL에서 사용할 수 있는 xp_cmdshell을 통해 윈도우 명령어를 사용할 수 있게 된다.
  • 단, 공격자가 시스템 권한을 획득 해야 하므로 공격난이도가 높으나 공격에 성공한다면, 서버에 직접적인 피해를 입힐 수 있는 공격이다.

6. Mass SQL Injection #

  • 다량의 SQL Injection 공격
  • 2008년에 처음 발견된 공격기법으로 기존 SQL Injection과 달리 한 번의 공격으로 다량의 데이터베이스가 조작되어 큰 피해를 입히는 공격 방법이다.
  • MS-SQL을 사용하는 ASP 기반 웹 애플리케이션에서 많이 사용되며, 쿼리문은 Hex 인코딩 방식으로 인코딩하여 공격한다.
  • 데이터베이스 값을 변조하여 데이터베이스에 악성 스크립트를 삽입하고, 사용자들이 변조된 사이트에 접속 시 좀비 PC로 감염되게 한다.
  • 이렇게 감염된 좀비 PC들은 DDoS 공격에 사용된다.

대응방안 #

  • 입력값 검증 및 정제

    • 사용자 입력값을 검증하고, 필요한 경우 정제하여 허용되지 않는 문자나 명령어를 필터링하거나 데이터 길이를 제한한다.
    • 정규 표현식이나 라이브러리를 사용하여 유효성을 검사할 수 있다.
  • Prepared Statements 사용

    • SQL 쿼리를 동적으로 생성하는 대신, Prepared Statements를 사용하여 사용자 입력을 적절하게 처리한다.
    • 이는 입력값을 쿼리에 직접 삽입하지 않고, 파라미터로 전달함으로써 SQL Injection 공격을 방지할 수 있다.
  • 파라미터화된 쿼리 사용

    • 사용자 입력값을 쿼리에 직접 연결하는 대신, 파라미터화된 쿼리를 사용한다.
    • 대부분의 프로그래밍 언어나 ORM(Object-Relational Mapping) 라이브러리에서 이를 지원하고 있다.
  • 권한 제한

    • 데이터베이스 사용자에게 애플리케이션이 필요로 하는 최소한의 권한만 부여함으로써 피해를 최소화할 수 있다.
  • 에러 핸들링 방안

    • 디버깅 정보를 최소화하고, 사용자에게는 일반적인 오류 메시지만 제공한다. 세부적인 오류 정보는 로그에 기록되도록 한다.
  • 웹 방화벽 사용

    • 웹 애플리케이션 방화벽(WAF)을 사용하여 SQL Injection과 같은 공격을 감지하고 차단할 수 있다.
    • 웹 방화벽은 아래와 같이 3가지 종류로 나뉜다.
      1) 소프트웨어 형 : 서버 내에 직접 설치하는 방법이다.
      2) 하드웨어 형 : 네트워크상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 것이다.
      3) 프록시 형 : DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법이다.

이러한 대응 방안을 조합하여 사용하면 SQL Injection과 같은 보안 공격에 대응할 수 있다.



Reference #

0.0.1_20240214_1_v81