This page looks best with JavaScript enabled

Flare-On 8 2021 Challenge 8 Solution - 08_beelogin

Hosted by FireEye's FLARE team from 10 September - 22 October

 ·  ☕ 9 min read  ·  🌚 drome

Thanks drome for sharing his knowledge and skills! He completed all 10 challenges and this series of writeups is done by him :)

Details Links
Official Challenge Site https://flare-on.com/
Official Challenge Announcement https://www.fireeye.com/blog/threat-research/2021/08/announcing-the-eighth-annual-flare-on-challenge.html
Official Solutions https://www.mandiant.com/resources/flare-on-8-challenge-solutions
Official Challenge Binaries http://flare-on.com/files/Flare-On8_Challenges.zip

08_beelogin

You’re nearly done champ, just a few more to go. we put all the hard ones at the beginning of the challenge this year so its smooth sailing from this point. Call your friends, tell ’em you won. They probably don’t care. Flare-On is your only friend now.

We are given a HTML file with a lot of JS code inside, and the page looks like this in the browser:

Bee Webpage Login

The form has the following fields:

1
2
3
4
5
<input type="Password" name="LLfYTmPiahzA3WFXKcL5BczcG1s1" id="LLfYTmPiahzA3WFXKcL5BczcG1s1" placeholder="LLfYTmPiahzA3WFXKcL5BczcG1s1"><br><br>
<input type="Password" name="qpZZCMxP2sDKX1PZU6sSMfBJA" id="qpZZCMxP2sDKX1PZU6sSMfBJA" placeholder="qpZZCMxP2sDKX1PZU6sSMfBJA"><br><br>
<input type="Password" name="ZuAHehme2RWulqFbEWBW" id="ZuAHehme2RWulqFbEWBW" placeholder="ZuAHehme2RWulqFbEWBW"><br><br>
<input type="Password" name="ZJqLM97qEThEw2Tgkd8VM5OWlcFN6hx4y2" id="ZJqLM97qEThEw2Tgkd8VM5OWlcFN6hx4y2" placeholder="ZJqLM97qEThEw2Tgkd8VM5OWlcFN6hx4y2"><br><br>
<input type="Password" name="Xxb6fjAi1J1HqcZJIpFv16eS" id="Xxb6fjAi1J1HqcZJIpFv16eS" placeholder="Xxb6fjAi1J1HqcZJIpFv16eS"><br><br>

Removing redundant functions

There is a lot of junk code in the JS code/functions that never gets called, for example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function VPDuWp7OyscVQRf(lfkbVmO1) {
	assert.expect(1);

	var elem = jQuery("#firstp")
	, log = []
	, check = [];

	jQuery.each(new Array(100), function(i) {
		elem.on("click", function() {
			log.push(i);
		});

		check.push(i);

	});

	elem.trigger("click");

	assert.equal(log.join(","), check.join(","), "Make sure order was maintained.");

	elem.off("click");
}
;

We write a script to remove all the unused functions,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import re

def get_matching_brace_offset(brace_offset, jsfile):
	i = brace_offset
	height = 1
	while height:
		i += 1
		if jsfile[i] == '{':
			height += 1
		if jsfile[i] == '}':
			height -= 1
	return i

def remove_useless_functions(jsfile):
	function_names = list(set(re.findall(r"function (\w+)\(\w+\) {", jsfile)))
	print(f"{len(function_names)} functions found.")
	print("Removing useless functions")
	for function_name in function_names:
		if function_name == 'Add':
			continue

		pattern1 = r"function " + function_name + r"\(\w+\) ({)"
		pattern2 = function_name

		if len(re.findall(pattern1, jsfile)) != len(re.findall(pattern2, jsfile)):
			continue

		brace_offsets = []
		for m in re.finditer(pattern1, jsfile):
			offset = m.start(1)
			brace_offsets.append((offset, get_matching_brace_offset(offset, jsfile)))

		prev_offset = 0
		new_parts = []

		for s, e in brace_offsets:
			new_parts.append(jsfile[prev_offset:s])
			prev_offset = e + 1

		new_parts.append(jsfile[prev_offset:])
		new_jsfile = "".join(new_parts)
		new_jsfile = re.sub(r"function " + function_name + r"\(\w+\) ", "", new_jsfile)

		jsfile = new_jsfile
	return jsfile

def remove_semicolons(jsfile):
	print("Removing semicolons")
	jsfile = re.sub(r";\n", "", jsfile)
	return jsfile

