Writeup - Oracle (SDCTF 2022)
Oracle
Category: Rev
Level: Easy
Points: 130
Description:
1 | An oracle is a black box in a Turing machine. You can run it but how do you inspect it? |
Writeup
This challenge was really enjoyable and although I bet I solved it in a way different from everyone else, it worked! The first step was to decompile the Java class
file into something more readable. Using an online Java decompiler, I was able to create the flag.java
file, which was very readable:
1 | import java.io.Console; |
The code was well-labeled, so it didn’t take too long to understand what was happening. I knew the flag was 42 characters long (35 minus the sdctf{}
). It was being validated by running the characters through three functions that did a bunch of math stuff to it and compared it to the CHECK
array at the end. Instead of trying to reverse the math and making some really ugly code, I decided it would be easier (and cooler-looking) to brute force it character by character.
The three functions looped through each character in the inputted string, modified the character, stored it in the numbers
array, and the CHECK array stored what the end result should be for each character in order. So, I added a print statement in the loop where the inputted string was compared to CHECK
that printed out each number in the numbers
array so I could see if the character I had inputted was successful or not. I also modified the code slightly so that the inputted flag came through as an argument instead of typed in. The main function then looked like this:
1 | public static void main(String[] paramArrayOfString) { |
I then wrote a Python script that ran the Java code, captured the output, and determined if the character I inserted into the flag was valid or not by comparing it to the CHECK
array that I imported into my script. If the character wasn’t valid, I went on to the next one and repeated the process. My code is below:
1 | import subprocess |
One problem I ran into was that there were multiple characters that returned valid in a specific position. For example, putting the flag sdctf{qaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}
revealed that the first 7 characters (sdctf{q
) were valid, but so were sdctf{p
, sdctf{r
, sdctf{s
, etc. However, if I assumed that sdctf{q
was correct and tried to find the 8th character in the flag, none of them returned true. To fix this, I changed my script so it ran recursively, meaning that it would assume sdctf{q
was correct and try to brute force the second character. If nothing came back valid, it would go back to the previous function call and try it with sdctf{p
and so on until one of them worked. This trial-and-error process ended up taking a lot longer than I expected it to, but I got the flag about an hour later.
Flag - sdctf{u_f0und_th3_LANGu4ge_0f_th1s_0r4cl3}