buffer overflows - courses.cs.washington.edu€¦ · buffer overflows spring 2016 x86-64 linux...
Embed Size (px)
TRANSCRIPT

Spring 2016Buffer Overflows
Bufferoverflows¢ BufferoverflowsarepossiblebecauseCdoesnotcheckarray
boundaries¢ Bufferoverflowsaredangerousbecausebuffersforuser
inputareoftenstoredonthestack
¢ Specifictopics:§ Addressspacelayout§ Inputbuffersonthestack§ Overflowingbuffersandinjectingcode§ Defensesagainstbufferoverflows
1

Spring 2016Buffer Overflows
x86-64LinuxMemoryLayout
¢ Stack§ Runtimestack(8MBlimit)§ E.g.,localvariables
¢ Heap§ Dynamicallyallocatedasneeded§ Whencallmalloc,calloc,new,…
¢ Data§ Staticallyallocateddata§ Read-only:stringliterals§ Read/write:globalarraysandvariables
¢ Code/SharedLibraries§ Executablemachineinstructions§ Read-only
HexAddress
0x00007FFFFFFFFFFF
0x000000
Stack
InstructionsData
Heap
0x400000
8MB
notdrawntoscale
SharedLibraries
2
Heap

Spring 2016Buffer Overflows
Reminder:x86-64/LinuxStackFrame
¢ Caller’s StackFrame§ Arguments(if>6args)forthiscall§ Returnaddress
§ Pushedbycall instruction
¢ Current/ Callee StackFrame§ Oldframepointer(optional)§ Savedregistercontext
(whenreusingregisters)§ Localvariables
(Ifcan’tbekeptinregisters)§ “Argumentbuild”area
(Ifcallee needstocallanotherfunction-parametersforfunctionabouttocall,ifneeded)
ReturnAddr
SavedRegisters
+Local
Variables
ArgumentBuild
(Optional)
Old%rbp
Arguments7+
CallerFrame
Framepointer%rbp
Stackpointer%rsp
(Optional)
3LowerAddresses
HigherAddresses

Spring 2016Buffer Overflows
MemoryAllocationExample
4
char big_array[1L<<24]; /* 16 MB */char huge_array[1L<<31]; /* 2 GB */
int global = 0;
int useless() { return 0; }
int main (){
void *p1, *p2, *p3, *p4;int local = 0;p1 = malloc(1L << 28); /* 256 MB */p2 = malloc(1L << 8); /* 256 B */p3 = malloc(1L << 32); /* 4 GB */p4 = malloc(1L << 8); /* 256 B *//* Some print statements ... */
}
notdrawntoscale
Wheredoeseverythinggo?
Stack
InstructionsData
Heap
SharedLibraries
Heap

Spring 2016Buffer Overflows
MemoryAllocationExample
5
char big_array[1L<<24]; /* 16 MB */char huge_array[1L<<31]; /* 2 GB */
int global = 0;
int useless() { return 0; }
int main (){
void *p1, *p2, *p3, *p4;int local = 0;p1 = malloc(1L << 28); /* 256 MB */p2 = malloc(1L << 8); /* 256 B */p3 = malloc(1L << 32); /* 4 GB */p4 = malloc(1L << 8); /* 256 B *//* Some print statements ... */
}
notdrawntoscale
Wheredoeseverythinggo?
Stack
InstructionsData
Heap
SharedLibraries
Heap

Spring 2016Buffer Overflows
x86-64ExampleAddresses
&local 0x00007ffe4d3be87c p1 0x00007f7262a1e010 p3 0x00007f7162a1d010 p4 0x000000008359d120 p2 0x000000008359d010 &big_array[0] 0x0000000080601060 huge_array 0x0000000000601060 main() 0x000000000040060cuseless() 0x0000000000400590
address range~24700007F
000000
InstructionsData
Heap
notdrawntoscale
Heap
Stack
6
Whatis&p1?(approximately)

Spring 2016Buffer Overflows
Today¢ MemoryLayout¢ BufferOverflow
§ Vulnerability§ Protection
7

Spring 2016Buffer Overflows
InternetWorm¢ ThesecharacteristicsofthetraditionalLinuxmemorylayout
provideopportunitiesformaliciousprograms§ Stackgrows“backwards”inmemory§ Dataandinstructionsbothstoredinthesamememory
¢ November,1988§ InternetWormattacksthousandsofInternethosts.§ Howdidithappen?
¢ Stackbufferoverflow exploits!
8

