小言_互联网的博客

初学Web安全之sql注入(一)

336人阅读  评论(0)

初学Web安全之sql注入(一)

sql注入产生原因

sql注入漏洞的产生需要满足以下两个条件:

  • 参数用户可控
  • 传入的参数拼接到sql语句并且带入到数据库查询

一般来说,用户登录网页所使用的sql语句为:

select * from user where username='admin' and password='password';

而如果程序员设计网页之初没有对用户的输入进行过滤,使得用户的输入可以带入到数据库,那么这时候就可以产生sql注入,最简单的一种,就是构造万能密码,这里拿dvwa来测试一下:

打开dvwa,修改等级为low,选择sql注入:


输入如下:

' or '1'='1'#


输入结果如图:


那么原理是什么呢?首先我们查看源代码:


其中sql语句为:

SELECT first_name, last_name FROM users WHERE user_id = '$id';

再看看我们前面输入的:

’ or ‘1’=‘1’#

将它带入到sql语句中,就变成了:

SELECT first_name, last_name FROM users WHERE user_id = '' or '1'='1'#';

这里利用了or语句,只要有一个true那么语句就返回true,这时候语句就会被带到数据库中,查询出全部的"first_name"和"last_name" (第一个引号与前面的引号形成了闭合,变为’’,后面的#为注释符,将后面的单引号注释掉)


sql注入方法

sql注入有get型,post型和cookie型,因为笔者是初学者,所以先从get型开始,正常的注入步骤如下:

判断有无注入点
回显正常——联合查询,回显报错——报错注入
联合查询步骤:
判断字符型还是数字型
如果是字符型,判断闭合情况
判断字段数
判断显示位
查看数据库版本(因为MYSQL4.0和MYSQL5.0版本注入方法不一样,不过现在普遍是5.0以上版本)
获取全部数据库名字(可用可不用,看情况而定)
获取当前数据库下所有的表名
判断关键表列名
获取数据

拿sqli-lab来测试一下,这里使用的是mysql数据库,打开sqli-lab的第一关:
(可以在url输入,这里笔者使用的是hackbar插件)

输入单引号报错,判断有注入点:

删除单引号,输入单引号,没报错,判断是字符型,闭合是单引号(原理后面再细说):

利用order by判断字段数,输入order by 3不报错,输入order by 4报错,说明字段是是3,注意,因为是字符型,所以最后面要加注释符注释掉引号:

接着判断显示位,使用union拼接select 1,2,3,发现页面并无变化,判断有可能是前面的id=1占用了显示位,改为id=-1,发现2和3显示出来了,说明2,3是显示位:



接着便是查看数据库版本了,顺带查看了下当前数据库名字(因为后面所使用是同个数据库,所以这个步骤在后面文章里会省略):


获取全部数据库名字(这个步骤只是演示一下,在后面也会省略):


获取当前数据库下所有的表名,判断管理员账号密码存放在users表里:

判断关键表列名为username和password:

最后一步,获取数据:

至此,第一关完成。


那么现在来解释下判断数字型和字符型还有闭合的原理:

  • 数字型的sql语句:
select * from user where id=1;
  • 字符型的sql语句:
select * from user where id='1';
select * from user where id="1";

拿数字型来说,你不管在后面加单引号还是双引号,都会导致语句错误而报错,那么两种引号都报错,我们就可以判定为数字型;

字符型的话,拿单引号类型来说,加入单引号之后:

id='1''

会导致语句后面多出来一个单引号,使得语句错误,如果加入双引号:

id='1"'

双引号被单引号包裹着,那么会将双引号也认为是一个字符,所以并不会报错,从而可以判断出是单引号闭合。双引号类型也是同理,只是引号相反而已。

总结:两种引号都报错为字符型,单引号报错双引号不报错为单引号闭合,双引号报错单引号不报错为双引号闭合,字符型最后要加注释符注释掉闭合后多余出来的引号。


笔者这里的注入是针对MYSQL数据库的,所以需要了解MYSQL的相关知识:

mysql5.0版本之后,默认有一个“information_schema”数据库,里面有三张表:

SCHEMATA: 存放了所有数据库信息
关键字段:schema_name——数据库名字

TABLES:存放所有数据表信息
关键字段:table_schema——数据库名字
-------------- table_name ——数据表名字

COLUMNS:存放所有列的信息
关键字段:table_schema——数据库名字
-------------- table_name——数据表名字
-------------- column_name——列名

理解了这些,相信上面的sql语句也就明白了>_<


转载:https://blog.csdn.net/weixin_47531846/article/details/109735250
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场