본문 바로가기
야미스터디/Database

[DB] SQL Injection 📌

by 의정부핵꿀밤 2022. 8. 31.
728x90

SQL Injection (SQL 삽입 공격)

  • 악의적인 사용자가 보안상의 취약점을 이용하여 임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위
  • SQL Injection 공격은 OWASP Top 10 중 첫번쨰에 속해 있으며, 공격이 비교적 쉬운 편이고 공격에 성공할 경우 큰 피해를 입힐 수 있다
  • 이는 대부분 클라이언트가 입력한 데이터를 제대로 필터링하지 못하는 경우에 발생한다

 

 

 

SQL Injection의 성립 조건

  • 웹 애플리케이션이 DB와 연동되어 있다
  • 사용자가 입력한 외부 입력값이 SQL 구문의 일부로 사용된다

위의 두 조건을 만족해야 SQL Injection이 가능하다

그러나 현대 웹 애플리케이션의 대부분은 위 조건들을 충족하고 있기 때문에 SQL Injection의 대상이 될 수 있다

 

 

 

SQL Injection의 발생 원인

  • 데이터베이스와 연동된 웹 애플리케이션에서 입력된 데이터에 대한 유효성 검증을 하지 않아 발생하는 취약점이다
  • 취약한 앱 애플리케이션은 사용자로부터 입력된 값을 필터링 과정 없이 넘겨받아 동적 쿼리(Dynamic Query)를 생성한다
  • 이로인해 개발자가 의도하지 않은 쿼리가 생성되어 정보 유출에 악용될 수 있는 것이다

 

 

 

 

SQL Injection의 공격 방법

1. 인증 우회

보통 로그인을 할 떄, 아이디어와 비밀번호를 input 창에 입력하게 된다

예를 들어 아이디가 abc, 비밀번호가 1234인 경우, 쿼리는 다음과 같은 방식으로 전송된다

SELECT * FROM USER WHERE ID = "abc" AND PASSWORD = "1234";

 

SQL Injection은 공격할 때 input 창에 비밀번호를 입력함과 동시에 다른 쿼리문을 입력하는 것이다

1234; DELETE * USER FROM ID = "1";

보안이 완벽하지 않은 경우, 이처럼 비밀번호가 아이디와 일치해서 True가 되고 뒤에 작성한 DELETE 문도 데이터베이스에 영향을 줄 수도 있게 되는 치명적인 상황이다

 

이 밖에도 기본 쿼리문의 WHERE 절에 OR 문을 추가하여 '1'='1' 과 같은 true 문을 작성하여 무조건 적용되도록 수정한 뒤 DB를 마음대로 조작할 수도 있다

 

 

2. 데이터 노출

  • 시스템에서 발생하는 에러 메시지를 이용해 공격하는 방법이다
  • 보통 에러는 개발자가 버그를 수정하는 면에서 도움을 받을 수 있는 존재다
  • 해커들은 이를 역이용하여 악의적인 구문을 삽입하여 에러를 유발시킨다
  • 예를 들어, 해커는 GET 방식으로 동작하는 URL 쿼리 스트링을 추가하여 에러를 발생시킨다
  • 이에 해당하는 오류가 발생하면, 이를 통해 해당 웹앱의 데이터베이스 구조를 유추할 수 있고 해킹에 활용된다

 

 

 

 

😈 SQL Injection 종류

1. Error based SQL Injection

  • 논리적 오류 기반 SQL Injection
  • 고의로 SQL 문에 에러를 발생시키는 기법
    • 위의 사진처럼 1=1 과 같이 항상 참이 되는 구문을 주입하고 뒤의 조건은 -- 로 주석처리 한다
    • 그러면 조건절이 성립되어 Users 테이블의 모든 정보를 조회가 가능하게 된다
  • 에러 메시지를 통해 쿼리문의 구성을 추측할 수 있다
  • 또한 DB의 테이블명, 컬럼명, 데이터 내용까지도 알아낼 수 있다

 

논리적 에러를 발생시킬 수 있는 패턴

 

 