Spring 2016Buffer Overflows
BufferOverflowinanutshell¢ ManyclassicUnix/Linux/Cfunctionsdonotcheckargumentsizes¢ Cdoesnotcheckarraybounds¢ Allowsoverflowing(writingpasttheendof)buffers(arrays)¢ Overflowsofbuffersonthestackoverwriteinterestingdata¢ Attackersjustchoosetherightinputs¢ Whyabigdeal?
§ Itis(was?)the#1technical causeofsecurityvulnerabilities§ #1overall causeissocialengineering/userignorance
¢ Simplestform§ Uncheckedlengthsonstringinputs§ Particularlyforboundedcharacterarraysonthestack
§ sometimesreferredtoas“stacksmashing”
9

Spring 2016Buffer Overflows
StringLibraryCode¢ ImplementationofUnixfunctiongets()
§ Whatcouldgowronginthiscode?
/* 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;
}
10
pointertostartofanarray
sameas:*p=c;p++;

Spring 2016Buffer Overflows
StringLibraryCode¢ ImplementationofUnixfunctiongets()
§ Nowaytospecifylimit onnumberofcharacterstoread
¢ SimilarproblemswithotherUnixfunctions§ strcpy:Copiesstringofarbitrarylengthtoadest§ scanf,fscanf,sscanf,whengiven%s conversionspecification
11
/* 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;
}

Spring 2016Buffer Overflows
VulnerableBufferCode
void call_echo() {echo();
}
/* Echo Line */void echo(){
char buf[4]; /* Way too small! */gets(buf);puts(buf);
}
unix> ./bufdemo-nspType a string: 012345678901234567890123012345678901234567890123
unix> ./bufdemo-nspType a string: 0123456789012345678901234Segmentation Fault
12

Spring 2016Buffer Overflows
BufferOverflowDisassembly
00000000004006cf <echo>:4006cf: 48 83 ec 18 sub $0x24,%rsp4006d3: 48 89 e7 mov %rsp,%rdi4006d6: e8 a5 ff ff ff callq 400680 <gets>4006db: 48 89 e7 mov %rsp,%rdi4006de: e8 3d fe ff ff callq 400520 <puts@plt>4006e3: 48 83 c4 18 add $0x24,%rsp4006e7: c3 retq
4006e8: 48 83 ec 08 sub $0x8,%rsp4006ec: b8 00 00 00 00 mov $0x0,%eax4006f1: e8 d9 ff ff ff callq 4006cf <echo>4006f6: 48 83 c4 08 add $0x8,%rsp4006fa: c3 retq
call_echo:
echo:
13

Spring 2016Buffer Overflows
BufferOverflowStack
echo:subq $24, %rspmovq %rsp, %rdicall gets. . .
/* Echo Line */void echo(){
char buf[4]; /* Way too small! */gets(buf);puts(buf);
}
Beforecalltogets
14
Stackframeforcall_echo
Returnaddress(8bytes)
20bytesunused
[3] [2] [1] [0] buf ⟵%rsp

Spring 2016Buffer Overflows
BufferOverflowStackExampleecho:
subq $24, %rspmovq %rsp, %rdicall gets. . .
void echo(){
char buf[4]; gets(buf);. . .
}
Beforecalltogets
. . .4006f1: callq 4006cf <echo>4006f6: add $0x8,%rsp. . .
call_echo:
15
Stackframeforcall_echo
00 00 00 00
00 40 06 f6
20bytesunused
[3] [2] [1] [0] buf ⟵%rsp

Spring 2016Buffer Overflows
BufferOverflowStackExample#1Aftercalltogets
unix> ./bufdemo-nspType a string: 0123456789012345678901201234567890123456789012
Overflowedbuffer,butdidnotcorruptstate 16
Stackframeforcall_echo
00 00 00 00
00 40 06 f6
00 32 31 30
39 38 37 36
35 34 33 32
31 30 39 38
37 36 35 34
33 32 31 30
echo:subq $24, %rspmovq %rsp, %rdicall gets. . .
void echo(){
char buf[4]; gets(buf);. . .
}
. . .4006f1: callq 4006cf <echo>4006f6: add $0x8,%rsp. . .
call_echo:
buf ⟵%rsp

Spring 2016Buffer Overflows
BufferOverflowStackExample#2Aftercalltogets
unix> ./bufdemo-nspType a string: 0123456789012345678901234Segmentation Fault
Overflowedbufferandcorruptedreturnpointer 17
echo:subq $24, %rspmovq %rsp, %rdicall gets. . .
void echo(){
char buf[4]; gets(buf);. . .
}
. . .4006f1: callq 4006cf <echo>4006f6: add $0x8,%rsp. . .
call_echo:
buf ⟵%rsp
Stackframeforcall_echo
00 00 00 00
00 40 00 34
33 32 31 30
39 38 37 36
35 34 33 32
31 30 39 38
37 36 35 34
33 32 31 30

