Tags: engineering reverse

Rating: 5.0

### Analysis

Reading the source code with cat re.c presents the following:

c
#include <stdlib.h>

int win(){
int fd = open("./flag.txt",0);
sendfile(1,fd,0,100);
exit(0);
}

int main() {
srand(time(0));
int rand_num;
int user_num;

printf("Give me a number: ");
scanf("%d", &user_num);

rand_num = rand();

if (rand_num == user_num) {
printf("Correct \n ");
win();
}

printf("Wrong!\n");
printf("I randomly generated:\n%d", rand_num);
}


From line 22 (if (rand_num == user_num)), we can see that in order to fulfill the win condition, we have to input a string to the program which matches the randomly generated number. The srand() function used on line 13 seeds the pseudorandom number generator with the current time, meaning that the "random" number will be the same whenever executed in the same millisecond.

### Testing

This can be tested easily in Bash:
bash
for _ in {1..9} do # Repeat 9 times
echo "test" | ./re # Run the program with a dummy input string
echo -e "\n" # Print a blank line to delimit each loop, for readability
done


This provides an output such as the following example:

bash
Give me a number: Wrong!
I randomly generated:
1606725990

Give me a number: Wrong!
I randomly generated:
1606725990

Give me a number: Wrong!
I randomly generated:
1606725990

# <Repeats 6 more times>


### Exploitation

We can see that the randomly generated number is displayed on the third line each time, so we can extract just the line containing the number using sed -n 3p. Then, we can pipe that number back into the program, since the random number will be unchanged, assuming execution happens within the same millisecond.

Our final code is this:

bash
echo "test" | ./re | sed -n 3p | ./re


Executing it will provide the following output:
bash
Give me a number: Correct
SAH{Can_I_Have_Your_Number?}


### Flag

#### ? SAH{Can_I_Have_Your_Number?}