> For the complete documentation index, see [llms.txt](https://davidjosearaujo.gitbook.io/notes-mcs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://davidjosearaujo.gitbook.io/notes-mcs/analysis-and-exploration-of-vulnerabilities/buffers/stack-smashing.md).

# Stack Smashing

A stack smashing attack is a specific type of security exploit that takes advantage of a buffer overflow vulnerability in a program to compromise its integrity and potentially execute arbitrary code.

What about writing the correct values to the stack?

* Some value to RBP.
* An address belonging to the process in RIP.

When the message ends the flow will be restored.

* That is, stored RBP and stored RIP are loaded into the registers.
* The stack frame will start at RBP.
* Program jump to the address in RIP.

If the addresses aren't in a mapped area, the program will receive a `SIGSEV`.

## Practical Example: program\_flow\.c

```c
void secret(){
    printf("Secret message\n");
    exit(0);
}
char foo(int size, char* arg){
    char buffer[8];
    memcpy(buffer, arg, size);
    return buffer[0];
}
int main(int argc, char* argv[]){
    char buffer[64];
    printf("%p\n", &secret);
    
    FILE *fp = fopen(argv[1], "r");
    int size = fread(buffer, 1, 64, fp);
    fclose(fp);
    
    foo(size, buffer);
    return 0;
}
```

Flow:

* Reads data from file;
* Calls `foo` function with size and buffer;
* `foo` has an overflowing `memcpy`.
* `secret` function is never called.

Attack: Overflow the buffer:

* writing over stored `$RBP`.
* writing over stored `$RIP`, placing `&secret` there.

Consider ASLR to be disabled.

<figure><img src="https://3744219775-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUaTnynVhA2CYjsGJT14j%2Fuploads%2Fe2eeI0DxThO6fF8NJ5gK%2FScreenshot%20from%202024-01-11%2017-28-54.png?alt=media&amp;token=c94ee84e-c055-436f-9461-420f929e0ffa" alt=""><figcaption></figcaption></figure>

Attack strategy:

* Overwrite buffer over `RBP/RIP`

How to find the addresses?

* If we have the source code: `printf("%p\n", secret)`
* If we don't: `gdb` or bruteforce.

<figure><img src="https://3744219775-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUaTnynVhA2CYjsGJT14j%2Fuploads%2FVGRb73MLOWgrFDeoQrhF%2FScreenshot%20from%202024-01-11%2017-30-52.png?alt=media&amp;token=73086f27-a40a-4d2d-a910-c774cc73c900" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3744219775-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUaTnynVhA2CYjsGJT14j%2Fuploads%2F26uz3oX0Nrv9slSykpKV%2FScreenshot%20from%202024-01-11%2017-31-41.png?alt=media&amp;token=f09dc8e6-d797-48d5-ae06-9b447d9500ed" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3744219775-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUaTnynVhA2CYjsGJT14j%2Fuploads%2F3kU7MbEIq0zwJoNEp4Cz%2FScreenshot%20from%202024-01-11%2017-32-12.png?alt=media&amp;token=80d58e11-6076-4b0d-820c-b19fef40cd58" alt=""><figcaption></figcaption></figure>

## Practical Example: return\_to\_libc.c

Instead of returning to a program function, it is possible to jump to other locations.

* In theory, to any segment that is allocated to the program.
* In practice, permission mechanisms limit the available segments.

Segments for libraries have several generic libraries.

* In particular: system().
* Is mostly executable.

The stack can be executable, but it isn't on recent systems.

<figure><img src="https://3744219775-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUaTnynVhA2CYjsGJT14j%2Fuploads%2FnaZ1h5O7DQbN0VDakeQk%2FScreenshot%20from%202024-01-11%2017-35-02.png?alt=media&amp;token=9b81ea4f-202a-485f-82ef-68d932279cb0" alt=""><figcaption><p>Typical Flow</p></figcaption></figure>

Return to `libc`

* Build “fake” Stack frame and call system() with one argument.
  * The argument is the command to execute (e.g. a reverse shell).
* Must take into consideration calling convention.
  * Which is architecture-dependent.

Arguments are passed in the stack.

* Approach: store values to the stack so that the system is called with a payload.
  * Then call the system.

<figure><img src="https://3744219775-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUaTnynVhA2CYjsGJT14j%2Fuploads%2FipktMYG8arS1WF8tEKmF%2FScreenshot%20from%202024-01-11%2017-37-07.png?alt=media&amp;token=b71c7910-d6bc-4e2c-badb-32a5e7169dc4" alt=""><figcaption></figcaption></figure>
