# XSS 跨站脚本介绍

跨站脚本攻击(Cross Site Scripting)是指攻击者利用网站程序对用户输入过滤不足,输入可以显示在页面上对其他用户(普通用户、第三方用户、网站拥有者)造成影响的 HTML+Js 代码,从而盗取用户资料利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。

为了与层叠样式表(Cascading Style Sheets)的缩写 CSS 区分开,跨站脚本攻击通常简写为 XSS

image-20221004202321913

# 反射型 XSS

发射型就是将应用程序的运行结果或错误返回到页面上显示。典型的反射型 XSS 是在搜索框里体现。

# 存储型 XSS

存储在服务器、数据库(后台)上,能稳定持久执行的跨站脚本。

# DOM 型 XSS

能够构成 HTML 的 DOM 树的一部分,或者能够影响 DOM 结构的跨站脚本。

# XSS 攻击方式与样例

# XSS 盗用用户信息

# XSS 盗取 Cookie

# XSS 钓鱼攻击

链接上含有攻击代码

# XSS 蠕虫攻击

XSS 蠕虫的破坏力和影响力都是巨大的。XSS 蠕虫主要发生在用户之间存在交互行为的页面中,当 Web 引用程序对用户输入的数据信息没有做严格的过滤时,通过结合用户的登录状态、API 调用、 Ajax的异步提交 ,就可以实现在植入恶意代码的同时,将恶意代码进行对外发送,即实现了代码的感染和传播,也就形成了 XSS 蠕虫。

MySpace 的 Samy XSS 蠕虫攻击事件是出现最早、最出名的 XSS 蠕虫攻击事件。

# 通过实验深入了解 XSS 三个分类

首先我们安装 DVWA,使用账号:admin,密码:password 进行登录

注意 :如果登录不上去,就访问 127.0.0.1/dvwa/setup.php ,点击最下方的 Create/Reset 按钮

image-20221004210441095

设置 DVWA Security【从最低难度 low 开始吧】,点击 submit 等待刷新设置完成

image-20221004210537809

# DOM 型 XSS

image-20221004210944194

首先我们看到下拉框,就要想一想,这个下拉框是从哪里来的。

我们可以 F12 刷新,看一下 XHR 请求【Ajax】

这里讲一下 XHRAJax 的关系

  • XMLHttpRequest (简称 XHR )对象用于和服务器交换数据,是基于 XMLHTTP 请求。
  • XMLHttpRequest 是一个浏览器接口,使得 Javascript 可以进行 HTTP(S) 通信。
  • 自从浏览器提供有了 XMLHTTPRequest 这个接口之后,Ajax 操作就此诞生。
  • 我们再来说说什么是 AjaxAjaxAsynchronous JavaScript and XML ,翻译为: 异步JavaScript XML 。【重点!!
  • Ajax 就是基于浏览器提供的 XMLHttpRequest 对象来实现的。【重点!!

传统的网页(不使用 Ajax)如果需要更新内容,必需重载整个网页面。

自从有了 Ajax 之后,我们就可以实现异步地加载网页

什么叫异步?

异步,异嘛,不同的意思,这里也就是指 不跟 浏览器加载执行网页代码的 步伐 一致,也就是说在一个网页中 需要用户操作来触发执行代码 ,而不是整个网页代码 一次性执行完毕 (这里的用户操作是指在同一个网页下面请求代码执行渲染,而不是让浏览器直接跳转渲染另一个页面)。

Ajax 指的是异步 JavaScript 和 XML(Asynchronous JavaScript and XML)。所以,XMLHttpRequest 对象如果要用于 Ajax 的话,其 open () 方法的 async 参数必须设置为 true。

xmlhttp.open("GET","ajax_test.html",true);

image-20221004211458850

所以表明,这个页面没有单独去请求一个功能链接来返回下拉链表内容。

因此,我们直接去看源代码,鼠标右键,查看源代码【XSS 攻击是基于前台源码的攻击】。

搜索关键字符:

image-20221004213743525

对于 HTML 的标签基本定义如下

