picoCTF

Rps [200 pts]

 Challenge Description

Challenge Description:

Here’s a program that plays rock, paper, scissors against you. I hear something good happens if you win 5 times in a row.
Connect to the program with netcat:
$ nc saturn.picoctf.net [port #]
The program’s source code with the flag redacted can be downloaded here.


We’re given a C source file to analyze. Taking a look at the play function, I noticed something interesting:

bool play () {
  char player_turn[100];
  srand(time(0));
  int r;

  printf("Please make your selection (rock/paper/scissors):\n");
  r = tgetinput(player_turn, 100);
  // Timeout on user input
  if(r == -3)
  {
    printf("Goodbye!\n");
    exit(0);
  }

  int computer_turn = rand() % 3;
  printf("You played: %s\n", player_turn);
  printf("The computer played: %s\n", hands[computer_turn]);

  if (strstr(player_turn, loses[computer_turn])) {
    puts("You win! Play again?");
    return true;
  } else {
    puts("Seems like you didn't win this time. Play again?");
    return false;
  }
}

But, here’s what the strstr function does according to documentation:

strstr
const char * strstr ( const char * str1, const char * str2 );      char * strstr (       char * str1, const char * str2 );
Locate substring
Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.

The matching process does not include the terminating null-characters, but it stops there.

So strstr isn’t checking if the strings are equal. Rather, it’s checking if str2 is in str1! In other words, it’s checking if loses[computer_turn] is contained within player_turn. If it is, then we win that round.
We are also given the following:

char* loses[3] = {"paper", "scissors", "rock"};

Hence, the value of loses[computer_turn] can only ever be one of these. Well, what if we just input paperscissorsrock? Then, the value of loses[computer_turn] will always be a substring of the player input, and we will win every time!
Connect to the service and input paperscissorsrock 5 times in a row to get the flag!

picoCTF{50M3_3X7R3M3_1UCK_C85AF58A}