def main():
	with open('script_beautified.js', 'r') as fp:
		jsfile = fp.read()

	jsfile = remove_useless_functions(jsfile)
	jsfile = remove_semicolons(jsfile)

	with open('script_no_functions.js', 'w') as fp:
		fp.write(jsfile)

if __name__ == '__main__':
	main()

Removing junk variables

Afterwards we use an online JS beautifier to remove the newlines and fix the indentation, and get a file that is 183 lines long.

Javascript code after removing junk and beautifying

There is another obfuscation method being used here, which is where they take a form object and then call .split(''), then eval it if it is less than rFzmLyTiZ6AHlL1Q4xV7G8pW32, but throwing away the result, which means it’s just junk code.

We initially tried to remove those lines using Sublime Text with the following patterns:

\w+ = formObject\.\w+\.value\.split\(''\)
if \('rFzmLyTiZ6AHlL1Q4xV7G8pW32' >= \w+\) eval\(\w+\)

which gives us a 21-line file that is much easier to analyze:

Javascript code after removing more junk code

However, this would cause us to delete lines like the one below that are of use:

1
qguBomGfcTZ6L4lRxS0TWx1IwG = xDyuf5ziRN1SvRgcaYDiFlXE3AwG.ZJqLM97qEThEw2Tgkd8VM5OWlcFN6hx4y2.value.split(';')

Hence, we instead went with a script to filter out and delete only the useless variables that have 3 occurrences — 1 from the .split('') line and 2 from the eval lines.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import re

def remove_useless_evals(jsfile):
	eval_vars = list(set(re.findall(r"(\w+) = xDyuf5ziRN1SvRgcaYDiFlXE3AwG\.\w+\.value\.split\(';'\)", jsfile)))
	print(f"{len(eval_vars)} eval variables found.")
	print("Removing useless eval variables")
	for eval_var in eval_vars:
		pattern1 = eval_var + r" = xDyuf5ziRN1SvRgcaYDiFlXE3AwG\.\w+\.value\.split\(';'\)"
		pattern2 = r"if \('rFzmLyTiZ6AHlL1Q4xV7G8pW32' >= " + eval_var + r"\) eval\(" + eval_var + r"\)"

		if re.search(pattern2, jsfile) is None:
			continue

		if len(re.findall(eval_var, jsfile)) != 3:
			continue

		jsfile = re.sub(pattern1, "", jsfile)
		jsfile = re.sub(pattern2, "", jsfile)
	return jsfile

def main():
	with open('script_no_functions_beautified.js', 'r') as fp:
		jsfile = fp.read()

	jsfile = remove_useless_evals(jsfile)

	with open('script_no_functions_no_evals.js', 'w') as fp:
		fp.write(jsfile)

if __name__ == '__main__':
	main()

After beautifying and renaming variables, we get this final function, with the first Base64 string truncated because it’s gigantic:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
function Add(form_object) {
    b64_str1 = "4fny3zLzDRYIOe37Axvh5Toquw4GGWWdN..."
    b64_str2 = "b2JDN2luc2tiYXhLOFZaUWRRWTlSeXdJbk9lVWxLcHlrMXJsRnk5NjJaWkQ4SHdGVjhyOENQeFE5dGxUaEd1dGJ5ZDNOYTEzRmZRN1V1emxkZUJQNTN0Umt6WkxjbDdEaU1KVWF1M29LWURzOGxUWFR2YjJqQW1HUmNEU2RRcXdFSERzM0d3emhOaGVIYlE3dm9aeVJTMHdLY2Vhb3YyVGQ4UnQ2SXUwdm1ZbGlVYjA4YVRES2xESnlXU3NtZENMN0J4MnBYdlZET3RUSmlhY2V6Y3B6eUM2Mm4yOWs="
    form_str = form_object.ZJqLM97qEThEw2Tgkd8VM5OWlcFN6hx4y2.value.split(';')
    decoded_str1 = atob(b64_str1).split('')
    decoded_str1_len = decoded_str1.length
    decoded_str2 = atob(b64_str2).split('')
    password = 'gflsdgfdjgflkdsfjg4980utjkfdskfglsldfgjJLmSDA49sdfgjlfdsjjqdgjfj'.split('')
    if (form_str[0].length == 64) password = form_str[0].split('')
    for (i = 0; i < decoded_str2.length; i++) {
        decoded_str2[i] = (decoded_str2[i].charCodeAt(0) + password[i % 64].charCodeAt(0)) & 0xFF
    }
    decrypted_str = decoded_str1
    for (i = 0; i < decoded_str1_len; i++) {
        decrypted_str[i] = (decrypted_str[i].charCodeAt(0) - decoded_str2[i % decoded_str2.length]) & 0xFF
    }
    final_eval_str = ""
    for (i = 0; i < decoded_str1.length; i++) {
        final_eval_str += String.fromCharCode(decrypted_str[i])
    }
    if ('rFzmLyTiZ6AHlL1Q4xV7G8pW32' >= final_eval_str) eval(final_eval_str)
}