<div> 标签定义 HTML 文档中的一个分隔区块或者一个区域部分。
<div>标签常用于组合块级元素,以便通过 CSS 来对这些元素进行格式化。
<p> 标签用于定义一个段落。 段落和段落之间有空隙。

<form> 标签用于创建供用户输入的 HTML 表单。表单用于向服务端发送数据。
<form> 元素包含一个或多个如下的表单元素:
<input> 有输入框
<textarea> 标签定义多行的文本输入控件
<button> 提交按钮
<select> 有下拉菜单属性
<option> 单选框
<optgroup> 复选框
<fieldset> 标签将表单内容的一部分打包,生成一组相关表单的字段。
<label> 标签为 input 元素定义标注(标记)。

其中,源码中显示这个 form 标签里面嵌有一段 script 标签引起的 JavaScript 代码

<script>
if (document.location.href.indexOf("default=") >= 0) {
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
document.write("<option value='" + lang + "'>" + (lang) + "</option>");
document.write("<option value='' disabled='disabled'>----</option>");
}

document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");
</script>

主逻辑是:

获取当前 form 表单 document 的 location 对象的 href(当前浏览的 url 值,对于下图就是 http://127.0.0.1/DVWA/vulnerabilities/xss_d/

然后判断这个 url 字符串中 “default=” 第一次出现的位置是否 >=0

image-20221004215924339

当然,我们回到刚刚的页面上就是在获取这个 url

http://127.0.0.1/DVWA/vulnerabilities/xss_d/?default=English

image-20221004220400905

substring(start,stop)

然后截取从 “default=” 第一次出现的位置 + 8【也就是 = 号右边第一个字符,把整个 “default=” 跨了过去】到结尾的内容的字符串,保存到 lang 变量。

往 document,也就是当前 html 页面的 option 标签的 value 值中写入刚刚获取到的 lang 值,其选项显示部分使用 decoreURI 对 lang 进行解码,由于 English 中未含有非英文部分,所以就是 English。【这一步会往选项里再添加一个 English】

接着往当前 html 页面的 option 标签里的 value 写入空,且关闭其选择属性,加入 ---- 这个选项。【这一步会往选项里再添加一个 ----】

image-20221004221129050

那么,我们可以看到,这个 lang 是从当前 url 里获取到的,且未经过任何校验就直接写入标签中。

我们可以控制这个 lang 变量,使其直接执行 js 脚本

image-20221004221907384

http://127.0.0.1/DVWA/vulnerabilities/xss_d/?default=<script>alert(/xss/)</script>

image-20221004222113645

其改变了当前 HTML 的页面 DOM 结构,因此,我们称其为 DOM 型 XSS 攻击。

# 反射型 XSS

我们输入 11111,结果看到页面回显了 "Hello 11111"

image-20221004222654007

看一下前台代码,是使用 GET 请求去将获取 text 的内容发送给服务器,而 text 我们可控

image-20221004222954963

输入 11111,会回显到前台。

image-20221004223147315

那么,我们发现 11111 可能未经过处理,直接放入 pre 标签显示。

因此可以在 pre 标签里插入 script 标签,完成弹窗操作。

<script>alert(666)</script>

image-20221004223056096

因为这个页面将一些交互内容回显到了前台上,使得我们成功利用 Js 脚本完成攻击,我们称其为反射型 XSS 攻击。

# 存储型 XSS

image-20221004223720910

我们通过留言功能,可以看到我们的输入会被记录在页面上。

image-20221004223847678

我们按照刚刚的思路,直接尝试看看能否弹窗。

Name:jack
Message:<script>alert(1234)</script>

刷新回来后会一直弹窗

image-20221004224120560

我们看下源码信息

image-20221004224444379

我们看到 Name 的 maxlength 为 10,Message 的 length 为 50,所以使用 Message 来做 XSS 攻击更合适一些

<script>alert()</script>
最简短的js脚本也有24个字符

image-20221004224705526

如果两个长度都不限,则都适合用来 XSS 攻击。