SQL注入学习笔记

SQL注入学习笔记

一、漏洞原因分析

web应用在接收相关应用参数的时候没有做好过滤,将其直接带入数据库中查询,因此攻击者可以恶意拼接构造SQL语句实施攻击。

二、漏洞的危害

  1. 数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。
  2. 网页篡改:通过操作数据库对特定网页进行篡改。
  3. 网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。
  4. 数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。
  5. 服务器被远程控制,被安装后门:经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。
  6. 破坏硬盘数据,瘫痪全系统。

三、 SQL注入防范

解决SQL注入问题的关键是对所有可能来自用户输入的数据进行严格的检查、对数据库配置使用最小权限原则。通常有以下几种解决方式:

1、代码层面
  1. 对输入进行严格的转义和过滤
    在php中最基本的就是自带的magic_quotes_gpc函数,用于处理 ’ " 符号加上/ 防止转义, 比如:
 ?id=1' and 1=1#  ===> ?id=1/' and 1=1#

另外还有addslashes(),也具有相同的效果。

mysql_escape_string($string):用反斜杠转义字符串中的特殊字符,用于mysql_query()查询。
mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。
转义的符号包括 \x00 \n \r \ ’ " \x1a

  1. 使用参数化(Parameterized):
    为什么参数化查询能预防SQL注入
  2. PDO预处理 (Java、PHP防范推荐方法:
    没有进行PDO预处理的SQL,在输入SQL语句进行执行的时候,web服务器自己拼凑SQL的时候有可能会把危险的SQL语句拼凑进去。但如果进行了PDO预处理的SQL,会让MYSQL自己进行拼凑,就算夹带了危险的SQL语句,也不会进行处理只会当成参数传进去,而不是以拼接进SQL语句传进去,从而防止了SQL注入
    PDO预处理防御SQL注入
2、网络层面:

(1)通过WAF设备启用防SQL注入策略(防护系统);
(2)云端防护(360安全卫士,阿里云盾);

四、挖掘SQL注入漏洞

可能存在的注入点:

1、首先判断是否与数据库有数据交互,可以优先观察页面存在传值的地方,例如GET传参:?id=2

2、或者是搜索框,前端将用户输入的数据代入到数据库中进行查询,这种以POST方法进行发送数据的地方。
3、HTTP请求头部字段的Cookie等。

参数类型分类

1、数字型注入:

当输入的参 x 为整型时,通常 abc.php 中 Sql 语句类型大致如下:
select * from <表名> where id = x
这种类型可以使用经典的 and 1=1 和 and 1=2 来判断:

Url 地址中输入 http://xxx/abc.php?id= x and 1=1 页面依旧运行正常,继续进行下一步。
Url 地址中继续输入 http://xxx/abc.php?id= x and 1=2 页面运行错误,则说明此 Sql 注入为数字型注入。
原因如下:
当输入 and 1=1时,后台执行 Sql 语句:

select * from <表名> where id = x and 1=1

2、字符型注入:

当输入的参 x 为字符型时,通常 abc.php 中 SQL 语句类型大致如下:
select * from <表名> where id = ‘x’
这种类型我们同样可以使用 and ‘1’='1 和 and ‘1’='2来判断:

Url 地址中输入 http://xxx/abc.php?id= x’ and ‘1’=‘1 页面运行正常,继续进行下一步。
Url 地址中继续输入 http://xxx/abc.php?id= x’ and ‘1’='2 页面运行错误,则说明此 Sql 注入为字符型注入。
原因如下:
当输入 and ‘1’='1时,后台执行 Sql 语句:

select * from <表名> where id = ‘x’ and ‘1’=‘1’

SQL闭合符的判断方法

SQL注入中的–+:起着注释的作用,将后面的语句注释掉。

五、注入手法

诸如常见函数

**

user() :当前数据库用户
database() :当前数据库名
version() :当前使用的数据库版本
@@datadir :数据库存储数据路径
concat() :联合数据,用于联合两条数据结果。如 concat(username,0x3a,password)
group_concat() :和 concat() 类似,如
group_concat(DISTINCT+user,0x3a,password) ,用于把多条数据一次注入出来
concat_ws() :用法类似
hex() 和 unhex() :用于 hex 编码解码
load_file() :以文本方式读取文件,在 Windows 中,路径设置为 \\
select xxoo into outfile '路径' :权限较高时可直接写文件

**

1、联合注入(Union)

union 运算符可以将两个或两个以上 select 语句的查询结果集合合并成一个结果集合显示,即执行联合查询。需要注意在使用 union 查询的时候需要和主查询的列数相同
联合查询适合于有显示位的注入,即页面某个位置会根据我们输入的数据的变化而变化

?id=-1' union select 1,2,database() --+

2、报错注入

报错注入用在数据库的错误信息会回显在网页中的情况,如果联合查询不能使用,首选报错注入。
报错注入利用的是数据库的报错信息得到数据库的内容,这里需要构造语句让数据库报错。
常见的报错函数:

1.floor()
select * from test where id=1 and (select 1 from (select
count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by
x)a);
2.extractvalue()
select * from test where id=1 and (extractvalue(1,concat(0x7e,(select
user()),0x7e)));
3.updatexml()
select * from test where id=1 and (updatexml(1,concat(0x7e,(select
user()),0x7e),1));
4.geometrycollection()
select * from test where id=1 and geometrycollection((select * from(select *
from(select user())a)b));
5.multipoint()
select * from test where id=1 and multipoint((select * from(select * from(select
user())a)b));
6.polygon()
select * from test where id=1 and polygon((select * from(select * from(select
user())a)b));
7.multipolygon()
select * from test where id=1 and multipolygon((select * from(select *
from(select user())a)b));
8.linestring()
select * from test where id=1 and linestring((select * from(select * from(select
user())a)b));
9.multilinestring()
select * from test where id=1 and multilinestring((select * from(select *
from(select user())a)b));
10.exp()
select * from test where id=1 and exp(~(select * from(select user())a));

讲一下常用的几个:
1、extractvalue()
函数语法:extractvalue(XML_document,XPath_string)

适用的版本:5.1.5+

利用的原理是xpath格式不符报错注入

例子:获取当前是数据库名称及使用mysql数据库的版本信息:

and extractvalue(1,concat(0x7e,database(),0x7e,version(),0x7e))

2、updatexml()
updatexml()函数语法:updatexml(XML_document,Xpath_string,new_value);

函数语法解析:

XML_document:是字符串String格式,为XML文档对象名称

Xpath_string:Xpath格式的字符串

new_value:string格式,替换查找到的符合条件的数据

适用版本是:5.1.5+

利用方式:在执行两个函数时,如果出现xml文件路径错误,就会产生报错 那么我们就需要构造Xpath_string格式错误,也就是我们将Xpath_string的值传递成不符合格式的参数,mysql就会报错

查询当前数据库的用户信息以及数据库版本信息

http://172.20.10.13/sqli-labs/Less-5/?id=1' and updatexml(1,concat(0x7e,user(),0x7e,version(),0x7e),3)--+

3、BigInt数据类型溢出报错注入

exp(int)函数 利用的就是BigInt数据类型溢出 适

用mysql数据库版本是:5.5.5~5.5.49

函数作用:返回e的x次方,当x的值足够大的时候就会导致函数的结果数据类型溢出,也就会因此报错

注入时的利用方式:当涉及到注入时,我们使用否定查询来造成"DOUBLE value is out of range"

因为函数成功执行时,会返回0,那么我们先将0按位取反,在获取e的那个数的次方,就会造成BigInt大数据类型溢出,就会报错

http://172.20.10.13/sqli-labs/Less-5?id=1' and exp(~(select * from (select user())a))--+

and exp(~(select * from (select user())a))
1.先查询select user()这个语句的结果,然后将查询出来的数据作为一个结果集取名为a

2.然后在查询select * from a 查询a,将结果集a全部查询出来

3.查询完成,语句成功执行,返回值为0,再取反获取,是exp调用的时候报错

注意:这里必须使用select语句进行嵌套,不然无法大整数溢出 获取表名信息。

4、主键重复group by:
这种方式可以实现报错的原因是:虚拟表的主键重复。

首先,主键重复方式的报错注入利用的函数有: floor() + rand() + group() + count()

其中, floor()函数的作用就是返回小于等于该值的最大整数,即向下取整,只保留整数部分

count()函数是一个计数函数 group by 语句与count()函数结合,根据一个或多个列对结果集进行分组 rand()函数用来随机生成0或1,在sql报错注入中,我们使用rand(0)获取有规律可循的0或1随机数字(rand()生成的数字是完全随机的)

主键重复报错注入原理

在mysql数据库中,使用group by 进行分组查询的时候,数据库会生成一张虚拟表,并且使用group by还要进行两次运算,第一次运算是先获取group by后面的值,然后拿group by后面的值去和虚拟表中的值比较;第二次是对比虚拟表中的值如果group by后面的值在虚拟表中不存在,那么就将group by后面的值插入到虚拟表中,当插入虚拟表中时,进行运算。那么,rand()函数存在一定的随机性,所以group by后面的值两次计算结果可能不一致,但是这个运算的结果可能在虚拟表中已经存在了,那么这时候吧值插入到虚拟表中就会导致主键重复,进而引发错误。

and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a)--+