Decryption

The decryption algorithm is decrypted[i] = str1[i] - str2[i] - password[i], not considering mod effects after 64 bytes.

We initially tried guessing some 64 byte password that would give a valid value that can be evaluated. Considering the lengths of the default values in the form inputs,

  • LLfYTmPiahzA3WFXKcL5BczcG1s1 - 28
  • qpZZCMxP2sDKX1PZU6sSMfBJA - 25
  • ZuAHehme2RWulqFbEWBW - 20
  • ZJqLM97qEThEw2Tgkd8VM5OWlcFN6hx4y2 - 34
  • Xxb6fjAi1J1HqcZJIpFv16eS - 24

we tried to concat them as passwords but none of them made sense.

We decided to checked the website’s background image which was suspicious because it was labelled as a GIF but its file format was actually JPEG, but we couldn’t find anything particular about the file format, or any information hidden with steganography.

New strategy: the decoded string must contain only valid JS characters. We know the pattern the decrypted files will be in so we can use that to narrow the possible ranges of password.

Hence we can write a script to find a possible password:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
with open('script_original.js', 'rb') as fp:
	jsfile = fp.read()

allowed_chars = list(set(jsfile))
print(allowed_chars)

with open('decoded_b64_1', 'rb') as fp:
	str1 = fp.read()

str2 = b"obC7inskbaxK8VZQdQY9RywInOeUlKpyk1rlFy962ZZD8HwFV8r8CPxQ9tlThGutbyd3Na13FfQ7UuzldeBP53tRkzZLcl7DiMJUau3oKYDs8lTXTvb2jAmGRcDSdQqwEHDs3GwzhNheHbQ7voZyRS0wKceaov2Td8Rt6Iu0vmYliUb08aTDKlDJyWSsmdCL7Bx2pXvVDOtTJiacezcpzyC62n29k"

password = [-1 for _ in range(64)]

for i in range(64):
	for b in allowed_chars:
		valid = True
		for j in range(i, len(str2), 64):
			if not valid:
				break
			for k in range(j, len(str1), len(str2)):
				new_char = (str1[k] - b - str2[j]) & 0xff
				if new_char not in allowed_chars:
					valid = False
					break
		if valid:
			password[i] = b

print(bytes(password))

Which gives us ChVCVYzI1dU9cVg1ukBqO2u4UGr9aVCNWHpMUuYDLmDO22cdhXq3oqp8jmKBHUWI, and trying to decipher the message with that key gives us the following

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//Yes, but who can deny the heart that is yearning?
//Affirmative!
//Uh-oh!
//This.
//At least you're out in the world. You must meet girls.
//Why is yogurt night so difficult?!
//I feel so fast and free!
//Good idea! You can really see why he's considered one of the best lawyers...
//One's bald, one's in a boat, they're both unconscious!
//You know what a Cinnabon is?
//Just one. I try not to use the competition.
//Heads up! Here we go.
//Whose side are you on?
//Did you ever think, "I'm a kid from The Hive. I can't do this"?
//Can I get help with the Sky Mall magazine? I'd like to order the talking inflatable nose and ear hair trimmer.
//It's a close community.
//Which one?
//That's why I want to get bees back to working together. That's the bee way! We're not made of Jell-O.
//Yeah. It doesn't last too long.
//Not that flower! The other one!
//Surf's up, dude!
//My parents wanted me to be a lawyer or a doctor, but I wanted to be a florist.
//Bees don't smoke!
//Good idea! You can really see why he's considered one of the best lawyers...
//Nah.
//Like what? Give me one example.
//Why not? Isn't John Travolta a pilot?
//What were they like?
//You know what your problem is, Barry?
//This is a bit of a surprise to me. I mean, you're a bee!
//Hey, you want rum cake?
//You have no job. You're barely a bee!
//My mosquito associate will help you.
//Yes, I know.
//I know.
//Up on a float, surrounded by flowers, crowds cheering.
//This is a total disaster, all my fault.
//Black and yellow.
//Oh, my.
//I assume wherever this truck goes is where they're getting it. I mean, that honey's ours.
//Yeah.
//What's the difference?
//My only interest is flowers.
//Coming!
//You did? Was she Bee-ish?
//Oh, no. More humans. I don't need this.
//What are you?
//Yeah.
//Maybe I'll pierce my thorax. Shave my antennae. Shack up with a grasshopper. Get a gold tooth and call everybody "dawg"!
//But I have another idea, and it's greater than my previous ideas combined.
//To the final Tournament of Roses parade in Pasadena.
//Giant, scary humans!
//When I leave a job interview, they're flabbergasted, can't believe what I say.
//Oh, this is so hard!
//You'll regret this.
//You want a smoking gun? Here is your smoking gun.
//You're in Sheep Meadow!
//Mamma mia, that's a lot of pages.
//My sweater is Ralph Lauren, and I have no pants.
//Here's your change. Have a great afternoon! Can I help who's next?
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]...

