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 |
|
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 |
|
It's a very typical case, leading "overwrite" problem :)
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
- Raw Bytes:
len('\xff')
= 1
- Characters can be represented as bytes too
'A'
='\x41'
- 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¶
- The most common kind of buffer overflow
- Occurs on stack memory
- 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 theRIP
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¶
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
- Find a memory safety (e.g. buffer overflow) vulnerability
- Write malicious
shellcode
at a known memory address - 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
- Often, the
- Return from the function
- Begin executing malicious
shellcode
Case: Constructing Exploits¶
If SHELLCODE
is short enough, we can insert it under RIP
Else, we have to place it above RIP
Walking Through
Memory-Safe Code¶
Vulnerable C Library Functions
gets
- Read a string from stdin- Use
fgets
instead
- Use
strcpy
- Copy a string- Use
strncpy
(more compatible, less safe) orstrlcpy
(less compatible, more safe) instead
- Use
strlen
- Get the length of a string- Use
strnlen
instead (ormemchr
if you really need compatible code)
- Use