Spring 2016Buffer Overflows
BufferOverflowStackExample#3Aftercalltogets
unix> ./bufdemo-nspType a string: 012345678901234567890123012345678901234567890123
Overflowedbuffer,corruptedreturnpointer,butprogramseemstowork! 18
echo:subq $24, %rspmovq %rsp, %rdicall gets. . .
void echo(){
char buf[4]; gets(buf);. . .
}
. . .4006f1: callq 4006cf <echo>4006f6: add $0x8,%rsp. . .
call_echo:
buf ⟵%rsp
Stackframeforcall_echo
00 00 00 00
00 40 06 00
33 32 31 30
39 38 37 36
35 34 33 32
31 30 39 38
37 36 35 34
33 32 31 30

Spring 2016Buffer Overflows
BufferOverflowStackExample#3ExplainedAftercalltogets
. . .400600: mov %rsp,%rbp400603: mov %rax,%rdx400606: shr $0x3f,%rdx40060a: add %rdx,%rax40060d: sar %rax400610: jne 400614400612: pop %rbp400613: retq
register_tm_clones:
“Returns”tounrelatedcodeLotsofthingshappen,withoutmodifyingcriticalstateEventuallyexecutesretq backtomain
19
buf ⟵%rsp
Stackframeforcall_echo
00 00 00 00
00 40 06 00
00 32 31 30
39 38 37 36
35 34 33 32
31 30 39 38
37 36 35 34
33 32 31 30

Spring 2016Buffer Overflows
MaliciousUseofBufferOverflow:CodeInjectionAttacks
¢ Inputstringcontainsbyterepresentationofexecutablecode¢ OverwritereturnaddressAwithaddressofbufferB¢ Whenbar() executes ret,willjumptoexploitcode
int bar() {char buf[64]; gets(buf); ...return ...;
}
void foo(){bar();
A:...}
returnaddressA
Stackaftercalltogets()
A (returnaddress)
foo stackframe
bar stackframe
B
exploitcode
paddatawrittenbygets()
20
LowAddresses
HighAddresses
AB+24
buf startshere

Spring 2016Buffer Overflows
ExploitsBasedonBufferOverflows¢ Bufferoverflowbugscanallowremotemachinestoexecute
arbitrarycodeonvictimmachines¢ Distressinglycommoninrealprograms
§ ProgrammerskeepmakingthesamemistakesL§ Recentmeasuresmaketheseattacksmuchmoredifficult
¢ Examplesacrossthedecades§ Original“Internetworm”(1988)§ Stillhappens!!Heartbleed (2014,affected17%ofservers)§ Fun: Nintendohacks
§ Usingglitchestorewritecode:https://www.youtube.com/watch?v=TqK-2jUQBUY
§ FlappyBird inMario:https://www.youtube.com/watch?v=hB6eY73sLV0
§ …andmany,manymore
¢ Youwilllearnsomeofthetricksinlab3§ Hopefullytoconvinceyoutoneverleavesuchholesinyourprograms!!
21

Spring 2016Buffer Overflows
Example:theoriginalInternetworm(1988)¢ Exploitedafewvulnerabilitiestospread
§ Earlyversionsofthefingerserver(fingerd)usedgets() toreadtheargumentsentbytheclient:§ finger [email protected]
§ Wormattackedfingerd serverbysendingphonyargument:§ finger “exploit-code padding new-return-address”
§ exploitcode:executedarootshellonthevictimmachinewithadirectTCPconnectiontotheattacker.
¢ Onceonamachine,scannedforothermachinestoattack§ invaded~6000computersinhours(10%oftheInternetJ )
§ seeJune1989articleinComm.oftheACM§ theyoungauthorofthewormwasprosecuted…
22

Spring 2016Buffer Overflows
Heartbleed(2014!)¢ Bufferover-readinOpenSSL
§ Opensourcesecuritylibrary§ Buginasmallrangeofversions
¢ “Heartbeat”packet§ Specifieslengthofmessage§ Serverechoesitback§ Libraryjust“trusted”thislength§ Allowedattackerstoreadcontents
ofmemoryanywheretheywanted
¢ Est.17%ofInternetaffected§ “Catastrophic”§ Github,Yahoo,
StackOverflow,AmazonAWS,...
23
ByFenixFeather - Ownwork,CCBY-SA 3.0,https://commons.wikimedia.org/w/index.php?curid=32276981

Spring 2016Buffer Overflows
Whattodoaboutbufferoverflowattacks…1. Avoidoverflowvulnerabilities
2. Employsystem-levelprotections
3. Havecompileruse“stackcanaries”
¢ Letstalkabouteach…
24

