웹사이트의 보안상 허점을 이용해 '특정 SQL 쿼리문'을 전송하여 공격자가 원하는 DB의 중요한 정보를 가져오는 해킹 기법
논리적 에러를 이용
로그인 기능인,
SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2' 이라는 쿼리문이 있을때 INPUT1에 'OR 1=1 -- 을 넣어서 WHERE 절을 모두 참으로 만들고 --를 넣어줌으로 뒤의 구문을 모두 주석처리 해줌.
로그인 성공
Union 명령어를 이용 (Union : 중복 값을 제외한 정체를 합침)
게시글 검색 기능인,
SELECT * FROM Board WHERE title LIKE '%INPUT%' OR contents '%INPUT%' 이라는 쿼리문이 있을때 INPUT값에 'Union SELECT null,id,passwd FROM Users-- 을 넣어서 Union명령어와 SELECT 구문을 함께 넣어주게되면 하나의 테이블 값을 모두 볼 수 있음.
여기서 컬럼 갯수가 일치해야만 오류가 나지않기 때문에 null 값을 맞춰줌
사용자의 개인정보, 게시글 함께 탈취 성공
True/False 정보를 통해 DB의 정보를 유추하는 기법
Boolean based SQL
DB로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 True/False의 정보만 알 수 있을때 사용
SQL Injection이 가능한 상황에서 서버가 응답하는 메시지를 이용하여 DB의 테이블 정보등을 추출해낼 수 있음
로그인 기능에 임의의 회원가입한 아이디로
SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2' 이라는 쿼리문이 있으면,
INPUT1에다가 (MySQL 환경)
abc123' and ASCII(SUBSTR(SELECT name FROM information_schema.tables WHERE table_type='base table' limit 0,1)1,1) > 100 --
으로 테이블 명을 조회하는 구문으로 limit 키워드를 통해 하나의 테이블만 조회하고 SUBSTR 함수로 첫글자만 추출, 그리고 ASCII 값을 통해 테이블명의 첫글자를 얻은다음 뒤의 100이라는 숫자를 변경해가면서 참이될때까지 비교를 하면됨. 이걸 script로 자동화한다면 단시간내에 테이블 명을 알아낼 수 있음.
Time based SQL
MySQL 경우 : mysqli_real_escape_string() 함수를 사용하여 특별한 의미를 갖는 문자들을 escape해서 SQL injection을 방지할 수 있음
PHP 경우 : prepare함수를 사용하면 사용자의 입력이 쿼리문으로부터 분리되기 때문에 SQL 삽입을 효과적으로 방어 가능
escape() 함수 도입해서 이걸로 사용자로부터 받은 안전하지 않은 데이터를 별개로 구분해서 sql 구문 생성해야함
웹 방화벽 도입
시큐어 코딩