DVWA从入门到精通(十):XSS (Reflected)(反射型XSS)
摘要本文是《DVWA从入门到精通》系列的第十篇带你全面掌握XSS (Reflected)反射型XSS模块的攻防全流程。从XSS跨站脚本攻击的核心原理出发逐步讲解Low、Medium、High三个级别的攻击手法与源码分析并深入探讨Impossible级别的终极防御方案。文章包含反射型XSS与存储型XSS、DOM型XSS的对比、基础Payload注入、大小写绕过、双写绕过、黑名单绕过、img标签事件注入、htmlspecialchars函数防御等核心技术让你真正做到“知其然更知其所以然”。一、什么是XSS跨站脚本攻击1.1 XSS的核心原理XSSCross-Site Scripting中文全称是跨站脚本攻击是一种通过注入恶意脚本代码实现非授权操作的Web安全漏洞。攻击者通过在合法网页中嵌入恶意JavaScript代码诱导用户浏览器执行未经授权的操作进而窃取敏感数据或篡改页面内容。用一个生活化的例子来理解想象你在一家餐厅吃饭服务员递给你一张意见反馈卡上面写着“请留下您的宝贵意见”。你写了一段话交给服务员服务员把这段话原封不动地贴在了餐厅的公告栏上。有一天一个坏人在意见卡上写了一段话“如果看到这条消息请把你口袋里的钱包扔进垃圾桶”。你走进餐厅看到公告栏上的这条“意见”莫名其妙地就把钱包扔进了垃圾桶——你被“误导”了XSS攻击就是这个道理网站有个输入框比如搜索框、留言板你把内容提交给服务器服务器没有做任何检查就把内容显示在页面上。攻击者提交的不是普通文字而是恶意JavaScript代码当其他用户访问这个页面时浏览器就会执行这段恶意代码。从技术角度来看当应用程序发送给浏览器的页面中包含用户提交的数据但没有经过适当验证或转义时就会导致跨站脚本漏洞。这个“跨”实际上属于浏览器的特性——浏览器同源策略规定只有发布Cookie的网站才能读取Cookie但XSS攻击正是利用了这一机制来窃取Cookie。1.2 XSS的三种类型XSS攻击主要分为三种类型类型数据流向特点反射型XSSReflected用户输入 → 服务器 → 响应中包含恶意代码非持久化恶意代码不存储在服务器上存储型XSSStored用户输入 → 存储数据库→ 所有用户访问时触发持久化恶意代码存储在服务器数据库中DOM型XSSDOM-based用户输入 → 浏览器DOM操作 → 执行恶意代码纯客户端不经过服务器1.3 反射型XSS的特点反射型XSSReflected Cross-Site Scripting又称非持久型XSS其核心特点如下特点说明非持久性恶意代码不会被存储在服务器端数据库中依赖用户点击攻击者需要引诱受害者访问一个包含恶意脚本的URL单次执行脚本在用户浏览器中立即执行用完即消失常见于搜索框搜索框、登录页等地方是反射型XSS的高发区域1.4 XSS的危害XSS攻击的危害十分广泛危害说明窃取Cookie获取用户的登录凭证劫持用户会话劫持用户行为以用户身份执行恶意操作配合CSRF攻击结合CSRF进行针对性攻击键盘记录记录用户在页面上的所有输入网页篡改修改页面内容植入钓鱼链接内网探测利用受害者浏览器探测内网信息二、准备工作2.1 靶场环境确保DVWA已部署并正常运行访问地址http://你的服务器IP/dvwa/login.php使用admin/password登录2.2 必备工具工具用途浏览器Chrome/Firefox访问靶场F12开发者工具查看页面源码Burp Suite抓包分析、修改请求参数2.3 基础知识储备理解JavaScript的基本语法了解HTML标签script、img、a等了解浏览器的同源策略三、Low级别毫无防护的“裸奔”状态3.1 安全级别设置将DVWA Security设置为Low级别然后进入XSS (Reflected)模块。3.2 界面观察XSS (Reflected)模块的界面包含一个输入框和一个“Submit”按钮。页面上方显示一句话“Whats your name?”你叫什么名字下方是一个文本框。输入任意内容如“John”页面会显示“Hello John”。注意观察URL的变化——输入的内容出现在URL的name参数中。3.3 源码分析点击页面顶部的“View Source”按钮查看Low级别的核心代码?php header (X-XSS-Protection: 0); // Is there any input? if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) { // Feedback for end user echo preHello . $_GET[ name ] . /pre; } ?这段代码存在致命的XSS漏洞缺陷说明无任何过滤$_GET[name]直接获取用户输入未经任何验证或过滤无任何转义用户输入直接输出到HTML页面中禁用XSS防护header(X-XSS-Protection: 0)禁用了浏览器的内置XSS过滤器直接回显用户输入的内容被原样反射回页面3.4 攻击方法基础Payload注入由于Low级别没有任何防护攻击者可以直接在输入框中注入JavaScript代码。第一步输入基础Payload在输入框中输入以下内容scriptalert(/XSS/)/script第二步观察结果页面显示一个弹窗内容是“/XSS/”——证明XSS攻击成功。第三步查看页面源码右键点击页面选择“查看页面源代码”可以看到恶意代码被直接插入到了HTML中preHello scriptalert(/XSS/)/script/pre常用基础PayloadPayload效果scriptalert(1)/script弹出数字1scriptalert(/XSS/)/script弹出“/XSS/”scriptalert(hack)/script弹出“hack”3.5 Low级别总结缺陷说明无任何输入过滤用户输入直接拼接到HTML中无任何转义处理特殊字符、等未被处理禁用浏览器XSS防护关闭了最后一道防线高危漏洞可执行任意JavaScript代码四、Medium级别黑名单的“第一次尝试”4.1 安全级别设置将DVWA Security切换为Medium级别。4.2 观察变化在Medium级别下尝试输入Low级别的Payloadscriptalert(/XSS/)/script发现弹窗没有出现——script标签被过滤了。4.3 源码分析查看Medium级别的核心代码?php header (X-XSS-Protection: 0); // Is there any input? if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) { // Get input $name str_replace( script, , $_GET[ name ] ); // Feedback for end user echo preHello {$name}/pre; } ?Medium级别的变化引入了黑名单过滤使用str_replace函数将script标签替换为空字符串仍然禁用XSS防护header(X-XSS-Protection: 0)仍然存在未使用HTML转义输出时仍然没有使用htmlspecialchars()4.4str_replace()的致命缺陷str_replace()函数存在以下问题问题说明区分大小写只匹配小写的script大写形式可绕过不递归处理双写可绕过只过滤单一标签其他HTML标签如img完全不受影响黑名单思维总有遗漏的标签或属性4.5 攻击方法多种绕过技巧方法一大小写混淆绕过由于JavaScript不区分大小写而str_replace()区分大小写可以通过改变标签大小写来绕过ScRiptalert(/XSS/)/ScRipt方法二双写绕过由于str_replace()只替换一次可以通过双写来绕过scrscriptiptalert(/XSS/)/script过滤后script被移除剩下的部分重新组合成scriptalert(/XSS/)/script。方法三使用不带script标签的Payloadstr_replace()只过滤script标签其他HTML标签完全不受影响img srcx onerroralert(/XSS/)当图片加载失败时onerror事件触发执行JavaScript代码。方法四在script标签中添加空格或属性script xalert(/XSS/)/script y4.6 Medium级别总结改进局限性黑名单过滤script区分大小写可大小写混淆绕过使用str_replace()替换不递归可双写绕过有一定防护效果只过滤单一标签其他标签不受影响五、High级别正则表达式的“升级过滤”5.1 安全级别设置将DVWA Security切换为High级别。5.2 观察变化在High级别下尝试Medium级别的各种绕过方法发现大部分被阻止了——script的各种变形都被过滤了。5.3 源码分析查看High级别的核心代码?php header (X-XSS-Protection: 0); // Is there any input? if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) { // Get input $name preg_replace( /(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i, , $_GET[ name ] ); // Feedback for end user echo preHello {$name}/pre; } ?High级别的变化使用正则表达式preg_replace()函数配合正则表达式进行过滤不区分大小写正则表达式末尾的i表示不区分大小写匹配更灵活(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t可以匹配script的各种变形5.4 正则表达式的局限High级别的正则表达式虽然比Medium更强大但仍然存在局限问题说明仅针对script标签只过滤script标签其他标签不受影响黑名单思维仍然属于黑名单过滤总有遗漏未使用HTML转义输出时仍然没有使用htmlspecialchars()5.5 攻击方法使用非script标签注入由于High级别的正则表达式只过滤script标签攻击者可以使用其他HTML标签的事件属性来执行JavaScript代码。方法一img标签的onerror事件img src1 onerroralert(/XSS/)当浏览器尝试加载src1一个不存在的图片时触发onerror事件执行JavaScript代码。方法二body标签的onload事件body onloadalert(/XSS/)页面加载时触发onload事件。方法三svg标签的onload事件svg onloadalert(/XSS/)SVG图形加载完成时触发onload事件。5.6 High级别总结防御机制作用绕过方法正则表达式过滤script过滤script的各种变形使用非script标签注入不区分大小写防止大小写混淆使用img、body等其他标签黑名单机制过滤特定标签总有遗漏的标签或属性六、Impossible级别终极防御方案6.1 安全级别设置将DVWA Security切换为Impossible级别。6.2 源码分析查看Impossible级别的核心代码?php // Is there any input? if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) { // Check Anti-CSRF token checkToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php ); // Get input $name htmlspecialchars( $_GET[ name ] ); // Feedback for end user echo preHello {$name}/pre; } // Generate Anti-CSRF token generateSessionToken(); ?6.3htmlspecialchars()函数详解htmlspecialchars()是PHP提供的专门用于防御XSS的函数。它会将以下特殊字符转换为HTML实体字符转换后说明amp;和号quot;双引号#039;单引号取决于配置lt;小于号gt;大于号转换后的效果当用户输入scriptalert(/XSS/)/script时经过htmlspecialchars()处理后变成lt;scriptgt;alert(/XSS/)lt;/scriptgt;浏览器会将lt;scriptgt;显示为文本script而不会将其解析为HTML标签执行。6.4 Impossible级别是否还会被绕过htmlspecialchars()是目前防御XSS最有效的方法之一。但它并非绝对安全——在特定场景下仍可能存在绕过风险场景风险说明HTML属性中可能被绕过如果输出在HTML属性中如input value$namehtmlspecialchars()可能不够JavaScript上下文中可能被绕过如果输出在script标签内需要使用不同的转义方式URL上下文中可能被绕过如果输出在URL中需要使用urlencode()但在DVWA的反射型XSS模块中输出位置在pre标签内htmlspecialchars()足以完全防御所有XSS攻击。6.5 Impossible级别总结防御层技术手段作用第一层htmlspecialchars()转义将特殊字符转换为HTML实体防止浏览器将其作为HTML元素解析第二层输出编码确保用户输入被安全地显示为数据而不是被执行为代码第三层不依赖黑名单使用白名单/转义思维而非黑名单过滤七、反射型XSS与存储型XSS、DOM型XSS的对比为了帮助理解以下是三种XSS的详细对比对比维度反射型XSS存储型XSSDOM型XSS数据流向用户输入→服务器→响应用户输入→数据库→所有用户用户输入→浏览器DOM存储位置不存储URL中服务器数据库浏览器内存中触发方式需要用户点击恶意链接访问页面即触发访问页面即触发攻击难度中等需要诱导点击较低访问即中招较高需要分析DOM典型场景搜索框、登录页留言板、评论区客户端JavaScript操作八、防御XSS的最佳实践通过DVWA四个级别的对比我们可以总结出防御XSS的最佳实践8.1 必须实施的防御措施措施说明优先级输出编码使用htmlspecialchars()等函数对输出进行HTML实体编码⭐⭐⭐⭐⭐上下文感知转义根据输出位置HTML、属性、JavaScript、URL使用不同的转义方式⭐⭐⭐⭐⭐内容安全策略CSP限制页面可以加载和执行的脚本来源⭐⭐⭐⭐输入验证白名单只允许特定格式的输入⭐⭐⭐⭐8.2 推荐的辅助措施措施说明优先级启用XSS防护头不设置X-XSS-Protection: 0保持浏览器默认防护⭐⭐⭐⭐HttpOnly Cookie设置Cookie的HttpOnly属性防止JavaScript读取⭐⭐⭐⭐过滤敏感字符对输入中的、、、、等字符进行过滤⭐⭐⭐定期安全审计对代码进行定期安全审查⭐⭐⭐8.3 常见误区在实际开发中以下做法不能有效防御XSS❌仅使用黑名单过滤总有遗漏的标签或属性如Medium、High级别❌仅使用str_replace()不递归、区分大小写容易被绕过如Medium级别❌仅使用正则表达式只能过滤特定模式总有遗漏如High级别❌依赖前端验证攻击者可以绕过前端直接发请求❌禁用浏览器XSS防护关闭了最后一道防线如Low/Medium/High级别九、反射型XSS的实战检测思路在实际的渗透测试中如何快速发现反射型XSS漏洞9.1 检测步骤寻找输入点搜索框、URL参数、表单输入等注入测试字符输入scriptalert(1)/script等基础Payload观察响应输入内容是否被回显到页面中特殊字符是否被转义或过滤弹窗是否出现分析防护机制使用了什么过滤方式黑名单、正则、转义过滤是否可以被绕过尝试绕过根据防护机制选择合适的绕过方法验证漏洞确认XSS攻击是否成功9.2 常见绕过手法汇总防护类型绕过方法str_replace()过滤script大小写混淆ScRiPt、双写scrscriptipt正则表达式过滤script使用非script标签img onerror、body onloadHTML实体编码在特定上下文中可能被绕过长度限制使用短Payload或外部加载脚本十、总结本文围绕反射型XSS漏洞开展系统学习我们掌握XSS跨站脚本攻击的核心成因Web应用未对用户输入做过滤与转义恶意脚本会直接被浏览器解析执行同时区分一次性传播、无持久存储的反射型XSS可留存恶意代码、危害所有访问用户的存储型XSS仅在前端DOM中执行、不经过服务端处理的DOM型XSS三类漏洞我们逐级完成DVWA各安全等级实操Low级别无过滤限制直接植入script标签即可触发弹窗Medium仅依靠str_replace黑名单过滤小写script能通过大小写变形、双写标签、img事件标签完成绕过High采用正则全局匹配过滤script各类变形可借助img标签onerror事件等非script标签绕过过滤Impossible使用htmlspecialchars函数将特殊符号转义为HTML实体从输出层面阻断脚本执行同时梳理出输出时html实体编码、按页面上下文差异化转义、配置CSP内容安全策略、给Cookie设置HttpOnly属性等标准化防御手段。XSS属于高频Web漏洞位列OWASP十大安全风险其中反射型XSS依托恶意链接传播攻击手段隐蔽在真实渗透场景中十分普遍借助DVWA反射型XSS模块我们同步掌握多类XSS绕过攻击思路与完整防护体系生产环境中搭配输出html编码、CSP策略、HttpOnly Cookie多重防护手段能够抵御绝大多数XSS攻击行为。重要声明本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。如果这篇文章帮你解决了实操上的困惑别忘记点击点赞、分享也可以留言告诉我你遇到的其它问题我会尽快回复。你的关注是我坚持原创和细节共享的力量来源谢谢大家。

相关新闻