SQL Injection

개요

SQL 인젝션 (SQL 삽입, SQL 주입으로도 불린다) 은 코드 인젝션의 한 기법으로 클라이언트의 입력값을 조작하여 서버의 데이터베이스를 공격할 수 있는 공격방식을 말한다. 주로 사용자가 입력한 데이터를 제대로 필터링, 이스케이핑하지 못했을 경우에 발생한다. 공격이 쉬운데 비해 파괴력이 어마어마 하기 때문에 시큐어 코딩을 하는 개발자라면 가장 먼저 배우게 되는 내용이다. 이러한 injection 계열의 취약점들은 테스트를 통해 발견하기는 힘들지만 스캐닝 툴이나 코드 검증절차를 거치면 보통 쉽게 발견되기 때문에 탐지하기는 쉬운 편이다. 보안회사 Imperva가 2012년에 발표한 보고서에 따르면 월 평균 4회 가량의 SQL 인젝션 공격이 일어난다고 한다. OWASP에서도 수년동안 인젝션 기법이 보안 위협 1순위로 분류되는 만큼 보안에 각별한 주의가 필요하다.

예제

로그인 폼에 아이디와 비밀번호를 입력하면 입력한 값이 서버로 넘어가고, 데이터베이스를 조회하여 정보가 있다면 로그인에 성공하게 된다. 이때 데이터베이스에 값을 조회하기 위해 사용되는 언어를 SQL이라고 하며 다음과 같이 생겼다고 가정하자.

SELECT user FROM user_table WHERE id='입력한 아이디' AND password='입력한 비밀번호';

(여기서는 패스워드를 평문으로 비교하는데 사실 이는 예제를 간단히 하기 위한거고 실제로 이런 식으로 짜면 개인정보보호법 29조 위반으로 과태료 폭탄을 맞을 수 있다. 패스워드는 반드시 SHA-256이상(SHA-512나 SHA-3 권장)의 보안성을 가지는 해시 함수로 해싱해야 한다. )

일반적인 유저 아래와 같이 정보를 입력하여 로그인 한다.

SELECT user FROM user_table WHERE id='일반' AND password='사용자';

여기서 악의를 품은 사용자가 아래와 같이 로그인 할 수 있다.

SELECT user FROM user_table WHERE id='악의' AND password=' ' OR '1' = '1';

비밀번호 입력값과 마지막 구문을 자세히 살펴보자. 따옴표를 올바르게 닫으며 password= '를 만들어 버림과 동시에 SQL 구문 뒤에 OR '1' = '1'을 붙였다. WHERE 뒤에 있는 구문을 간단히 축약하면 false AND false OR true로 정리할 수 있는데, 논리학에 따르면 AND 연산은 OR보다 연산 우선순위가 빠르기 때문에 해당 구문 전체는 true가 되어 올바른 값으로 판단하고 실행하게 된다. 즉 아이디와 비번을 제대로 매치하지 못했어도 ' OR '1' = '1''' 구문 때문에 로그인에 성공하게 되는 것이다.

위 구문으로 로그인 뿐만 아니라 JOIN이나 UNION같은 구문을 통해 원하는 코드를 실행하게 할 수도 있다.

방어방법

아마도 XSS와 상당부분 겹치겠지만 기본적으로 유저에게 받은 값을 직접 SQL로 넘기면 안 된다. 요즘에 쓰이는 거의 모든 데이터베이스 엔진은 유저 입력이 의도치 않은 동작을 하는 걸 방지하는 escape 함수와 prepared statement 를 제공한다. prepared statement 자체 내에 escape가 내장돼서 한 겹 감싸진 형태.

또한 DB에 유저 별로 접근 권한과 사용 가능한 명령어를 설정하면 최악의 경우에 SQL injection에 성공하였다고 하더라도 그나마 피해를 최소화 할 수 있다. 혹자는 SQL injection은 데이터베이스 스키마를 알아야 가능한 공격기법이라고 하지만 그 스키마 자체를 SQL injection으로 알아낼 수가 있다. 그리고 데이터베이스를 변조하려는 게 아니라 파괴하려는 거라면 와일드카드를 사용해서 그냥 싹 다 지워버리는 공격이 가능.

DB엔진별로 문법이 다 다르기 때문에 개발자가 그걸 다 고려해서 코딩하는 방법은 매우 비추천된다. 엔진에서 제공하는 prepared statement를 사용하는 게 최선. escape_string같은 함수를 사용하면 몇몇 군데에서 빼먹거나 하는 실수로 보안 구멍이 생길 수 있다. 그리고 prepared statement는 사용 전에 일부 컴파일돼서 DB쿼리를 가속시켜주므로 적극적으로 사용하자.

추천되는 방어법은 클라이언트측 자바스크립트로 폼 입력값을 한 번 검증하고, 서버측은 클라이언트측 필터가 없다고 가정하고(공격자가 자바스크립트를 꺼버리면 그만) 한번 더 입력값을 필터한다. 이때 정규표현식으로 필터하는게 가장 강력하고 좋다. 그 다음 SQL 쿼리로 넘길 때 해당 파라미터를 prepared statement로 입력한다. 다음, 쿼리의 출력값을 한번 더 필터하고(XSS 공격 방어의 목적이 강하다) 유저에게 전송한다. 이렇게 하면 해당 폼에 대해서는 SQL injection공격이 완전히 차단된다. 물론 이것이 공격 기법의 전부가 아니므로(스푸핑이나 맨 인 미들 공격, 키로거 등 아직 많다) 정보 유출에 민감한 사이트를 운영할 생각이라면 보안 회사에 컨설팅을 꼭 받아야 한다.