2. Blind SQL Injection

  • 이는 에러 메시지가 발생하지 않는 경우 주로 사용하는 기법이다
  • Blind -> 보이지 않는, 가려진 이라는 의미로 특정 쿼리문으로 인한 결과가 참/거짓인 것만 알 수 있을 때 사용한다
  • 예를 들어 로그인 시 성공하면 참, 실패하면 거짓인 것처럼 결과를 알 수 있을 때 사용한다
  • 위의 인젝션 쿼리 문은 테이블 명을 조회하는 구문이다
    • 해당구문은 MySQL 에서 테이블 명을 조회하는 구문으로 limit 키워드를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫 글자만그리고 마지막으로 ASCII 를 통해서 ascii 값으로 변환해준다
    • 만약에 조회되는 테이블 명이 Users 라면 ‘U’ 자가 ascii 값으로 조회가 될 것이고뒤의 100 이라는 숫자 값과 비교를 하게 된다
    • 거짓이면 로그인 실패가 될 것이고참이 될 때까지 뒤의 100이라는 숫자를 변경해 가면서 비교를 하면 된다
    • 공격자는 이 프로세스를 자동화 스크립트를 통하여 단기간 내에 테이블 명을 알아 낼 수 있다

 

 

 

3. Union SQL Injection

  • 이는 UNION 쿼리를 사용한 공격 기법을 아우른다
  • 공격하는 쿼리와 다른 쿼리를 결합하여 정보를 알아낼 때 사용하는 기법이다
    • 위의 그림과 같이 게시글을 조회하는 쿼리에 UNION을 통해서 인젝션한 구문을 넣게 되면 사용자의 개인정보와 게시글이 함께 조회가 된다
  • 공격에 성공하기 위해서는 쿼리 두 개의 컬럼 수와 데이터 형이 같아야 한다는 조건이 있다
  • UNION 쿼리에 따라 중복 결과를 얻을 수도 있고, 중복 결과를 제거하고 결과를 확인할 수 있다

 

4. Stored Procedure based SQL Injection

  • 저장된 프로시저에서의 SQL Injection
  • Stored Procedure는 일련의 쿼리를 하나의 함수처럼 실행하기 위한 쿼리의 집합
  • SQL Injection의 취약점으로 인해 웹에서 Stored Procedure에 대한 접근 권한을 가져서 실행이 가능하다
  • 시스템 권한을 획득해야 하므로 공격 난이도가 높으나 성공한다면 서버에 직접적인 피해를 입힐 수 있다

 

 

5. Mass SQL Injection

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

 

 

 

 

🥊 SQL Injection 공격 방어

1. 입력값 검증

사용자의 입력이 DB Query에 동적으로 영향을 주는 경우, 입력된 값이 개발자가 의도한 값(유효값)인지 검증한다

