从XSS Payload学习浏览器解码

2023-11-20

从XSS Payload学习浏览器解码


作为一个浏览器在解析一篇HTML文档时主要有三个处理过程,每个解析器负责解码和解析HTML文档中它所对应的部分,下面我将按照解码顺序依次讲解。

  1. HTMl解析
  2. URL解析
  3. JavaScript解析

HTML解析

一个HTML解析器作为一个状态机,它从输入流中获取字符并按照转换规则转换到另一种状态。在解析过程中,任何时候它只要遇到一个’<‘符号(后面没有跟’/'符号)就会进入“标签开始状态(Tag open state)”。然后转变到“标签名状态(Tag name state)”,“前属性名状态(before attribute name state)”…最后进入“数据状态(Data state)”并释放当前标签的token。当解析器处于“数据状态(Data state)”时,它会继续解析,每当发现一个完整的标签,就会释放出一个token。

用代码表示如下

存在<h1>hhhhhhhh</h1> 
首先状态机吃下< 进入标签开始状态然后转变到标签名状态开始匹配标签

当吃进去/>标签的时候进入标签结束状态然后进入Data state状态

字符实体
字符实体是一个转义序列,它定义了一般无法在文本内容中输入的单个字符或符号。一个字符实体以一个&符号开始,后面跟着一个预定义的实体的名称,或是一个#符号以及字符的十进制数字。

HTML字符实体
在HTML中,某些字符是预留的。例如在HTML中不能使用“<”或“>”,这是因为浏览器可能误认为它们是标签的开始或结束。如果希望正确地显示预留字符,就需要在HTML中使用对应的字符实体。一个HTML字符实体描述如下:

字符引用
字符引用包括“字符值引用”和“字符实体引用”。在上述HTML例子中,‘<‘对应的字符值引用为’&#60’,对应的字符实体引用为‘&lt’。字符实体引用也被叫做“实体引用”或“实体”。)

现在你大概会明白为什么我们要转义“<”、“>”、“'” (单引号)和“"” (双引号)字符了。

这里要提一下RCDATA的概念。要了解什么是RCDATA,我们先要了解另一个概念。在HTML中有五类元素:

  1. 空元素(Void elements),如<area>,<br>,<base>等等

  2. 原始文本元素(Raw text elements),有<script>和<style>

  3. RCDATA元素(RCDATA elements),有<textarea>和<title>

  4. 外部元素(Foreign elements),例如MathML命名空间或者SVG命名空间的元素

  5. 基本元素(Normal elements),即除了以上4种元素以外的元素

五类元素的区别如下:

  1. 空元素,不能容纳任何内容(因为它们没有闭合标签,没有内容能够放在开始标签和闭合标签中间)。

  2. 原始文本元素,可以容纳文本

  3. RCDATA元素,可以容纳文本和字符引用

  4. 外部元素,可以容纳文本、字符引用、CDATA段、其他元素和注释

  5. 基本元素,可以容纳文本、字符引用、其他元素和注释

如果我们回头看HTML解析器的规则,其中有一种可以容纳字符引用的情况是“RCDATA状态中的字符引用”。这意味着在<textarea>和<title>标签中的字符引用会被HTML解析器解码。这里要再提醒一次,在解析这些字符引用的过程中不会进入“标签开始状态”。,所以只能对HTML编码进行解码打印出文本,但不会执行解码后相应的字符引用。

另外,对RCDATA有个特殊的情况。在浏览器解析RCDATA元素的过程中,解析器会进入“RCDATA状态”。在这个状态中,如果遇到“<”字符,它会转换到“RCDATA小于号状态”。如果“<”字符后没有紧跟着“/”和对应的标签名,解析器会转换回“RCDATA状态”。这意味着在RCDATA元素标签的内容中(例如<textarea>或<title>的内容中),唯一能够被解析器认做是标签的就是“</textarea>”或者“</title>”。
因此,在“<textarea>”和“<title>”的内容中不会创建标签,就不会有脚本能够执行。

URL解析

URL的协议部分必须为ASCII字符,否则URL解析器的状态机将进入No Scheme状态
例如:

<a href="%6a%61%76%61%73%63%72%69%70%74:alert(1)"></a>
url编码部分为javascript,因为作为协议部分的"javascript"被编码,故不会触发JS

你不能对协议类型进行任何的编码操作,不然URL解析器会认为它无类型,该原则对协议后面的“:”(冒号)同样适用

<a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:%61%6c%65%72%74%28%32%29">
当HTML解析器工作完成后,URL解析器开始解析href属性值里的链接。
在这时,“javascript”协议已经被解码,它能够被URL解析器正确识别。
然后URL解析器继续解析链接剩下的部分。
由于是“javascript”协议,JavaScript解析器开始工作并执行这段代码。
这就是为什么代码能够被执行的原因。

其次,URL编码过程使用UTF-8编码类型来编码每一个字符。如果你尝试着将URL链接做了其他编码类型的编码,URL解析器就可能不会正确识别。

JavaScript解析

像\uXXXX一样的字符被称作Unicode转义序列。从上下文来看,你可以将转义序列放在3个部分:字符串中,标识符名称中和控制字符中。JavaScript能否解析这些字符来执行需要根据视情况而定。具体的说就是要看被编码的序列到底是哪部分。

字符串中:当Unicode转义序列存在于字符串中时,它只会被解释为正规字符,而不是单引号,双引号或者换行符这些能够打破字符串上下文的字符。因此,Unicode转义序列将永远不会破环字符串上下文,因为它们只能被解释成字符串常量。
例如:

<script>alert(“\u0031”);</script>
被编码的为1且是字符串,可以正常解码并触发执行

标识符名称中:当Unicode转义序列出现在标识符名称中时,它会被解码并解释为标识符名称的一部分,例如函数名,属性名等等。
例如:

<script>\u0061\u006c\u0065\u0072\u0074(1);</script>
被编码的部分为alert字符,是函数名,属于在标识符中的情况,因此会被正常解码并执行JS

控制字符:当用Unicode转义序列来表示一个控制字符时,例如单引号、双引号、圆括号等等,它们将不会被解释成控制字符,而仅仅被解码并解析为标识符名称或者字符串常量。如果你去看ECMAScript的语法,就会发现没有一处会用Unicode转义序列来当作控制字符。例如,如果解析器正在解析一个函数调用语句,圆括号部分必须为“(”和“)”,而不能是\u0028和\u0029。
例如:

<script>alert\u0028″xss”);</script>
\u0028会被解码为( 但是不会触发JS,因为是控制符

总的来说,Unicode转义序列只有在标识符名称里不被当作字符串,也只有在标识符名称里的编码字符能够被正常的解析。

案例解析

下面我将通过15个案例来复习上述所讲的内容

1.<a href="%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29">aaa</a>

无法弹窗,不能对协议类型进行任何的编码操作,不然URL解析器会认为它无类型(即被编码的javascript:),所以导致解码失败,不会被执行。

2.<a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:%61%6c%65%72%74%28%32%29">

先HTML解码,得到

<a href="javascript:%61%6c%65%72%74%28%32%29">

href中为URL,URL模块可识别为javascript协议,进行URL解码,得到

<a href="javascript:alert(2)">

由于是javascript协议,解码完给JS模块处理,于是被执行

3.<a href="javascript%3aalert(3)"></a>

和第一题一样url编码不能编码协议,所以导致解码失败,不会被执行。

4.<div>&#60;img src=x onerror=alert(4)&#62;</div>

<img src=x onerror=alert(4)>

从HTML解析机制看,在读取<div>之后进入数据状态,<会被HTML解码,但不会进入标签开始状态,只是将<文本打印出来,所以就不会创建img元素,也就不会执行。

5.<textarea>&#60;script&#62;alert(5)&#60;/script&#62;</textarea>

因为在RCDATA元素中唯一能够被解析器认做是标签的就是“</textarea>”或者“</title>”。所有其他的元素都会将当成文本直接打印,不会执行。

6.<textarea><script>alert(6)</script></textarea>

和第五题一样所有其他的元素都会将当成文本直接打印,不会执行。

7.<button onclick="confirm('7&#39;);">Button</button>

这里onclick中为标签的属性值(类比2中的href),会被HTML解码,得到
<button onclick="confirm('7');">Button</button>
所以可以直接执行

8.<button onclick="confirm('8\u0027);">Button</button>

因为在JS中unicode解析只能解析字符串和标识符,而单引号双引号圆括号这些会影响字符串上下文的符号将不能被unicode编码。而这一题编码的是单引号,所以JS执行失败。

9.<script>&#97;&#108;&#101;&#114;&#116&#40;&#57;&#41;&#59</script>

因为<script>属于原始文本元素(Raw text elements),只可以容纳文本,注意没有字符引用,所以直接由JS处理,JS也认不出来,执行失败。

10.<script>\u0061\u006c\u0065\u0072\u0074(10);</script>

因为没有编码符号,函数名alert属于标识符,所以直接将unicode编码直接解码,顺利被JS执行。

11.<script>\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029</script>

由于编码了圆括号,所以导致JS执行失败。

12.<script>\u0061\u006c\u0065\u0072\u0074(\u0031\u0032)</script>

这里看似将没毛病,但是这里\u0031\u0032在解码的时候会被解码为字符串12,注意是字符串,不是数字,文字显然是需要引号的,JS执行失败

13.<script>alert('13\u0027)</script>

和第八题一样,JSunicode编码不能编码符号。

14.<script>alert('14\u000a')</script>

因为\u000a在JavaScript里是换行,就是\n,所以代码会直接执行,但不会打破字符串上下文,所以正常执行JS代码。

15.<a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x33;&#x31;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x36;&#x33;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x33;&#x35;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x37;&#x25;&#x33;&#x32;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x37;&#x25;&#x33;&#x34;&#x28;&#x31;&#x35;&#x29;"></a>

先HTML解码,得到

<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)"></a>

在href中由URL模块处理,解码得到

javascript:\u0061\u006c\u0065\u0072\u0074(15)

识别JS协议,然后由JS模块处理,解码得到

javascript:alert(15)

最后被正常执行

总结

  1. <script><style>数据只能有文本,不会有HTML解码和URL解码操作
  2. <textarea><title>里会有HTML解码操作,但不会有子元素
  3. 其他元素数据(如div)和元素属性数据(如href)中会有HTML解码操作
  4. 部分属性(如href)会有URL解码操作,但URL中的协议需为ASCII
  5. JavaScript会对字符串和标识符Unicode解码

根据浏览器的自动解码,反向构造 XSS Payload 即可

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从XSS Payload学习浏览器解码 的相关文章

  • 无法显示由 Fine-uploader 上传到 Amazon s3 的图像

    我现在尝试设置fineuploader s3以显示在aws服务器上成功上传的文件的图像 如示例页面上所做的那样 http fineuploader com s3 demo http fineuploader com s3 demo 我 仍然
  • HTMLImageElement 作为 React Child 无效

    我正在尝试异步加载图像 并且仅在加载图像后才将其显示在 React 应用程序中 componentDidMount const img new Image img onload gt this setState originalImage
  • jQuery 中的 Javascript .files[0] 属性

    jQuery 中是否有与此语句等效的语句 var value document getElementById id files 0 使用附加 files 0 的标准 jQuery 选择器似乎不起作用 并且我找不到与 files 等效的 jQ
  • 如何使用键盘和鼠标控制相机 - Three.js

    我在 WEB GL 中有一个带有 Three js 的 3D 环境 并且我曾经使用 Orbitcontrols js http codepen io nireno pen cAoGI http codepen io nireno pen c
  • ant-d upload中如何为removeFile添加PopConfirm一个图片文件

    我正在使用 Ant d Upload 通过本地系统上传文件 然后单击文件预览图像上的删除图标 图像文件将被删除 我想添加一个弹出确认 所以我尝试在 onRemovefunction 中添加确认作为承诺但它不起作用 它在浏览器中显示警报 on
  • 将一个文本框的内容复制到另一个文本框

    假设在文本框中输入了一个条目 是否可以在第二个文本框中保留相同的输入文本 如果是这样 这是如何完成的
  • 在 BIRT 中输入参数后更新数据集查询

    在 BIRT 报告设计中传递参数后 如何更改或更新数据集的查询 详细说明 我有一个如下所示的查询 WHERE 该参数标记可以保存不同的值 在用户输入参数后 它看起来像这样 例如 WHERE column name 1 or WHERE co
  • 将 jquery-mobile 与 Webpack 结合使用

    我正在尝试使用 webpack 加载 jquery mobile 但到目前为止还没有运气 我知道 jquery mobile 依赖于 jquery ui 而 jquery ui 又依赖于 jquery 如何在 Webpack 中设置这样的场
  • 未捕获的引用错误:myFunction 未定义[重复]

    这个问题在这里已经有答案了 这到底是怎么回事 http jsfiddle net sVT54 http jsfiddle net sVT54
  • 禁用 JavaScript 中的右键单击

    当我尝试禁用右键单击时 它不起作用 我尝试使用下面的代码 document onclick function e console log e button if e button 2 e preventDefault return fals
  • Ember.JS - 如何在同一页面中使用多个模型、控制器和视图?

    我主要了解 Ember JS 的基础知识 大多数示例实际上只处理单个控制器和模型以在页面上显示某些内容 我真的很想用 Ember 构建一个完整的 Web 应用程序 所以有人能告诉我如何组织和连接多个控制器 模型和视图到一个页面中吗 例如 如
  • 保存/导出Chrome的JavaScript控制台输入历史记录

    无论如何 我可以保存或导出 JavaScript 控制台的历史记录吗 input 控制台历史记录 在 Google Chrome 中 我不想保存输出或错误 因此将鼠标悬停在控制台框上 右键单击并选择Save as 不是解决方案 我不想每次都
  • 使react-leaflet能够离线使用

    我一直在使用反应传单 https github com PaulLeCam react leaflet图书馆 到目前为止运作良好 现在我希望网站预加载尽可能多的图块 以便网络应用程序 也是 PWA 可以在没有互联网的情况下使用 我找到了一些
  • 使水平滚动条始终可见,即使底部不在视图中

    我将用一个片段来开始这个问题 该片段几乎显示了我想要完成的任务 wrapper overflow hidden display flex sidebar min width 200px background 333 color FFF co
  • 选中复选框时提交表单

    有没有办法在选中复选框时提交表单
  • 如何将 Browserify 与外部依赖项一起使用?

    我正在尝试慢慢地将 Browserify 引入我的网站 但我不想重写所有 js 也不希望 jquery 和其他库的重复实例与我的 Browserify 版本捆绑在一起 如果我构建将 jquery 列为外部依赖项的模块 那么如何将其指向我的全
  • 如何在网页上实现文件上传进度条?

    当用户将文件上传到我的网络应用程序时 我想显示比动画 gif 更有意义的内容 我还有哪些可能性 编辑 我正在使用 Net 但我不介意是否有人向我展示与平台无关的版本 如果您对这一切在客户端通常如何工作感兴趣 就是这样 所有解决方案都通过 J
  • ng-model 和值组合不适用于输入文本框

    我有两个输入文本框 我需要组合在两个文本框中输入的值并将其显示在第三个文本框中 如果我只使用value在第三个文本框中 Box 1
  • React Native - 跨屏幕传递数据

    我遇到了一些麻烦react native应用程序 我不知道如何跨屏幕传递数据 我意识到还有其他类似的问题在 SO 上得到了回答 但是这些解决方案对我来说不起作用 我正在使用StackNavigator 这是我的设置App js file e
  • 如何在 SVG 元素上使用箭头标记?

    我需要在 d3 js 中创建一个箭头 但我找到的只是带有节点图的示例 我需要的是简单地制作一个从 A 点到 B 点的箭头 我尝试实现以下示例中的部分代码 http bl ocks org 1153292 http bl ocks org 1

随机推荐

  • 《剑指offer》系列---2

    1 求斐波那契数列的第N项 这个题目很简单 讲递归的书上都是用这个来讲的 但是面试的时候 如果你写个递归 那估计会让人失望的 因为递归的效率真是一个问题 你可以测试一下 输入50 基本上得到结果的时间 够你去喝杯茶了 include
  • 端口开放,ubuntu开放指定端口 包括TCP UDP

    netstat nupl UDP类型的端口 netstat ntpl TCP类型的端口 a 表示所有 n 表示不查询dns t 表示tcp协议 u 表示udp协议 p 表示查询占用的程序 l 表示查询正在监听的程序 在ubuntu下面开放端
  • Echarts出现图表被压缩到很窄的情况的解决方法

    图表被压缩到很窄 可能是因为JSs执行太快 CSS来不及渲染 导致canvas只有默认的宽度 可以使用setTimeout 延迟加载JS
  • SpringSecurity+vue实现前后端分离实现登录注册退出

    前提 需要有springSecurity mybatis plus vue redis等知识 对springSecurity执行流程有点了解 需要代码可评论获取 首先先创建vue项目 创建好之后 下载axios element ui 将其目
  • Sqlilabs Less-26

    判断是单引号字符注入 id 1 当接下来进行操作时会发现很多被注释掉了 查看源码黑名单过滤了很多 or and 空格等等 function blacklist id id preg replace or i id strip out OR
  • 【无标题】记录一次external在vue项目的配置

    module exports publicPath chainWebpack config gt if process env NODE ENV production config plugin webpack bundle analyze
  • 在windows系统下使用IDEA对kafka源码进行编译环境搭建以及配置

    目录 一 前期准备工作 step1 安装JDK1 8 step2 安装zookeeper单机版 step3 安装Gradle 5 4 step4 安装scala 2 11 12 二 将kafka源代码部署到编辑器IDEA并测试 step1
  • java中map的使用,及底层源码

    java util Map public interface Map
  • python运行不显示结果图示_pycharm运行和调试不显示结果的解决方法

    刚在虚拟机里面安装了pycharm 配置 setting 完后 新建一个py文件 键入 hello world 竟然没有结果 虽然运行成功 pycharm太不友好了吧 然后开始找问题 1 有人说是文件名的问题 这个可能有 但是我没有改 我觉
  • CAD 4种反应器

    CAD中4种反应器 按照执行的先后顺序分别为 文档反应器 编辑器反应器 数据库反应器 文档反应器当用户输入命令和命令结束之时 文档反应器函数documentLockModeChanged XXXXX const char pGlobalCm
  • Linux中设置开机启动脚本(fedora)

    rc是runlevel control directory的缩写 大多数的Linux 发行版本中 启动脚本都被放在 etc rc d init d 这些脚本被ln 命令来连接到 etc rc d rcn d 目录 这里的n 就是运行级0 6
  • AES加密及解密

    public class AesUtil static Security addProvider new BouncyCastleProvider private static final String ALGORITHM AES ECB
  • tensorflow运行报错解决方法

    1 ImportError DLL load failed 找不到指定的模块 解决方法 把TensorFlow卸载了重新安装 可能是因为版本不对应的问题 在anaconda里面删除TensorFlow库 再重新安装回去 2 keras报错
  • 旧电脑再利用:完整版 Chrome OS 安装指南

    很多人家里应该都有用了好几年 配置略微有些老旧的笔记本或台式电脑 如果不考虑二手变卖 为它们安装更加轻量的操作系统其实也是一个不错的旧物利用技巧 此前我曾经为大家介绍过在普通 PC 安装 Fyde OS 的方法 虽然无论是 Fyde OS
  • 联想E540笔记本电脑拆键盘、换键盘

    我的联想ThinkPad E540键盘坏了几个按键 按下去没有反应 在京东第三方买了一个新的原装键盘 自己把它给换上去 下图中 几个涂红色的按键是坏的 编程的时候特别不方便 第一步 在电脑背面卸掉几个螺丝 因为键盘上也有螺丝 刚开始我卸的螺
  • 分享16个Python接单平台,做私活他不香吗?(附100个爬虫源码)

    一 python爬虫是可以做副业的 主要是爬取网站 小程序或者APP的数据 对数据进行分析与处理 或者直接向客户提供爬虫程序与技术支持 当初学会Python那会儿 有朋友来介绍我去接私活 是为一家公司做网站 那一单我赚了3 5K 从那之后逐
  • 零基础学python-1.2 什么是idle

    下面是摘自百度百科 IDLE是开发python程序的基本IDE 集成开发环境 具备基本的IDE的功能 是非商业Python开发的不错的选择 当安装好python以后 IDLE就自动安装好了 不需要另外去找 同时 使用Eclipse这个强大的
  • ❤ 高德地图报错 AMap.ElasticMarker is not a constructor

    高德地图报错 AMap ElasticMarker is not a constructor 原因 未定义高德的插件 解决 出现这个报错可以添加 AMap plugin AMap Geocoder function tip 出现 xxx i
  • Git clone 时 出现SSL certificate problem error

    出现这个问题的原因是本地默认开启了SSL认证 但是在本地找不到SSL证书 解决办法就是关掉 SLL认证 git clone 时加上参数 no ssl check 完整的命令应该是 git clone no ssl check https g
  • 从XSS Payload学习浏览器解码

    从XSS Payload学习浏览器解码 HTML解析 URL解析 JavaScript解析 案例解析 总结 作为一个浏览器在解析一篇HTML文档时主要有三个处理过程 每个解析器负责解码和解析HTML文档中它所对应的部分 下面我将按照解码顺序