Buffer overflows - courses.cs.washington.edu€¦ · Buffer Overflows Spring 2016 x86-64 Linux...

Click here to load reader

  • date post

    28-Sep-2020
  • Category

    Documents

  • view

    6
  • download

    0

Embed Size (px)

Transcript of Buffer overflows - courses.cs.washington.edu€¦ · Buffer Overflows Spring 2016 x86-64 Linux...

  • 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

  • Spring 2016Buffer Overflows

    MemoryAllocationExample

    5

    char big_array[1L

  • 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 :4006cf: 48 83 ec 18 sub $0x24,%rsp4006d3: 48 89 e7 mov %rsp,%rdi4006d6: e8 a5 ff ff ff callq 400680 4006db: 48 89 e7 mov %rsp,%rdi4006de: e8 3d fe ff ff callq 400520 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 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 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 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 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 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 40074b: mov %rsp,%rdi40074e: callq 400570 400753: mov 0x8(%rsp),%rax400758: xor %fs:0x28,%rax400761: je 400768 400763: callq 400580 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