sql注入
sql注入
动态网站的访问流程
浏览器发起访问>DNS解析域名>服务器电脑==>服务软件
Apache是一种帮助计算机向互联网上的其他计算机发送和接收网页的程序。
html是一种用于创建网页的标准标记语言。HTML是一种基础技术,和其他语言一起被众多网站用于设计网页、网页应用程序以及移动应用程序的用户界面。网页浏览器可以读取HTML文件,并将其渲染成可视化网页。
PHP的主要用途是生成动态网页内容,例如处理表单数据、与数据库交互、管理会话等。
MySQL 是一种功能强大、易于使用且广泛应用的关系型数据库管理系统,凭借其开源性、高性能和跨平台兼容性,成为全球最受欢迎的数据库之一。

sql注入是一种利用web应用程序安全漏洞,将恶意sql代码插入到用户输入的参数中,从而欺骗数据库服务器执行没有被授权操作的技术。
web应用程序:可以通过web访问的应用程序
sql注入成立的两个条件:
参数用户可控;
参数代入数据库查询。
Hackbar的主要用途是帮助安全测试人员进行手动漏洞检测,比如SQL注入、XSS,以及提供编码工具。
我们先来看一道题
sql-labs第一关
请输入值为数字的id作为参数。
这道题就满足了sql注入的两个条件,id参数是我们输入的,然后这个参数被代入sql语句中查询数据库的信息,所以我们就可以在这里进行sql注入
我们先看一下源码中php的部分

我们先看这条sql语句,查找users表中id=$id的数据
这个$id就是get请求中 我们输入的数值 所以说我们刚刚输入id=1 就可以查询到id为1的用户的相关信息
- GET 请求
GET 用于从服务器获取资源(如网页、图片、数据等),请求参数附加在 URL 中。
第一关是get请求,GET请求中的问号(?)在HTTP协议中起到分隔URL路径与查询参数的作用。
-
POST 请求 (less 11)
POST 用于向服务器提交数据(如表单、文件上传),请求参数放在 HTTP 请求体中。
![]()
我们再分析一下这个源码是什么意思
if(isset($_GET['id']))
这是一个if语句,如果存在GET 请求中包含名为 id 的参数,该条件返回true,
$id=$_GET['id'];
$_GET['id']中的id就是get请求传递的id参数 是url ?后面的id
然后再将url中以get请求传递的id参数,赋值给变量$id
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
这是一句sql的查询语句,从 users 表中查询 id 字段等于用户输入值 $id 的记录,并仅返回第一条结果。
LIMIT 0,1:限制返回结果的数量。0表示从第0行(即第一行)开始,1表示仅返回一行数据。
这里的第三个id就是users表中的id字段
我们可以在本地的mysql数据库看一下


我们可以在本地看一下 当id=1时 这个sql语句在后台怎么运行的
SELECT * FROM users WHERE id='1' LIMIT 0,1;

第一关是get请求,GET请求中的问号(?)在HTTP协议中起到分隔URL路径与查询参数的作用。
刚刚输入id=1 可以看到显示登陆名和密码
我们如果想获取数据库中的其它信息 就可以利用它的漏洞添加一些sql代码到参数中
然后我们先猜测是什么类型的闭合
因为输入\ 出现sql的语法错误 所以就会报错
查询数据库执行的是刚刚的源码 所以报错时会看到部分源码
通过反斜杠报错可以看到 输入的 id=1\ 是单引号包裹
所以是单引号闭合
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1\' LIMIT 0,1' at line 1
我们看源码 也可以看到

我们看这条sql语句 可以看到$id用单引号圈起来了 这就是单引号闭合
Less 2 中就是数字型 没有引号闭合

我们可以用万能密码
?id=-1' or 1=1--+
这条完整语句是
$sql="SELECT * FROM users WHERE id='-1' or 1=1--+' LIMIT 0,1";
这条语句的意思是查询users表中id=-1 或者1=1 后面的这个单引号被--+注释掉了
or就是有一个条件正确就可以成立
因为1=1恒成立 所以 虽然id=-1不成立 这个语句不会报错
但是这样只能查询到第一个 所以我们可以用联合注入
再查看表格有几个字段数 没有报错说明是3个
?id=1' order by 3--+
通过union select联合查询 改变它显示的内容
?id=-1' union select 1,2,3--+
查看显示位 发现是第二列和第三列的数据会显示在表上
我们可以在本地看一下

