10 Machine Bugs
10 Machine Bugs
Machine-Level Programming:
Bugs
COMP 222: Introduction to Computer Organization
Instructor:
Alan L. Cox
Vulnerability
Protection
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
Vulnerability
Protection
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
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
void call_echo() {
is big enough?
echo();
}
unix>./bufdemo-nsp
Type a string:012345678901234567890123
012345678901234567890123
unix>./bufdemo-nsp
Type a string:0123456789012345678901234
Segmentation Fault
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
/* Echo Line */
Return Address void echo()
(8 bytes) {
char buf[4]; /* Way too small! */
gets(buf);
puts(buf);
20 bytes unused }
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
unix>./bufdemo-nsp
Type a string:01234567890123456789012
01234567890123456789012
unix>./bufdemo-nsp
Type a string:0123456789012345678901234
Segmentation Fault
unix>./bufdemo-nsp
Type a string:012345678901234567890123
012345678901234567890123
void P(){
P stack frame
Q(); return
... address
} A B
unix>./bufdemo-sp
Type a string:0123456
0123456
unix>./bufdemo-sp
Type a string:01234567
*** stack smashing detected ***
20 bytes unused
Canary
(8 bytes)
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
*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
Gadget 2 code c3
%rsp
Gadget 1 code c3