The last line is a huge JSFuck string. We put it into this online deobfuscator, rename the variables, and get something very similar to our original password finding function:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
(function (qguBomGfcTZ6L4lRxS0TWx1IwG) {
    b64_str1 = "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";
    b64_str2 = "N0l2N2l2RTVDYlNUdk5UNGkxR0lCbTExZmI4YnZ4Z0FpeEpia2NGN0xGYUh2N0dubWl2ZFpOWm15c0JMVDFWeHV3ZFpsd2JvdTVSTW1vZndYRGpYdnhrcGJFS0taRnZOMnNJU1haRXlMM2lIWEZtN0RSQThoMG8yYUhjNFZLTGtmOXBDOFR3OUpyT2RwUmFOOUdFck12bXd2dnBzOUVMWVpxRmpnc0ZHTFFtMGV4WW11Wmc1bWRpZWZ6U3FoZUNaOEJiMURCRDJTS1o3SFpNRzcwRndMZ0RCNFFEZWZsSWE4Vg==";
    str1 = atob(b64_str1).split('');
    str1_len = str1.length;
    str2 = atob(b64_str2).split('');
    password = '87gfds8f4h4dsahfdjhkDHKHF83hNNFDHHKFBDSAKFSfsd47lmkbfjghgdfgda34'.split('');
    if (qguBomGfcTZ6L4lRxS0TWx1IwG[1].length == 64) password = qguBomGfcTZ6L4lRxS0TWx1IwG[1].split('');
    for (i = 0; i < str2.length; i++) {
        str2[i] = (str2[i].charCodeAt(0) + password[i % 64].charCodeAt(0)) & 0xFF;
    };
    for (i = 0; i < str1_len; i++) {
        str1[i] = (str1[i].charCodeAt(0) - str2[i % str2.length]) & 0xFF;
    };
    str1 = String.fromCharCode.apply(null, str1);
    if ('rFzmLyTiZ6AHlL1Q4xV7G8pW32' >= Oz9nOiwWfRL6yjIwvM4OgaZMIt0B) eval(str1);
})(qguBomGfcTZ6L4lRxS0TWx1IwG);

We search for qguBomGfcTZ6L4lRxS0TWx1IwG in the original script, and find that it is also from the password field after splitting it by ;.

After making slight modifications to our password finding script, we get UQ8yjqwAkoVGm7VDdhLoDk0Q75eKKhTfXXke36UFdtKAi0etRZ3DoHPz7NxJPgHl as the second password. Decrypting it gives us more JSFuck code, so we decode it and get this final JS code containing our flag:

1
alert("I_h4d_v1rtU411y_n0_r3h34rs4l_f0r_th4t@flare-on.com")

Using the password to get the flag

This is not necessary since we already have the flag, but if you type this as the password under the ZJqLM97qEThEw2Tgkd8VM5OWlcFN6hx4y2 field:

ChVCVYzI1dU9cVg1ukBqO2u4UGr9aVCNWHpMUuYDLmDO22cdhXq3oqp8jmKBHUWI;UQ8yjqwAkoVGm7VDdhLoDk0Q75eKKhTfXXke36UFdtKAi0etRZ3DoHPz7NxJPgHl

the flag will appear as an alert:

Flag in Javascript alert

Flag

I_h4d_v1rtU411y_n0_r3h34rs4l_f0r_th4t@flare-on.com
Share on