Advance ROP Attacks

     Rashid Bhatt

      @raashidbhatt
Agenda
• Introduction to ROP Attacks

• ROP Attack Variants

• Alphanumeric ROP exploits

• Searching gadgets

• Questions?
ROP Attacks
•   Introduced by hovad shacham
•   Circumvents DEP (data execution prevention)
•   Turing Complete`ness
•   More useful than ret-2-lib ( branching)
•   Applicable to various architectures
ROP Attacks
• Gadgets are the building blocks
• Gadgets end with RET instruction
• Example gadgets
     •   Mov eax, ebx
     •   Ret
     •   Pop eax
     •   Ret
ROP attacks
    x86 stack layout
    . Registers ebp and esp point to base and top of the
stack respective
    . EBP used to access local and passed paramters
    eg . [ebp + 8] first parameter (EBP + 4) for ret
address
    . ESP used are a pointer for popping values out from
stack
ROP attacks
• RET x86 instruction
     • Pops a value from the stack into EIP

     • Used to return control from a function

     • RET can have a argument eg RET 8

     • RET 8 == EIP = stack[top], add ESP , 8
X86 stack layout
                             calling conventions
                             __stdcall ( varadic arguments)
Int __stdcall function(int a, int b) // < paramerts
              {
                             int b,c; // local c variables
                             return 0;
              }
function(10, 20); // function call __stdcall

X86 disassembly

              push 20 // arguments pushed from right to left
              push 10
              call function
function:
              push ebp                                        // Stack epilouge
              mov ebp, esp
              sub esp, 8                                      //8 bytes for two variabeles
              ….
              ….
              add esp, 8
              pop ebp
              ret 8                                           // ret 8 stack clearance by callie
X86 stack layout
                             calling conventions
                             __cdecl( const no of args)
Int __cdelc function(int a, int b) // < paramerts
              {
                             int b,c; // local c variables
                             return 0;
              }
function(10, 20); // function call __cdecl

X86 disassembly

              push 20 // arguments pushed from right to left
              push 10
              call function
              add esp, 8 // stack clearance
function:
              push ebp                                       // Stack epilouge
              mov ebp, esp
              sub esp, 8                                     //8 bytes for two variabeles
              ….
              ….
              add esp, 8
              pop ebp
              ret                                            // ret no stack clearence
Basic stack overflow
• A local stack variable gets overflowed

• CALL instruction pushes the EIP to the stack

• Find a trampoline eg jmp esp to change the
  value to eip to attacker controlled buffer

• demo
What about NX bit ?
• DEP restricts the execution of segments
  marked as r/w
• We can re-use code from the address space of
  executable
• Useful code chunks called as ROP gadgets
• Multiple gadgets can be chained together and
  even API calls
ROP Basics(load and store gadgets)
• storing and loading values from and into
  memory

• Primitive example pop eax; ret / pop ebx ret/ pop r32, ret

• To memory store           pop eax, pop edx, ret / mov [eax], edx; ret
Wait a sec!
            » Handling NULL bytes



•   Some parameters contain NULL
•   Even some addresses contain zero values
•   Cannot inject NULL or zero values
•   Bug prone functions eg strcpy stop copying
    when they encounter a NULL byte (00 hex)
Handling NULL bytes
•   Let x = value containing a ( many) NULL byte
•   Let y = mask = 0xffffffff
•   Mathematical axiom
•   A xor B = z (say)
•   Now z xor B = A
•   We can 0x00000000 xor 0xffffffff = z (say)
•   Xor it back to get the original value
•   We have xor esi, ebx ; ret!
ROP basics(arithmetic )
• Msvcrt32.dll 0x77c4d6f add ebx, esi; stc; ret

• Kernel32.dll 0x7c902af5 sub eax,ecx; ret

• We have same for mul and div !

• Try in immunity search: add r32, r32;any;ret;

• You will find huge no. of gadgets
ROP basics(LOOPS)
• UNCONDITIONAL LOOPS or INFINITE LOOPS
• Pop back the value in ESP, pop esp;ret
 7C80BCA8 5C     POP ESP //kernel32.dll
 7C80BCA9 C3     RETN
ROP basics(conditional jumps )
• The tricky part
• We need to modify ESP , based on certain
  comparisons
. comparisons include greater than , less than ,
  equal to;
    X <y
    X >y
    X == some_val
.
Comparing with zero
•   Divert flow through adding a certain value to esp

•   Store two values on the stack , value_to_be_checked and esp_delta (the value to
    be added to esp)


• Load the val in a general purpose register say eax
•   X86 instruction NEG computes the two's complement and updates CF

. if val == 0 the CF = 0; else CF = 1
• ADC x86 instruction add the source and dest with carry flag(ADC – add
  with carry flag)
• Make a general purpose reg and zero by xor r32,r32; then apply adc
  r32,32
Comparing with zero(contd..)
•   We have a REG (say eax) containing a single 1 bit or all 0 bits

•   Apply NEG instruction on that REG to obtain the two's complement


• 2's comp will transform it into all zero's or all ones
•   Perform bit-wise AND with ESP_DELTA

.   according we will get ESP_DELTA as zero or its original value


• ADD esp, ESP_DALTA to divert the control flow


• DEMO
Checking for == (equality)
•   Two values val1, val2 to be checked for equality

•   Load two values using load and store gadgets as shown earlier


• Perform x86 SUB val1, val2,store back the result
•   If both the values are same result will be zero,

.   Check the result to zero as show in the previous slide
• ADD esp, ESP_DALTA to divert the control flow


• DEMO
Checking for <, > (less or greater)
•   Two values val1, val2 to be checked for equality

•   Load two values using load and store gadgets as shown earlier


• Perform x86 SUB val1, val2, SUB intruction sets the CF if dest > source
•   Save CF using xor r32, r32;ret; adc r32,r32 ret; as shown in ealier slide

.   CF will be 1 if dest > source else 0
• DEMO
ROP Attack Variants
JUMP oriented Programming
                  Attacks

•   ROP used gadgets ending with RET x86 instruction

•   JOP uses statements ending with Indirect Jump call


• Instead of stack uses a dispatcher table to jump to different locations

•   Thwarts certain Anti-ROP defences
JOP attacks (Dispatch table and
      Dispatcher gadget)
JUMP oriented Programming
                  Attacks

•   Dispatcher gadget increments a REG by certain value to make it point to next loc to
    jump on

•   Add ebx, 4 ; JMP [ebx]


•   Here , EBX points to the Dispatcher table


•   Same gadgets as in ROP attacks
JOP(attack Model)


•   Cannot work on stack buffer overflow , because control flow diverts through a ret
    Instruction
•   Will be detected by anti-ROP defenses if(stack overflow is used)


•   Attack vectors include


•   1: pointer overwrite
•   2: Arbitrary DWORD overwrite
•   3: C++ vtable overwrite
Alphanumeric ROP Shell-code
Alphanumeric ROP Shellcode
•   Traditional Shellcode can be made alphanumeric by choosing only certain
    instruction

Example . pop ecx has an
opcode 0x59 which is the ASCII code of the character Y)



•   Similar technique used in ROP shellcode

.   Selecting a printable address rather than a printable opcode(in trad.
    shellcodes)
Alphanumeric ROP Shellcode
Basic Technique by adding two printable addresses. The range of ASCII printable
   characters is between 0x21 and 0x7e

Example . A non-printable gadget in kernel32.dll at 0x77D4B8C2 {pop ebx;ret} can be
   represented by adding two printable addresses

0X225D414B(printable) + 0x55777777(printable) = 0x77D4B8C2(no-printable)


• Combined together can be used to transform a printable code into non-
  printable
•   Similar technique used in ROP shellcode

.   Selecting a printable address rather than a printable opcode(in trad.
    shellcodes)
Alphanumeric ROP
                   Shellcode(gadgets)
• Gadgets used for decoding addresses should be printable(bytes should be
  in range of 0x21 - 0x7e
•   We also need a memory region which has a printable address to store the
    decoded gadgets addresses marked as r/w

.   From reg to mem we have urlmon.dll
        0x772C2E5E      MOV DWORD PTR DS:[ECX],EAX
. ESP related CRYPTUI.dll 0x775513E30 XCHG EAX,ESP
.   MSCTF.DLL 0x74722973         POP EAX
. Mshtml.dll     0x7D504962         ADD EAX,ECX
. msimtf.dll MEM to reg        0x74714263 MOV EAX,DWORD PTR DS:[ECX]
. All of the dll's loaded by internet explorer
Alphanumeric ROP Shellcode

Alphanumeric ROP Messagebeep Shellcode >>




s)rt:i=3PI'w""w"bIP}PI'www""bIP}PI'w"P`
w^.,wxxxxs)rt"P`w0>Qu

 DEMO
