SQL injection을 통해 공격할 DBMS 특정하기(DBMS Fingerprint)

고둑·2021년 9월 8일
0

스터디 발표

목록 보기
2/4

데이터 베이스를 다룰때 우리는 대부분 DBMS를 이용하고 대부분의 DBMS는 SQL이라는 언어를 이용하여 데이터베이스를 관리하게된다.

이러한 SQL에는 표준적인 사용법이 존재한다. 하지만 이 세상에는 수도 없이 많은 특색을 가진 데이터베이스들이 존재하고 이렇게 다양한 상황에 맞춰 각각 특정 부분에서 강점을 보이는 여러 DBMS가 개발되었다.

이런 DBMS들은 표준적인 SQL 문법을 따르지만 각각의 특정한 DBMS에서만 작동하는 명령어도 포함하고 있다.

이러한 이유로 SQL injection 공격이 성공하려면 정확한 DBMS 종류을 알아야 하는 경우가 많다. (MySQL로 찍고 공격하다 피 본적이 한 두번이 아니다...)

이러한 이유로 DBMS를 특정해야하는 이유를 알았고 방법을 찾아보기 시작했다.

1. 포트 확인

이 방법은 SQL Injection을 이용하는 방법이 아니지만 가장 기본적인 방법으로 포트를 확인해보면 된다.
DBMS별 원래 기본적으로 설정된 포트는
MySQL : 3306
Oracle : 1521
MS SQL Server: 1433
PostgreSQL : 5432

추가적으로 nmap을 이용하면 추가적인 보안 설정을 하지 않은 서버는 DBMS를 알 수 있다.

내 개인 서버를 nmap을 이용하여 스캔한 결과이다.
MySQL을 사용하고 3306포트가 열려있는것을 볼 수 있다.
추가적으로 Ubuntu 18.04.1을 사용하는 것도 볼 수 있다.

2. 오류 기반 탐색

SQL Injection을 시도할때 잘못된 값을 주입하면 잘못된 쿼리가 완성되게 되고 이러한 오류 쿼리를 테이터베이스에 입력하게 되면 DBMS로 부터 오류가 출력되게 된더ㅏ. 이러한 오류들을 보면 DBMS를 추정할 수 있게된다.

[MySQL 오류 출력 예시]

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''''' at line 1

[Oracle 오류 출력 예시]

ORA-01789: query block has incorrect number of result columns.

3. 데이터베이스 버전 함수 사용

가장 애용하는 방법이고 가장 확실한 방법 중에 한개이다.
SELECT 구문을 통하여 DBMS의 버전 정보를 가저올 수 있는데 이때 사용하는 함수가 DBMS별로 차이가 있기 때문에 이걸로 DBMS를 알아낼 수 있다.

  • MySQL: SELECT @@version || SELECT version()

  • MariaDB: SELECT version()
  • PostgreSQL: SELECT version();
  • Oracle: SELECT banner FROM v$version WHERE rownum=1
  • MS SQL Server: SELECT @@version
  • SQLite : SELECT sqlite_version()

    예시를 보면 알 수 있듯이 같은 version()을 사용해도 mysql은 깔끔하게 숫자만 나오고 PostgreSQL이나 MariaDB는 뒤에 문자열이 붙는다.

따라서 버전 출력 명령어와 결과 값을 확인해 보면 DBMS를 매우 근접하게 추측할 수 있다.

4. 문법 차이 이용

1. 숫자 연산 함수

error-base SQL injection을 하기 위해 에러를 강제적으로 발생시키는 과정에서 integer overflow를 나는 자주 이용한다.
그때마다 연산 함수를 이용하면 편하게 오류를 발생시킬 수 있다.
이때 DBMS마다 사용가능한 연산 함수가 있으므로 그걸로 판별할 수 있다.

MySQL: POW(1,1)
Oracle: BITAND(1,1)
MS SQL Sever: SQUARE(1)

등등 다른 DBMS에서는 정의가 되어있지 않은 함수를 이용하면 다른 DBMS에서 Syntax 오류가 발생한다.

2. 문자열 연산 함수

각각 DBMS는 문자열을 합치는 과정에서 사용하게 되는 연산에 미세한 차이가 존재한다. 각각의 DBMS는 문자열 example을 합치는데 각각의 방법으로 합칠 수 있다.

  • MySQL: 'exam' 'ple'
  • Oracle: 'exam'||'ple'
  • MS SQL Sever: 'exam'+'ple'

즉 'exam'+'ple'로 연산이 된다면 MS SQL이고 다릉 DBMS에서는 Syntax 오류가 발생한다.

3. 주석 방식

MySQL은 다른 DBMS와는 다른 주석 방식을 가지고 있다.

MySQL: /*블록 주석*/,-- (공백 필수), #
Oracle: /*블록 주석*/,--
MS-SQL: /*블록 주석*/,--

위와 같이 Syntax 오류를 통해서 우리는 MySQL을 사용하는 서버을 알 수 있다.

기타 방식

위의 방법이 모두 막힌 비극적인 경우가 있을 것이다.
그럼 눈물을 닦고 짐작에 들어가야한다.
그나마 좋은 소식은 일부 기술과 DBMS 사이에는 연관성이 있기때문에 사용된 기술을 보면 DBMS를 유추할 수 있다.

ASP.NET 기술을 이용한 웹 어플리케이션은 SQL SERVER을 이용할 가능성이 크고 은행과 같은 공공기관이나 기업과 같이 안정된 서비스를 원하는 곳은 오라클, PHP를 이용하는 소규모 서버는 MySQL을 이용할 가능성이 크다. (CTF에서 사람 빡치게 만드려면 SQLite를 쓴다.....)

뻘짓 멈춰

그냥 sqlmap과 같은 분석 도구를 돌리고 밥 먹고 오면 자동적으로 분석이 끝나있다.

우리 모두 툴을 애용하자.

profile
문워킹은 하지말자

0개의 댓글