'보안 & 보안' 카테고리의 다른 글

SandBox란?  (0) 2016.07.28
AES와 SHA 차이  (2) 2016.07.21
AES  (0) 2016.07.21
Man In The Middle Attack  (0) 2016.07.19
SQL Injection  (0) 2016.07.06
SHA  (0) 2016.07.06

SHA란?

SHA(Secure Hash Algorithm, 안전한 해시 알고리즘) 함수들은 서로 관련된 암호학적 해시 함수들의 모음이다. 이들 함수는 미국 국가안보국(NSA)이 1993년에 처음으로 설계했으며 미국 국가 표준으로 지정되었다. SHA 함수군에 속하는 최초의 함수는 공식적으로 SHA라고 불리지만, 나중에 설계된 함수들과 구별하기 위하여 SHA-0이라고도 불린다. 2년 후 SHA-0의 변형인 SHA-1이 발표되었으며, 그 후에 4종류의 변형, 즉 SHA-224SHA-256SHA-384SHA-512가 더 발표되었다. 이들을 통칭해서 SHA-2라고 하기도 한다.

SHA-1은 SHA 함수들 중 가장 많이 쓰이며, TLS, SSL, PGP, SSH, IPSec 등 많은 보안 프로토콜과 프로그램에서 사용되고 있다. SHA-1은 이전에 널리 사용되던 MD5를 대신해서 쓰이기도 한다. 혹자는 좀 더 중요한 기술에는 SHA-256이나 그 이상의 알고리즘을 사용할 것을 권장한다.

SHA-0과 SHA-1에 대한 공격은 이미 발견되었다. SHA-2에 대한 공격은 아직 발견되지 않았으나, 전문가들은 SHA-2 함수들이 SHA-1과 비슷한 방법을 사용하기 때문에 공격이 발견될 가능성이 있다고 지적한다. 미국 표준 기술 연구소(NIST)는 SHA-3로 불리는 새로운 암호화 해시 알고리즘에 대한 후보를 공모하였다.

SHA 함수군

최초의 알고리즘은 1993년에 미국 표준 기술 연구소(NIST)에 의해 안전한 해시 표준(Secure Hash Standard, FIPS PUB 180)으로 출판되었으며, 다른 함수들과 구별하려 보통 SHA-0이라고 부른다. 얼마 안 있어 NSA는 이 표준을 폐기했고, 1995년에 개정된 알고리즘(FIPS PUB 180-1)을 새로 출판했으며 이를 SHA-1이라고 부른다. SHA-1은 SHA-0의 압축 함수에 비트 회전 연산을 하나 추가한 것으로, NSA에 따르면 이는 원래 알고리즘에서 암호학적 보안을 감소시키는 문제점을 고친 것이라고 하지만 실제로 어떤 문제점이 있었는지는 공개하지 않았다. 일반적으로 SHA-1은 SHA-0보다 암호학적 공격이 힘든 것으로 알려져 있으며, 따라서 NSA의 주장은 어느 정도 설득력이 있다. SHA-0과 SHA-1은 최대 264비트의 메시지로부터 160비트의 해시값을 만들어 내며, 로널드 라이베스트가 MD4 및 MD5 해시 함수에서 사용했던 것과 비슷한 방법에 기초한다.

NIST는 나중에 해시값의 길이가 더 긴 네 개의 변형을 발표했으며, 이들을 통칭하여 SHA-2라 부른다. SHA-256, SHA-384, SHA-512는2001년에 초안으로 처음으로 발표되었으며, 2002년에 SHA-1과 함께 정식 표준(FIPS PUB 180-2)으로 지정되었다. 2004년 2월에 삼중 DES의 키 길이에 맞춰 해시값 길이를 조정한 SHA-224가 표준에 추가되었다. SHA-256과 SHA-512는 각각 32비트 및 64비트 워드를 사용하는 해시 함수이며, 몇몇 상수들이 다르긴 하지만 그 구조는 라운드의 수를 빼고는 완전히 같다. SHA-224와 SHA-384는 서로 다른 초기값을 가지고 계산한 SHA-256과 SHA-512 해시값을 최종 해시값 길이에 맞춰 잘라낸 것이다.

크기비교

알고리즘해시값 크기내부 상태 크기블록 크기길이 한계워드 크기과정 수사용되는 연산충돌
SHA-0160160512643280+,and,or,xor,rotl발견됨
SHA-1160160512643280+,and,or,xor,rotl공격법만 존재
SHA-256/224256/224256512643264+,and,or,xor,shr,rotr-
SHA-512/384512/38451210241286480+,and,or,xor,shr,rotr-

예제

다음은 SHA-1 해시값의 예제이다.

SHA1("The quick brown fox jumps over the lazy dog")
  = 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12

해시값은 눈사태 효과 때문에 메시지가 조금만 바뀌어도 완전히 바뀔 수 있다. 다음 예시는 위의 예제 끝에 마침표(.)를 찍은 것이다.

SHA1("The quick brown fox jumps over the lazy dog.")
  = 408d94384216f890ff7a0c3528e8bed1e0b01621

빈 문자열의 해시는 다음과 같다.

SHA1("") = da39a3ee5e6b4b0d3255bfef95601890afd80709


'보안 & 보안' 카테고리의 다른 글

SandBox란?  (0) 2016.07.28
AES와 SHA 차이  (2) 2016.07.21
AES  (0) 2016.07.21
Man In The Middle Attack  (0) 2016.07.19
SQL Injection  (0) 2016.07.06
SHA  (0) 2016.07.06

+ Random Posts