Skip to content

Instantly share code, notes, and snippets.

@kassyi
Created March 4, 2026 15:45
Show Gist options
  • Select an option

  • Save kassyi/630d7c815cfa1cead48b2b85ee47d7e7 to your computer and use it in GitHub Desktop.

Select an option

Save kassyi/630d7c815cfa1cead48b2b85ee47d7e7 to your computer and use it in GitHub Desktop.
const bom = function() {
const d = document, w = window, M = Math, R = M.random;
const c = d.createElement('canvas'), ctx = c.getContext('2d');
c.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999;pointer-events:none';
d.body.appendChild(c);
const rs = () => { c.width = w.innerWidth; c.height = w.innerHeight; };
w.addEventListener('resize', rs); rs();
let pt = [], fl = [];
const ex = (x, y, s=1) => {
fl.push(s*.7);
for(let i=0; i<150*s; i++) {
let a = R()*M.PI*2, sp = R()*50*s;
pt.push({x, y, vx:M.cos(a)*sp, vy:M.sin(a)*sp, r:R()*5*s+2, c:R()>.8?'#fff':`hsl(${R()*50+10},100%,${R()*40+50}%)`, a:1, d:R()*.02+.005});
}
};
const els = Array.from(d.querySelectorAll('body *:not(script):not(style):not(canvas)'))
.filter(e => e.offsetWidth > 0).map(e => {
const r = e.getBoundingClientRect();
e.style.position='fixed'; e.style.left=r.left+'px'; e.style.top=r.top+'px'; e.style.width=r.width+'px'; e.style.margin='0'; e.style.zIndex='9998';
if(e.children.length) { e.style.background='transparent'; e.style.border='none'; e.style.boxShadow='none'; }
return {e, x:r.left, y:r.top, vx:(R()-.5)*15, vy:R()*-8, an:0, va:(R()-.5)*.3};
});
d.body.style.transition = 'background-color 2s';
d.body.style.backgroundColor = '#000';
let st = Date.now(), msgOn = 0;
const loop = () => {
let t = Date.now() - st;
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = 'rgba(255,255,255,.3)'; ctx.fillRect(0,0,c.width,c.height);
ctx.globalCompositeOperation = 'lighter';
fl.forEach(f => { if(f>0){ ctx.fillStyle=`rgba(255,255,255,${f})`; ctx.fillRect(0,0,c.width,c.height); }});
fl = fl.map(f => f-.05).filter(f => f>0);
pt.forEach(p => {
p.x+=p.vx; p.y+=p.vy; p.vy+=.8; p.vx*=.92; p.vy*=.95; p.a-=p.d;
ctx.globalAlpha = M.max(0, p.a); ctx.fillStyle = p.c;
ctx.beginPath(); ctx.arc(p.x, p.y, p.r, 0, M.PI*2); ctx.fill();
});
pt = pt.filter(p => p.a>0);
if(t > 500) {
els.forEach(p => {
p.x+=p.vx; p.y+=p.vy; p.vy+=.9; p.an+=p.va;
p.e.style.transform = `translate(${p.x-parseFloat(p.e.style.left)}px, ${p.y-parseFloat(p.e.style.top)}px) rotate(${p.an}rad)`;
if(p.y > w.innerHeight+500) p.e.style.display='none';
});
}
if(t > 2000 && !msgOn) {
const m = d.createElement('div');
// ご提示の教育的警告を組み込み、圧縮しつつスマホ対応
m.innerHTML = `<b style='color:#ffeb3b;font-size:12px;letter-spacing:1px'>⚠ SECURITY ALERT</b><br><span style='color:#f00;font-size:36px;font-weight:900;text-shadow:0 0 10px #f00'>HACKED!</span>
<p style='color:#0f0;font-family:monospace;font-size:clamp(11px,1.5vw,16px);margin:15px 0 0;font-weight:bold'>[VULNERABILITY DETECTED]: Reflected XSS</p>
<div style='text-align:left;background:rgba(255,0,0,.1);padding:12px;border-left:4px solid #f00;margin-top:15px;font-size:clamp(11px,1.2vw,14px);line-height:1.5'>
<p style='color:#fcc;margin:0 0 8px;font-weight:bold'>【教育的警告】スクリプト実行の具体的脅威:</p>
<ul style='color:#ddd;margin:0;padding-left:20px'>
<li style='margin-bottom:4px'><strong>セッションハイジャック:</strong> Cookieを盗みアカウント乗っ取り</li>
<li style='margin-bottom:4px'><strong>フィッシング詐欺:</strong> 偽画面等を表示し認証情報を窃取</li>
<li style='margin-bottom:4px'><strong>権限の不正操作:</strong> ブラウザを操り不正データ送信等</li>
<li><strong>マルウェア誘導:</strong> 危険なサイトへ強制リダイレクト</li>
</ul>
</div>
<p style='color:#888;font-size:clamp(10px,1vw,12px);margin:15px 0 0'>※脆弱性通知のためのPoCであり実害はありません。<br>入力値の適切なエスケープ等の速やかな修正を推奨します。</p>`;
// スマホでの縦幅オーバーを考慮し max-height: 85vh と overflow-y: auto を追加。max-width も少し広げて見やすく調整。
m.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);font-family:sans-serif;color:#fff;background:rgba(10,10,10,.95);padding:20px;border:2px solid #f00;z-index:10000;text-align:center;border-radius:8px;width:90%;max-width:420px;max-height:85vh;overflow-y:auto;box-shadow:0 0 30px rgba(255,0,0,.5)';
d.body.appendChild(m);
msgOn = 1;
}
requestAnimationFrame(loop);
};
ex(w.innerWidth*.5, w.innerHeight*.4, 2);
let ec = 0, ei = setInterval(() => {
ex(w.innerWidth*(.1+R()*.8), w.innerHeight*(.1+R()*.8), R()*.8+.4);
if(++ec > 15) clearInterval(ei);
}, 120);
loop();
};
setTimeout(bom, 3000); // 発火までの待機時間を1秒に短縮
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment