0% found this document useful (0 votes)
27 views32 pages

10 Machine Bugs

Uploaded by

ahktanov.a
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views32 pages

10 Machine Bugs

Uploaded by

ahktanov.a
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 32

Carnegie Mellon

Machine-Level Programming:
Bugs
COMP 222: Introduction to Computer Organization

Instructor:
Alan L. Cox

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 1


Machine-level Programming: Bugs
 Memory Layout
 Buffer Overflow

 Vulnerability
 Protection

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 2


not drawn to scale
x86-64 Linux Memory Layout
() 0000 7FFF FFFF F000
randomized
 Stack 128
8MB Stack %rsp
MB
 Runtime stack (8MB limit)
0000 7FFF F800 0000
 e.g., local variables randomized
 Heap Shared
 Dynamically allocated as needed Libraries
 When call malloc(), new
 Data
 Statically allocated data
 e.g., global vars, static vars, string constants
 Text / Shared Libraries
Heap
 Executable machine instructions
 Read-only Data
Text
Hex Address 40 0000
1000
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 0000 3
Memory Allocation not drawn to scale

Example 0000 7FFF FFFF F000


randomized
char big_array[1L << 24]; /* 16 MB */
char huge_array[1L << 31]; /* 2 GB */ Stack

int global = 0; randomized

int useless(void) { return 0; } Shared


Libraries
int main(void)
{
void *phuge1, *psmall2, *phuge3,
*psmall4;
int local = 0;
phuge1 = malloc(1L << 28); /* 256 MB */
psmall2 = malloc(1L << 8); /* 256 B */
phuge3 = malloc(1L << 32); /* 4 GB */ Heap
psmall4 = malloc(1L << 8); /* 256 B */
// Some print statements ... Data
} Text
40 0000
Where does everything go?
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 4
x86-64 Example not drawn to scale

Addresses 0000 7FFF FFFF F000


randomized

ddress range ~247 Stack

randomized

Shared
local 0x00007ffe4d3be87c
Libraries
phuge1 0x00007f7262a1e010
and Huge
phuge3 0x00007f7162a1d010
Malloc Blocks
psmall4 0x000000008359d120
psmall2 0x000000008359d010
big_array 0x0000000080601060
huge_array 0x0000000000601060
main() 0x000000000040060c
useless() 0x0000000000400590
Heap
(Exact values can vary)
Data
Text
40 0000

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 5


Machine-level Programming: Bugs
 Memory Layout
 Buffer Overflow

 Vulnerability
 Protection

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 6


Carnegie Mello

Recall: Memory Referencing Bug


Example
typedef struct {
int a[2];
double d;
} struct_t;

double fun(int i) {
volatile struct_t s;
s.d = 3.14;
s.a[i] = 1073741824; /* Possibly out of bounds */
return s.d;
}

fun(0) ➙ 3.14
fun(1) ➙ 3.14
fun(2) ➙ 3.1399998664856
fun(3) ➙ 2.00000061035156
fun(4) ➙ 3.14
fun(6) ➙ Segmentation fault
 Result is system specific
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 7
Carnegie Mello

Memory Referencing Bug


Example
typedef struct { fun(0) ➙ 3.14
int a[2]; fun(1) ➙ 3.14
double d; fun(2) ➙ 3.1399998664856
} struct_t;
fun(3) ➙ 2.00000061035156
fun(4) ➙ 3.14
fun(6) ➙ Segmentation fault

Explanation:
Critical State 6
? 5
? 4
d7 ... d4 3 Location accessed by
d3 ... d0 2 fun(i)
struct_t
a[1] 1
a[0] 0

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 8


Such problems are a BIG
deal
 Generally called a “buffer overflow”
 when exceeding the memory size allocated for an array
 Why a big deal?
 It’s the #1 technical cause of security vulnerabilities
 #1 overall cause is social engineering / user ignorance
 Most common form
 Unchecked lengths on string inputs
 Particularly for bounded character arrays on the stack
 sometimes referred to as stack smashing

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 9


