URL 变形记
url语法
通用语法<scheme>://<user>:<password>@<host>:<port>/<url-path>
,其中scheme包含http、ftp、gopher、file 等网络协议
漏洞条件
黑盒
- 单点登陆的服务器下,登陆请求会存在?service=xxx,若参数未作白名单过滤,可能导致url不安全跳转
- 出现类似ssrf的攻击情景,即加载外部资源时,加载的链接(url)可控
白盒
public class RedirectAction extends ActionSupport{
public String execute() throw Exception{
HttpServletRequest ServletActionContext.getRequest();
HttpServletResponse ServletActionContext.getResponse();
String url = request.getParameter("service");
if(url!=null && url.length()!=0){
response.sendRedirect(url);
return "success";
}else
return "fail";
}
}
可以看到url未作任何过滤
Bypass
url截断
分号
形如:
分号 http://xxx.xxxx.xxx/xxx/xx;lougout.jsp
分号 http://xxx.xxxx.xxx/xxx/xx;lougout.css
白盒demo
requestURL.endswith(“flag”)
// payload
http://ss.xx/xxx;flag
@号
形如:
利用@符号
http://xxx.xxx.xxx@xxxx.xxxx/xxx
利用@ (两个@在URI中无法到host部分从而进入错误分支)
http://@@xxx.xxx/xxx/xx
URI e = new URI(url)
StringUtils.isEmpty(e.getHost())
这个畸形url会导致e.getHost返回空
从而进入302分支(如果有的的话),而浏览器层会忽略多重@,直接解析xxx.xx玉米
#
井号
形如:
http://xxx.xxx.xxx#xxxx.xxxx/xxx
?问号
形如
http://xxx.xxx.xxx?xxxx.xxxx/xxx
\
反斜杠
形如
http://evil.com\@good.com ->(302跳转) ->浏览器解析为 http://evil.com/@good.com
编码绕过
url编码
假设原始访问URL为 http://www.xxx.com/training/sys.jsp
可以利用URL编码:http://www.xxx.com/training/%73%79%73%2e%6a%73%70
原理解释:由于经过过滤器或拦截器后、定位到所访问资源前,Web容器会自动进行一次URL解码,所以构造http://www.xxx.com/training/%73%79%73%2e%6a%73%70
可以访问到:http://www.xxx.com/training/sys.jsp
此外,部分url编码可用于绕过contains,endswith,startwith
base64编码
利用base64编码:http://www.xxxx.com/training/c3lzLmpzcA==
案例
Wooyun上找到的一个案例,腾讯网站任意URL跳转,请求的URL如下: http://websites.imqq.com/go/1004/aHR0cDovL3d3dy5ldmlsc2l0ZS5jbi8=/from/websites 待跳转的URL地址是:aHR0cDovL3d3dy5ldmlsc2l0ZS5jbi8=(base64解密后是 http://www.evilsite.cn/)
unicode编码
形如:
利用unicode编码:http://www.xxx.com.evilsite.cn\111.xxx.com@www.xxx.com/
利用unicode编码:http://evilsite.cn\u2100B.xxx.com/
利用unicode编码: http://www.vmall.com.evilsite.cn\111.vmall.com@www.vmall.com/
try{
URI myurl = new URI('http://www.vmall.com.evilsite.cn\111.vmall.com@www.vmall.com/');
System.out.println(myurl);
System.out.println(myurl.getHost());
if(myurl.getHost().equals("www.vmall.com")){
System.out.println("hi");
}
}catch(..){...}
当服务器中的解码器遇到大于ASCII范围的字符时,它将尝试使用Unicode编码对其进行 解码。解码过程有出现错误的情况
https://evil.com%ff@good.com
-> https://evil.com%ff@good.com
-> https://evil.com?@good.com
-> https://evil.com?@good.com
服务器返回302后,浏览器解析为问号
springSecurity
springSecurity的一些弱点
浅谈SpringSecurity与CVE-2023-22602 - 知乎 (zhihu.com)
payload是
/admin/..
/admin/abc%0a
/admin/abc%0a%0d
白名单配置有误
白名单未加入/
-
例1
比如说有个checkReferer
其中的一个白名单字符串systemurl是"https://xx.xxxx.com
", 正常应该在后面再加一个/
然后有个逻辑
String referer = httpServletRequest.getHeader(“Referer”)
return (Normalizer.normalize(referer, Normalizer.Form.NFKC).startsWith(systemUrl))
可以构造多级域名进行绕过,是的子域名referer满足systemUrl的校验,如
“https://xx.xxxxx.com.evilsite.cn/”
- 例2
白名单列表中,存在没有使用“/”闭合的域名→[“https://www.good.com”,“XXX”] 可构造URL:https://www.good.com@www.evilsite.cn,绕过白名单校验。实际访问的将 是https://www.evilsite.cn/,攻击者可利用此漏洞进行钓鱼、在WebView中调用java层开放接 口。
并且其用的是startsWith
缺少“.”闭合
- 例3
paramString.endsWith("palmebook.com")
攻击者只需要注册“evilsitezhangyue.cc”
- 例4
正则检验绕过 ,如果正则表达式某些字符未作转移的话可以导致正则校验绕过
URL白名单如果使用了正则表达式中的特殊字符($()*+.[?\^{|),且这些字符未做转义 的话(比如“.”用“\.”转义),可能导致正则校验绕过。
StringBuilder.append("([A-Za-z0-9.-]*\\.)").append(str2).append("|").append(str2);
预设URL白名单中的“https://app.vmall.com/”包含“.”,未做转义,由于“.”在正则表达式 中可以代表任意单个字符,所以攻击者可构造“https://appsvmall.com/”通过上述校验器校验。
二义性绕过
CVE-2017-13274
外部传入URL https://www.evilsite.cn\\www.good.com/training/sys.jsp 在服务端使用 getHost解析 取到Host部分是:www.evilsite.cn\www.good.com "www.good.com".endsWith("www.evilsite.cn\www.good.com") //通过 在浏览器侧实际 到达 https://www.evilsite.cn/www.good.com/training/sys.js
CVE-2017-13176
外部传入URL https://a:a@www.good.com:b@www.evilsite.cn/training/sys.jsp 在服务端使用 getHost解析 取到Host部分是:www.good.com "www.good.com".equal("www.good.com") //通过 在浏览器侧实际 到达 https://www.evilsite.cn/training/sys.jsp
推荐使用BrowserStack模拟各个版本的浏览器。假设redirect_uri=auth.app.com.evil.com, 绕过方式举例(能否成功与浏览器版本有关,以实际返回结果为准):
auth.app.com.evil.com
evil.com?auth.app.com
evil.com?@auth.app.com
auth.app.com@evil.com
auth.app.com\@evil.com
evil.com\auth.app.com
evil.com:\auth.app.com
evil.com\.auth.app.com
evil.com:\@auth.app.com
schema校验绕过
变形绕过
由于浏览器的特性,下述访问最终都会访问http://www.evilsite.cn
http:\//www.evilsite.cn
http:\\\//www.evilsite.cn
http:/\/www.evilsite.cn
http:/\\\/www.evilsite.cn
/\/evilsite.cn
http:www.evilsite.cn
大小写不统一
正常来说,必须要添加统一大小写的操作,如果没有都可以尝试大小写绕过
schema替换/添加
String url= "evilsite.cn://good.com/attack.html";
String urlHost = Uri.parse(url).getHost();
String urlScheme = Uri.parse(url).getScheme();
try{
if(urlHost.equals("good.com")){
if(!urlScheme.startsWith("http")){
url = "https://" + url;
loadUrl(url);
}
}
}
如上图,WebView白名单校验函数中,外部传入url通过预设白名单校验(第5行)。为 防止http传输,统一在loadUrl之前判断追加“https://”。最终到达的地址是https://evilsite.cn/。
没有校验schema
可以用各种各样的伪协议进行绕过
JavaScript://www.xxx/%0a%0dalert(1)
file://xxx.xxx.
http://