YYMusic项目渗透测试

可疑漏洞

  1. 请求伪造
  2. CSRF

请求伪造

  • 抓包分析参数
1
{"keyword":"%E9%9D%92%E8%8A%B1%E7%93%B7","platform":"wyy","ky":"47edd1412c16e01a","pk":"IFOBGd%2BakUwzpu1z2aQVuqMJqfCawZHsbhcaG11yOmlFQFhp5EfhIWZ3paxWcZqhllI%2BkcbYJYT1zPwO3191zA%3D%3D","verify":"QJJcFb8IEqZjLdOq5ClClS9IWx6r47TEtyHrim276Kl3bzXE0jotR07synIAnmcaptQIETCqfC%2BrRESFN6qhJA%3D%3D","ymy":"66g9GkeCJLKqO2fnTV99yM003f%2FIeJNGz8Mei7kWM9n4tX%2BOBi4KdckfeVWYNgJ6Yw5aLTq%2Fy04sd8s9yfAiCtDqOKqai7EkaEr1msMcoS21Mb0YmBPWqTIlOdhLypb6U4iV1HIH8COXnP5U1IK1SEtEJkVMDtrZHGds9QkH5FLDWECQHk1FW7lGTvjJ105SM456FQ30auIRE7pqmx4%2BeQ%3D%3D","m":"f997e5c515b9b55e4190d0d4a353314c|1677985213000"}
  • 代码审计分析
    登录用户 mdtest2 会生成一个 mdtest2.html 页面。

mdtest2.html

1
2
3
4
5
6
7
8
9
var data = {
"keyword": encodeURIComponent(form__input.value),
"platform": get_platform(),
"ky":window.kky,
"pk":encodeURIComponent(asrr()),
"verify":encodeURIComponent(verify),
"ymy":encodeURIComponent(window.ymy),
"m":window.mm(),
}

(1)keyword:对输入框输入的歌曲进行 url 编码
(2)platform:歌曲获取的来源(wyy、kw、qq),这个在之后的代码中写看到,不过也很容易根据取名猜出来。
(3)ky:抓同一个用户多个包分析后,发现 ky 每次都一样。
(4)pk:每次都不一样,应该是进行了某种加密处理。
(5)verify:每次都一样。
(6)ymy:每次都不一样,应该是进行了某种加密处理。
(7)m:每次都不一样,应该是进行了某种加密处理。
所以主要集中对 pk,ymy,m 三个参数进行研究。

pk 参数

“pk”:encodeURIComponent(asrr())
所以我们进入 asrr () 进行查看
进入了 rsa.js 文件
发现这应该是引用了别人写好的 js 包,采用 rsa 加密

1
2
3
4
5
6
7
8
9
10
function asrr() {
plain_text=window.kky;
var public_modulus = "b32e685b13983b6e84fe62c8e062aa167210b8b2a237fa010425cdc65180cb7a9168faf609ed24e5266f9bd04d383c7b2746223eb3bda399521ad21e56bbecff";
var public_exponent = "10001";
var Crypt = new asr.JSEncrypt();
Crypt.setPublic(public_modulus, public_exponent);
Crypt.setPublicKey({"n": Crypt.n, "e": Crypt.e});
var enc_str = Crypt.public_encryptLong(plain_text, 2, true);
return enc_str;
}

并且 "ky":window.kky,所以 ky 就是明文,既然每次明文都一样,根据 rsa 加密验证原理,我们不更改 pk 参数值,传回后端解密的密文也可以一致!
ps:可以抓两个包,只更改 ky 参数试一试,也可以成功返回数据包。

ymy 参数

这应该是这里面最难分析的一个参数了。
找遍整个前端也没看见 ymy,之后偶然进入控制台输出 eval (window.xmy),发现进入了一个函数,进入这个函数发现

1
2
3
window.ymy=p(w)
var w={ts:(new Date).getTime(),cts:(new Date).getTime(),brVD:d(),brR:l(),aM:h(),code:""};
var p=function(e){v(e);e.cts=(new Date).getTime();

然后这个函数参数就一层一层套下去了,这代码还真不好看懂,那就默认应该是可以利用这个 SE.js 生成的。
后续又进行了简单验证,发现还需要向服务器发一下请求获取当前 cookie,生成的 ymy 才有作用,否则会显示重新登录。

m 参数

登录用户 mdtest2 会生成一个 mdtest2.html 页面。
前几行直接用 script 引入一个很大的内容,里面就算生成 m 参数,简单了解了一下,发现是时间戳。
那也解决了,我们可以引入这个包也可以生成对应的 m 参数值。

poc 构造

访问量 访客