Just guess the word in 6 tries. What do you mean it’s hard?
By oops (former ISSS officer)
Officer in charge: jyu
nc betta.utctf.live 7496
We’re provided a Python source file:
1 | #!/usr/bin/env python3 |
To be honest, when I solved this challenge, I somehow completely missed the PYthon source file. idk how, I’m blind I guess. Managed to solve it anyways with some observation skills :)
But regardless, the main observation here is that the number outputted for each guess is equivalent to the product of all the differences between the correct answer and the guess, character-by-character. Of course, this guess is equivalent to 0 if one of the characters is correct.
With some testing by sending the following guesses:
1 | aaaaa |
I realized that the guess changed by a fixed amount for each one-letter change. Knowing that a guess is 0 if one character is correct, we can very easily calculate the correct letter for that position given that fixed amount via the following program:
1 | all_a = ? |
Naturally, this lead me to consider sending the following guesses:
1 | aaaaa |
However, this would take up our 6 guesses, and we could only use 5 guesses before we needed to try to guess the actual word.
But, since I didn’t have the source file when I solved it (I assume there is a deterministic way to solve it with the source file), I simply cut the last string off, sending:
1 | aaaaa |
And then, since the wordlist includes actual words (which I had figured out once I solved one manually with >6 guesses), I just guessed the last character :)
Also, guessing was easier before because I actually did it when it was only 1 try.
Here’s the full implementation. Also, note that I ended up changing all a’s to all z’s in this script instead because having to solve 3 times in a row means a much higher likelihood that one word will contain an ‘a’. If it does, that makes most of the guesses return 0, which we don’t want!
1 | from pwn import * |
solve2.py:
1 | import string |
utflag{sometimes_pure_guessing_is_the_strat}