RopSteg: Program Steganography with Return Oriented Programming Kangjie Lu, Siyang Xiong, and Debin Gao CODASPY '14
Overview Introduce new property in software obfuscation, program steganography. Describe the implementation of a software obfuscation system (RopSteg) that provides program steganography through the use of return oriented programming. Apply RopSteg to various Window's binaries to evaluate the effectiveness and performance impact.
Related Topics Software Watermarking Traditional Obfuscation Tries to embed a secret message into a cover program The message being hidden is not related to the cover program. Traditional Obfuscation Makes static analysis of program much more difficult. May make instruction sequences hard to understand May make the program generate instructions sequences or modify existing sequences dynamically during run-time Raises suspicion, violates W ⊕ X, and not suitable for mandatory code signing environments.
StegRop vs Related Techinques Hides part of the program's executable code within the program itself Does not raise suspicion Does not violate W ⊕ X Works in mandatory code signing environments
Intro to ROP Search program for small pieces of code ending with the retn instruction called gadgets. (can use intended or unintended instructions) String the gadgets together to create a desired functionality Force the program to load the stack with the addresses of the gadgets in their correct order. Force the program to return to the first gadget address on the stack
Unintended Instructions Not placed into the program by the compiler. Instructions are found in “the middle” of valid instructions Not detected by disassembly techniques
Rop Example msvcr71.dll – v7.10.3052.4 Shipped with : JRE (Java) 1.6 works on : XP/Vista/Win7/2003/2008 Load on demand in browser : YES Rebase : False ASLR : False Safeseh : True Base : 0x7c340000 Top : 0x7c396000 Size : 0x56000 Technique : kernel32.VirtualProtect() Author : corelanc0d3r 0x7c37653d, # POP EAX # POP EDI # POP ESI # POP EBX #POP EBP # RETN 0xfffffdff, # Value to negate, will become 0x00000201 (dwSize) 0x7c347f98, # RETN (ROP NOP) [msvcr71.dll] 0x7c3415a2, # JMP [EAX] [msvcr71.dll] 0xffffffff, # 0x7c376402, # skip 4 bytes [msvcr71.dll] 0x7c351e05, # NEG EAX # RETN [msvcr71.dll] 0x7c345255, # INC EBX # FPATAN # RETN [msvcr71.dll] 0x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN [msvcr71.dll] 0x7c344f87, # POP EDX # RETN [msvcr71.dll] 0xffffffc0, # Value to negate, will become 0x00000040 0x7c351eb1, # NEG EDX # RETN [msvcr71.dll] 0x7c34d201, # POP ECX # RETN [msvcr71.dll] 0x7c38b001, # &Writable location [msvcr71.dll] 0x7c347f97, # POP EAX # RETN [msvcr71.dll] 0x7c37a151, # ptr to &VirtualProtect() - 0x0EF [IAT msvcr71.dll] 0x7c378c81, # PUSHAD # ADD AL,0EF # RETN [msvcr71.dll] 0x7c345c30, # ptr to 'push esp # ret ' [msvcr71.dll] # rop chain generated with mona.py
High Level
Finding the Gadgets Galileo Algorithm Recursive algorithm that looks for ALL gadgets Looks for a C3 byte (retn instruction) and makes it the root of a gadget Prepends all previous instructions to gadget Stops when an instruction that causes the processor to transfer execution away (jmp, another retn) is encountered
Finding the Gadgets Modified Galileo algorithm Algorithm to find ONE SPECIFIC gadget Searches for some gadget in a way similar to original algorithm. However, partial matches are also found. Partial matches incapable of being modified to make equivalent instruction are discarded. Partial matches are ranked based on their likelihood of being transformed into a a complete match.
Turning Partial into Complete Matches Insert instructions before and/or after partially matching instructions Instructions must not alter functionallity during intended execution Instructions must perform “hidden operations” during “unintended” execution
Picking Canidates Candidates are discarded if: Candidates are ranked by:
Picking Candidates Instruction to hide: F7 D8 1B C0 C3
Picking Candidates Instruction to hide: F7D8 1BC0 3C30 .data:0x00000000 f7d8 neg eax .data:0x00000002 8d4a3d lea ecx,[edx+0x3d] .data:0x00000005 1bc0 sbb eax,eax .data:0x00000007 c3 ret
Ineffective Instructions RopSteg constructs semantically equivalent modified executables by only inserting ineffective instructions. Ineffective instructions have no effect on an executable's functionality. Can be context sensitive or insensitive
Ineffective Instructions
Inserting ineffective instructions Case 1 (matched byte is first byte in candidate): Add ineffective instruction before Case 2 (matched byte is last byte in candidate): Add ineffective instruction after Case 3 (matched byte(s) is in the middle of instruction): Case specific. Ineffective instruction may have to be added before and/or after.
Inserting ineffective instructions Instruction to Match: F7 D8 1B C0 C3
Getting to the Gadget Rop Board: Instruction sequence designed to transfer control to “hidden” instructions (performs indirect jmp) and back (places a return address on the stack) Assumes location of gadget is stored in memory (gets put there by the Rop Generator) Is located at the offset of the orignal instruction being hidden. Multiple variants of how data storage is acessed and how registers are loaded (to avoid static analysis detection)
Getting to the Gadget Rop Generator: Responsible for loading the gadget and return address into memory Uses a call-pop instruction sequence commonly used in position independent executable to load EIP into EAX Adds the offset of gadget to EIP to find actual offset (required for handling exe's compatible with ASLR)
Modifying the Executable Binary Rewriting: If .reloc segment exists rewriting is trivial. If .reloc segment has been stripped the binary is disassembled with IdaPro.
Putting it all together:
Hiding Specific Components Protecting a secret algorithm Hide part of a quick sort function (90 instructions long) in a program (266 instructions long) 5 critical instruction sequences are hidden Each sequence is 1-3 instructions long
Hiding Specific Components
Hiding Malicious Code Ropsteg applied to trojan.dll from Gh0st malware Dll functionality includes file management, screen monitoring, key monitoring, remote shell support, and a system manager. Hid instructions that are used for virus signature detection
Hiding Malicious Code Kaspersky, Macfee, and 360 Anti-Virus were unable to identify the program as malicious Run-time results:
Hiding Random Instructions Apply RogSteg to 8 common Windows programs Hide 100 different instruction sequences in each Instruction sequences range from 2 – 13 bytes in length Instructions cover load/store, arithmetic, condition branch, function call, and system call instructions
Hiding Random Instructions All instruction sequences are hidden Size Overhead:
Limitations Dynamic Analysis: Compatibility with ROP defenses: Does not intend to hide instructions from dynamic analysis Suggests previously proposed techniques for dealing with dynamic analysis Compatibility with ROP defenses: Many existing ROP defenses will flag RopSteg'd programs as malicious
Discussion Could RopSteg be more effective at compile time? Instead of using retn could other control flow instructions be used? (jmp) Does RopSteg make programs more vulnerable to malicious Rop attacks? Can RopSteg be detected by searching for groups of ineffective instructions? Can Rop be used for other non-malicious purposes?