SQL Injection
코드 인젝션의 한 기법으로 클라이언트의 입력값을 조작하여 서버의 데이터 베이스를 공겨할 수 있는 공격방식
주로 사용자가 입력한 데이터를 제대로 필터링 하지 않았을 경우 발생한다
공격은 쉬운데 파괴력이 어마어마하며 자주 일어난다.
이제 문제를 풀어보자
난이도 - (low)
SQL Injection 문제를 선택하면 다음과 같이 나온다.
대충 영화이름을 치면 그 영화제목에 맞는 영화에 대한 설명이 나오는것 같다.
여기 입력칸에 '(작은따옴표)를 입력하여 SQL Injection이 가능한지 알아보자
※ 작은 따옴표를 입력하는 이유 : DB에서는 작은 따옴표로 문자 데이터를 구분하기 때문에
SELECT * FROM movies WHERE title LIKE ' ' '
따옴표를 입력했으면 다음과 같이 DB에 입력될 것이다.
입력결과
다음 에러를 확인해보면 MySQL을 이용한다는 것을 알 수 있다.
DB서 주석문자는 -- 와 #이 있는데 여기서 어떤 주석문자를 사용하는지 알아보자
(기본적인 SQL Injection 공격 방식은 ' or 1=1주석문자)
※ or 1=1인경우 앞에 내용이 틀려도 1=1이 항상 참이기 때문에 모든 정보가 출력됨
1. 주석문자 == --
-- 를 사용하였을 경우 아무 정보도 나오지 않고 에러만 나온다.
2. 주석문자 == #
# 주석문자를 사용하여 SQL Injection 공격을 수행하니 DB의 모든 정보를 알 수 있었다.
더 자세한 정보를 알아내보기 위해 UNION SELECT 구문을 사용하겠다.
UNION은 SELECT 문이 둘 이상일 때 이를 결합해 두 질의 결과를 하나로 반환한다.
-> ' UNION SELECT ALL 컬럼수#
결과
공격을 수행하면 다음과 같이 컬럼수가 다르다고 나오는데 UNION 구문을 사용하려면 이전 쿼리에서 사용하는 SELECT 문의 컬럼수가 일치해아한다.
컬럼수를 맞추기 위해 계속해서 숫자를 늘려나가 보았다.
확인해보니 총 7개의 컬림이 있는걸로 나왔다.
이 방식 말고 ' ORDER BY 컬럼수# 오름차순(ASC) or 내림차순(DESC) 방식도 있는데 단순히 컬럼 갯수 파악을 할 때는 이게 더 간단하다.
좀 더 정보를 알아내보자
SQL 명령어 중 @@version으로 MYSQL의 버전을 알아낼 수 있다.
맨 오른쪽 컬럼(4번)에 @@version을 넣어 버전을 알아보자
-> ' UNION SELECT ALL 1,2,3,@@version,5,6,7#
다음과 같이 MySQL 5.0.96버전이라는 것을 알 수 있다.
그 외 여러가지 시스템 변수 및 함수
시스템 변수 및 함수 | 설명 |
database() | 데이터베이스 명 알려주는 함수 |
user() |
현재 사용자 아이디 |
system_user() | 최고 권한 사용자 아이디 |
@@version | 데이터 베이스 서버 버전 |
@@datadir | 데이터 베이스 서버가 존재하는 디렉터리 |
현재 사용중인 MYSQL 버전이 5.0 이상이므로 테이블 명을 확인하려면 information_schema를 사용해 쿼리를 입력해야 한다.
-> 0' UNION SELECT ALL 1, table_name,3,4,5,6,7 from information_schema.tables#
0' UNION SELECT ALL 1, table_name,3,4,5,6,7 from infromation_schema.tables#
0' = 영화 목록 출력을 방지하기 위해 검색값을 0으로 지정
information_schema = 데이터 베이스에 속한 데이터의 정보를 저장 하는 데이터 사전
다음과 같이 입력하면
2번째 컬럼에서 현재 데이터 베이스에 저장되어 있는 모든 테이블명을 알려주고 있다.
여기서 users라는 테이블에 계정 정보가 들어있을 것이라 추측하여 where 절을 이용하여 users 테이블 정보만 출력하도록 하였다.
입력 결과 다음과 같이 users 테이블의 칼럼명을 출력해준다.
컬럼들을 보면 id, login, password 등 사용자 개인정보와 관련된 정보 있을 가능성이 많아 보인다.
이제 컬럼명도 알아 내었으니 컬럼의 내용을 확인 해 보겠다.
책에서는 id, login, password, email, secret 5개의 내용을 알아 보았다.
0' UNION SELECT ALL 1,concat(id,login),password,email,secret,6,7 from users#
concat = 두개의 문자열을 합쳐 하나의 문자열로 만듦
하지만 id는 순서번호만 나오길래 id는 제외하고 login, password, email, secret만 알아보기로 하였다.
-> 0' UNION SELECT ALL 1,login,password,email,secret,6,7 from users#
결과
다음과 같이 아이디, 해시가 적용된 비밀번호 이메일 등 사용자의 계정 정보를 확인할 수 있었다.
난이도 - (medium,high)
(low) 단계와 동일하게 SQL 인젝션 공격이 먹히는지 알아보기 위해 '(작은 따옴표)를 입력하였다.
1. 공격이 통할경우
SQL Injection 공격이 통할경우 다음과 같이 에러메시지를 출력한다.
하지만 medium 단계 공격에서는
데이터 베이스의 오류가 출력되지 않는다. 이유는 비박스 서버에서 입력 데이터를 우회하고 있기 때문이다.
그럼 어떻게 우회하고 있는지 알아보자
코드는 /var/www/bWAPP에 있다.(/var/www/bWAPP sqli_1.php)
gedit으로 코드를 열어보면
다음과 같이 medium 난이도는 sqli_check_1이라는 함수가 적용되어 있고, high 난이도는 sqli_check_2 함수가 적용되어 있다.
이제 이 함수가 정의 되어있는 코드를 찾아가 보자 다음 코드는 functions_external.php라는 코드에 정의되어 있다.
(var/www/bWAPP/functions_externals.php)
다음과 같이 sqli_check_1 함수는 addslashes라는 함수가 sqli_check_2 함수는 mysql_real_escape_string 이라는 함수가 적용되어 있다.
1. addslashes : ', ", \ 등을 데이터가 아닌 제어문자롤 인식하기에 슬래시로 이스케이프 해줌
(<-> stripslashes : \'. \", \\로 저장되어 있는 값에서 \를 제거하고 보여줌)
2. mysql_real_escape_string : SQL 명령문에 사용되는 문자열에서 특수 문자를 회피시켜주는 함수
라고 한다.
그렇기에 (medium, high) 난이도에서는 '와 같은 특수문자가 먹히지 않는 것이다.
'웹해킹 > bee-box' 카테고리의 다른 글
OS Command Injection (0) | 2019.07.31 |
---|---|
SQL Injection(Post/Search) (0) | 2019.07.30 |
iframe Injection (2) | 2019.07.27 |
HTML Injection- Stored(blog)(low) (0) | 2019.07.26 |
HTML Injection- POST(medium, high) (1) | 2019.07.26 |