It first reads a seed value from /dev/urandom and generates a random number. It stores this random number in v35. After that, it reads the user input using std::getline(std::cin, &v27). Since it is a std::string, it first calls c_str() function to get a C string pointer and stores that pointer in v10. Finally, it calls strcpy(&dest, v10) to copy our string to dest. The good thing is that there were no length checks during these operations which means we can overwrite other variables using buffer overflow.

Let’s continue our analysis.

After reading our input and copying it to dest, it calls srand(v35). So, the first random generated number was actually a seed value for further uses. Finally, it generates 100 random numbers using rand() and expect us to guess them correctly.

As we can see, the distance from dest to v35 is 700 bytes which means after 700 characters, the next 4 characters will overwrite the value in v35 which is the seed. Since we can set the seed value as we like, we can guess the numbers that will be generated.

Let’s create a C program that prints 100 random numbers using 0xDEADBEEF as seed value.