본문 바로가기
WEB HACKING/웹 해킹[이론]

SQL Injection

by madevth 2021. 10. 21.
반응형

SQL Injection은 웹 해킹의 꽃이라고도 불리는, 많이 알려진 해킹 공격 중 하나이다.

SQL Injection의 개념에 대해 살펴보고, SQL Injection을 어떻게 사용할 수 있는지 예시를 살펴보자.

 

① SQL 이란?

SQL은 Structured Query Language의 줄임말로, 관계형 데이터베이스 시스템에서 자료를 관리하기 위해 사용되는 언어를 의미한다. 쉽게 말하자면 DB 서버와 통신하기 위해 사용되는 언어이다.

SQL 문법은 크게 DDL, DML, DCL 세 가지로 나눌 수 있는데, DDL은 데이터를 정의하는 Create 같은 문법들,

DML은 데이터를 선택하고 추가하는 SelectInsert 같은 문법들, DCL은 권한을 주거나 삭제하는 GrantRevoke 같은 문법들로 이루어져 있다.

 

② SQL Injection이란?

웹 서비스에서는 사용자의 입력 값이 그대로 SQL 구문의 일부로 사용될 때가 있다.

이 점을 이용하여 입력으로 SQL 구문을 조작할 수 있는 값을 삽입하여 데이터 베이스가 비정상적인 동작을 끌어내는 공격이 바로 SQL Injection이다.

SQL Injection으로 DB에 조작된 명령을 실행할 수 있기 때문에 1. 인증 우회 / 2. 데이터 탈취 및 변조 / 3. (일부) 서버 장악 등이 가능하다.

 

③ SQL Injection을 통한 인증 우회

SQL Injection 인증 우회란 로그인과 같은 인증 과정에서 정상적인 계정 정보 없이 인증을 획득하는 것을 의미한다. 이번 포스팅에서는 대표적인 SQL Injection 예시를 살펴보고, (로그인 기능을 구현하는 방식은 크게 5가지로 나눌 수 있는데) 케이스 별 SQL Injection 사용 방식은 다음 포스팅에서 살펴보자.

 

Case 1: 논리 기호를 이용한 SQL Injection

Select * from users where id = 'INPUT1' and pw = 'INPUT2';

로그인 시 위와 같은 SQL 구문이 실행된다고 가정해보자.

ID와 PW를 입력하면, 그 값이 각각 INPUT1과 INPUT2로 들어가면서 SQL Query가 실행된다.

이때, ID 값으로 ' or 1 = 1 -- 을 넣으면 SQL Query는 다음과 같아진다.

Select * from users where id = '' or 1 = 1 --' and pw = 'INPUT2';

SQL 문법에서 --는 주석을 의미한다. (C에서는 //, 파이썬에서는 #, SQL에서는 --)

--에 의해 뒤의 password 구문은 주석처리가 되고, SQL Query는 "id가 ''이거나 1 = 1이면 users에서 정보를 가져와줘"가 되고 (A or 1 = 1)은 항상 참이므로 모든 정보를 얻게 된다. 이렇게 논리 기호를 통해 인증을 우회할 수 있다.

 

Case 2: Union 문법을 이용한 SQL Injection

SQL에서 Union을 사용하면 두 개의 쿼리문에 대한 결과를 한 번에 볼 수 있게 된다.

위와 같은 경우에서 ID값에 ' union select 'test', '1234를 넣고 pw에 1234를 입력하면 로그인을 우회할 수 있다.

Select id, pw from users where id = '' union select 'test', '1234';

왜 그런지 살펴보자.

우선 mysql에서 select 'test', '1234';를 실행하면 'test', '1234' 값이 그대로 출력된다.

이때, id와 pw를 선택하는 구문과 함께 union을 사용하여 select 'test', '1234';를 실행하면, id와 pw의 콜럼으로 'test'와 '1234'의 데이터가 들어가게 된다. (Column과 Table 이름이 달라서 그 부분만 가렸다.)

따라서 pw로 1234를 입력해주면 DB에서 가져온 1234라는 값과 일치하게 되므로 로그인에 성공한다.

(Case 1과 Case 2는 식별과 인증 과정이 조금 다른 경우인데, 이 역시 다음 포스팅에서 살펴볼 것이다.)

꼭 로그인 상황이 아니라도 게시글을 검색할 때 ' union select * from user -- 같은 구문을 통해 user 정보를 획득할 수도 있다. 한 가지 주의할 점은, union을 사용하기 위해서는 두 테이블에서 얻고자 하는 column 수와 데이터 타입이 일치해야 한다는 것이다.

 

④ SQL Injection을 막는 방법

SQL Injection으로 인한 피해를 최소화하기 위해서는 Error Message로 Column이나 Table 이름의 노출되는 것을 막고, 웹 방화벽을 사용하여 공격을 방어하는 것이 좋다. Prepared Statement라는 구문 사용하면 사용자의 입력값이 DB의 파라미터로 들어가기전에 입력값을 그저 문자열로 인식하도록 만들어서 SQL Injection의 의도대로 작동하지 않도록 막는 방식도 존재한다.

반응형

댓글