newind2000 2017. 6. 7. 17:01

[SQL Injection]

   웹에서 URL(Uniform Resource Locator) 또는 form에서의 SQL 요청 문을 활용하여 원하는 정보를 열람하는 것을 SQL Injection이라고 한다. SQL Injection을 사용하기 위해서는 기본적은 query문에 대한 이해가 필요하며, 웹 관리자가 설정해 놓은 SQL문을 파악하여 상황에 맞게 SQL Injection 공격을 해야 한다.  


   Form을 통해(ex: ID 혹은 패스워드 입력 form) SQL 문을 삽입하여 공격하는 form injection과 url에 SQL을 입력하는 URL injection으로 나눌 수 있다. SQL Injection 공격 시 일부로 오류를 유도하여 DB 구조에 대한 정보를 파악할 수 있는데, SQL 에러 메세지가 온전하게 나오는 경우 에러 부분을 수정함으로써 DB 자료 구조를 파악하는 Error Base SQL Injection과 에러메세지가 나오지 않는 경우 참과 거짓으로 DB 자료 구조를 파악하는 Blind SQL Injection 공격이 있다.

   웹 서버에 게시판을 구축 후, SQL Injection을 통해 가입 없이 로그인을 시도해 보자.



'아이디' 부분에 사용자가 입력한 정보를 SQL문을 활용하여 저장된 사용자 정보와 비교하는 SQL문을 사용할 것을 짐작할 수 있다. '아이디' form에 입력된 정보가 홑 따옴표(')로 감싸져 있을 것이라 예상하고 '아이디' 부분에 홑 따옴표를 먼저 입력해 주어 SQL 문에 전달한 값을 아래와 같이 SQL문 형식에 맞게 조작할 수 있다. 


ID = ' or 1=1 --


DB를 전달에 대한 요청을 하기 위해서는 첫째는 SQL문에 에러가 없어야 하고, 참과 거짓을 판변할 수 있는 구문으로 이루어 져야 한다. 조건 연산자 'or'을 사용한 후 그 후에 참의 값을 입력해 주면 그 구문은 참이 되게 된다. 그리고 뒤에 쿼리 부분에 대해서는 주석을 처리하는 '--'을 입력하여 뒤의 구문은 무효가 되도록 만들어주고 '확인'을 누르면 로그인이 가능해진다.



SQL문에 의도적으로 오류를 발생시킨 후 에러 메세지를 나타내어 DB구조를 파악하는 예를 살펴보자.

SQL문에서 'having'은 집계함수 'group by'를 사용한 후 특정 조건에 맞는 값만 추출하는 구문이다. 게시판 검색 form에 의도적으로 'having'을 삽입하여 에러를 발생시킨 후 에러를 하나씩 제거하면서 DB의 구조를 파악해 보자.



아래의 에러 메세지를 파악하여 어떤 SQL 서버를 사용하는지, 그리고 어떤 열의 이름을 파악할 수 있다.


위와 같이 친절하게 SQL 에러 코드가 제공되지 않는 경우에는 SQL 구문이 참 혹은 거짓임을 판단하여 DB의 구조를 파악하는 방법이 있다.

이미 특정 도메인에 회원가입을 한 상황이다. ID는 1111이고 비밀번호 또한 1111이다. 해당 웹에서 사용하는 db의 이름을 알고 싶다고 할 때, 문자 하나 하나를 일일히 입력하여 값과 거짓 값을 받아내면 시간은 걸리지만 원하는 정보를 알아낼 수 있다.

ID: 1111' and ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0))) AS varchar(20)),2,1))=ASCII('a')--

비밀번호: 1111



참이라면 로그인이 될 것이고 거짓이라면 위와 같은 메세지가 뜬다.

완전 노가다... 프로그래밍이 필요하다.





반응형