/*, –, ‘, “, ?, #, (, ), ;, @, =, *, +, union, select, drop, update, from, where, join, substr, user_tables, user_table_columns, information_schema, sysobject, table_schema, declare, dual,…

입력값을 받을 때 위와 같이 특수문자를 검사하여 의도하지 않은 입력값에 대해 검증하고 차단해야 한다

 

 

*Java 입력값 검증 예시 코드

import java.util.regex.Matcher;
import java.util.regex.Pattern;
 

/* 특수문자 공백 처리 */
final Pattern SpecialChars = Pattern.compile(“[‘\”\\-#()@;=*/+]”);
UserInput = SpecialChars.matcher(UserInput).replaceAll(“”);
 

final String regex = “(union|select|from|where)”;
 

final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
final Matcher matcher = pattern.matcher(UserInput);
 

if(matcher.find()){
    out.println(“<script>alert(‘No SQL-Injection’);</script>”);
}

 

🖤 블랙 리스트 방식

  • SQL 쿼리의 구조를 변경시키는 문자나 키워드, 특수문자를 제한하는 방식이다
  • SQL의 예약어인 UNION, GROUP BY와 COUNT() 등의 함수명, 세미콜론(;)이나 주석(--) 등의 특수 문자들을 블랙리스트로 미리 정의하고, 블랙리스트로 지정되어 있는 문자나 키워드가 외부 입력값 안에 존재하면 공백 등으로 치환하는 방식으로 방어한다
  • 하지만 정교하게 입력값을 검증하지 않는다면 블랙 리스트 방식의 검증을 우회할 수 있기 때문에 주의해야 한다
    • 예를 들어 외부 입력갑셍 SESELECTLECT라는 표현이 있을 때 중간의 SELECT가 공백으로 치환되면, 그 좌우에 있는 문자들이 합쳐져서 다시 SELECT 키워드가 완성된다

 

🤍 화이트 리스트 방식

  • 허용된 문자를 제외하고는 모두 허용되지 않는 방식으로, 금지된 문자 외에는 모두 허용하는 블랙리스트 방식보다 보안성 측면에서는 훨씬 더 강력한 방법이다
  • 웹 애플리케이션의 기능에 따라 알맞게 화이트 리스트를 작성해야 하는 번거로움이 존재한다
  • 그러한 번거로움을 해결하고 유지보수의 편리함을 증진시키기 위해 개별 문자를 일일이 하나씩 모두 정의하는 것보다 정규식 등을 이용해서 화이트 리스트를 범주화/패턴화시키는 편이 좋다

 

 

 

2. 저장 프로시저 (Prepared Statement) 사용

저장 프로시저는 사용하고자 하는 Query에 미리 형식을 지정하는 것을 말한다

지정한 형식의 데이터가 아니면 Query가 실행되지 않기 때문에 보안성을 크게 향상시킨다

 

*Java 취약 코드 예시

try{
  String uId = props.getProperty(“jdbc.uId”);
 

  String query = “SELECT * FROM tb_user WHERE uId=” + uId;
  stmt = conn.prepareStatement(query);
  ResultSet rs = stmt.executeQuery();
  while(rs.next()){
    .. …
  }
}catch(SQLException se){
  .. …
}finally{
  .. …
}

 

 

*Java 안전한 코드 예시

try {
  String uId = props.getProperty(“jdbc.uId”);
 

  String query = “SELECT * FROM tb_user WHERE uId= ?”
 

  stmt = conn.prepareStatement(query);
  stmt.setString(1, uId);
 

  ResultSet rs = stmt.executeQuery();
  while(rs.next()){
    .. …
  }
} catch(SQLException se){
  .. …
} finally{
  .. …
}

 

 

 

3. 서버 보안

  • 최소 권한 유저로 DB를 운영한다
  • 사용하지 않는 저장 프로시저와 내장 함수 제거 또는 권한 제어
  • 목적에 따라 Query 권한 수정
  • 공용 시스템 객체의 접근 제어
  • 신뢰할 수 있는 네트워크, 서버에 대해서만 접근 허용
  • 에러 메세지 노출 차단

 

 


참고)

http://blog.plura.io/?p=6056 

 

SQL Injection 대응 방안

SQL Injection 공격은 무엇인가? SQL Injection 은 웹 어플리케이션에서 DB 에 Query 시 입력된 데이터의 유효성 검증을 하지 않아, 개발자가 의도하지 않은 동적 쿼리(Dynamic Query) 를 생성하여 DB 정보를 열

blog.plura.io

https://gyoogle.dev/blog/computer-science/data-base/SQL%20Injection.html

 

SQL Injection | 👨🏻‍💻 Tech Interview

SQL Injection 해커에 의해 조작된 SQL 쿼리문이 데이터베이스에 그대로 전달되어 비정상적 명령을 실행시키는 공격 기법 공격 방법 1) 인증 우회 보통 로그인을 할 때, 아이디와 비밀번호를 input 창

gyoogle.dev

https://mong9data.tistory.com/133

 

[DB] SQL Injection (SQL 인젝션)

정의 SQL Injection은 응용 프로그램 보안 상의 허점을 의도적으로 이용해 악의적인 SQL문을 실행되게 함으로써 데이터베이스를 비정상적으로 조작하는 코드 인젝션 공격 방법입니다. SQL Injection을

mong9data.tistory.com

https://kk-7790.tistory.com/74

 

SQL Injection 이란?

SQL injection은 보안이나 IT 공부하거나, 그렇지 않더라도 뉴스나 다른 매체를 통해 들어본 적이 있을 법한 용어이다. 그만큼 웹 취약점에 있어서 SQL Injection은 흔하게 발생하며, 가장 크리티컬한 공

kk-7790.tistory.com

https://doh-an.tistory.com/27

 

[DB] SQL 인젝션 (SQL Injection )

✔️SQL 인젝션(SQL Injection)이란? 보안상의 취약점을 의도적으로 이용하여 악의적 SQL문을 실행되게 함으로써 데이터베이스를 비정상적으로 조작하는 코드 인젝션 공격 방법중 하나. *코드 인젝션

doh-an.tistory.com

https://seey.tistory.com/6

 

논리적 에러를 이용하는 sql injection

★★★실제 상용 사이트에 사용시 잡혀갈 수 있습니다★★★ ◆ sql injection 웹 어플리케이션에서 데이터베이스로 전달되는 sql 쿼리 값을 변조 및 삽입하여 비정상적으로 데이터 베이스에 접근

seey.tistory.com

 

728x90

'야미스터디 > Database' 카테고리의 다른 글

[DB] Redis 📌  (0) 2022.09.13
[DB] DB View 📌  (0) 2022.09.07
[DB] DDL, DML, DCL 📌  (0) 2022.08.10
[DB] RDB vs NoSQL 📌  (0) 2022.08.04
[DB] DB Index 📌  (0) 2022.07.17

댓글