3、基于布尔的盲注

在SQL注入过程中,SQL语句执行后,选择的数据不能回显到前端页面,此时需要利用一些
方法进行判断或者尝试,这个过程称之为盲注。

在盲注中,攻击者根据其返回页面的不同来判断信息(可能是页面内容的不同,也可以是响
应时间不同)。一般情况下,盲注可分为两类
基于布尔的盲注(Booleanbased)
基于时间的盲注(Timebased)
某些场合下,页面返回的结果只有两种(正常或错误)。通过构造SQL判断语句,查看页面的返回结果(True or False)来判断哪些SQL判断条件成立,通过此来获取数据库中的数据。

常用函数:

1、if()
功能:条件判断。
语法格式:if(expr1,expr2,expr3):expr1为true则返回expr2,expr1为false则返回expr3。
注:仅MySQL支持if(expr1,expr2,expr3)
2、left()
功能:截取具有指定长度的字符串的左边部分。
语法格式:left(strlength),如果str或length参数为NULL,则返回NULL值。
参数说明
str:要提取子串的字符串。
length:正整数,指定将从左边返回的字符数。length为0或为负,则LEFT返回一个空字符串
length大于str字符串的长度,则leftO返回整个str字符串。
3、length()
功能:返回字符串的长度,以字节为单位。
语法格式:length(str)