(Old) Standard Library Code
 Implementation of function gets()
/* Get string from stdin */
char *gets(char *dest)
{
int c = getchar();
char *p = dest;
while (c != EOF && c != '\n') {
*p++ = c;
c = getchar();
}
*p = '\0';
return dest;
}

 No way to specify limit on number of characters to read


 Similar problems with other library functions
 strcpy, strcat: Copy strings of arbitrary length
 scanf, fscanf, sscanf, when given %s conversion specification
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 10
Vulnerable Buffer Code
/* Echo Line */
void echo()
{
char buf[4];
gets(buf);
puts(buf);
/* Way too small! */
btw, how big
}

void call_echo() {
is big enough?
echo();
}

unix>./bufdemo-nsp
Type a string:012345678901234567890123
012345678901234567890123

unix>./bufdemo-nsp
Type a string:0123456789012345678901234
Segmentation Fault

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 11


Buffer Overflow
Disassembly
echo:
00000000004006cf <echo>:
4006cf: 48 83 ec 18 sub $0x18,%rsp
4006d3: 48 89 e7 mov %rsp,%rdi
4006d6: e8 a5 ff ff ff callq 400680 <gets>
4006db: 48 89 e7 mov %rsp,%rdi
4006de: e8 3d fe ff ff callq 400520 <puts@plt>
4006e3: 48 83 c4 18 add $0x18,%rsp
4006e7: c3 retq

call_echo:
4006e8: 48 83 ec 08 sub $0x8,%rsp
4006ec: b8 00 00 00 00 mov $0x0,%eax
4006f1: e8 d9 ff ff ff callq 4006cf <echo>
4006f6: 48 83 c4 08 add $0x8,%rsp
4006fa: c3 retq

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 12


Buffer Overflow Stack
Before call to gets
Stack Frame
for call_echo

/* Echo Line */
Return Address void echo()
(8 bytes) {
char buf[4]; /* Way too small! */
gets(buf);
puts(buf);
20 bytes unused }

[3] [2] [1] [0] buf %rsp

echo:
subq $24, %rsp
movq %rsp, %rdi
call gets
. . .
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 13
Buffer Overflow Stack
Example
Before call to gets
void echo() echo:
Stack Frame { subq $24, %rsp
for call_echo char buf[4]; movq %rsp, %rdi
gets(buf); call gets
. . . . . .
00 00 Address
Return 00 00 }
00 (8
40bytes)
06 f6
call_echo:
. . .
20 bytes unused 4006f1: callq 4006cf <echo>
4006f6: add $0x8,%rsp
. . .
[3] [2] [1] [0] buf %rsp

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 14


Buffer Overflow Stack
Example
After call to gets #1
void echo() echo:
Stack Frame { subq $24, %rsp
for call_echo char buf[4]; movq %rsp, %rdi
gets(buf); call gets
. . . . . .
00 00 Address
Return 00 00 }
00 (8
40bytes)
06 f6
00 32 31 30 call_echo:
39 38 37 36 . . .
20 bytes
35 34 unused
33 32 4006f1: callq 4006cf <echo>
31 30 39 38 4006f6: add $0x8,%rsp
37 36 35 34 . . .
33 32 31 30 buf %rsp

unix>./bufdemo-nsp
Type a string:01234567890123456789012
01234567890123456789012

Overflowed buffer, but did not corrupt state


Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 15
Buffer Overflow Stack
Example
After call to gets #2
void echo() echo:
Stack Frame { subq $24, %rsp
for call_echo char buf[4]; movq %rsp, %rdi
gets(buf); call gets
. . . . . .
00 00 Address
Return 00 00 }
00 (8
40bytes)
00 34
33 32 31 30 call_echo:
39 38 37 36 . . .
20 bytes
35 34 unused
33 32 4006f1: callq 4006cf <echo>
31 30 39 38 4006f6: add $0x8,%rsp
37 36 35 34 . . .
33 32 31 30 buf %rsp

