-4

Recently i was trying buffer overflow on a simple c code that has been shown in opensecuritytraining's exploit class 1. Here is the code

#include<stdio.h>
char *secret ="hello";
void go_shell()
{
        printf("This is go_shell\n");
}
int authorize()
{
        char password[64];
        printf("Enter the password: ");
        gets(password);
        if(!strcmp(password,secret))
        {
                return 1;
        }
        else
                return 0;
}
int main ()
{
        if (authorize())
        {
                printf("Login ok!\n");
                go_shell();
        }
        else
                printf("Incorrect\n");
}

In this one when i enter more than 72 'A' then it starts to overwrite the rip part of the stack . This is the stack when i enter 73 'A' . In it the rip is saved at 0x7ffffffee308 and its being overwritten . This is the result on the overflow. But the problem is when i enter more than 78 'A' This is the stack when i give 78 'A' as input. This is Successfully overwritten rip This is when 79 'A' are given as input. Although stack is successfully overwritten but rip points to correct location . Why is this happening ? I am using ubuntu in wsl .

  • 1
    Please review your post. Clearly nobody can read that code you have posted since it is all on one long line. Please reformat it such that it is readable. See [Editing help](https://stackoverflow.com/editing-help). – kaylum Apr 24 '21 at 06:44
  • Welcome to Stack Overflow. Please read [the help pages](http://stackoverflow.com/help), take the SO [tour], read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Lastly please learn how to create a [mcve]. – Some programmer dude Apr 24 '21 at 06:46
  • @Anurag Kashyap - In your stack images you assume the saved RIP at `0x7ffffffee308`, but you write _the rip is saved at **0x7ffffffee350**_. – Armali Apr 24 '21 at 07:28
  • 1
    Thanks @Armali , I corrected it. BTW do you know why this is happening? – Anurag Kashyap Apr 24 '21 at 07:49
  • I'm just having a look. At the moment, I think the last case where _rip points to correct location_, what seems to puzzle you, is rather normal, because the wrong return address is detected at the `retq` instruction and the RIP stays at the error instruction. Still I have to look at the former cases. – Armali Apr 24 '21 at 07:56
  • If compiled with optimizations enabled, the compiler might decide to inline the call to `authorize()`, so no `ret` instruction will be executed that would load the instruction pointer from the stack. – G. Sliepen Apr 24 '21 at 08:04
  • 1
    I am tcc for it , so no optimizations there . – Anurag Kashyap Apr 24 '21 at 10:45

1 Answers1

0

I could reproduce the observations. Indeed there are two behavioral cases:

  1. The corrupted return address is loaded into RIP, and the segfault occurs at the corrupted instruction pointer.
  2. The corrupted return address is detected before being loaded into RIP, and the segfault occurs at the retq instruction pointer.

I still have to delve into the processor documentation, but it appears that the early detection of a wrong return address depends on "how wrong" it is - when there are only some LSB wrong, the return is taken, while when only one MSB remains correct, the return isn't taken.

Armali
  • 18,255
  • 14
  • 57
  • 171
  • Which book do you prefer for reference on such things . Please tell me so that i can also refer to it in times. – Anurag Kashyap Apr 24 '21 at 09:10
  • I didn't find a clear reference. It's just noticeable that `/proc/cpuinfo` contains `address sizes : 46 bits physical, 48 bits virtual`, case 1 occurs up to return address 0x7FFFFFFFFFFF, and case 2 starts at 0x800000000000, which, if sign extended, exceeds the 48 bit address space. – Armali Apr 24 '21 at 11:09