SimonProgrammer 2
Description
SimonProgrammer 2: The Next Octave
Bandwidth notice:
Please only download the audio you need to complete the challenge. You can use the audio files from Simon Programmer 1 to calibrate your solver, if required. Thanks! - CTF Organizers
Music to my ears!
Ok, ok. Yeah. That was a mistake.
An intentional mistake laughs in evil genius.
I... uh... intended to... uh...
...
I patched it now! And now uh... the old way of doing the challenge seems broken... uh...
...
Ok, ok. We'll say the previous challenge was so folks could calibrate... automated solvers... cause...
The robots are taking our jobs writing articles about the robots taking our jobs!
Now, automation is the name of the game, and Simon Says... automate!
As Mr. Schmitt says, there are a whole lot of techniques to answer back with a pitch, but his is the best!
Visit https://simon2.web.2023.sunshinectf.games, and play a game of listening to the present!
But don't worry that this game will get old! The flags in this game are split into three octaves, with one flag in each... you'll never find them all! And since it's random, no two games will ever be alike!
Flag will be given by our backend in the standard sun{} format!
Notes
I am not unreasonable.
All I ask is you listen to the music with 99.9% accuracy.
That's better than last year, which required 100% accuracy! Much better.
Flag
sun{simon_says_wait_that_was_a_mistake_what_do_you_mean_the_filenames_were_frequencies}
Solution
- This solution is based on using Base64 URL4
- It didn't work by using https://stackoverflow.com/a/66892766
import requests
import string
import base64
requests.packages.urllib3.disable_warnings()
BASE_URL = "https://simon2.web.2023.sunshinectf.games"
s = requests.Session()
# s.proxies = {"https": "http://127.0.0.1:8080"}
s.headers = {
"Accept": "application/json",
"Content-Type": "application/json",
}
def paths2frequencies(path_list: list[str]) -> list[str]:
frequencies = []
for path in path_list:
base64encoded = path.replace("/static/", "").replace(".wav", "")
freq = "".join(
[
chr(s)
for s in base64.urlsafe_b64decode(base64encoded)
if chr(s) in string.printable
]
).strip()
frequencies.append(freq)
return frequencies
def get_frequencies() -> dict:
resp = s.get(f"{BASE_URL}/frequencies", verify=False)
return resp.json()
def get_flag(frequencies: list[str]) -> str:
resp = s.post(
f"{BASE_URL}/flag",
json=frequencies,
verify=False,
)
return resp.text
def main():
frequencies = paths2frequencies(get_frequencies()["frequencies"])
resp = get_flag(frequencies)
print(resp)
if __name__ == "__main__":
main()