就是将两个查询语句通过union连接在一起 因为id=-1不存在 所以会输出1,2,3
接下来我们可以改成其它我们想要知道的信息
比如说database()查询数据库名,version()查看数据库管理系统的版本
?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='security'),3 --+
查看数据表名
我们现在看这条语句,
table_name 就是数据表名
information_schema.tables表示数据库下的数据表
table_schema 是数据表所属的数据库名
group_concat ()就是把要查询的东西联接起来 比如说要查询的这个数据库下的数据表有好几个,把他们连接起来就可以全部显示,如果不使用的话只能查询出一个数据表
然后我们查询数据表的列名
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() --+
最后再查询数据库内的信息
?id=-1' union select 1,group_concat(id,username,password),3 from security.users --+
下来我们可以看看按照不同标准下sql的几大分类
一、按注入点数据类型分类
-
数字型注入
注入点参数为数字类型(如id=1),无需引号闭合。
-
字符型注入
注入点参数为字符串类型(如name='admin'),需闭合单引号或双引号。
-
搜索型注入
出现在搜索功能中,参数未经严格过滤(如keyword=测试),常伴随模糊查询符号(如%)。
示例:



%字符来表示任意字符,如果没有使用百分号 %, LIKE 子句与等号 = 的效果是一样的。
二、按数据提交方式分类
-
GET注入
通过URL参数提交,直接在地址栏可见。
-
POST注入
通过表单POST请求提交。
-
Cookie注入 (Less 20)
利用Cookie中的参数进行注入。
' union select 1,database(),3 #;[先随便提交一个 发现和cookie有关
在bp中进行联合查询]
-
HTTP头部注入 (Less 18)
攻击HTTP头部字段(如User-Agent、X-Forwarded-For)
' or updatexml(1,concat(0x7e,(database()),0x7e),0) or '[通过提示可知 和User-Agent有关
在bp中进行报错注入]
其中,Cookie注入也算是HTTP头部注入的子类型
HTTP请求头是HTTP协议中用于描述客户端与服务器通信时附加信息的重要部分,能够提供关于客户端环境、请求内容以及客户端期望的响应格式等详细信息,帮助服务器正确处理请求并生成相应的响应。
User-Agent
提供客户端的用户代理信息,包括浏览器类型、版本号、操作系统等。例如:User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
Cookie
包含之前发送给服务器的cookie信息,用于会话管理。例如:Cookie: sessionID=abc123
referer
指示请求来源的URL,用于跨域请求验证。例如:Referer: [https://www.example.com ](https://www.example.com )
三、按注入技巧或执行方式分类
-
联合查询注入 (Less 1)
通过UNION合并查询结果,直接返回数据到前端。 -
报错型注入 (Less 5)
利用数据库函数(如updatexml()、extractvalue())触发错误回显信息。![]()
![微信截图_20250409221015]()
extractvalue() 和 updatexml() 的区别- extractvalue()函数:用于从XML文档中提取特定路径的内容
- updatexml()函数:用于更新XML文档中的特定路径内容。
-
布尔盲注 (Less 8)
通过页面返回的布尔值(真/假)推断数据,不直接显示查询结果。在布尔盲注中,常用的函数包括length()、substr()、ascii()等,这些函数可以帮助攻击者逐步猜测数据库中的信息。
length()函数:用于判断字符串的长度
substr()函数:用于从字符串中截取指定位置的字符
ascii()函数:将字符转换为ASCII码
id=1' and length((select database()))>9 --+id=1' and ascii(substr((select database()),1,1))=115 --+ -
时间盲注 (Less 9)
通过时间延迟函数(如sleep())判断注入是否成功。SLEEP()函数会暂停指定秒数的执行时间BENCHMARK()函数则会执行指定次数的空操作,从而消耗时间。sleep(n);BENCHMARK(count,expr)count 是要重复执行的次数
expr是要执行的表达式
示例:
BENCHMARK(10000000, MD5('aaa'))来测试 MD5 函数的执行时间 -
堆叠注入 (Less 38)
执行多条SQL语句,常用于插入或删除数据。 -
二次注入 (Less 24)
恶意数据先被存储,后续操作触发执行。 -
宽字节注入 (Less 32)
利用编码转换漏洞绕过转义(如GBK编码)。



浙公网安备 33010602011771号