bambi7-service-fireworx

ESDSA-signed firework A/D service for BambiCTF7 in 2022
git clone https://git.sinitax.com/sinitax/bambi7-service-fireworx
Log | Files | Refs | README | LICENSE | sfeed.txt

content.js (4586B)


      1
      2function launch(x, y) {
      3	var wish = prompt("Wish upon a firework?", "");
      4	if (wish === null) {
      5		wish = "";
      6	}
      7	var xhr = new XMLHttpRequest();
      8	var params = new URLSearchParams({x: x, y: y, wish: wish})
      9	xhr.open("POST", "/launch", true);
     10	xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
     11	xhr.onload = () => {
     12		if (xhr.status != 200) {
     13			alert("Launch failed: " + xhr.responseText);
     14		}
     15	}
     16	xhr.send(params.toString());
     17}
     18
     19function pow(beginsWith, min, max) {
     20	var time = new Date().getTime();
     21	for (var i = min; i < max; i++) {
     22		var hash = SparkMD5.hash(new String(i));
     23		if (hash.indexOf(beginsWith) === 0) {
     24			console.log(hash);
     25			return new String(i);
     26		}
     27	}
     28	return null;
     29}
     30
     31var generating = false;
     32function gen_privkey() {
     33	if (generating) return;
     34	generating = true;
     35
     36	var log = document.querySelector("p#errorlog")
     37	log.innerHTML = ""
     38
     39	prefix = document.getElementById("pow_prefix").content;
     40	console.log("POW prefix:", prefix)
     41	work = pow(prefix, 0, 10000000);
     42	if (work === null) {
     43		log.innerHTML = "Proof of Work failed, try again";
     44		generating = false;
     45		return;
     46	}
     47
     48	fetch("/genkey?pow_prefix=" + prefix + "&pow=" + work)
     49		.then(resp => resp.text())
     50		.then(data => {
     51			if (data[0] != "{") {
     52				log.innerHTML = "Generation failed:\n" + data;
     53				return;
     54			}
     55			data = JSON.parse(data);
     56			document.querySelector("input#p").value = data["p"]
     57			document.querySelector("input#q").value = data["q"]
     58			document.querySelector("input#g").value = data["g"]
     59			document.querySelector("input#x").value = data["x"]
     60			document.querySelector("input#y").value = data["y"]
     61		});
     62
     63	generating = false;
     64}
     65
     66function copy_privkey() {
     67	text = document.querySelector("input#name").value + "\n";
     68	text += document.querySelector("input#p").value + "\n";
     69	text += document.querySelector("input#q").value + "\n";
     70	text += document.querySelector("input#g").value + "\n";
     71	text += document.querySelector("input#x").value + "\n";
     72	text += document.querySelector("input#y").value + "\n";
     73	navigator.clipboard.writeText(text);
     74}
     75
     76function set_challenge() {
     77	fetch("/challenge").then(r => r.text()).then(text => {
     78		document.querySelector("input#challenge").value = text;
     79	})
     80}
     81
     82function do_login() {
     83	username = document.querySelector("input#username").value;
     84	challenge = document.querySelector("input#challenge").value;
     85	signature = document.querySelector("input#signature").value;
     86	var params = new URLSearchParams({
     87		username: username,
     88		challenge: challenge,
     89		signature: signature
     90	})
     91
     92	var log = document.querySelector("p#errorlog")
     93	log.innerHTML = ""
     94
     95	var xhr = new XMLHttpRequest();
     96	xhr.open("POST", "/login", true);
     97	xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
     98	xhr.onload = () => {
     99		if (xhr.status == 200) {
    100			window.location.replace("/");
    101		} else {
    102			log.innerHTML = xhr.responseText;
    103			set_challenge()
    104		}
    105	}
    106	xhr.send(params.toString());
    107}
    108
    109function do_register() {
    110	username = document.querySelector("input#username").value;
    111	p = document.querySelector("input#p").value;
    112	q = document.querySelector("input#q").value;
    113	g = document.querySelector("input#g").value;
    114	x = document.querySelector("input#x").value;
    115	y = document.querySelector("input#y").value;
    116	var params = new URLSearchParams({
    117		username: username,
    118		p: p,
    119		q: q,
    120		g: g,
    121		x: x,
    122		y: y
    123	})
    124
    125	var log = document.querySelector("p#errorlog")
    126	log.innerHTML = ""
    127
    128	var xhr = new XMLHttpRequest();
    129	xhr.open("POST", "/register", true);
    130	xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    131	xhr.onload = () => {
    132		if (xhr.status == 200) {
    133			window.location.replace("/");
    134		} else {
    135			log.innerHTML = xhr.responseText;
    136		}
    137	}
    138	xhr.send(params.toString());
    139}
    140
    141function event_handler() {
    142	let socket = new WebSocket("ws://" + document.location.hostname + ":1812/ws");
    143
    144	socket.onmessage = function(e) {
    145		event = JSON.parse(e.data);
    146		if (event.type == "firework")
    147			fireworks.push(new Firework(
    148				canvas.width / 2, canvas.height,
    149				canvas.width * event.x, canvas.height * event.y));
    150	}
    151}
    152
    153window.onload = function() {
    154    var overlay = document.getElementById("canvas_overlay");
    155	var canvas = document.getElementById("canvas");
    156	if (canvas !== null) {
    157		canvas.addEventListener("mousedown", function(e) {
    158			overlay.hidden = true;
    159			mx = e.pageX - canvas.offsetLeft;
    160			my = e.pageY - canvas.offsetTop;
    161			launch(mx / canvas.clientWidth, my / canvas.clientHeight);
    162		});
    163
    164		firework_loop()
    165
    166		event_handler()
    167	}
    168
    169	loginform = document.getElementById("loginform")
    170	if (loginform !== null) {
    171		set_challenge();
    172	}
    173}