尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

DVWA High级别XSS绕过实战:HTML5标签与Unicode编码的攻防对抗

DVWA High级别XSS绕过实战:HTML5标签与Unicode编码的攻防对抗 1. 项目概述从“三板斧”到“迂回渗透”的思维跃迁如果你玩过DVWADamn Vulnerable Web Application这个经典的Web安全靶场并且已经轻松拿下了Low和Medium级别的XSS跨站脚本攻击挑战那么当你信心满满地进入High级别时大概率会遭遇当头一棒。你会发现那些在低级关卡里无往不利的scriptalert(1)/script之类的“三板斧”招式在这里通通失效了。页面平静如水你的攻击载荷仿佛石沉大海。这恰恰是High级别XSS关卡设计的精妙之处——它强制你跳出对script标签的路径依赖去探索更广阔、更隐蔽的攻击面。这个项目就是一次针对DVWA High级别XSS防护机制的深度实战演练。我们不再执着于正面强攻被严格过滤的script标签而是将目光转向HTML5规范中那些同样能执行JavaScript但可能被忽略的新标签、新属性并结合Unicode编码这种“文字魔术”来巧妙地绕过前端或后端的过滤逻辑。这不仅仅是一次通关教程更是一次Web安全攻防思维的升级从“有什么漏洞打什么”转变为“在限制条件下如何创造性地组合利用现有资源达成目标”。无论是安全研究人员、渗透测试工程师还是希望深入理解防御机制的前后端开发者通过这个实战过程你都能对XSS攻击的多样性和现代过滤规则的局限性有更立体的认识。2. 核心思路拆解为何script失效以及我们的破局点在DVWA的XSS High级别中开发者显然吸取了低级关卡的教训部署了更严格的过滤机制。通常它会采用一个“黑名单”或“正则表达式替换”的策略核心目标就是让script标签无论大小写无法完整地出现在最终的页面输出中。常见的过滤方式包括直接删除将script和/script字符串直接从输入中移除。正则替换使用类似preg_replace(/script.*?/i, , $input)的代码不区分大小写地匹配并移除脚本标签。编码转换可能将和转换为HTML实体如和但这在High级别较少见因为我们的目标是绕过。所以当你输入scriptalert(XSS)/script服务器端处理后返回给浏览器的可能就只剩下alert(XSS)这段孤零零的文本它不会被解析为可执行的代码。我们的破局思路基于两个层面2.1 利用HTML5的“非主流”执行点现代浏览器对HTML5的支持引入了大量新的标签和属性其中一些在设计上就允许执行JavaScript但它们的安全风险可能未被所有过滤规则充分考虑。例如事件处理器属性除了经典的onclick、onloadHTML5为许多元素新增了事件如img的onerrorsvg的onloaddetails的ontoggle等。如果过滤规则只盯着script而忽略了这些事件属性的过滤它们就是绝佳的突破口。可执行脚本的标签svg标签内可以嵌套script但有时对svg本身的过滤较弱。iframe的srcdoc属性可以直接包含HTML可能构成一个沙箱内的执行环境。JavaScript伪协议a标签的href属性或者iframe、embed的src属性可以使用javascript:伪协议。虽然很多过滤器会检查并拦截javascript:这个字符串但我们可以通过编码来伪装它。2.2 利用Unicode编码进行“视觉欺骗”Unicode编码允许我们用多种方式表示同一个字符。这对于绕过基于字符串匹配的过滤器至关重要。十六进制编码可以表示为\u003c或\x3c在某些上下文如JavaScript字符串中。HTML实体编码是是。但浏览器在解析某些属性值时会先进行HTML解码。关键点过滤器在检测javascript:或onclick时匹配的是明文字符串。如果我们在输入时将其中关键字符用Unicode编码替换过滤器可能认不出来。但浏览器在渲染页面、解析HTML或执行JavaScript前会先进行解码从而还原出可执行的代码。我们的核心战术就是将含有HTML5事件处理器或伪协议的Payload对其中的关键字符进行Unicode编码以绕过过滤器的字符串匹配待浏览器解码后成功触发执行。3. 实战环境准备与初步侦察在开始构造复杂Payload之前我们必须先摸清DVWA High级别XSS模块的具体过滤规则。盲目尝试效率低下。3.1 环境搭建与配置确保你的DVWA已正确安装并运行。将安全级别设置为“High”。在DVWA Security页面调整。访问“XSS (Reflected)”模块。你会看到一个简单的输入框提示你输入名字。3.2 试探性输入与规则分析我们首先进行一些简单的测试以推断其过滤行为测试1基础脚本输入scriptalert(1)/script输出页面显示空白或仅显示你输入的其他文本。查看网页源代码CtrlU你会发现script和/script标签消失了。这说明它采用了删除策略。测试2大小写变异输入ScRiPtalert(1)/ScRiPt输出同样被删除。说明过滤是不区分大小写的。测试3嵌套与混淆输入scrscriptiptalert(1)/scr/scriptipt输出理想情况下内部的script被删除剩下外部的script和/script可能触发。但在High级别这种简单的嵌套混淆通常也会被递归处理或整体删除。测试后通常失败。说明过滤逻辑可能比较“聪明”会进行递归或一次性匹配删除。测试4测试其他标签输入img srcx onerroralert(1)输出这是关键一步查看页面输出和源代码。你会发现整个img标签被完整地输出到了页面上这意味着过滤器可能只针对script这个特定的标签进行了删除而对于其他标签如img及其属性并没有进行严格的过滤或编码。这为我们利用HTML5事件处理器打开了大门。通过以上侦察我们基本确定了DVWA High级别XSSReflected的过滤策略它主要聚焦于删除script和/script字符串但对其他HTML标签和属性的过滤非常宽松。这符合很多初级防护措施的特点——堵住了最明显的漏洞却留下了更隐蔽的后门。4. 利用HTML5标签与事件构造初级Payload既然img标签可以存活我们就从它开始。onerror事件是一个经典载体当图片加载失败src指向一个不存在的资源时就会触发。4.1 基础事件处理器Payload尝试输入img src\https://invalid.url\ onerror\alert(XSS-High)\提交后如果页面弹出了警告框恭喜你你已经绕过了对script的依赖。但现实往往没那么简单。High级别的防护有时会对事件处理器属性值中的引号或括号进行一些处理。我们查看输出源代码可能会发现属性值被改变了。4.2 应对属性值过滤如果发现onerror\alert(XSS-High)\中的引号被转义或删除我们可以尝试省略引号利用HTML的属性解析特性在某些情况下属性值可以不用引号包裹直到遇到空格或。 尝试img srcx onerroralert(1)这里srcx会加载失败触发onerror。alert(1)作为属性值虽然没有引号但在浏览器解析时是有效的。注意省略引号时确保你的JavaScript代码中没有空格。例如alert(document.cookie)中的空格会提前终止属性值导致错误。此时可以用反引号包裹如果浏览器支持或者使用其他无空格写法如alert(document[cookie])。4.3 探索更多HTML5载体img只是开始。我们可以测试更多标签和事件组合增加攻击的隐蔽性和成功率svg标签SVG本质是XML内联JavaScript能力很强。svg onload\alert(1)\或svgscriptalert(1)/script/svg注意内部script可能被过滤但svg标签和onload事件可能存活。body事件如果输入点出现在body标签内或附近可以尝试闭合前一个标签并注入/textareabody onloadalert(1)需要结合上下文。input标签的onfocus需要配合autofocus属性在页面加载时自动触发。input autofocus onfocusalert(1)details标签的ontoggle用户点击展开/收缩时触发。details ontogglealert(1)summary点击我/summary/details通过这一步我们已经证明了绕过script过滤的可行性。但真正的High级别挑战往往还有第二道防线对onerror、onload这类明显的事件处理器名称进行过滤。这就需要祭出我们的“编码大法”了。5. Unicode编码进阶绕过事件处理器名称过滤假设DVWA的High级别加强了过滤它不仅删除script还会查找并删除onerror、onload、onclick等常见事件属性。这时明文的事件处理器名称就无法使用了。5.1 Unicode编码原理浏览器在解析HTML时会识别并解码HTML实体和在某些上下文中的Unicode转义序列。例如onclick中的o可以用其Unicode十六进制码点\u006f表示。在HTML属性值中我们可以使用HTML实体o是o。关键技巧在于我们可以对事件处理器名称本身进行编码但保证浏览器在解析阶段能正确解码它。5.2 构造编码Payload我们的目标是让服务器端收到的字符串里没有明文的onerror但浏览器渲染时却能看到它。方法一HTML实体编码整个属性名我们可以将onerror每个字符都转换成它的十进制或十六进制HTML实体。o-o或on-nr-re-er-rr-r注意第二个r重复了onerror只有两个r这里示例有误正确应为o,n,e,r,r,o,r? 等等onerror拼写为 o-n-e-r-r-o-r不对是 o-n-e-r-r-o-r 更正onerror是 o-n-e-r-r-o-r 拼写检查onerror正确拼写就是 o-n-e-r-r-o-r。所以字符是 o, n, e, r, r, o, r。但通常我们不需要全部编码编码关键部分即可。一个更实用的方法是只编码部分字符以绕过简单的字符串匹配。例如编码on 输入img srcx o#x6e;erroralert(1)这里#x6e;是n的十六进制HTML实体。对于过滤器来说它匹配的字符串是o#x6e;error这并不等于onerror因此可能绕过。浏览器则会将其解析为onerror。方法二利用JavaScript Unicode转义在HTML属性值中这种方法更巧妙。我们可以在事件处理器的值即JavaScript代码中使用Unicode转义来“动态生成”事件处理器名称本身。但这通常需要结合其他技巧如利用eval或setAttribute。 一个经典的Payload是img srcx id\xss\ style\display:none\scriptxss.setAttribute(onerror, alert(1)); // 这里用字符串拼接绕过对‘onerror’的检测xss.src; // 触发错误/script但注意High级别下script标签会被删除所以这个方案行不通。我们需要在不依赖script标签的情况下在HTML层面实现类似效果。这非常困难因为HTML本身不支持这种动态拼接。因此更可靠的方法仍然是直接对HTML标签内的事件处理器名称进行HTML实体编码。5.3 实战编码绕过测试让我们构造一个综合性的测试Payloadimg src\x\ o#x6e;error\al#x65;rt(XSS-Encoded)\这个Payload做了两处编码onerror中的n被编码为#x6e;。alert中的e被编码为#x65;。提交这个Payload并仔细观察页面行为。如果成功弹窗说明DVWA High级别的过滤规则没有解码检查我们成功绕过了。如果失败我们需要查看页面源代码看输出变成了什么。可能过滤器对#x;这种实体编码也进行了处理或者对属性值中的括号、引号进行了转义。实操心得编码绕过不是盲目的需要根据过滤器的响应进行迭代测试。从编码一个字符开始逐步增加编码范围。优先编码那些在正则表达式中可能是关键字的字符如on中的o和nscript中的s、c、r、i、p、t。同时注意编码的一致性确保浏览器能正确解码回有效的语法。6. 组合拳HTML5标签编码伪协议及其他技巧在单一技巧可能被防御的情况下组合多种技术能大大提高成功率。6.1 结合javascript:伪协议a标签的href属性是另一个常见的攻击向量。High级别肯定会过滤javascript:这个字符串。我们可以用编码来绕过。尝试a href\javascript:alert(1)\Click/a大概率javascript:被过滤或置空。编码绕过对javascript:进行编码。注意这里编码需要在能被浏览器URL解码的上下文中生效。 一种方法是使用HTML实体编码冒号或部分字母jav#x61;script:alert(1)可能不行因为:是协议分隔符必须明文。 可以尝试对协议名整体进行UTF-16编码或其他形式的混淆但现代浏览器对javascript:协议的处理非常严格简单的编码可能无法正确识别。更可行的方法是结合事件处理器而不是依赖伪协议。6.2 利用iframe的srcdoc属性iframe srcdoc\img srcx onerroralert(1)\srcdoc属性允许内联HTML。如果过滤器只检查了主文档的输入而没有递归检查srcdoc内的内容那么内层的Payload可能被执行。并且我们可以对srcdoc值内的HTML进行二次编码。6.3 利用HTML5表单属性formaction或form此技巧更适用于存储型XSS或特定上下文某些表单相关的标签如button或input type\submit\具有formaction属性可以覆盖表单的提交地址为JavaScript伪协议。但这在反射型XSS且输入点不在表单内的场景下较难利用。6.4 编码的嵌套与多重编码有时一层编码可能被过滤器的解码层剥掉。我们可以尝试双重编码。 例如的HTML实体是。如果我们输入lt;服务器端过滤器如果只解码一次可能得到然后被其script过滤规则删除。但如果过滤器不解码lt;输出到浏览器浏览器会将其解码为。 对于事件处理器我们可以尝试img srcx #x6f;#x6e;#x65;#x72;#x72;#x6f;#x72;alert(1)这里将onerror每个字符都编码为十六进制HTML实体。这串字符对于字符串匹配的过滤器来说是完全陌生的。7. 常见问题、调试与高级绕过思路在实际操作中你可能会遇到各种意外情况。以下是一些常见问题及排查思路7.1 Payload提交后无任何反应查看源代码这是最重要的调试步骤CtrlU。看看你输入的Payload被服务器处理成了什么样子。是整体消失了还是被截断了属性值是否被加上了引号或转义了检查控制台打开浏览器的开发者工具F12查看Console面板。是否有JavaScript语法错误错误信息能精准定位Payload哪里出问题了。使用更简单的Payload先测试img srcx看标签是否能存活。再测试img srcx onerrorconsole.log(1)在控制台观察输出这比alert更隐蔽且不受弹窗拦截影响。7.2 事件被触发但代码未执行语法错误在编码时可能破坏了JavaScript语法。确保编码解码后的字符串是合法的JS。例如alert(1)被编码成al#x65;rt(1)浏览器解码后是alert(1)语法正确。但如果编码了括号如al#x65;rt#x28;1#x29;解码后是alert(1)也正确。关键在于整体语法在解码后必须正确。作用域问题在某些沙箱环境或srcdoc中alert函数可能不可用。尝试使用parent.alert或top.alert或者使用console.log证明代码执行。7.3 高级绕过思路如果上述均失效如果DVWA的High级别实现了非常严格的过滤例如使用DOM Purify、CSP或严格的HTML解析器白名单那么上述基于标签和事件的方法可能都会失效。这时你需要考虑基于DOM的XSS检查页面是否存在客户端JavaScript其不安全地操作了innerHTML、document.write或eval并且你的输入能影响其参数。这需要分析前端JS代码。滥用合法的HTML属性例如某些标签的style属性支持expression()旧版IE或现代浏览器的CSSurl()函数中执行JavaScript限制很多。或者link标签的href结合某些协议。字符集与编码混淆如果网站指定了特殊的字符集或者存在编码转换问题可能利用UTF-7等旧编码如ADw-scriptAD4-alert(1)ADw-/scriptAD4-但现代浏览器默认已不易受此攻击。注意事项在进行XSS测试时务必在授权环境下进行如自己的DVWA靶场。切勿对未授权的真实网站进行测试这是违法行为。本实战的所有技巧仅用于安全学习与研究旨在帮助开发者理解漏洞原理从而构建更安全的应用程序。8. 防御视角从攻击中学习如何防护通过这一系列的绕过尝试我们站在攻击者的角度深刻体会了过滤的难点。那么作为开发者应该如何有效防御这类攻击呢输出编码Output Encoding是黄金法则永远不要相信用户输入。根据数据输出的上下文HTML体、HTML属性、JavaScript、CSS、URL进行相应的编码。输出到HTML正文将 \ 等转换为HTML实体lt;,gt;,amp;,quot;,#x27;。输出到HTML属性值除了上述字符空格和换行也可能有问题建议使用引号包裹属性值并对引号进行编码。输出到JavaScript需进行Unicode转义如转为\u003c。使用成熟的库如OWASP ESAPI、Java的StringEscapeUtils Python的html.escape等来完成这项工作而不是自己写正则。使用内容安全策略CSPCSP是一个强大的深度防御工具。通过HTTP头Content-Security-Policy你可以告诉浏览器只允许执行来自特定来源的脚本禁止内联脚本unsafe-inline和eval。这能从根本上杜绝大部分XSS攻击包括我们上面使用的所有基于事件处理器和内联脚本的技巧。例如一个严格的CSP头可能是Content-Security-Policy: default-src self; script-src self。输入验证与规范化在接收输入时进行严格的类型、长度、格式检查。对于姓名框可以限制只允许字母、数字和少量符号。但记住输入验证是辅助不能替代输出编码。避免危险的DOM操作前端JavaScript避免使用.innerHTML、.outerHTML、document.write()直接插入未经验证的用户数据。优先使用.textContent或.setAttribute等安全的API。使用现代框架的安全特性如React、Vue、Angular等主流前端框架默认都会对渲染的数据进行转义在很大程度上自动防护了XSS。但开发者仍需注意避免使用dangerouslySetInnerHTMLReact或v-htmlVue等绕过安全机制的方法。回到DVWA High级别XSS它的过滤策略之所以能被绕过正是因为它只做了局部的、基于黑名单的删除而没有进行彻底的上下文相关输出编码。这给我们上了生动的一课安全防护必须全面、深入并且要紧跟技术发展如HTML5新特性带来的新攻击面。通过这种攻防实战我们不仅能学会“破”更能深刻理解如何“立”从而在开发中写出更安全的代码。
返回列表