SQL Injection 접근 방법
목표
SQL Injection의 기법 종류
SQL Injection을 하기 위해 어떠한 방식으로 접근해야하는가?
SQL Injection의 기법 종류
1. Union SQL Injection
Union SQL Injection 기법이란 union 이라는 단어에서 유추할 수 있듯이 같이 사용이 가능하다는 뜻이다. 즉 Was에 요청한 SQL문에 다른 SQL문을 덧붙여서 Was로 보낼 수 있게 되는 것이다.
이런 기법은 결과가 시각적으로 보이는 웹에서 대표적으로 사용하는 기법이다.
대표적인 예시를 들어보겠다.
아래와 같이 대표적인 SQL 문을 작성해 봤다. usertable에서 user_id, user_pw에서 아이디가 a이고 비밀번호가 b인 데이터를 찾는 다는 의미이다.
Select from usertable where user_id = 'a' and user_pw = 'b'
만약 로그인시 입력된 값이 아래 코드 값과 같다면
x' union select mario', 'mariosuper
Select from usertable where user_id = 'x' union select mario', 'mariosuper' and user_pw = 'b'
위와 같은 코드가 될 것이다. x 라는 의미는 아무것도 안가져오고 그대신 mario 와 mariosuper라는 계정을 추가한다는 의미이다.
이렇게 되면 table 형식이 아래 처럼 나오게 된다. 이제 가져온 테이블을 가지고 여기서 x 를 사용하지 않았다면 로그인 시 맨 첫줄에 해당하는 값을 기준으로 로그인이 되기 때문에 user_pw에 넣은 값과 일치하지 않아 로그인에 성공하지 못하게 된다.
user_id | user_pw
----------------------
mario | mariosuper
이렇듯 내가 테이블의 값을 아무것도 안가져와도 내가 원하는 데이터를 table에 추가 시켜 가져 올 수 있다는 것이 union SQL Injection이다.
Error SQL Injection
이 기법은 대부분 논리적 에러를 이용하여 보안을 뚫는 방법이다.
아까 위에서 쓴 코드를 가져오면
Select from usertable where user_id = 'a' and user_pw = 'b'
여기서 만약 a의 값 대신에 a' or '1'='1이라는 값을 넣어보자 그러면 아래와 같은 코드가 되게 된다.
분석을 해보면 원래 기존 코드에서는 id와 pw 모두 일치해는 table을 가져오는 코드였다.
Select from usertable where user_id = 'a' or '1' ='1' and user_pw = 'b'
하지만 위 코드는 id가 a이기만 하면 일치하는 table을 가져오는 것으로 바뀐 것이다. 왜 이런일이 가능할까?
이를 알기 위해서는 우선 연산자를 알아야 한다.
우리가 만약 1+4*7= 이라는 연산을 한다 보면 곱하기를 먼저하고 더하기를 할 것이다. 이는 너무나 당연한 규칙이기 때문에 모두들 쉽게 이해하는데 이는 컴퓨터에서도 동일하게 적용 된다. and는 곱을 의미 or은 더하는 의미이다.
true or false 는 true, true and false는 false 인 것처럼 위에도 똑같이 적용된다. 그러면 user_pw를 비교하는 문구와 1=1이라는 문구에서 false가 반환되고 user_id =a 와 false가 비교문이 되는데 a와 일치하는 행만 존재한다면 전체 코드가 true가 되어 a 라는 데이터를 가져오게 되는 것이다.
즉 비밀번호를 아무값이나 입력해도 원하는 계정으로 로그인이 가능한 것이다. 이것이 Error Injection 이다.
Blind SQL Injection
Blind SQL Injection이란 정보를 직접적으로 볼 수는 없어도 웹에서 반환하는 True/False 값을 통해 DB의 구성 등 여러 정보를 알아내는 기법이다. 이것 말고도 응답 지연 시간을 이용한 Blind SQL Injection도 있다.
True/False로 알아내는 방법은 만약 영화 제목을 검색하는 Web이 있다고 생각해보자
이를 위해서는 영화 제목을 입력해야 할 것이다. 이때 입력한 값을 ' or '1' = '1' and length(database())= 1#을 입력해보면
Select from movie_table where m_name = '' or '1' = '1' and length(database())= 1#'
1=1 은 무조건 참이기 때문에 and가 되는 length에 의해 참 거짓이 결정이 되게 된다. 만약 길이가 맞아 참이 나오게 되면 m_name이 틀려도 true를 반환하기 때문에 DB의 명칭 길이를 유추해 낼 수 있게 된다. 이제 길이를 알아낸다면 substring을 이용하여 하나하나 글자를 대입해 그 글자가 있는지 비교하면 값을 꺼내오는 것이다.
말 그대로 눈감고 계속 두드리는 것이다.
이러다보면 DB의 형태를 알아낼 수 있게 되고 나중에 공격시 정보를 조금이라도 더 수집이 가능하게 된다.
오늘은 3가지 SQL Injection 기법에 대해 설명하였다.
그 안에 수많은 응용 방안이 있으니 추후에 응용 기법들을 추가하도록 하겠다!