LitCTF - Web

web/LIT BUGS (92 solves / 129 points)

Description

Last year�s LIT platform may or may not have had some security vulnerabilities. We have created a simplified version of last year�s platform called LIT BUGS (Lexington Informatics Tournament�s Big Unsafe Grading System). The flag is the team name of the only registered user. Visit LIT BUGS here Downloads: LIT Bugs.zip

Solution:

When I clicked the link the description I was presented with a website that looks a lot like the current ctf website. This website has only a home page, a register page, a login page, and a contest page. After analyzing the source code given, I found that the website uses websockets for the register and login functions. In addition to this, there is also an endpoint that returns a teams name when given their ID.

Relevant code:

	io.on('connection',(socket) => {
		socket.on('login',(tn,pwd) => {
			if(accounts[tn] == undefined || accounts[tn]["password"] != md5(pwd)) {
				socket.emit("loginRes",false,-3);
				return;
			}
			socket.emit("loginRes",true,accounts[tn]["rand_id"]);
			return;
		});

		socket.on('reqName',(rand_id) => {
			name = id2Name[parseInt(rand_id)];
			socket.emit("reqNameRes",name);
		});

		socket.on('register',(tn,pwd) => {
			if(accounts[tn] != undefined) {
				socket.emit("regRes",false,-1);
				return;
			}
			if(Object.keys(accounts).length >= 500) {
				socket.emit("regRes",false,-2);
				return;
			}
			var rand_id = Math.floor(Math.random() * 1000);
			while(id2Name[rand_id] != undefined) {
				rand_id = Math.floor(Math.random() * 1000);
			}
			accounts[tn] = {
				"password": md5(pwd),
				"rand_id": rand_id
			};
			id2Name[rand_id] = tn;
			socket.emit("regRes",true,rand_id);
		});
	});

As you can see from this code, ID’s are generated by taking a random number from 1 to 1000. With only 1000 possible ID’s, this is well within bruteforcing range. The endpoint that allows name lookup based on ID’s should be vulnerable to a bruteforce attack, as the flag is the name of a team. I made a short JS script to run in my browser’s JS console which bruteforced all 1000 ID’s: socket.on(“reqNameRes”,(name)=>{ console.log(name) }); for(var i = 0;i<1000;i++){ socket.emit(“reqName”,i) } This worked, and after looking through the results, I found the following flag:

Flag

flag{if_y0u_d1d_not_brut3force_ids_plea5e_c0ntact_codetiger}