Spring 2016Buffer Overflows
1.AvoidOverflowVulnerabilitiesinCode(!)
¢ Uselibraryroutinesthatlimitstringlengths§ fgets insteadofgets (secondargumenttofgets setslimit)§ strncpy insteadofstrcpy§ Don’tusescanfwith%s conversionspecification
§ Usefgets toreadthestring§ Oruse%nswheren isasuitableinteger
/* Echo Line */void echo(){
char buf[4]; /* Way too small! */fgets(buf, 4, stdin);puts(buf);
}
25

Spring 2016Buffer Overflows
2.System-LevelProtectionscanhelpRandomizedstackoffsets¢ Atstartofprogram,allocaterandomamountof
spaceonstack¢ Shifts stackaddressesforentireprogram
§ Addresseswillvaryfromoneruntoanother¢ Makesitdifficult forhackertopredictbeginning of
insertedcode¢ E.g.:5executionsofmemoryallocationcodefrom
slide4,addressofvariablelocal changeseachtime:§ 0x7ffe4d3be87c
§ 0x7fff75a4f9fc
§ 0x7ffeadb7c80c
§ 0x7ffeaea2fdac
§ 0x7ffcd452017c
§ Stackrepositionedeachtimeprogramexecutes
main’sstackframe
Otherfunctions’
stackframes
Randomallocation
B?
B?
exploitcode
pad
26
LowAddresses
HighAddresses

Spring 2016Buffer Overflows
2.System-LevelProtectionscanhelpNon-executablecodesegments¢ Intraditionalx86,canmarkregionof
memoryaseither“read-only”or“writeable”§ Canexecuteanythingreadable
¢ X86-64addedexplicit“execute”permission
¢ Stackmarkedasnon-executable§ DoNOTexecutecodeinstack,data,
orheapregions§ Hardwaresupportneeded
Stackaftercalltogets()
B
foo stackframe
bar stackframe
B
exploitcode
paddatawrittenbygets()
Anyattempttoexecutethiscodewill fail
27

Spring 2016Buffer Overflows
3.StackCanariescanhelp¢ Idea
§ Placespecialvalue(“canary”)onstackjustbeyondbuffer§ Secret valueknownonlytocompiler§ “After”bufferbutbeforereturnaddress
§ Checkforcorruptionbeforeexitingfunction
¢ GCCImplementation§ -fstack-protector
§ Nowthedefaultforgcc§ Codebackonslide12(bufdemo-nsp) compiledwithoutthisoption
unix>./bufdemo-spType a string: 01234560123456
unix> ./bufdemo-spType a string: 01234567*** stack smashing detected ***
28

Spring 2016Buffer Overflows
Protected BufferDisassembly
40072f: sub $0x18,%rsp400733: mov %fs:0x28,%rax40073c: mov %rax,0x8(%rsp)400741: xor %eax,%eax400743: mov %rsp,%rdi400746: callq 4006e0 <gets>40074b: mov %rsp,%rdi40074e: callq 400570 <puts@plt>400753: mov 0x8(%rsp),%rax400758: xor %fs:0x28,%rax400761: je 400768 <echo+0x39>400763: callq 400580 <__stack_chk_fail@plt>400768: add $0x18,%rsp40076c: retq
echo:
29

Spring 2016Buffer Overflows
SettingUpCanary
echo:. . .movq %fs:40, %rax # Get canarymovq %rax, 8(%rsp) # Place on stackxorl %eax, %eax # Erase canary. . .
/* Echo Line */void echo(){
char buf[4]; /* Way too small! */gets(buf);puts(buf);
}
Beforecalltogets
30
Stackframeforcall_echo
Returnaddress(8bytes)
Canary(8bytes)
[3] [2] [1] [0]
Segmentregister(don’tworryabout it)
buf ⟵%rsp

Spring 2016Buffer Overflows
CheckingCanary
echo:. . .movq 8(%rsp), %rax # Retrieve from stackxorq %fs:40, %rax # Compare to canaryje .L6 # If same, OKcall __stack_chk_fail # FAIL
.L6:. . .
/* Echo Line */void echo(){
char buf[4]; /* Way too small! */gets(buf);puts(buf);
}
Aftercalltogets
Input:0123456
31
Stackframeforcall_echo
Returnaddress(8bytes)
Canary(8bytes)
00 36 35 34
33 32 31 30 buf ⟵%rsp

Spring 2016Buffer Overflows
Summary:Avoidingbufferoverflowattacks1. Avoidoverflowvulnerabilities
§ Uselibraryroutinesthatlimitstringlengths
2. Employsystem-levelprotections§ RandomizedStackoffsets§ Codeonthestackisnotexecutable
3. Havecompileruse“stackcanaries”
32