substr()、substring()
功能:从指定的位置开始,截取字符串指定长度的子串。
语法格式:substr(str,pos)或substr(str,pos,len),substring(str,pos)substring(str,pos,len)
参数说明
str:要提取子串的字符串。
pos:提取子串的开始位置
len:指定要提取的子串的长度

ascii()、ord()
功能:返回字符串最左边字符的ASCII码值
语法格式:ascii(str),ord(str)

cast()、convert()
功能:获取一个类型的值,并产生另一个类型的值。
语法格式:cast(value as type),convert(value,type)

例子:

http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>5 --+  //正常显示
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>10 --+  //不显示任何数据

4、基于时间的盲注

也叫延时注入。通过观察页面,既没有回显数据库内容,又没有报错信息也没有布尔类型状态,就可以考虑延时注入。延时注入就是将页面的时间线作为判断依据,一点一点注入出数据库的信息。

用具有延时功能的函数sleep、benchmark

延时函数sleep()
功能:让语句延退执行一段时间,执行成功后返回0。
语法格式:sleep(N),即延退执行N秒。

延时函数benchmark()
功能:让某语句执行一定的次数,执行成功后返回0。
语法格式:benchmark(coun,texpr),即让expr执行count次
注:仅MySQL支持该函数。

其余的与基于布尔的盲注类似

5、HTTP头注入

HTTPHeader注入
有时候,后台开发人员为了验证客户端HTTPHeader(比如常用的Cookie验证等)或者通过HTTPHeader头信息获取客户端的一些信息(比如User-Agent、Accept字段等),会对客户端HTTPHeader进行获取并使用SQL语句进行处理,如果此时没有足够的安全考虑,就可能导致基于HTTPHeader的注入漏洞

HTTPHeader注入的前提条件

能够对请求头消息进行修改
修改的请求头信息能够带入数据库执行
数据库没有对输入的请求头做过滤

常见的HTTPHeader注入类型

Cookie注入
Referer注入
User-Agent注入
XFF注入

HTTPHeader内容
User-Agent:使服务器能够识别客户端使用的操作系统,浏览器版本等(很多数据量大的
网站中会记录客户使用的操作系统或浏览器版本等存入数据库中)。
Cookie:网站为了辩别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常
经过加密)。
Host:客户端指定自己想访问的Web服务器的域名/IP地址和端口号。
X-Forwarded-For:简称XFF头,它代表客户端(即HTTP的请求端)真实的IP(通常一些
网站的防注入功能会记录请求端真实IP地址并写入数据库or某文件[通过修改XXF头可以实
现伪造IP])。
client-IP:同上。
Referer:浏览器向Web服务器表明自己是从哪个页面链接过来的。