unix>./bufdemo-nsp
Type a string:0123456789012345678901234
Segmentation Fault

Overflowed buffer and corrupted return pointer


Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 16
Buffer Overflow Stack
Example
After call to gets #3
void echo() echo:
Stack Frame { subq $24, %rsp
for call_echo char buf[4]; movq %rsp, %rdi
gets(buf); call gets
. . . . . .
00 00 Address
Return 00 00 }
00 (8
40bytes)
06 00
33 32 31 30 call_echo:
39 38 37 36 . . .
20 bytes
35 34 unused
33 32 4006f1: callq 4006cf <echo>
31 30 39 38 4006f6: add $0x8,%rsp
37 36 35 34 . . .
33 32 31 30 buf %rsp

unix>./bufdemo-nsp
Type a string:012345678901234567890123
012345678901234567890123

Overflowed buffer, corrupted return pointer, but program seems to work!


Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 17
Buffer Overflow Stack Example
#3
AfterExplained
call to gets
Stack Frame
for call_echo
register_tm_clones:
. . .
400600: mov %rsp,%rbp
00 00 Address
Return 00 00 400603: mov %rax,%rdx
400606: shr $0x3f,%rdx
00 (8
40bytes)
06 00
40060a: add %rdx,%rax
33 32 31 30
40060d: sar %rax
39 38 37 36 400610: jne 400614
20 bytes
35 34 unused
33 32 400612: pop %rbp
31 30 39 38 400613: retq
37 36 35 34
33 32 31 30 buf %rsp

“Returns” to unrelated code


Lots of things happen, without modifying critical state
Eventually executes retq back to main

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 18


Code Injection Attacks
Stack after call to gets()

void P(){
P stack frame
Q(); return
... address
} A B

int Q() { data written pad


char buf[64]; by gets()
gets(buf);
... exploit Q stack frame
return ...; code
B
}

 Input string contains byte representation of executable code


 Overwrite return address A with address of buffer B

 When Q executes ret, will jump to exploit code


Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 19
Exploits Based on Buffer
Overflows
 Buffer overflow bugs can allow remote machines to
execute arbitrary code on victim machines
 Distressingly common in real progams

 Programmers keep making the same mistakes 


 Recent measures make these attacks much more difficult
 Examples across the decades
 Original “Internet worm” (1988)
 “IM wars” (1999)
 Twilight hack on Wii (2000s)
 … and many, many more
 You will learn some of the tricks in attacklab
 Hopefully to convince you to never leave such holes in your programs!!

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 20


OK, what to do about buffer
overflow attacks
 Avoid overflow vulnerabilities

 Employ system-level protections

 Have compiler use “stack canaries”

 Lets talk about each…

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 21


1. Avoid Overflow Vulnerabilities
in Code (!)
/* Echo Line */
void echo(void)
{
char buf[4]; /* Way too small! */
fgets(buf, 4, stdin);
puts(buf);
}

 For example, use library routines that limit string


lengths
 fgets instead of gets
 strlcpy instead of strcpy or strncpy
 Don’t use scanf with %s conversion specification
 Use fgets to read the string
 Or use %ns where n is a suitable integer
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 22
2. System-Level Protections
can help
 Randomized stack offsets Stack base
 At start of program, allocate random
amount of space on stack
Random
 Shifts stack addresses for entire allocation
program
 Makes it difficult for hacker to
predict beginning of inserted code main
 E.g.: 5 executions of memory Applicatio
allocation code n
Code
B?
 Stack repositioned each time
program executes pad
exploit
B? code

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 23


2. System-Level Protections
can help Stack after call to gets()
 Nonexecutable code
segments
 In traditional x86, can mark P stack frame
region of memory as either
“read-only” or “writeable” B
 Can execute anything
readable data written pad
 X86-64 added explicit “execute”by gets()
