SQL Injection 제목이 곧 내용이다.
보이지 않는 손 같이 멋지고 섹시한 네이밍센스는 이과, 공대에서 찾기 힘들다. 대부분 이름이 내용이거나 만든사람 이름이다.
SQL Injection이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위이다.
-- tmi
OWASP(Open Web Application Security Project)라는 프로젝트가 있다.
애플리케이션 보안에만 전념하는 여러 커뮤니티 그룹의 조직이 있는데 이중 가장 큰 그룹이 OWASP이다.
주로 웹에 관한 정보노출, 악성 파일 및 스크립트, 보안 취약점 등을 연구하며, 2013년, 2017년, 2021년 10대 웹 애플리케이션의 취약점 OWASP TOP 10을 발표했다. 선정 기준은 웹 애플리케이션 취약점 중에서 공격 빈도가 많고, 보안상 영향을 크게 줄 수 있는 가성비 좋은 취약점들이다. 13년과 17년에선 1위, 21년엔 3위를 기록한 취약점이 SQL Injection이다.
실제로 2017년 여기어때도 SQL Injection으로 인한 개인정보 유출사건이 발생했고 피해가 엄청났다고 한다.
SQL Injection은 보안과목에서 다뤄야하지 않나 싶어서 주제 바꾸자고 말하려다가.. 수업내용도 나오고... 그래도 알아두면 좋을거같아서 입꾹닫고 포스팅한다.
아무리 가성비 좋은 SQL Injection이라고 해서 아무거나 생각나는데로 쿼리를 막 넣는게 아니다.
여러가지 방법, 종류가 있는데 종류에 대해 알아보고 대응 방안에 대해 알아보자
SQL Injection 종류
Error based SQL Injection (논리적 에러를 이용한 SQL Injection)
논리식에 허점을 이용한 SQL Injection이다. 가장 많이 쓰이며, 대중적인(?) 공격기법이다.
아래는 일반적으로 로그인할 때 가장 많이 사용되는 sql 구분이다.
SELECT * FROM Useres WHERE id='input1' and password = 'input2'
여기서 사용자가 input1에 아래와 같은 인풋을 넣는다고 가정해보자.
' OR 1=1 --
input1을 처리한 쿼리는 아래와 같다.
SELECT * FROM Users WHERE id='' OR 1=1 -- ' AND password = 'input2'
--를 이용하여 input1 뒤의 문장을 전부 주석처리하고, OR 1=1을 넣음으로서 해당 조건은 모두 True가 된다.
따라서 위의 쿼리는 아래의 쿼리와 결과가 항상 같다.
SELECT * FROM Users
매우 간단한 input1인데 결론적으로 Users 테이블에 있는 모든 정보를 조회하게 되고, 가장 먼저 만들어진 계정으로 로그인에 성공하게 된다. 심지어 대부분 관리자 계정을 가장 처음 만들기 때문에 계정에 관리자 계정으로 로그인 될 확률이 크다.
Union based SQL Injection (Union 명령어를 이용한 SQL Injection)
SQL에서 Union 키워드는 두개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드이다.
정상적인 쿼리문에 Union 키워드를 사용하여 인젝션하면, 원하는 쿼리문을 실행할 수 있게 된다.
설명보다 쿼리부터 확인하는게 이해하기 쉬워보인다.
-- 게시글 조회
SELECT * FROM Board WHERE title LIKE '%INPUT%' OR contents '%INPUT%'
위와 같은 쿼리가 있다. 게시글의 제목이나 내용에 input과 같은게 있으면 보여달라는 검색하는 쿼리이다.
여기서 사용자가 INPUT으로 아래와 같은 쿼리를 넣는다고 가정해보자.
'
UNION
SELECT null,id,passwd FROM Users --
INPUT을 처리한 쿼리는 아래와 같다.
SELECT * FROM Board WHERE title LIKE '%'
UNION
SELECT null,id,passwd FROM Users -- %' OR contents '%INPUT%'
이 쿼리문의 수행 결과는 보드의 타이틀과 아무거나 매치되는 결과와 유저의 id와 passwd를 함께 보여주는 테이블이 보여지게 된다. 인젝션이 성공하게 된다면, 사용자의 개인정보가 게시글과 함께 화면에 보여지게 될 것이다.
물론 패스워드를 평문으로 데이터베이스에 저장하지는 않겠지만 인젝션이 가능하다는 점에서 보안 위험에 노출되어 있다.
예시에서 null을 넣어주었는데 UNION 연산은 컬럼 수를 맞춰줘야하기때문에 null을 넣었다.
컬럼수, 테이블의 컬럼 이름 등 테이블의 구조를 필요로하는 경우가 많은데 이또한 SQL Injection으로 획득이 가능하다.
Blind SQL Injection (Boolean based SQL)
데이터베이스로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓 정보만 알 수 있을때 사용한다.
로그인 폼에 SQL Injection이 가능하다고 가정했을때 서버가 응답하는 로그인 성공과 로그인 실패 메세지를 이용하여, DB의 테이블 정보 등을 추출할 수 있다. 즉, 사용자의 데이터보단 데이터베이스, 테이블의 정보를 알아내는 방법이다.
다시 한 번 로그인할때 자주 사용되는 SQL을 보자
SELECT * FROM Users WHERE id = 'input1' AND password = 'input2'
그리고 역시 input1에 내가 원하는 sql을 삽입한다.
abc123' AND ASCII(SUBSTR(SELECT name FROM information_schema.tables WHERE table_type='base table' limit 0,1)1,1)) > 100 --
위와같은 긴 인풋을 넣는다. (MySQL 가정)
사용자는 임의로 회원가입한 abc123이라는 아이디와 함께 주입한다. AND 뒤에 오는 SELECT 구문은 MySQL에서 테이블명을 조회하는 구문으로 limit키워드를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫글자만, 마지막으로 ASCII를 통해서 ascii값으로 변환해준다. 만약에 조회되는 테이블명이 Users라면 'U'자가 ascii값으로 조회될 것이고, 뒤의 100이라는 숫자 값과 비교하게 된다. 거짓이면 로그인 실패가 될 것이고 참이라면 로그인에 성공할 것인데, 참이 될 때 까지 뒤의 100이라는 숫자를 변경해가며 비교한다. 공격자는 이 프로세스를 자동화 스크립트를 통해 단기간내에 테이블 명을 알아낼 수 있다.
Blind SQL Injection (Time based SQL)
얘도 마찬가지로 서버로부터 특정한 응답대신 참, 거짓의 응답을 통해서 데이터베이스의 정보를 유추하는 기법이다.
사용되는 함수는 MySQL 기준 SLEEP과 BENCHMARK이다.
다시 로그인하는 SQL
SELECT * FROM Users WHERE id = 'input1' AND password = 'input2'
삽입할 쿼리
abc123' OR (LENGTH(DATABASE())=1 AND SLEEP(2)) --
-- SLEEP이 치환처리 되어있다면 BENCHMARK() 함수 사용
abc123' OR(LENGTH(DATABASE())=1 AND BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye'));
위의 쿼리는 데이터베이스의 길이를 알아내는 방법으로 SLEEP(2)가 동작할때까지 (LENGTH(DATABASE())=1에서 숫자 1을 변경해가며 시도한다. (AND연산 특성상 LENGTH(DATABASE())가 1이라면 SLEEP(2)가 동작할것이고 아니라면 동작하지 않는다.)
만약 SLEEP이라는 단어가 치환처리 되어있다면 또다른 방법으로 BENCHMARK나 WAIT함수를 사용할 수 있다.
치환처리는 뒤에 대응방안에서 알아보자.
Stored Procedure SQL Injection (저장된 프로시저에서의 SQL Injection)
저장 프로시저(Stored Proceduere)은 일련의 쿼리들을 모아 하나의 함수처럼 사용하기 위한 것이다.
공격에 사용되는 대표적인 저장 프로시저는 MS-SQL에 있는 xp_cmdshell로 윈도우 명령어를 사용할 수 있게 된다. 단, 공격자가 시스템 권한을 획득해야 하므로 공격난이도가 높으나, 공격에 성공한다면 서버에 직접적인 피해를 입힐 수 있는 공격이다.
Mass SQL Injection (다량의 SQL Injection 공격)
기존 SQL Injection과 달리 한번의 공격으로 다량의 데이터베이스가 조작되어 큰 피해를 입히는 것을 의미한다.
데이터베이스에 악성스크립트를 삽입하고, 사용자들이 변조된 사이트에 접속 시 좀비 PC로 감염되게 하며 해당 좀비 PC들을 DDos공격에 사용한다.
대응 방안
입력값에 대한 검증
SQL Injection에서 사용되는 기법과 키워드는 엄청나게 많다.
사용자의 입력값에 대한 검증이 필요한데, 서버단에서 화이트리스트 기반으로 검증해야한다. 즉, 가능한 키워드를 리스트로 만들어 검증해야한다. 불가능한 키워드를 리스트로(블랙리스트) 만들어 검증할 경우 보다 많은 키워드를 등록해야하며, 하나라도 빠지면 공격 당할 수 있기 때문이다.
여기서 화이트리스트에 포함되지 않거나, 블랙리스트에 포함된다면, 문자를 치환하는 방법을 많이 쓴다. 이때 공백으로 치환하는 경우가 종종있는데 공백으로 치환하는 방법은 취약한 검증 방법이다.
예를들어 공격자가 SESELECTLECT 를 입력한다면 중간의 SELECT가 공백으로 치환되며 다시 SELECT가 완성된다. 이러한 경우의 수를 전부 처리하기보다 공백대신 공격키워드와는 의미없는 단어로 치환하는 방법이 적절하다.
Prepared Statement 구문 사용
Prepared Statement 구문을 사용하게 되면, 사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에 DBMS가 미리 컴파일 하여 실행하지 않고 대기한다.
그 후 사용자의 입력값을 문자열로 인식하게 하여 공격쿼리가 들어간다하더라도, 사용자의 입력은 의미 없는 단순 문자열이 된다.
SELECT * FROM Users WHERE id = 'input1' AND password = 'input2'
에서 input1과 input2를 처리한 쿼리문을 입력받은 뒤 컴파일하는것이 아니라, 쿼리문을 미리 컴파일해놓고, input1과 input2를 처리한다면 뒤의 내용이 -- 를 통해 주석이 될 일도, 다른 쿼리문이 삽입 될 일도 없다.
괜히 교수님이 prepared statement쓰라는게 아니다. 이내용과 아래 Error Message 노출금지 내용이 없었으면 아마 SQL Injection말고 주제 하자고 했을 수도 있다.
Error Message 숨기기
공격자가 SQL Injection을 수행하기 위해서는 데이터베이스의 정보(테이블 명, 컬럼명 등)가 필요하다. DB에서 에러발생시 따로 처리해주지 않았다몀ㄴ, 에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환해주는데 이 내용을 바로 보여준다면 테이블 명, 컬럼명, 쿼리문이 노출될 수 있다. 따라서 사용자에게 보여줄 수 있는 페이지를 별도로 만들거나, 메세지박스를 따로 만드는것이 좋다.
(에러 처리는 꼭 할 수 있어야해요~~)
https://security04.tistory.com/171
SQL Injection 우회 정리
SQL Injection 우회 정리 기본적인 우회 1. 주석 ‘ or 1=1# ‘ or 1=1– – ‘ or 1=1/* (MySQL < 5.1) ' or 1=1;%00 ' or 1=1 union select 1,2 as ` ' or#newline 1='1 ' or– -newline 1='1 ' /*!50000or..
security04.tistory.com
요약해보면
위의 블로그 내용은 엄청나게 많은 예시가 있다. 사용자가 input으로 넣으면 위험한 내용들이다. 따라서 얘네의 입력을 막거나, 검증된 입력만 받을 수 있도록 리스트를 작성해야한다.
그리고 교수님말 잘듣자 :)
여기어때에서 발생한 개인정보 유출사건 ++ SQL Injection, 여기어때
안녕하세요! 오늘은 여기 어때 에서 발생한 해킹 사건에 관해서 알아보도록 하겠습니다! 먼저 여기어때는 국내 숙박 예약 플랫폼 회사로 야놀자와 함께 국내 숙박 업계의 양대산맥일 만큼 입지
hobbylists.tistory.com
https://noirstar.tistory.com/264
SQL Injection 이란? (SQL 삽입 공격)
1. SQL Injection 1.1 개요 SQL Injection SQL Injection 이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작
noirstar.tistory.com
https://kk-7790.tistory.com/74
SQL Injection 이란?
SQL injection은 보안이나 IT 공부하거나, 그렇지 않더라도 뉴스나 다른 매체를 통해 들어본 적이 있을 법한 용어이다. 그만큼 웹 취약점에 있어서 SQL Injection은 흔하게 발생하며, 가장 크리티컬한 공
kk-7790.tistory.com
https://security04.tistory.com/171
SQL Injection 우회 정리
SQL Injection 우회 정리 기본적인 우회 1. 주석 ‘ or 1=1# ‘ or 1=1– – ‘ or 1=1/* (MySQL < 5.1) ' or 1=1;%00 ' or 1=1 union select 1,2 as ` ' or#newline 1='1 ' or– -newline 1='1 ' /*!50000or..
security04.tistory.com
'CS > DB' 카테고리의 다른 글
CAP - Consistency, Availability, Partition tolerance - C (0) | 2023.04.30 |
---|---|
DB 데드락이란? (3) | 2022.08.30 |
DB Index 란 (7) | 2022.08.15 |