跳转至

Lecture 3: Memory Safety Vulnerabilities

Buffer Overflow Vulnerabilities

Recall: C has no concept of array length; it just sees a sequence of bytes

If you allow an attacker to start writing at a location and don’t define when they must stop, they can overwrite other parts of memory!

This is technically valid C code, because C doesn’t check bounds:

C
1
2
char bxhu[5];
bxhu[5] = 'a';

Vulnerable Code

gets is easily leading to vulnerable program

Usage

The gets function will write bytes until the input contains a newline ('\n'), not when the end of the array is reached.

Case

C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
char name[20]; // Defined in "Data"
char instrux[20] = "none"; // Defined in "Data"

/*
    name and instrux are declared in static memory (outside of the stack)
    , which is why name is below instrux
*/

void vulnerable(void) { 
    ...
    gets(name); 
    ...
}

It's a very typical case, leading "overwrite" problem :)

alt text

alt text

alt text

Trap by RIP

It’s a common model for attacking (changing RIP):

If we can touch bytes in fnptr, we can change it into the address of “our attack” code

Then when the function returns, it will go to our trap directly :)

Python Syntax

We usually use Python Syntax to achieve SHELLCODE in our lab and project

  1. Raw Bytes:
    • len('\xff') = 1
  2. Characters can be represented as bytes too
    • 'A' = '\x41'
  3. For the project: '\\' is a literal backslash character (转义字符)
    • len('\\xff') == 4, because the slash is escaped first
    • A literal slash character; A literal 'x' character; And 2 literal 'f' characters
    • In fact, '\\xff' == '\x5c\x78\x66\x66' here
      • \: \x5c
      • x: \x78
      • f: \x66
      • f: \x66

Stack Smashing

  1. The most common kind of buffer overflow
  2. Occurs on stack memory
  3. What are some values on the stack an attacker can overflow?
    • Local variables
    • Function arguments
    • Saved frame pointer (SFP) -Return instruction pointer (RIP)
Attacking Design
  • Recall: When returning from a program, the EIP is set to the value of the RIP saved on the stack in memory
  • Like the function pointer, this lets the attacker choose an address to jump (return) to!

Case: Overwriting the RIP

alt text

We should use garbage bytes to overwrite all of name and the SFP of vulnerable, so that we can reach RIP and let it points to our attack code.

Case: Writing Malicious Code

Overwrite RIP to point to SHELLCODE

Shellcode: Malicious code inserted by the attacker into memory, to be executed using a memory safety exploit

  • Called shellcode because it usually spawns a shell (terminal)
  • Could also delete files, run another program, etc.

Step

  1. Find a memory safety (e.g. buffer overflow) vulnerability
  2. Write malicious shellcode at a known memory address
  3. Overwrite the RIP with the address of the shellcode
    • Often, the shellcode can be written and the RIP can be overwritten in the same function call (e.g. gets), like in the previous example
  4. Return from the function
  5. Begin executing malicious shellcode

Case: Constructing Exploits

If SHELLCODE is short enough, we can insert it under RIP

alt text

alt text

Else, we have to place it above RIP

alt text

Walking Through

alt text

Memory-Safe Code

Vulnerable C Library Functions

  1. gets - Read a string from stdin
    • Use fgets instead
  2. strcpy - Copy a string
    • Use strncpy (more compatible, less safe) or strlcpy (less compatible, more safe) instead
  3. strlen - Get the length of a string
    • Use strnlen instead (or memchr if you really need compatible code)

Integer Memory Safety Vulnerabilities

Signed/Unsigned Vulnerabilities

alt text

Integer Overflow Vulnerabilities

alt text