Now in a class excerise we did some basic CTF.
Idea is simple win Rock Paper Sissors 1000 times in a row. So I started playing with the program (only binary was given).
Basically the idea is that I type r s or p and the computer checks if I win.
Interestingly the sequence of answers do not change indicating that a fixed seed is used.
Now originally I though of two solutions.
Now set a python script to execute this program. First give p s or r and if it is wrong it would switch.
For example, if the correct sequence is rsppp than the python script will try p -> s -> r -> rp -> rs -> rsp -> rspp -> ...
This would mean assuming all guesses are wrong (answer is pppppppppppppp...) The python script would have to compute 3000 inputs but that is actually really doable.
Two problems arise. Well scrypt needs to know that a solution flopped and use a new iteration. Not really good with inter-process related stuff so yeah.
Another is this solution is not a fundamental one.
This is the solution I went with. Now probably this basic function uses srand() and rand() to do its trick.
Probably since there are three solutions rand()%3 would be our candidate to check.
Identifying 0, 1, 2 to r p s would just have to compare the order!
We only have to know the key.
objdump -d EXECUTABLE_NAME
To be clear there were two srand() functions in the objdump. However one didn't seem to be accessible in normal circumstances. (Tried to set breakpoint)
Here we see before executing srand a number is placed to stack.
That number is 2019 in decimal form. Which seems to be the seed.
Remember the executable order was
r
s
p
p
p
...
So we generate the following code:
#include <stdio.h>
#include <stdlib.h>
int main(){
srand(2019);
for(int i = 0; i < 10; i++){
printf("%d\n", rand()%3);
}
} // result: 1 2 0 0 0 1 1 1 2 2
We now know r = 1, s = 2, and p = 0.
Finally we generate a code to use as input:
#include <stdio.h>
#include <stdlib.h>
int main(){
srand(2019);
for(int i = 0; i < 1000; i++){
int tmp = rand()%3;
if(tmp == 1){
printf("r ");
}else if(tmp == 2){
printf("s ");
}else{
printf("p ");
}
}
}
./GENERATOR_NAME | ./EXECUTABLE_NAME
And we seem to have got our flag.