-
SQLINJECTION#02. 기존공부/#02.3 웹해킹 2019. 1. 16. 21:22
1. SQL INjection
OWASP TOP 10에 지속적으로 이름을 남기고 있는 SQL Injection에 대해 알아보자.
SQL Injection은 Mysql과 Oracle 같은 DBMS(DataBase Management System)에서 발생한다. 서버 설정, 소스코드의 오류 등에 의해 발생하며 코드 인젝션의 일종이다.
SELECT * FROM users WHERE name='{$input1}' AND passwd='{$input2}'
위와 같은 user 테이블에서 name이 $input1이며 동시에 passwd가 $input2를 만족하는 결과값을 모두(*)출력하라는 쿼리문이 존재한다. input1과 input2변수에는 사용자에게 입력받은 값이 들어간다. 이때 $input2 변수의 값을 sqlinjection' OR 1=1-- -라 입력하면 쿼리문은 아래와 같이 변조된다.
SELECT * FROM users WHERE name='{$input1}' AND passwd='sqlinjection' OR 1=1-- -'
초심자를 위한 + 내 정리용이니 하나씩 읽어보자. 우선 AND와 OR이라는 논리연산자가 들어간다. 논리연산자의 계산순서는 괄호가 없을 시 AND > OR 순이다. 그러므로 아래와 같은 계산순서가 적용된다.1) name='$input1' 이며 passwd가 sqlinjection인 것2) 1) 또는 1=1인 것(항상 참)1)을 만족하거나 또는 항상 참인 것이란 쿼리문이 완성된다. name에 어떠한 값을 넣더라도 항상 참이된다.이렇게 사용자의 입력값을 조작하여 쿼리문을 조작하는 방법을 SQL INjection이라고 한다.2. 보안방안
기본적으로 사용자의 입력값은 모두 의심해야한다.
(못된 사람들이 많다._)아래와 같은 보안 방안들이 대표적으로 사용된다.
2.1 Addslashes
데이터베이스 질의 등에서 처리할 필요가 있는 문자 앞에 백슬래시를 붙인 문자열을 반환한다. 싱글쿼터('), 더블쿼터("), 백슬래시(\), 널(NULL Byte)를 통한 SQL Injection 공격을 막기위해 사용된다.
우회방안은 특수한 상황에 가능하다. mb_convert_encoding 함수에 의해 싱글바이트가 멀티바이트로 인식될 때 발생하는 취약점이 있다.
mb_convert_encoding과 비교되는 것이 iconv함수이다. 그러나 iconv함수의 경우 없는 문자가 입력될 시 에러가 발생한다. \xa1\xa0부터 에러가 발생한다.
iconv('EUC-KR', 'UTF-8', $input); == 에러발생
iconv('EUC-KR', 'UTF-8//IGNORE', $input); == 우회가능
2.2 magic_quotes_gpc
GET, POST, COOKIE 값을 검증하는 방법으로 파라미터의 싱글쿼터('), 더블쿼터("), 슬래시(/), 널(null, %00)이 입력 될 때 역슬래시(\)를 앞에 붙여준다.
역슬래시를 붙으면 이는 문자열로 인식한다.
php 설정파일로 할 수 있는 보안방안으로 php.ini에 있는 magic_quotes_gpc을 On으로 바꿔주면 적용된다.
하지만 프로그래밍 관점에서 본다면 위의 파라미터가 들어가는 모든 요청을 공격으로 간주한다고 비난받았다. 예를들면 메일을 사용할 때 다수의 /를 확인할 수 있다. 이때 stripslashes함수를 사용하여 개별로 풀어줘야한다.
상기 이유로 인하여 php 6.0이후에는 제거되었다.
그러므로 우회방안은 기입하지 않는다!(우회방안의 힌트는 싱글바이트와 멀티바이트이다)2.3 데이터 타입 검사
1) is_numeric()을 사용하여 문자인지 검사한다. 문자열이라면 TRUE를 아니면 FALSE를 반환한다.
2) is_bool()을 사용하여 논리형인지 검사한다. Boolean이라면 TRUE를 아니면 FALSE를 반환한다.
개인적으로 Type Juggling에 의해 0과 FALSE가 같은 것이라 은연중에 생각했다.
하지만 이 함수는 0을 Boolean으로 인식하지 않는다.
2.4 prepare statement
Mysql과 같은 DBMS에서 동일하거나 비슷한 쿼리를 반복실행하기 위해 사용되는 기능으로 지정된 명령어만을 실행할 수 있다 ▶ statement객체는 실행 시 쿼리를 지정하여 여러 쿼리를 하나의 statement객체로 수행이 가능하여 재사용이 가능하지만 : prepared statement는 객체 생성 지에 지정된 쿼리만을 수행하기에 재사용이 불가하다.
쿼리의 문법 실행과정은 아래와 같이 4가지 과정을 거쳐 나타난다.
쿼리의 문법 검사를 위해 첫번째 parse과정을 거치게 되고 여기서는 SELECT를 의미한다.
Statement의 경우 SELECT 쿼리 입력 시 parse부터 patch까지의 과정이 매번 수행되지만 Prepared Statement의 경우 parse 과정을 최초 한번만 수행하고 이후에는 생략한다.
parse 과정을 모두 거친 후 생성된 결과는 메모리 어딘가에 저장해두고 필요할 때마다 사용한다. 반복적 사용을 위해 변경되는 부분을 변수로 선언하고 매번 다른 값을 Bind(치환/매핑)하여 사용한다.
Binding한 데이터는 SQL 문법이 아닌 내부 인터프리터나 컴파일 언어로 처리하기 때문에 문법적인 의미를 가질 수 없다. 바인딩 변수에 SQL 쿼리를 입력할지라도 의미있는 동작을 하지 않는다.
※인터프리터란
프로그래밍 언어의 소스코드를 바로 실행하는 컴퓨터 프로그램 또는 환경으로 컴파일러의 경우 원시코드를 기계어로 번역한다. 한줄씩 바로 실행 이 키워드이다.
3. 공격기법
3.1 Group By와 DISTINCT
DISTINCT는 주로 중복을 제거한 컬럼이나 레코드를 조회하는 경우에 사용하며 GROUP BY는 데이터를 그룹핑하여 결과를 가져오는 경우에 사용한다. 두 기능 모두 Oracle 10g 부터는 모두 Hash를 이용하여 처리한다.
DISTINCT를 사용한 중복 제거
SELECT DISTINCT deptno FROM emp;
GROUP BY를 사용한 중복 데이터 제거
SELECT deptno FROM emp GROUP BY deptno;
집계함수를 사용하여 특정 그룹으로 구분할 때는 GROUP BY절을 사용하며 특정 그룹 구분 없이 중복된 데이터를 제거할 경우에는 DISTINCT 절을 사용한다.
3.2 HAVING 절
HAVING절은 집계함수를 가지고 조건 비교를 할 때 사용한다. HAVING 절은 GROUP BY절과 함께 사용된다. 이에 HAVING절만 입력 시 출력되는 에러를 통해 Error Based SQL Injection에 활용된다.
SELECT job, SUM(sal) “급여합계”
FROM emp
WHERE job != ‘SALSES’ //판매원은 제외
GROUP BY job //job(업무별)을 기준으로 GROUP BY
HAVING SUM(sal) > 5000 //전체 월급이 500을 초과하는 경우
ORDER BY SUM(sal) DESC; // 월 급여 합계로 내림차순 한다.
반환된 오류를 통해 컬럼, 테이블 명을 추측하고 추측된 쿼리문의 형식에 맞춰 공격문을 변경시킨다.
3.3 별명값 주기
SELECT AA FROM table ORDER BY id DESC LIMIT 1
위와 같은 쿼리문이 있을 때 AA값을 변경시켜 admin이라는 결과값이 나오게 하는 문제가 있다. 이때 사용하는 방법이 바로 별명값 주기이다.
SELECT ‘admin’ id
위 쿼리의 의미는 admin을 id라고 부르겠다는 것이다. 결국 id 칼럼 안에 admin이라는 값이 들어가게 된다. 결국 table이라는 테이블에서 AA라는 값을 골라오는데 이 값을 id를 기준으로 내림차순 정렬하여 그중 첫 번째 1개를 출력하라 라는 구문이 완성된다.
무조건 id 컬럼에 있는 admin이라는 결과 값을 출력하게 된다. SELECT ‘admin’만을 입력 시 admin컬럼안의 admin이라는 결과값이 출력된다.
본래 형태는 AS구문이다.
참고1: Parepare Statement가 SQL INjection에 안전한 이유
https://m.blog.naver.com/PostView.nhn?blogId=blogpyh&logNo=220675109307&proxyReferer=https%3A%2F%2Fwww.google.com%2F
초안: 2019.01.16 / version 0.1
수정: 2019.01.18 / version 0.2 / 2.3/2.4항목 추가
'#02. 기존공부 > #02.3 웹해킹' 카테고리의 다른 글
XSS-Game (0) 2019.04.12 XSS (0) 2019.03.29 DVWA 풀이 (0) 2019.03.12 root me 풀이 (0) 2019.03.12 VMware 포트포워딩/ SQL 복원/ SSL 서버 설치 (0) 2019.02.03 댓글