可以参考这篇文章

6、二阶注入

所谓二阶注入(又称存储型注入)是指已存储(数据库、文件)的用户输入被读取后再次进入到SQL查询语句中导致的注入。
二阶注入与普通注入的区别:
(1)普通SQL注入:发生在一个HTTP请求和响应中,对系统的攻击是立即执行的:
1)攻击者在http请求中提交非法输入
2)应用程序处理非法输入,使用非法输入构造SQL语句
3)在攻击过程中向攻击者返回结果。
(2)二阶SQL注入:
1)攻击者在http请求中提交某种经过构思的输入
2)应用程序存储该恶意输入(通常保存在数据库中)以便后面使用并响应请求
3)攻击者提交第二次(不同的)http请求
4)为处理第二次http请求,程序会检索存储在数据库中的恶意输入并进行处理,从而导致攻击者构造的SQL查询被执行
5)如果攻击成功,在第二次请求响应中向攻击者返回查询结果。
例子------>

7、宽字节注入

宽字节是相对于ascII这样单字节而言的;像 GB2312、GBK、GB18030、BIG5、Shift_JIS 等这些都是常说的宽字节,实际上只有两字节。GBK 是一种多字符的编码,通常来说,一个 gbk 编码汉字,占用2个字节。一个 utf-8 编码的汉字,占用3个字节。

统一的国际规范的理想状态是所有应用程序都使用Unicode编码,所有的网站都使用UTF-8编码。但因为一些历史原因,国内及国外(特别是非英语国家)的一些cms仍然使用着自己国家的一套编码(如GBK);也有一些cms为了考虑老用户,出了GBK和UTF-8两个版本。一个GBK编码汉字,占用2个字节:一个UTF-8编码的汉字,占用3-4个字节当Web应用程序的编码方式为GBK,而数据库的编码方式为UTF-8,且WAF利用AddSlashes0等函数对敏感字符进行转义时,此时可以利用Web应用程序和数据库编码方式上的差异,想办法将,前面添加的转义符一除掉,以实现注入。

宽字节注入指的是 mysql 数据库在使用宽字节(GBK)编码时,会认为两个字符是一个汉字(前一个ascii码要大于128(比如%df),才到汉字的范围),而且当我们输入单引号时,mysql会调用转义函数,将单引号变为’,其中\的十六进制是%5c,mysql的GBK编码,会认为%df%5c是一个宽字节,也就是’運’,从而使单引号闭合(逃逸),进行注入攻击。
也就是说数据库使用的是宽字节编码,两个连在一起的字符会被当做是一个汉字,而在PHP使用的UTF8编码则认为是两个独立的字符,如果我们在单或双引号前添加一个字符,使其和斜杠(\)组合被当作一个汉字,从而保留单或双引号,使其发挥应用的作用。

例子----->

8、堆叠注入

堆叠注入,顾名思义,就是将语句堆叠在一起进行查询
原理很简单,mysql_multi_query() 支持多条sql语句同时执行,就是个;分隔,成堆的执行sql语句,例如

select * from users;show databases; 

就同时执行以上两条命令,所以我们可以增删改查,只要权限够。
传送门