permission exploit Q stack frame
 Stack marked as non-executable code
B

Any attempt to execute this code will fail

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 24


3. Stack Canaries can help
 Idea
 Place special value (“canary”) on stack just beyond buffer
 Check for corruption before exiting function
 GCC Implementation
 -fstack-protector
 Now the default (disabled earlier)

unix>./bufdemo-sp
Type a string:0123456
0123456

unix>./bufdemo-sp
Type a string:01234567
*** stack smashing detected ***

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 25


Protected Buffer
Disassembly
echo:
40072f: sub $0x18,%rsp
400733: mov %fs:0x28,%rax
40073c: mov %rax,0x8(%rsp)
400741: xor %eax,%eax
400743: mov %rsp,%rdi
400746: callq 4006e0 <gets>
40074b: mov %rsp,%rdi
40074e: callq 400570 <puts@plt>
400753: mov 0x8(%rsp),%rax
400758: xor %fs:0x28,%rax
400761: je 400768 <echo+0x39>
400763: callq 400580 <__stack_chk_fail@plt>
400768: add $0x18,%rsp
40076c: retq

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 26


Setting Up Canary
Before call to gets
/* Echo Line */
Stack Frame void echo()
for call_echo {
char buf[4]; /* Way too small! */
gets(buf);
Return Address puts(buf);
(8 bytes) }

20 bytes unused
Canary
(8 bytes)

[3] [2] [1] [0] buf %rsp

echo:
. . .
movq %fs:40, %rax # Get canary
movq %rax, 8(%rsp) # Place on stack
xorl %eax, %eax # Erase canary
. . .
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 27
Checking Canary
After call to gets
Before call to gets /* Echo Line */
Stack Frame void echo()
forStack Frame
call_echo {
for main char buf[4]; /* Way too small! */
gets(buf);
Return Address puts(buf);
Return Address
(8 bytes) }
Saved %ebp
Saved %ebx
20 bytes unused
Canary Input: 0123456
(8Canary
bytes)
[3]
00 [2]36 [1]
35 [0]
34
33 32 31 30 buf %rsp
echo:
. . .
movq 8(%rsp), %rax # Retrieve from
stack
xorq %fs:40, %rax # Compare to canary
je .L6 # If same, OK
call
Bryant and O’Hallaron, Computer Systems: A Programmer’s __stack_chk_fail
Perspective, Third Edition # FAIL 28
Return-Oriented Programming
Attacks
 Challenge (for hackers)
 Stack randomization makes it hard to predict buffer location
 Marking stack nonexecutable makes it hard to insert binary code
 Alternative Strategy
 Use existing code

E.g., library code from stdlib
 String together fragments to achieve overall desired outcome
 Does not overcome stack canaries
 Construct program from gadgets
 Sequence of instructions ending in ret

Encoded by single byte 0xc3
 Code positions fixed from run to run
 Code is executable
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 29
Gadget Example #1
long ab_plus_c
(long a, long b, long c)
{

return a*b + c;

00000000004004d0 <ab_plus_c>:
4004d0: 48 0f af fe imul %rsi,%rdi
}
4004d4: 48 8d 04 17 lea (%rdi,%rdx,1),%rax

4004d8: c3 retq
rax  rdi + rdx
Gadget address = 0x4004d4

 Use tail end of existing functions

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 30


Gadget Example #2
void setval(unsigned *p) {

*p = 3347663060u;
Encodes movq %rax, %rdi

<setval>:
} 4004d9: c7 07 d4 48 89 c7 movl $0xc78948d4,(%rdi)
4004df: c3 retq

rdi  rax
Gadget address = 0x4004dc

 Repurpose byte codes

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 31


ROP Execution
Stack
Gadget n code c3




Gadget 2 code c3

%rsp
Gadget 1 code c3

 Trigger with ret instruction


 Will start executing Gadget 1
 Final ret in each gadget will start next one

Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 32

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy