• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
An introduction to ROP
 

An introduction to ROP

on

  • 6,010 views

Slides from my workshop at Hack.LU 2010 in Luxembourg. This workshop introduced the basic concepts of Return Oriented Programming with some hands-on exercises.

Slides from my workshop at Hack.LU 2010 in Luxembourg. This workshop introduced the basic concepts of Return Oriented Programming with some hands-on exercises.

Statistics

Views

Total Views
6,010
Views on SlideShare
5,975
Embed Views
35

Actions

Likes
15
Downloads
0
Comments
0

4 Embeds 35

http://hienact.wordpress.com 32
https://www.linkedin.com 1
http://www.linkedin.com 1
https://hienact.wordpress.com 1

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    An introduction to ROP An introduction to ROP Presentation Transcript

    • net-squareIntroduction to ROPa first look at return oriented programmingSaumil Shah, Net-SquareHack.LU 2010 - Luxembourg
    • net-squareIntroduction• DEP• EIP control• Ret2LibC• Return Oriented Programming
    • net-squareDEP• Hardware enforced (NX).• Data areas marked non-executable.– Stack marked non-executable.– Heap marked non-executable.• You can load your shellcode in the stackor the heap...• ...but you cant jump to it.
    • net-squareEIP control• Stack - forbidden• Heap - forbidden• Binary - OK• DLLs - OKProgram ImageHeapStackDLLDLLDLL
    • net-squareRet2LibC• Return to LibC.• Pioneered by Solar Designer in 1997.• EIP made to "return to a function".• Need control of the stack memory.– We usually have it.
    • net-squareRet2LibC - how does it work?• Create a fake frame on the stack.• After an overflowed function returns...• ...set the EIP return address to the newfunction.• Append the fake frame.• New function executes.– parameters consumed from the fake frame.• system("/bin/sh")
    • net-squareReturn Oriented Programming• Series of function returns.• Chained frames.• Transform EIP based primitives into stubsthat can be "returned into".• ESP is the new EIP!
    • net-squareTopics• Function calls and returns• Stack overflows revisited• Creating stack frames• Chaining frames• ESP control
    • net-squareCalling a function• Add two ints x, y.• add(3,4)• What does the callingframe look like?void add(int x, int y){int sum;sum = x + y;printf("%dn", sum);}int main(){add(3, 4);}
    • net-squareStack frame for add(3,4)frame for add()return address from add()34call add
    • net-squareReturn from add(3,4)• add() is about to return.• RET after epilogue of add().• Where does ESP point to?– immediately before the RET• What does the stack look like?
    • net-squareBefore the RETreturn address from add()34ESP
    • net-squareAnother function• Stack overflow infunc1.• Can we call add(5, 6)after returning fromfunc1?void func1(char *s){char buffer[128];strcpy(buffer, s);}int main(){func1(argv[1]);}
    • net-squareStack frame for func1()bufferreturn address from func1s
    • net-squarestrcpy(buffer, s)bufferreturn address from func1sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    • net-squareBefore the RETbufferreturn address from func1sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESP
    • net-squareAfter the RETbufferreturn address from func1sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEIP = 0x41414141ESP
    • net-squareReturn to add()• Insert a fake frame in the buffer.• Make func1() return to:add(01010101, 02020202)• What does the stack frame look like?
    • net-squarestrcpy(buffer, s)bufferreturn address from func1sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaddress of addreturn address from add0101010102020202
    • net-squareBefore func1() returnsbufferreturn address from func1sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaddress of addreturn address from add0101010102020202ESP
    • net-squareReturn to add()bufferreturn address from func1sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaddress of addreturn address from add0101010102020202ESPEIP = add()
    • net-squareReturn to add()• By carefully creating a frame...• ...we can make the program "return toour function".• We control the parameters.• We also control where to jump to afterour function returns.
    • net-squarevictim2.cint main(int argc, char *argv[]){add(3, 4);func1(argv[1]);}void func1(char *s){char buffer[128];strcpy(buffer, s);}void print_hello(void){printf("Hello Worldn");}void add(int x, int y){int sum;sum = x + y;printf("%d + %d = %dn", x, y, sum);}stack overflow lurks here!
    • net-squarevictim2.c• Compile victim2.c• Run victim2 under a debugger• Study the stack frame before add(3, 4)gcc victim2.c -o victim2gdb victim2
    • net-squaregdbing add• Set a breakpoint before add(3, 4)0x804836c <main>: push %ebp0x804836d <main+1>: mov %esp,%ebp0x804836f <main+3>: sub $0x8,%esp0x8048372 <main+6>: and $0xfffffff0,%esp0x8048375 <main+9>: mov $0x0,%eax0x804837a <main+14>: sub %eax,%esp0x804837c <main+16>: sub $0x8,%esp0x804837f <main+19>: push $0x40x8048381 <main+21>: push $0x30x8048383 <main+23>: call 0x80483de <add>0x8048388 <main+28>: add $0x10,%esp0x804838b <main+31>: cmpl $0x1,0x8(%ebp)
    • net-squareStack frame before add(3, 4)• Dump the stack• Continue(gdb) x/64 $esp0xbffff8ac: 0x08048388 0x00000003 0x00000004 0xbffff8c80xbffff8bc: 0x0804841c 0x40148f50 0x40012780 0xbffff8e80x0804838834
    • net-squareOverflowing func1()• Overflow func1 and......return to add(01010101, 02020202)• Create a fake frame.• Overwrite stack.• frame1.plreturn from func1param1param2return from add0x080483de0x010101010x020202020x42424242
    • net-squareframe1.pl• Creates the overflow buffer as follows:• Set this in an environment variable EGGand run victim2 with $EGG:080483deAAAAAA...140...AAAAAA 42424242 01010101 02020202distanceto EIPaddressof addreturnfrom addparam1 param2export EGG=`./frame1.pl`gdb victim2(gdb) run $EGG
    • net-squareESP• Where will ESP be after returning fromadd?• Verify080483deAAAAAA...140...AAAAAA 42424242 01010101 02020202(gdb) x/64 $esp0xbffff824: 0x01010101 0x02020202 0x08048400 0x40148f500xbffff834: 0x40012780 0xbffff858 0x4002e7f7 0x00000002ESP
    • net-squareChaining functions• After add(01010101, 02020202), we wantto run add(03030303, 04040404).• How should we set up the frames?• First, study the frame after add() returns.
    • net-squareAfter add() returnsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaddress of add424242420101010102020202ESPEIP = 42424242
    • net-squareWhere does the new frame go?AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaddress of add424242420101010102020202address of add??0303030304040404
    • net-squareWhere does the new frame go?• We get only ONE chance at strcpy.• How do we preserve params 01010101and 02020202?• We can only APPEND the second framebelow our first frame.• We have to UNWIND the first framebefore returning to the second frame.• Return to epilogue!
    • net-squareChaining the framesAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaddress of addaddress of POP/POP/RET0101010102020202address of add424242420303030304040404add(01010101, 02020202)add(03030303, 04040404)
    • net-squareKeeping ESP in controlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaddress of addaddress of POP/POP/RET0101010102020202address of add424242420303030304040404Return from func1Return to add()Return to POP/POP/RETPOPPOPESPRET - Return to add()Finally EIP = 0x42424242
    • net-squareframe2.pl• Creates the overflow buffer as follows:080483deAAAAAA...140...AAAAAA 0804843d 01010101 02020202distanceto EIPaddressof addPOP/POP/RETparam1 param2080483de 42424242 03030303 04040404addressof addreturnfrom addparam1 param2 Use msfelfscan tofind the address ofPOP/POP/RET fromvictim2 binary.
    • net-squareframe2.pl• Set this in an environment variable EGGand run victim2 with $EGG:export EGG=`./frame2.pl`gdb victim2(gdb) run $EGGStarting program: /home/user0/victim2 $EGG3 + 4 = 71010101 + 2020202 = 30303033030303 + 4040404 = 7070707Program received signal SIGSEGV, Segmentation fault.0x42424242 in ?? ()
    • net-squareIts all about ESP!• ESP is the new EIP.• ROP involves keeping the ESP movingthrough the frames on the stack.• Frames can be chained by returning toepilogues of functions.– to appropriately unwind the parameterspushed on the stack.• We must never lose sight of RET.
    • net-squareROP frames - generic approachf1(A, B)f2(X)f1(C, D)f3(P, Q, R, S)f2(Y)::& f1()& POP/POP/RETAB& f2()& POP/RETX& f3()& POPAD/RETPQR& f1()& POP/POP/RETCDjunkjunkjunk& f2()& POP/RETYS
    • net-squareTopics• Transforming classic EIP code to ROP• ROP vs. classic programming• Thinking in ROP terms• Assembling frames• Gadgets• Searching for gadgets• Generic techniques
    • net-squareEIP vs. ESPClassic EIP code• N ops = N instructions.• EIP increments.• ESP fluctuates.• The CPU increments EIPautomatically.ROP code• N ops = N frames.• ESP increments.• EIP fluctuates.• We have to control ESPthrough RET instructions.
    • net-squareTransform EIP code to ROP• Load two registers• Call a function– with params 3,4• How does thistranslate in ROPterms?mov eax, 14mov ecx, 02500000push 3push 4call 77fe3210
    • net-squareThinking in ROP terms??AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA14ESPPut 14 in the next stack word, and POPit into EAX.RETfunction bodyepilogueprologuevulnerable functionEIPmov eax, 14RETPOP EAXPOP EBXfunctionX700344fe700344fd700344ff
    • net-squareThinking in ROP terms700344feAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA14ESPRETfunction bodyepilogueprologuevulnerable functionEIPJump to address of "POP EAX; RET".Search function epilogues.RETPOP EAXPOP EBXfunctionXmov eax, 14
    • net-squareThinking in ROP terms700344fe??AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1402500000ESPRETfunction bodyepilogueprologuevulnerable functionEIPPlace 02500000 as the next stack word,to be loaded into ECX.RETPOP EAXPOP EBXfunctionXeax = 00000014mov ecx, 02500000
    • net-squareThinking in ROP terms700344fe6d894430AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1402500000RETfunction bodyepilogueprologuevulnerable functionWe now need an address of a "POP ECX;RET" sequence.RETPOP EAXPOP EBXfunctionXRETPOP ECXfunctionYESP EIPeax = 00000014mov ecx, 025000006d8944306d894431
    • net-squareThinking in ROP terms700344fe6d894430AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1402500000ESPRETfunction bodyepilogueprologuevulnerable function02500000 is popped into ECX.RETPOP EAXPOP EBXfunctionXEIPRETPOP ECXfunctionYeax = 00000014mov ecx, 02500000
    • net-squareThinking in ROP terms700344fe6d894430AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1402500000??ESPRETfunction bodyepilogueprologuevulnerable functionWe now need to call a function at77fe3210, with parameters 3, 4RETPOP EAXPOP EBXfunctionXEIP RETPOP ECXfunctionYpush 3; push 4; call 77fe3210eax = 00000014 ecx = 02500000
    • net-squareGadget DictionaryPOP EAX; RETLoad value intoregistervaluePOP ECX; RETRead memory ataddressaddressADD EAX,n; RETAddMOV EAX,[ECX]; RETPOP EAX; RETWrite value ataddressaddressPOP ECX; RETvalueMOV [EAX],ECX; RETINC EAX; RETIncrementaddress of functionCall a functionparam cleanupparam 1param 2RETNOPparam NPOP; POP ... RETADD ESP,24; RETPOPAD; RETPOP EAX; RETCall a functionpointeraddressCALL [EAX]; RETXCHG EAX,ESP; RETStack flip ESP=EAXLEAVE; RETStack flip ESP=EBPPOP ESP; RETStack flip ESP=addraddress
    • net-squareInstruction OpcodesInstruction OpcodesRET C3RET n C2 16bitsPOP EAX 58POP ECX 59MOV EAX,[ECX] 8B 01MOV [EAX],ECX 89 08MOV [ECX],EAX 89 01INC EAX 40ADD EAX, n 83 C0 8bits
    • net-squareInstruction OpcodesInstruction OpcodesPOP EBX/EDX/ESI/EDI/EBP 5B/5A/5E/5F/5DPOPAD 61ADD ESP,24 83 C4 18CALL [EAX] FF 10XCHG EAX,ESP 94LEAVE C9 (mov esp,ebp; pop ebp)POP ESP 5C
    • net-squareSearching for Gadgets• Use msfpescans regex search.• Example: MOV EAX,[ECX]; RETmsfpescan -D -r x8Bx01xC3 <file>msfpescan -D -r x8Bx01xC2.x00 <file>msfpescan -D -r x8Bx01.xC3 <file>msfpescan -D -r x8Bx01..xC3 <file>• Sometimes you may need to improvise.
    • net-squareGeneric Techniques• Run arbitrary shellcode.• Difficult to transform entire shellcode toROP frames.• Create a ROP loader:– Allocate RWX memory– Copy classic shellcode to this memory– Jump to shellcode• Load and run any shellcode.
    • net-squareDEMO TIME!• Java JNLP docbase overflow• Exploiting IE8 using ROP
    • net-squareKTHXBAI!saumil@net-square.comlinked-in: saumilshahno LOLcats were harmed in preparation of these slides