参考:
sql注入详解
sql注入基础原理(超详细)
Gjqhs的博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: SQL基础教程是一本系统介绍SQL语言的教材,下面是我整理的一些笔记。 首先,SQL是Structured Query Language(结构化查询语言)的缩写,是一种用于管理和操作关系型数据库的计算机语言。 SQL语言包括了对数据库进行增、删、改、查的操作。其中,增操作使用INSERT语句,可以将新的数据插入到数据库中。删操作使用DELETE语句,可以删除数据库中的数据。改操作使用UPDATE语句,可以修改数据库中已有的数据。查操作使用SELECT语句,可以从数据库中查询所需数据。 在SQL中,还存在着一些操作符,如等于(=)、不等于(<>)、大于(>)、小于(<)、AND(并且)、OR(或者)等,用于帮助我们实现更复杂的查询条件。 SQL还提供了一些函数,如SUM、COUNT、AVG、MAX和MIN等,用于对数据进行统计和计算。 此外,SQL还提供了一些关键字,如DISTINCT、ORDER BY、GROUP BY等,用于进一步操作查询结果,实现去重、排序和分组等需求。 除了查询语句,SQL还支持多表联结查询,通过JOIN语句可以将多个表连接起来,在查询结果中展示多个表的数据。 在使用SQL语言操作数据库时,需要注意一些安全性问题。比如,应该使用参数化查询,防止SQL注入攻击。同时,对于敏感的数据,应该限制访问权限,保证数据的安全性。 总而言之,SQL基础教程是一个可以帮助我们深入学习和理解SQL语言的教材。通过学习这个教程,我们可以掌握SQL的基本语法、常用操作符、函数和关键字,进而能够熟练地使用SQL进行数据库管理和操作。 ### 回答2: SQL(Structured Query Language)是结构化查询语言的缩写,是一种用于管理和操作关系型数据库的标准语言。下面是我对《SQL基础教程》的笔记总结: 这本教程首先介绍了SQL的基本概念和发展历史,以及SQL数据库管理系统中的重要性。然后,详细说明了SQL的语法规则和常用命令,包括SELECT、INSERT、UPDATE、DELETE等。通过学习这些基本命令,我们可以对数据库中的数据进行查询、添加、更新和删除操作,实现对数据的管理和维护。 接下来,教程介绍了SQL的数据类型和约束条件。数据类型包括数值型、字符型、日期型等,而约束条件可确保数据的完整性和一致性,包括主键、外键、唯一性约束等。理解和应用这些数据类型和约束条件,能够使我们创建和维护高质量的数据库。 在教程的后半部分,作者还介绍了SQL的高级应用技巧,包括多表查询、子查询、联合查询等。多表查询可方便地从多个表中检索数据,子查询可用于嵌套查询,联合查询可将多个查询结果合并。掌握这些高级应用技巧,可以更加高效地利用SQL查询复杂的数据。 此外,教程还介绍了SQL的数据操作语言(DML)和数据定义语言(DDL),以及对权限的管理和控制。数据操作语言包括SELECT、INSERT、UPDATE、DELETE等命令,用于操作和管理数据库中的数据;数据定义语言包括CREATE、ALTER、DROP等命令,用于管理数据库的结构和定义。 通过学习这本教程,我掌握了SQL的基本概念和语法,了解了SQL数据库管理中的重要性和应用场景。我能够使用SQL语言对数据库中的数据进行各种操作,并且能够通过SQL优化查询语句,提高查询效率。这本教程为我进一步学习和应用SQL打下了坚实的基础。 ### 回答3: SQL(Structured Query Language)是一种用于管理和操作关系数据库的标准化语言。在SQL基础教程中,我学到了许多关于SQL的重要概念和技术。 首先,我学习SQL的起源和发展历史。SQL最初是由IBM的Edgar F. Codd在20世纪70年代提出的,旨在为关系数据库提供一个通用的查询语言。随着时间的推移,SQL逐渐成为了关系数据库管理系统(RDBMS)的行业标准。 其次,我学习SQL的基本语法和查询操作。SQL通过使用不同的关键字和语句来查询和操作数据库。我学会了使用SELECT语句来检索数据,使用FROM和WHERE子句来指定数据来源和筛选条件。我还学会了使用INSERT、UPDATE和DELETE语句来插入、更新和删除数据。 在SQL基础教程中,我还学习了如何创建和管理数据库表。我学会了使用CREATE TABLE语句来创建表,并定义表的列和数据类型。我还学会了使用ALTER TABLE语句来修改表的结构,并使用DROP TABLE语句来删除表。 此外,我还学习了如何使用SQL来处理表之间的关系。我学会了使用JOIN语句来合并多个表,并通过指定关联条件来检索符合要求的数据。我还学会了使用GROUP BY和HAVING子句来对数据进行分组和过滤。 在SQL基础教程中,我还学习了如何使用SQL来创建和管理索引。索引可以提高查询的性能,我学会了使用CREATE INDEX语句来创建索引,并使用DROP INDEX语句来删除索引。 总之,SQL基础教程帮助我建立了对SQL语言的基本理解和技能。我认为SQL是一个非常重要的技能,在处理和管理数据库时非常实用。通过学习SQL,我可以更有效地查询和操作数据库,提高数据管理和分析的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值