반응형

SQL인젝션이란?

웹 애플리케이션 사용자의 입력 값에 필터링이 제대로 적용돼 있지 않을 때 발생합니다. 공격자는 사용자의 입력 값을 조작해 개발자가 의도치 않은 SQL문을 실행하게 만들어 데이터베이스를 공격하는 것을 SQL인젝션이라고 합니다.

 

SQL이란?

SQL은 데이터베이스(DB)를 만들고 유지하는 데 사용하는 프로그래밍 언어 중 하나입니다. DB를 구축하고 조작하기 위해 사용하는 일종의 명령어인 셈입니다. SQL을 이용하면 데이터를 정의, 조작, 제어할 수 있습니다.

 

SQL인젝션의 2가지공격인 에러 기반 공격과 블라인드 공격

에러 기반 공격은 해커가 검사하지 않은 입력값을 발견하고, 이를 악용할 때 발생하는 공격이다. 검사 입력값은 입력한 데이터 중에서 불필요한 부분을 제거하는데, 해커는 잘못된 정보를 입력하고 피드백을 기다리기만 하면 그 정보를 가로채는 방식입니다.

 

블라인드 공격은 에러 기반 공격과 달리 DB 서버 에러 메시지를 이용하지 않고 바로 DB를 공격한다. 에러 메시지가 정보가 아무런 도움이 되지 않을 때 사용한다. 대표적인 기술로는 시간 지연 공격이 있다. 간단하게 몇 초 정도의 time for delay 를 이용해 원하는 시간 만큼 데이터베이스가 움직여 준다면 취약하다고 볼 수 있습니다.

이 공격은 DB 취약점을 노리고 공격하는 기법보다 성공하기 어렵긴 하지만, 꾸준히 발생하는 공격 중 하나입니다.

 

SQL 인젝션 공격

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

 

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

 

보통 사용자라면 아이디와 비밀번호를 입력하고 거기에 해당하는 정보가 DB에 있다면 로그인이 될 것이고 아니면 아이디나 비밀번호가 틀렸다는 메시지를 받을 것입니다.

하지만 여기서 SQL인젝션 공격을 한다면 아래와 같이

 

SELECT user FROM user_info WHERE id='입력한 아이디' AND pw=' ' OR '1' = '1';

 

비밀번호 입력란에 ' OR '1' = '1 입력해서 pw의 값을 무효화 시켜 로그인이 성공하게 만들어 버립니다.

로그인 폼도 결국엔 서버에 요청을 해서 받는 것입니다. http헤더를 보면 응답 헤더에 서버의 종류와 버전이 나온다. Apache서버는 mysql서버,iisms-sql같은 방식으로 데이터베이스의 종류를 추측할 수 있습니다. DB엔진을 알아내서 해당 시스템에 맞는 명령어를 이용해 데이터를 뽑아내거나 할수 있습니다.

 

방어법

아마도 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공격이 완전히 차단됩니다. 물론 이것이 공격 기법의 전부가 아니므로(스푸핑이나 맨 인 미들 공격, 키 로거 등등) 정보 유출에 민감한 사이트를 운영할 생각이라면 보안 회사에 컨설팅을 꼭 받는게 좋을 것 같습니다.



-나무위키 SQL인젝션, google검색 참조

반응형

'IT > 보안' 카테고리의 다른 글

Yasca 설치 및 사용법  (0) 2017.09.28
Naver lucy-xss-servlet-filter 적용하기  (0) 2017.09.27
XSS정의 / XSS공격 / XSS방어  (0) 2017.09.27
web 어플리케이션 공격기법의 종류  (0) 2017.09.27

+ Recent posts