Software Security Return to Libc and ROP Jan Nordholz Prof. - - PowerPoint PPT Presentation

software security
SMART_READER_LITE
LIVE PREVIEW

Software Security Return to Libc and ROP Jan Nordholz Prof. - - PowerPoint PPT Presentation

Software Security Return to Libc and ROP Jan Nordholz Prof. Jean-Pierre Seifert Security in Telecommunications TU Berlin SoSe 2014 jan (sect) Software Security SoSe 2014 1 / 13 Recap: Overflow Bugs Ingredients: fixed-size buffer on the


slide-1
SLIDE 1

Software Security

Return to Libc and ROP Jan Nordholz

  • Prof. Jean-Pierre Seifert

Security in Telecommunications TU Berlin

SoSe 2014

jan (sect) Software Security SoSe 2014 1 / 13

slide-2
SLIDE 2

Recap: Overflow Bugs

Ingredients:

fixed-size buffer on the stack missing bounds check while writing to buffer executable stack

Recipe:

  • verflow buffer
  • verwrite return pointer beyond buffer

return into attack code stored in buffer wreak havoc

jan (sect) Software Security SoSe 2014 2 / 13

slide-3
SLIDE 3

XD / NX

Recap: processor’s paging mechanism translates virtual to physical addresses. Translation entries also contain flags, e. g. permission bits. Historically: only one bit for writability. R and X always granted. Around 2000: AMD64 / Intel PAE introduce the NX / XD bit (respectively). NX/XD: marks a page as non-executable. ⇒ Non-code areas can now be made non-executable!

jan (sect) Software Security SoSe 2014 3 / 13

slide-4
SLIDE 4

Back to Overflow Bugs

Ingredients:

fixed-size buffer on the stack missing bounds check while writing to buffer NON-executable stack

Recipe:

  • verflow buffer
  • verwrite return pointer beyond buffer

try to return into attack code stored in buffer SEGMENTATION FAULT

jan (sect) Software Security SoSe 2014 4 / 13

slide-5
SLIDE 5

Options for placing attack code

Placing attack code into the overflowed stack buffer: hopeless. Stuffing the code into the environment before launching the vulnerable program: also on the stack, so hopeless. Heap, other global variables. . . : non-executable, so hopeless, too. Areas that are executable cannot be written to. ⇒ The only natural conclusion: Use code that’s already there!

jan (sect) Software Security SoSe 2014 5 / 13

slide-6
SLIDE 6

Return to Libc

Assumption: we know the address of system(). . . . . . and we have a stack buffer we can overflow, as before. Idea: instead of calling the function (as regular code would), we ret into it. Remember:

call itself pushes the return pointer the called function pushes the caller’s frame pointer onto the stack arguments to the called function start at %ebp + 8

On the other hand:

ret pops one word from the stack we have to take this into account when preparing arguments

jan (sect) Software Security SoSe 2014 6 / 13

slide-7
SLIDE 7

Return to Libc

Stack pointer will be at ”filler” when we enter system() Function will mistake this as its return address. . . . . . push the caller’s frame pointer below it. . . . . . and expect arguments above it. (Cf. picture.) ⇒ If you know the address of system(): easy as pie. You might not always know (see next week, keyword: ASLR). Or your libc may come with system() disabled.

jan (sect) Software Security SoSe 2014 7 / 13

slide-8
SLIDE 8

Interlude: Code at the Machine Level

Skeleton of a usual function:

setup frame pointer push registers the function is going to use (i. e. clobber) make room for local variables (subtract from stack pointer) (function body) reclaim room restore register state possibly adjust/set return value unwind frame pointer, return

Idea: return into the footer of a function, executing a few instructions

  • f choice before hitting the inevitable return.

⇒ That next return is also controlled by us (we own the stack)!

jan (sect) Software Security SoSe 2014 8 / 13

slide-9
SLIDE 9

Return Oriented Programming (ROP)

pop %ebx ret We target this code fragment with our first return. Pops the next value from the stack into EBX (which we control!). . . and returns again, once more to a value of our choice. ⇒ Technically equivalent to mov $CONSTANT, %ebx in ”normal” shellcode Find suitable fragments for all registers we want to set. . . daisy-chain them to form our exploit! We don’t care about other registers being clobbered. If a function epilogue we want to use adjusts the stack pointer, just include enough padding room into our ROP chain.

jan (sect) Software Security SoSe 2014 9 / 13

slide-10
SLIDE 10

Return Oriented Programming (ROP)

Usual ROP exploits chain dozens of fragments (gadgets) together. Virtually every possible instruction has a ”translation” in ROP. Some might require more than one gadget, though. Stack space required usually extends way beyond the overflowed buffer (amount depends on the space efficiency of selected gadgets,

  • i. e. the amount of stack pointer adjustment incurred)

Number of available gadgets depends on size of executable and whether library load adresses are known

jan (sect) Software Security SoSe 2014 10 / 13

slide-11
SLIDE 11

Unaligned ROP

Number of gadgets is even higher on architectures with variable-size instructions (x86). Consider: 8B5C2420 mov ebx,[esp+0x20] 8B742424 mov esi,[esp+0x24] 8B7C2428 mov edi,[esp+0x28] 83C42C add esp,byte +0x2c C3 ret There is no inherent notion of ”alignment”! What would happen if we ROP to the 5C instead of the 8B?

jan (sect) Software Security SoSe 2014 11 / 13

slide-12
SLIDE 12

Unaligned ROP

8B5C2420 mov ebx,[esp+0x20] 8B742424 mov esi,[esp+0x24] 8B7C2428 mov edi,[esp+0x28] 83C42C add esp, +0x2c C3 ret 5C pop esp 2420 and al,0x20 8B742424 mov esi,[esp+0x24] 8B7C2428 mov edi,[esp+0x28] 83C42C add esp, +0x2c C3 ret We now have a pop esp, i. e. we could continue our ROP exploit from a different memory location (good if we’re running low on overflowable stack space) Note: x86 code stream reconverges pretty fast. ⇒ The already large number of gadgets increases again!

jan (sect) Software Security SoSe 2014 12 / 13

slide-13
SLIDE 13

Preventing ROP?

ROP reuses ”valid code” — hard to detect once the return pointer is

  • verwritten.

While initially restricted to gadgets in the executable (fixed load address), attackers can use ROP to read GOT/PLT and learn resolved library symbols Defense mechanisms must trigger earlier, i. e. detect stack corruption before forged return pointer is ”accepted” ⇒ Next week: defenses!

jan (sect) Software Security SoSe 2014 13 / 13