CSE543
Introduction to Computer and
Network Security
Module: Program Vulnerabilities
Asst. Prof. Syed Rafiul Hussain
CSE543 - Introduction to Computer and Network Security Page 1
Programming
• Why do we write programs?
‣ Function
• What functions do we enable via our programs?
‣ Some we want -- some we don’t need
‣ Adversaries take advantage of such “hidden” function
CSE543 - Introduction to Computer and Network Security Page 2
Some Attack Categories
• Control-flow Attacks
‣ Adversary directs program control-flow
• E.g., return address overwrite through buffer overflow
• Data Attacks
‣ Adversary exploits flaw to read/modify unexpected data
• E.g., critical variable overwrite through buffer overflow
• Code Injection Attacks
‣ Adversary tricks the program into executing their input
• E.g., SQL injection attacks
• Other types of attacks on unauthorized access (later)
• See CWE (http://cwe.mitre.org/)
CSE543 - Introduction to Computer and Network Security Page 3
Memory Errors
• Many attacks are possible because some programming
languages allow memory errors
‣ C and C++ for example
• A memory error occurs when the program allows an
access to a variable to read/write to memory beyond
what is allocated to that variable
‣ E.g., read/write beyond the end of a string
‣ Access memory next to the string
• Memory errors may be exploited to change the
program’s control-flow or data-flow or to allow
injection of code
CSE543 - Introduction to Computer and Network Security Page 4
A Simple Program
void myfunc()
{
char string[16];
printf("Enter a string\n");
scanf(“%s”, string);
printf(“You entered: %s\n”, string);
}
int main()
{
myfunc();
}
CSE543 - Introduction to Computer and Network Security Page 5
What Happened?
• Brief refresher on program address space
‣ Stack -- local variables
Stack
‣ Heap -- dynamically allocated (malloc, free)
‣ Data -- global, uninitialized variables
‣ Text -- program code
Heap
Data
Text
CSE543 - Introduction to Computer and Network Security Page 6
What Happened?
• Stack Layout
main() parameters(argc, argv)
Stack
return address
saved frame pointer
main() local vars
myfunc() parameters (void)
sghfjdsh return address
saved frame pointer
gjlkhgfd
myfunc() local vars
jlkseghrueioshja
string[16]
CSE543 - Introduction to Computer and Network Security Page 7
Exploiting Buffer Overflow
• Stack Layout
main() parameters(argc, argv)
Stack
return address
saved frame pointer
main() local vars
myfunc() parameters (void)
return address
address of string
saved frame pointer
more evil code
myfunc() local vars
my evil code
string[16]
CSE543 - Introduction to Computer and Network Security Page 8
Prevent Code Injection
• What if we made the stack non-executable?
‣ AMD NX-bit
‣ More general: W (xor) X
(DEP in Windows)
myfunc() parameters (void)
pc of libc call()
return address
argumentssaved
for frame pointer
libc call
myfunc() local vars
string[16]
CSE543 - Introduction to Computer and Network Security Page 9
Protect the Return Address
• Stackparameters(argc,
main() Layout argv)
• “Canary” on the stack
return address ‣ Random value placed
saved frame pointer between the local vars
and the return address
main() local vars
‣ If canary is modified,
myfunc() parameters (void) program is stopped
return address • Have we solved buffer
CANARY
overflows?
saved frame pointer
myfunc() local vars
string[16]
CSE543 - Introduction to Computer and Network Security Page 10
Canary Shortcomings
• Stackparameters(argc,
main() Layout argv)
• Other local variables?
return address • Frame pointers?
saved frame pointer • Anything left
main() local vars unprotected on stack
can be used to launch
myfunc() parameters (void)
attacks
return address
• Not possible to protect
CANARY everything
saved frame pointer ??? • Varargs
myfunc() local vars ??? • Structure members
string[16] • Performance
CSE543 - Introduction to Computer and Network Security Page 11
A Simple Program
int authenticated = 0;
char packet[1000];
while (!authenticated) {
PacketRead(packet);
if (Authenticate(packet))
authenticated = 1;
}
if (authenticated)
ProcessPacket(packet);
CSE543 - Introduction to Computer and Network Security Page 12
A Simple Program
int authenticated = 0;
char packet[1000];
What if packet is only
while (!authenticated) {
PacketRead(packet); 1004 bytes?
if (Authenticate(packet))
authenticated = 1; myfunc() parameters
} return address
if (authenticated)
CANARY
ProcessPacket(packet);
saved frame pointer
int authenticated
char packet[1000]
CSE543 - Introduction to Computer and Network Security Page 13
Overflow of Local Variables
• Don’t need to modify return address
‣ Local variables may affect control
• What kinds of local variables would impact control?
‣ Ones used in conditionals (example)
‣ Function pointers
• What can you do to prevent that?
CSE543 - Introduction to Computer and Network Security Page 14
A Simple Program
int authenticated = 0;
char *packet = (char *)malloc(1000);
while (!authenticated) { What if we allocate the
PacketRead(packet); packet buffer on the heap?
if (Authenticate(packet))
authenticated = 1;
}
if (authenticated)
ProcessPacket(packet);
CSE543 - Introduction to Computer and Network Security Page 15
Heap Overflows
• Overflows on heap also possible
char *packet = malloc(1000)
packet[1000] = ‘M’;
• “Classical” heap overflow corrupts
metadata
‣ Heap metadata maintains chunk size,
previous and next pointers, ...
• Heap metadata is inline with
heap data
‣ And waits for heap management
functions (malloc, free) to
write corrupted metadata to
target locations
CSE543 - Introduction to Computer and Network Security Page 16
Heap Overflows
• Heap allocators maintain a doubly-linked list of allocated
and free chunks
• malloc() and free() modify this list
• http://www.sans.edu/student-files/presentations/heap_overflows_notes.pdf
CSE543 - Introduction to Computer and Network Security Page 17
Heap Overflows
• free() removes a chunk from allocated list
chunk2->bk->fd = chunk2->fd
chunk2->fd->bk = chunk2->bk
• By overflowing chunk2, attacker controls bk and fd
‣ Controls both where and what data is written!
• Arbitrarily change memory (e.g., function pointers)
CSE543 - Introduction to Computer and Network Security Page 18
Heap Overflows
• free() removes a chunk from allocated list
chunk2->bk->fd = chunk2->fd v[chunk1+8]= chunk3
chunk2->fd->bk = chunk2->bk v[chunk3+12] = chunk1
• By overflowing chunk2, attacker controls bk and fd
‣ Controls both where and what data is written!
• Arbitrarily change memory (e.g., function pointers)
CSE543 - Introduction to Computer and Network Security Page 19
Heap Overflows
• By overflowing chunk2, attacker controls bk and fd
‣ Controls both where and what data is written!
• Assign chunk2->fd to value to want to write
• Assign chunk2->bk to address X (where you want to write)
• Less an offset of the fd field in the structure
• Free() removes a chunk from allocated list
chunk2->bk->fd = chunk2->fd
chunk2->fd->bk = chunk2->bk
• What’s the result?
CSE543 - Introduction to Computer and Network Security Page 20
Heap Overflows
• By overflowing chunk2, attacker controls bk and fd
‣ Controls both where and what data is written!
• Assign chunk2->fd to value to want to write
• Assign chunk2->bk to address X (where you want to write)
• Less an offset of the fd field in the structure
• Free() removes a chunk from allocated list
chunk2->bk->fd = chunk2->fd
chunk2->bk->fd = chunk2->fd => addrX+8 = value
addrX->fd = value If adversary wants to write
chunk2->fd->bk = chunk2->bk value 0xdeadbeef to address
0xbffffffc, she writes
value->bk = addrX
chunk2->fd = 0xdeadbeef
chunk2->bk = 0xbffffffc - 8
• What’s the result?
• Change a memory address to a new pointer value (in data)
CSE543 - Introduction to Computer and Network Security Page 21
Overflow Defenses
• Address space randomization
‣ Make it difficult to predict where a particular program
variable is stored in memory
• Rather than randomly locate every variable
‣ A simpler solution is to randomly offset each memory
region
• Address space layout randomization (ASLR)
‣ Stack and heap are located at different base addresses each
time the program is run
‣ NOTE: Always on a page offset, however, so limited in range
of bits available for randomization
• Also, works for buffer overflows
CSE543 - Introduction to Computer and Network Security Page 22
Other Heap Attacks
• Heap spraying
‣ Combat randomization by filling heap with allocated objects
containing malicious code
‣ Use another vulnerability to overwrite a function pointer to
any heap address, hoping it points to a sprayed object
‣ Heuristic defenses
• e.g., NOZZLE: If heap data is like
code, flag attack
• Use-after-free
‣ Type confusion
CSE543 - Introduction to Computer and Network Security Page 23
Heap Overflow Defenses
• Separate data and metadata
‣ e.g., OpenBSD’s allocator (Variation of PHKmalloc)
• Sanity checks during heap management
free(chunk2) -->
assert(chunk2->fd->bk == chunk2)
assert(chunk2->bk->fd == chunk2)
‣ Added to GNU libc 2.3.5
• Randomization
• Q. What are analogous defenses for stack overflows?
CSE543 - Introduction to Computer and Network Security Page 24
Another Simple Program
int size = BASE_SIZE;
char *packet = (char *)malloc(1000);
char *buf = (char *)malloc(1000+BASE_SIZE);
strcpy(buf, FILE_PREFIX);
Any problem with this
size += PacketRead(packet);
if (size >= 1000+BASE_SIZE)) {
conditional check?
return(-1)
}
else
strcat(buf, packet);
fd = open(buf);
}
CSE543 - Introduction to Computer and Network Security Page 25
Integer Overflow
• Signed variables represent positive and negative values
‣ Consider an 8-bit integer: -128 to 127
‣ Weird math: 127+1 = ???
• This results in some strange behaviors
‣ size += PacketRead(packet)
• What is the possible value of size?
‣ if ( size >= 1000+BASE_SIZE ) … {
• What is the possible result of this condition?
• How do we prevent these errors?
CSE543 - Introduction to Computer and Network Security Page 26
Another Simple Program
int size = BASE_SIZE;
char *packet = (char *)malloc(1000);
char *buf = (char *)malloc(1000+BASE_SIZE);
strcpy(buf, FILE_PREFIX);
size += PacketRead(packet);
if ( size < 1000+BASE_SIZE) {
strcat(buf, packet); Any problem with this
fd = open(buf); printf?
printf(packet);
}
CSE543 - Introduction to Computer and Network Security Page 27
Format String Vulnerability
• Attacker control of the format string results in a format
string vulnerability
‣ printf is a very versatile function
• %s - dereferences (crash program)
‣ printf(“Hello %s”); //expects 2 args
• %x - print addresses (leak addresses, break ASLR)
‣ printf(“Hello %x %x %x”); // expects 4 arguments
• %n - write to address (arbitrarily change memory)
‣ printf (“12345%n”, &x); // writes 5 into x
• Never use
‣ printf(string);
• Instead, use
CSE543 - Introduction to Computer and Network Security Page 28
Take Away
• Programs have function
‣ Adversaries can exploit unexpected functions
• Vulnerabilities due to malicious input
‣ Subvert control-flow or critical data
• Buffer, heap, integer overflows, format string vulnerabilities
‣ Injection attacks
• Application-dependent
• If applicable, write programs in languages that eliminate
classes of vulnerabilities
‣ E.g., Type-safe languages such as Java
CSE543 - Introduction to Computer and Network Security Page 29