腾讯Wiz课程第二讲以及SQL注入的自学

这一讲主要讲述了OWASP 的排名前十的漏洞。

这里确实很难接受,许多专有名词还是很难听懂。

但是重点是SQL注入的知识:

所以打算初步自学一下SQL注入的知识。

 

SQL注入是网站存在最多也是最简单的漏洞,主要原因是程序员在开发用户和数据库交互的系统时没有对用户输入的字符串进行过滤,转义,限制或处理不严谨,导致用户可以通过输入精心构造的字符串去非法获取到数据库中的数据。(对于看不懂的语句会自行百度)

SQL注入原理:

绕过登录

假设一个站点有一个登录表单,只允许注册用户进入该站点。 现在,假设你想绕过登录并以合法用户身份进入网站。 如果程序员没有正确清理登录脚本,您可能很幸运能够进入该站点。 通过与DB服务器交互,你可能无需知道真实用户名和真实密码即可登录该站点。 那么,这不就是SQL注入的美感吗?

一般用户登录用的SQL语句为:SELECT * FROM user WHERE username='admin' AND password='passwd',此处admin和passwd分别为用户输入的用户名和密码,如果程序员没有对用户输入的用户名和密码做处理,就可以构造万能密码成功绕过登录验证。

如用户输入'or 1#,SQL语句将变为:SELECT * FROM user WHERE username=''or 1#' AND password='',‘’or 1为TRUE,#注释掉后面的内容,所以查询语句可以正确执行。我们可以使用DVWA来测试一下。

DVWA 是一个渗透的环境

打开DVWA界面,登录,然后修改DVWA Security等级为Low点击submit,如图:

 

 

 

然后点击左侧SQL Injection,出现一个输入ID查数据的文本框,点击网站右下角的View Source可查看源代码,如图

 

 

 

可以看到SQL语句为SELECT first_name, last_name FROM users WHERE user_id = '$id';用户输入的字符串存在$id变量中,可以看到上面没有任何处理用户输入的字符串的函数,因此可以肯定这里存在SQL注入,我们仍然可以输入'or 1#,使SQL语句变为:SELECT first_name, last_name FROM users WHERE user_id = ''or 1#';从而查询到所有的first_name和last_name,如图:

 

 

 查询到了所有的first_name和last_name,着实有趣。

 

SQL注入分类及判断

事实上SQL注入有很多种,

按数据类型可以分为数字型、字符型和搜索型

按提交方式可分为GET型,POST型,Cookie型和HTTP请求头注入

按执行效果有可以分为报错注入、联合查询注入、盲注和堆查询注入

其中盲注又可分为基于bool的和基于时间的注入

从查询语句及可看出来这里是字符型的注入同时也是GET型注入和表单注入,

数字型注入查询语句为:SELECT * FROM user WHERE id=1,

搜索型注入为查询语句为:SELECT * FROM user WHERE search like '%1%'

 

在知道查询语句的情况下我们很容易辨别是否存在注入及注入类型,很多时候我们并不知道查询语句是什么,所以我们可以这样判断,在URL或者表单中输入一个单引号或者其他特殊符号,页面出现错误说明此页面存在SQL注入,如果页面正常显示说明有字符被过滤或者不存在注入,读者可自行测试,

如果存在注入可以进一步判断注入类型,在URL或者表单中输入0 or 1,如果可以查到数据,说明是数字型注入,如果输入0'or 1#,查到数据说明是字符型注入,方法不唯一。

总之数字型注入不需要使用单引号闭合前面的单引号就可以执行SQL语句,而字符型必须闭合前面的单引号,然后才可以执行SQL语句,同时也需要把后面的单引号闭合,而注释就是很好的一种闭合后面的单引号的方法。

GET型注入很容易从URL中看出来,如图,网页的URL为:http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=1,浏览器通常使用?来表示GET方法传递参数而使用POST传递参数是不会显示到URL中的,因此URL中含有?说明就是使用GET方法传递参数,如图:

 

 

SQL注入方法

注入方法可以直接在URL中提交注入语句,需要注意的是,在URL提交SQL语句,需要将注释符#进行URL编码,有时候所有SQL语句都需要URL编码,如图:

 

 

联合查询注入

POST型注入和Cookie注入需要插件和工具才可进行,以后在介绍,联合查询注入也是用的非常多的,可以在URL中提交SQL语句,也可以在表单提交,联合查询相当于把别的表的数据查询结果显示到当前表,使用联合查询时,必须使得两张表的表结构一致,因此我们需要判断当前表的列数有多少列,此外还需知道是字符型注入还是数字型注入,由前面实验可知这是字符型注入,所以我们闭合前面的单引号,构造联合注入语句,输入1'order by 1#,页面正常,然后输入1'order by 2#,依次增加,直到3时出现错误,如图,说明当前表有2列:

 

 接着我们构造联合查询语句暴露查询列显示在网页的位置:'union select 1,2#

 

 

接着构造联合查询语句查询当前数据库用户和数据库名,结果会显示在上图对应的位置:'union select user(),database()#;

 

 

我们知道每个MySQL数据库中都有数据库information,和mysql,而所有的数据库信息全部存储在information中,

MySQL的用户名和密码存储在mysql中的user表中,所以我们可以使用information来查询到所有的数据,查询当前数据库所有数据表:

'union select 1,table_name from information_schema.tables where table_schema=database()#;

查询当前数据库下数据表abc的所有字段:'union select 1,column_name from information_schema.columns where table_name='abc'#;

查询当前数据库下数据表abc的字段user的数据:'union select 1,user from abc#;

查询MySQL的root用户和密码hash值:'union select user,authentication_string from mysql.user#,如图:

 

 

 

将这篇几乎看不懂的博客从头到尾看了看,其实操作的步骤都比较清晰,但是为什么要这么做,不太理解。

posted @ 2020-06-13 10:31  Zeker62  阅读(74)  评论(0编辑  收藏  举报