On the challenge we are given a website [https://base65536.ctf.insecurity-insa.fr/](https://base65536.ctf.insecurity-insa.fr/) if we browse to this website in our browser we get a 405 error, so we know the page is not expecting a GET request so let's try a POST request without data:```Param 'sample' is expected```So let's add the param sample with content-type as x-www-form-urlencondedand we get the following response:```Your encrypted sample is ?ѕ and the flag is 劘??⯜䊍셶?釂?㈾ !```So it appears it encodes our input as Base65536 and also outputs the flag in base 65536 as well. Let's see if the enconding is the same by submitting a sample of string 'INSA' since we know that's part of the flag and we get the following response: ```Your encrypted sample is 쎙? and the flag is 쎙???먚츘램✭ꋏ? !```From this output we can see the same encoding is used for the flag and our input, so it's rather simple to solve this. At first I thought that every character encoded would result in a base65536 16 bit character(because 2\*\*16 == 65536) so I decided to create every possible combination of two characters like so:```jsconst alphabet="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{}_-0123456789"function generateNoRecursion(len, chars) {	// Indices that indicate what char to use on corresponding place.	var indices = [];	for (var i = 0; i < len; ++i)	indices.push(0); 	// While all indices in set of chars	while (indices[0] < chars.length)	{		// Print current solution		var str = "";		for (var i = 0; i < indices.length; ++i)		str += chars[indices[i]];		possibilities.push(str);		possibilities.push(str);		// Go to next solution by incrementing last index and adjusting		// if it is out of chars set.		indices[len-1]++;		for (var i = len-1; i > 0 && indices[i] == chars.length; --i)		{			indices[i] = 0;			indices[i-1]++;		}	}}generateNoRecursion(2, alphabet);```As I've said at first I thought only 2 byte chars were used for the encoding, but I was wrong, in fact it could be anything from 1 to 4 bytes that's why I push to the possibilities array the same string twice, so that I can later in the response figure out the number of enconded bytes.So let's make a request with every possible combination and save each encoded pair of characters in a map/dictionary:```jsfunction readNext(myEncodedInput) {//shit code inc	if(myEncodedInput.length >= 8 && !(myEncodedInput[0] != myEncodedInput[4] || myEncodedInput[1] != myEncodedInput[5] || myEncodedInput[2] != myEncodedInput[6] || myEncodedInput[3] != myEncodedInput[7])) {		return myEncodedInput.slice(0, 4).toString('hex');	} else if(myEncodedInput.length >= 6 && !(myEncodedInput[0] != myEncodedInput[3] || myEncodedInput[1] != myEncodedInput[4] || myEncodedInput[2] != myEncodedInput[5])) {		return myEncodedInput.slice(0, 3).toString('hex');	} else if(myEncodedInput.length >= 4 && !(myEncodedInput[0] != myEncodedInput[2] || myEncodedInput[1] != myEncodedInput[3])) {		return myEncodedInput.slice(0, 2).toString('hex');	} else if(myEncodedInput.length >= 2 && !(myEncodedInput[0] != myEncodedInput[1])) {		return myEncodedInput.slice(0, 1.toString('hex');	}else{		console.log('warning unknown encoding');		process.exit(0);	} }function makeReq() { request.post({		url: url,		encoding: null, //So that body is a buffer instead of string		form: {			sample: possibilities.join('')		}	}, function(err, response, body) {		var myInputEnd = body.indexOf(andTheFlagIs);		myEncodedInput = body.slice(0x19, myInputEnd);		flag = body.slice(myInputEnd + andTheFlagIs.length, body.length - 3);		var map = {}; 		for(var i = 0; i < possibilities.length; i += 2) {			var hexCode = readNext(myEncodedInput);			myEncodedInput = myEncodedInput.slice(hexCode.length);			map[hexCode] = possibilities[i];			//console.log(`map[${hexCode}] = ${map[hexCode]}`);		}		readTheFlag(map, flag)	})}```
With this done we only need to decode the flag with out generated map like so:```jsfunction readTheFlag(map, flag) {	const decodedFlag = []	while(flag.length !== 0) {		for(var i = 0; i < 4; i++) {			const code = flag.slice(0, i+1).toString('hex');			const code = s[i].apply(this, flag.slice(0, 4));			if(map[code] !== undefined)			{				decodedFlag.push(map[code])				flag = flag.slice(i + 1)				break;			}		}	}	console.log(decodedFlag.join(''))}```
Put it all together and we get the flag:**INSA{655e6_is_T0_Much}**