Effectively searching gadgets


•   Immunity debugger search for all sequences in all modules

•   ANY for any no of op codes and any reg


•   Match Different registers eg POP RA, RB ; RA and RB will be different


•   Best Practice search in reverse order
Questions ?

Advance ROP Attacks

  • 1.
    Advance ROP Attacks Rashid Bhatt @raashidbhatt
  • 2.
    Agenda • Introduction toROP Attacks • ROP Attack Variants • Alphanumeric ROP exploits • Searching gadgets • Questions?
  • 3.
    ROP Attacks • Introduced by hovad shacham • Circumvents DEP (data execution prevention) • Turing Complete`ness • More useful than ret-2-lib ( branching) • Applicable to various architectures
  • 4.
    ROP Attacks • Gadgetsare the building blocks • Gadgets end with RET instruction • Example gadgets • Mov eax, ebx • Ret • Pop eax • Ret
  • 5.
    ROP attacks x86 stack layout . Registers ebp and esp point to base and top of the stack respective . EBP used to access local and passed paramters eg . [ebp + 8] first parameter (EBP + 4) for ret address . ESP used are a pointer for popping values out from stack
  • 6.
    ROP attacks • RETx86 instruction • Pops a value from the stack into EIP • Used to return control from a function • RET can have a argument eg RET 8 • RET 8 == EIP = stack[top], add ESP , 8
  • 7.
    X86 stack layout calling conventions __stdcall ( varadic arguments) Int __stdcall function(int a, int b) // < paramerts { int b,c; // local c variables return 0; } function(10, 20); // function call __stdcall X86 disassembly push 20 // arguments pushed from right to left push 10 call function function: push ebp // Stack epilouge mov ebp, esp sub esp, 8 //8 bytes for two variabeles …. …. add esp, 8 pop ebp ret 8 // ret 8 stack clearance by callie
  • 8.
    X86 stack layout calling conventions __cdecl( const no of args) Int __cdelc function(int a, int b) // < paramerts { int b,c; // local c variables return 0; } function(10, 20); // function call __cdecl X86 disassembly push 20 // arguments pushed from right to left push 10 call function add esp, 8 // stack clearance function: push ebp // Stack epilouge mov ebp, esp sub esp, 8 //8 bytes for two variabeles …. …. add esp, 8 pop ebp ret // ret no stack clearence
  • 9.
    Basic stack overflow •A local stack variable gets overflowed • CALL instruction pushes the EIP to the stack • Find a trampoline eg jmp esp to change the value to eip to attacker controlled buffer • demo
  • 10.
    What about NXbit ? • DEP restricts the execution of segments marked as r/w • We can re-use code from the address space of executable • Useful code chunks called as ROP gadgets • Multiple gadgets can be chained together and even API calls
  • 11.
    ROP Basics(load andstore gadgets) • storing and loading values from and into memory • Primitive example pop eax; ret / pop ebx ret/ pop r32, ret • To memory store pop eax, pop edx, ret / mov [eax], edx; ret
  • 12.
    Wait a sec! » Handling NULL bytes • Some parameters contain NULL • Even some addresses contain zero values • Cannot inject NULL or zero values • Bug prone functions eg strcpy stop copying when they encounter a NULL byte (00 hex)
  • 13.
    Handling NULL bytes • Let x = value containing a ( many) NULL byte • Let y = mask = 0xffffffff • Mathematical axiom • A xor B = z (say) • Now z xor B = A • We can 0x00000000 xor 0xffffffff = z (say) • Xor it back to get the original value • We have xor esi, ebx ; ret!
  • 14.
    ROP basics(arithmetic ) •Msvcrt32.dll 0x77c4d6f add ebx, esi; stc; ret • Kernel32.dll 0x7c902af5 sub eax,ecx; ret • We have same for mul and div ! • Try in immunity search: add r32, r32;any;ret; • You will find huge no. of gadgets
  • 15.
    ROP basics(LOOPS) • UNCONDITIONALLOOPS or INFINITE LOOPS • Pop back the value in ESP, pop esp;ret 7C80BCA8 5C POP ESP //kernel32.dll 7C80BCA9 C3 RETN
  • 16.
    ROP basics(conditional jumps) • The tricky part • We need to modify ESP , based on certain comparisons . comparisons include greater than , less than , equal to; X <y X >y X == some_val .
  • 17.
    Comparing with zero • Divert flow through adding a certain value to esp • Store two values on the stack , value_to_be_checked and esp_delta (the value to be added to esp) • Load the val in a general purpose register say eax • X86 instruction NEG computes the two's complement and updates CF . if val == 0 the CF = 0; else CF = 1 • ADC x86 instruction add the source and dest with carry flag(ADC – add with carry flag) • Make a general purpose reg and zero by xor r32,r32; then apply adc r32,32
  • 18.
    Comparing with zero(contd..) • We have a REG (say eax) containing a single 1 bit or all 0 bits • Apply NEG instruction on that REG to obtain the two's complement • 2's comp will transform it into all zero's or all ones • Perform bit-wise AND with ESP_DELTA . according we will get ESP_DELTA as zero or its original value • ADD esp, ESP_DALTA to divert the control flow • DEMO
  • 19.
    Checking for ==(equality) • Two values val1, val2 to be checked for equality • Load two values using load and store gadgets as shown earlier • Perform x86 SUB val1, val2,store back the result • If both the values are same result will be zero, . Check the result to zero as show in the previous slide • ADD esp, ESP_DALTA to divert the control flow • DEMO
  • 20.
    Checking for <,> (less or greater) • Two values val1, val2 to be checked for equality • Load two values using load and store gadgets as shown earlier • Perform x86 SUB val1, val2, SUB intruction sets the CF if dest > source • Save CF using xor r32, r32;ret; adc r32,r32 ret; as shown in ealier slide . CF will be 1 if dest > source else 0 • DEMO
  • 21.
  • 22.
    JUMP oriented Programming Attacks • ROP used gadgets ending with RET x86 instruction • JOP uses statements ending with Indirect Jump call • Instead of stack uses a dispatcher table to jump to different locations • Thwarts certain Anti-ROP defences
  • 23.
    JOP attacks (Dispatchtable and Dispatcher gadget)
  • 24.
    JUMP oriented Programming Attacks • Dispatcher gadget increments a REG by certain value to make it point to next loc to jump on • Add ebx, 4 ; JMP [ebx] • Here , EBX points to the Dispatcher table • Same gadgets as in ROP attacks
  • 25.
    JOP(attack Model) • Cannot work on stack buffer overflow , because control flow diverts through a ret Instruction • Will be detected by anti-ROP defenses if(stack overflow is used) • Attack vectors include • 1: pointer overwrite • 2: Arbitrary DWORD overwrite • 3: C++ vtable overwrite
  • 26.
  • 27.
    Alphanumeric ROP Shellcode • Traditional Shellcode can be made alphanumeric by choosing only certain instruction Example . pop ecx has an opcode 0x59 which is the ASCII code of the character Y) • Similar technique used in ROP shellcode . Selecting a printable address rather than a printable opcode(in trad. shellcodes)
  • 28.
    Alphanumeric ROP Shellcode BasicTechnique by adding two printable addresses. The range of ASCII printable characters is between 0x21 and 0x7e Example . A non-printable gadget in kernel32.dll at 0x77D4B8C2 {pop ebx;ret} can be represented by adding two printable addresses 0X225D414B(printable) + 0x55777777(printable) = 0x77D4B8C2(no-printable) • Combined together can be used to transform a printable code into non- printable • Similar technique used in ROP shellcode . Selecting a printable address rather than a printable opcode(in trad. shellcodes)
  • 29.
    Alphanumeric ROP Shellcode(gadgets) • Gadgets used for decoding addresses should be printable(bytes should be in range of 0x21 - 0x7e • We also need a memory region which has a printable address to store the decoded gadgets addresses marked as r/w . From reg to mem we have urlmon.dll 0x772C2E5E MOV DWORD PTR DS:[ECX],EAX . ESP related CRYPTUI.dll 0x775513E30 XCHG EAX,ESP . MSCTF.DLL 0x74722973 POP EAX . Mshtml.dll 0x7D504962 ADD EAX,ECX . msimtf.dll MEM to reg 0x74714263 MOV EAX,DWORD PTR DS:[ECX] . All of the dll's loaded by internet explorer
  • 30.
    Alphanumeric ROP Shellcode AlphanumericROP Messagebeep Shellcode >> s)rt:i=3PI'w""w"bIP}PI'www""bIP}PI'w"P` w^.,wxxxxs)rt"P`w0>Qu DEMO
  • 31.
    Effectively searching gadgets • Immunity debugger search for all sequences in all modules • ANY for any no of op codes and any reg • Match Different registers eg POP RA, RB ; RA and RB will be different • Best Practice search in reverse order
  • 32.