Url跳转新思路

情景

image-20250729180611472

https://domain/qy/oa/login/callback?from=/h5/#/boc/beijing/shebaoka

Location:https://domain/h5/#/boc/beijing/shebaoka

follow一下跳转,下一次会请求

https://domain/h5/

这里的from参数的值改为@baidu.com时

https://domain/qy/oa/login/callback?from=@baidu.com

Location: https://domian@baidu.com

在follow一下跳转,发现成功跳转到了baidu

image-20250729181020567

为什么payload要这么构造呢?(为什么使用@)

分析

该payload的写法和URL的底层结构有关,回顾一下URL的底层结构

protocol://[[user[:password]@]host[:port]][/path][?query][#fragment]
[协议名]://[用户名]:[密码]@[主机名]:[端口]/[路径]?[查询参数]#[片段ID]

image-20250729182222863

最完整的Url组成,也就是最底层的逻辑,URL中包含了用户名和密码,@,以及我们熟知的host

而我们大多数见到的

http://www.baidu.com/error.html

都是省略了用户名,密码以及@符号,都是 protocol://host/....

而当我们构造payload:https://domain/qy/oa/login/callback?from=@baidu.com

Location变成https://domian@baidu.com,而此时,由于URL底层的逻辑,浏览器会把原来的host,当做URL中的用户名和密码,也就是说,会把http://和@中间的内容(原来的host)不考虑,从而将@后面的baidu.com当做host;所以,当我们再次follow一下,就会变成请求https://baidu.com

我们直接在浏览器访问https://domian@baidu.com,浏览器也会自动将@后面的识别为host

image-20250729183100125

问:当我们将payload写为https://domain/qy/oa/login/callback?from=/h5/#/boc/beijing/shebaoka@baidu.com,还会跳转到baidu吗?

答:当我们将payload写为https://domain/qy/oa/login/callback?from=/h5/#/boc/beijing/shebaoka@baidu.com,此时网站302的Location就会变为

Location: https://domain/h5/#/boc/beijing/shebaoka@baidu.com

而这个URL,因为https://与@符号中间存在/,所以并不会将domain/h5/#/boc/beijing/shebaoka部分当做用户名和密码,而是将后面的当做一个整体(请求路径),因此这样就无法触发URL跳转

总结

当响应中的Location可控,并且Location中是以https://开头的(网站策略没有固定域),并且在我们可控的参数之前没有/符号,我们就可以利用@绕过原来的host

此外,SSRF同理,请求外部地址,也可以用@进行绕过原始域

修复

  1. 固定跳转的域(我们渗透中也很常见其他站的跳转,响应中的Location不是以https://开头的,而是直接以路径开头,这是网站已经固定了跳转的域)
  2. 对传参进行过滤,对@符号过滤(和常规URL跳转的防御思路相同)