CSR 2024 Guess my token and flag finder misc challenges solution

yousef alaa
4 min readMay 12, 2024

--

GUESSMYTOKEN chellenge

problem description

looks interesting so far so i tried to run nc to see how the program operate.

so i guessed 8 bytes hex string and the program helps me to guess the right hex by flags but i only have 10 seconds to guess it so its impossible to do it without a script so i started doing one but take care that every time it takes about 2s to check your answer so we only have maximum of 5 tries to guess the right hex before the time go out.

import socket

server_address = 'guess-my-token.rumble.host'
server_port = 6903

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
client_socket.connect((server_address, server_port))

data = client_socket.recv(1024).decode()
message = list("0000000000000000")
hex = "0123456789abcdef"
left = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
right = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
while "CSR" not in data:
client_socket.recv(1024)
for i in range(0, len(left)):
mid = (left[i] + right[i]) // 2
message[i] = hex[mid]
client_socket.sendall("".join(message).encode())
client_socket.recv(1024)
data = client_socket.recv(1024)
data = data.decode().split(" ")[-1]
for i in range(0, len(data)):
if data[i] == '↑':
left[i] = (left[i] + right[i]) // 2 + 1
elif data[i] == '↓':
right[i] = (left[i] + right[i]) // 2 - 1
print("".join(message),data)


finally:
# Close the connection
client_socket.close()

ok let’s break this down a bit you already noticed we have to use binary search to solve this problem so i receive the first message (I’ve generated….) then i made some variables to help the binary search first is hex which map the index to to its hex (0->0, 10->a, 15->f), and then the messege which is the list we will send. For binary search i made left and right array that stores the maximum and minimum value possible for every index then the rest is just binary search i get the mid for every index then update the left and right every time by checking the arrows that i get from the program.

and voila that was perfect interactive problem simple and lovely.

FLAG FINDER

Ok for this problem its a source code review so the important point in this problem is this part.

@app.route("/search")
def search():
query = request.args.get("query", "")
real_query = parse_query(query)

app.logger.info("Searching for %s", real_query)

results = []
with pool.get_connection() as conn:
with conn.cursor() as cursor:
cursor.execute(
"SELECT name, answer FROM answers WHERE name RLIKE ?", (real_query,)
)
for name, answer in cursor:
results.append({"name": name, "answer": answer})

return render_template("index.tpl", results=results, query=query)

RLIKE interesting so we have to do some regex search to have an output but it was not that simple….

replace_map = str.maketrans(
{
"\\": "\\\\",
"[": "\\[",
"]": "\\]",
"{": "\\{",
"}": "\\}",
"?": "\\w",
"+": "\\w?",
".": "(?<=\\w)(\\.|\\w*?\\b)",
}
)


def parse_query(query: str) -> str:
if query.count("+") + query.count("?") > 2 or query.count(".") > 1:
return "^\\b$"

if len(query) > 1014:
return "^\\b$"

return f"^{query.translate(replace_map)}$"

Since it does some parsing to prevent you from using simple regex like using (. or *) so my teammate start trying some regex on a regex test website unitl we find that a|b working.

so yeah we got an output but this is not all the users so i guess you know what we have to do we need to add the rest of characters to match all characters so match all database records.

and we got the flag nice.

--

--

No responses yet