SQL Injection이란?

  • injection: 주입하다, 넣다

설계된 SQL 구문에서 사용자 입력값 검증이 미흡하여, 악의적인 명령을 실행하는 임의의 쿼리를 삽입하여 공격할 수 있는 취약점이다.

SQL Injection 취약점이 존재할 경우, 인증 우회, 데이터베이스 접근 등의 공격이 가능하기 때문에 데이터 유출, 변조, 삭제 등의 피해가 발생할 수 있다.

(예제) ID 조회 사이트

연습 사이트를 통해 이해해보자.

입력란에 값을 입력하면 그 값은 웹서버로 전달된다. 예) normaltic

이를 Burp Suite로 확인해보면 POST로 데이터가 날아가고 있는 것을 확인할 수 있다.

 

Request 최하단을 보면 query=normaltic 이라고 뜬다.

이는 WAS가 select * from member where id='_____'; 를 준비해놨다가 사용자 값을 입력하면 그 값을 넣는 것이다.

이를 확인하기 위해 id 조회에서 normaltic' 이라고 입력하면 오류가 발생한다.

구문이 select * from member where id='normaltic'' 이 되어 버리기 때문이다.

 

문법 오류 발생

AND 연산자를 활용한 공격

그렇다면, 위 입력칸에 normaltic' and '1'='1 으로 입력한다면 어떻게 되는가?

  • and '1'='1' : 참 구문 (그냥 나오는 값, 언제나 참인 값)

서버에서 실행되는 쿼리는 select * from member where id='normaltic' and '1'='1' 이 될 것이다.

id='normatlic'이 존재하고, 1은 항상 1이기 때문에 참이므로 id=normaltic인 모든 칼럼 정보를 출력한다.

 

normaltic' and pass='1234 으로 입력해도 결과는 동일하다.

select \* from member where id='normaltic' and pass='1234' 은 id = normaltic 이면서 동시에 pass = 1234 인 것이므로, 마찬가지로 normaltic에 대한 모든 칼럼 정보를 출력한다.

OR 연산자를 활용한 공격

여기서 더 응용을 하여, 하나의 id만 조회할 수 있는 입력란에서 한 명의 정보만이 아닌 다른 사람의 정보도 출력하는 것을 시도할 수 있다.

  • or '1'='1'

normaltic' or '1'='1 을 입력한다면 다음과 같이 모든 결과를 출력한다.

 

OR은 둘 중 하나가 참이면 되는데, 뒤에 나오는 조건믄 1=1이 무조건 참이므로 모든 데이터를 출력해준다.

서버에서 실제로 실행되는 쿼리는 select \* from member where id='normaltic' or '1'='1' 이다.

즉, 기존에 데이터를 가져오는 기능을 DB에게 공격자가 원하는 SQL 언어를 실행할 수 있도록 원하는 명령을 실행하는 기능으로 이용할 수 있다.

(예제) 로그인 사이트

 

결과가 존재하면 로그인에 성공하는 연습 사이트이다.

id와 password를 입력 받고 있으므로 웹 서버에서 준비한 구문은 select \* from member where id='\_\_\_' and pass='\_\_\_' 일 것이다. (= 인증/식별 동시 로직)

 

해당 문제에서 올바른 로그인 정보는 normaltic/1234이다. 하지만 틀린 비밀번호로도 로그인이 가능하게 해 보겠다.

ID : normaltic'#

PW: 아무거나 입력

  • # : SQL 언어에서 주석

비밀번호 입력란이 주석 처리되면서, select \* from member where id='normaltic' 이 되었고, id 데이터 존재하면 로그인 성공하도록 작동하는 구문이 되는 것이다.

앞에서 했던 방식인 normaltic' or '1'='1 을 해당 문제에서 실행해도 로그인이 가능하다.

select * from member where id='normaltic' or '1'='1' and pass=99'

위와 같이 만들어진 구문은 연산 우선 순위에 따라 실행되기 때문이다.

  • 연산 우선 순위: AND > OR
select * from member (where id='normaltic' or ('1'='1' and pass=99'))

 

따라서, 위와 같은 괄호가 들어간 것과 동일하게 연산을 한다.

공⠀백
SQL Injection 이해하기
상단으로
``