Managed Code with Licensing does not always mean
Transcription
Managed Code with Licensing does not always mean
Managed Code with Licensing does not always mean Software Protection R3JlSGFjayAyMDEyIC0gMXN0IFBhbmljaw0KVGhhbmtzIFBoaWwgZm9yIHRoZSB0ZW1wbGF0ZQ== OVERVIEW bswapeax OVERVIEW Managed EXE static void Main() { Console.WriteLine(“Hello”); Console.WriteLine(“Goodbye”); } Native CPU Instructions Console static void WriteLine() JITCompiler JITCompiler … JITCompiler function { 1. In the assembly that implements the type (Console), look up the method (WriteLine) being called in the metadata. 2. From the metadata, get the IL for this method. 3. Allocate a block of memory. 4. Compile the IL into native CPU instructions; the native code is saved in the memory allocated in step 3. 5. Modify the method’s entry in the Type’s table so that it now points to the memory block allocated in step 3. 6. Jump to the native code contained inside the memory block. } bswapeax Drawing Source : CLR via C# (Jeffrey Richter) static void WriteLine(string) MSCore.dll OVERVIEW Managed EXE static void Main() { Console.WriteLine(“Hello”); Console.WriteLine(“Goodbye”); } Native CPU Instructions Console static void WriteLine() JITCompiler Native … JITCompiler function { 1. In the assembly that implements the type (Console), look up the method (WriteLine) being called in the metadata. 2. From the metadata, get the IL for this method. 3. Allocate a block of memory. 4. Compile the IL into native CPU instructions; the native code is saved in the memory allocated in step 3. 5. Modify the method’s entry in the Type’s table so that it now points to the memory block allocated in step 3. 6. Jump to the native code contained inside the memory block. } bswapeax Drawing Source : CLR via C# (Jeffrey Richter) static void WriteLine(string) MSCore.dll OVERVIEW C# C# C# Resource Resource Resource Assembly csc.exe /t:module Stringer.cs csc.exe /addmodule:Stringer.netmodule /t:module Client.cs PE/COFF Header CLR Header .netmodule .netmodule .netmodule .netmodule Resource Resource CLR Data MetaData Sections natives (.data, .rdata, .reloc, .rsrc, .text) IL Code al.exe Client.netmodule Stringer.netmodule /main:MainClientApp.Main /out:myAssembly.exe /target:exe bswapeax C# Assembly Structure bswapeax Icon Source: http://www.gettyicons.com Playing with an Assembly is like playing with Russian dolls Hexdecimal View HelloWorld.exe bswapeax OVERVIEW CLR HEADER SECTION HEADER OPTIONAL HEADER NT HEADER + FILE HEADER 0x80 ? Bytes 24 bytes PE00 MS DOS Stub Program e_lfanew MS DOS Header 0x00 # of Sections * 40 bytes 64 bytes 64 bytes MZ bswapeax .text / .reloc / .rsrc – Virtual Size / Virtual Address / Raw Size / Raw Address… This one is a gold mine…. Machine : Intel 386 / EFI Byte Code… Characteristics : Executable, DLL, System File, 32 bit word machine…. Optional Header .NET Directory Debug Directory … .NET MetaData Directory RVA .NET MetaData Directory Size Export Directory Import Directory Section Headers [x] OPTIONAL HEADER Debug Information Type : CodeView / COFF / Fixup / CLSID… Data Directories Import Directory RVA Export Directory RVA # of entries … Debug Directory RVA .NET MetaData Directory RVA Header PE32 | PE64 Subsystem : Windows Console / Windows GUI / EFI BootDriver / EFI Application… DllCharacteristics: Dll can move, NX Compatible, using SEH… bswapeax .NET Directory MetaData Header Signature (BSJB) Major / Minor Version MZ - Mark Zbikowski BSJB - Brian Harry, Susan Radke-Sproull, Jason Zander, and Bill Evans Reserved Version Length Version String Flags Number Of Streams Resources Strong Name Signature .NET Directory ManagedNativeHeader RVA ExportAddressTableJump RVA … StrongNameSignature RVA Resources RVA MetaData RVA Flags EntryPointToken IL only, IL Library, 32 bit required, Strong Name Signed… Eg. 0x6000003 (More details later) bswapeax .NET MetaData Header / Stream #Blob … Contains all the assembly metadata #GUID #~ MetaData Stream Namespace, type and member names are stored #~ #Strings #US String directly used in the program (“Hello world”) #GUID #Blob MetaData Header Stores GUIDs used throughout the assembly Signature (BSJB) Major / Minor Version Reserved Version Length Heap for storing pure binary data – method signature, generic instantiations… Version String Flags Number Of Streams bswapeax .NET Assembly Metadata AssemblyRef Assembly CustomAttribute MemberRef Param Each row references an external assembly It stores information about the current assembly It indexes a constructor method – the owner of that constructor method is the Type of the Custom Attribute. Each row represents an imported method Each row represents a method’s param Method Each row represents a method in a specific class TypeDef Each row represents a class in the current assembly TypeRef Each row represents an imported class, its namespace and the assembly which contain it Module Represents the current Assembly Tables Header Major / Minor Version HeapOffsetSizes …. Mask Valid Mask Sorted Tells if the #String / #Guid / #Blob are > 2^16 (Word / DWord for an index) Bit field of table types: 0x0000000900001547 …1010101000111 00 – Module / 01 – TypeRef / 02 – TypeDef / 04 - Field / 06 – MethodDef 08 – Param / 09 - InterfaceImpl / 10 – MemberRef / 11 – Constant… Bit set means available Bit field of table types: 0x000016003325FA00 … bswapeax .NET Example using System; …. namespace HelloWorld { class Program { Stored in the TypeDef static void PrintHelloWolrd() { Console.Out.WriteLine("Hello World..."); } static void PrintHelloWolrd2() { Console.Out.WriteLine("Hello World2..."); } Stored in the Method table TypeRef Table static void Main(string[] args) { Program.PrintHelloWolrd(); } } } bswapeax Stored in the #US MetaData Streams MemberRef table Param table .NET Example 1. Each table is a structured byte stream… 2. Easy to compute its size 3. Header (Tiny or Fat) Tiny : No Exception, Max stack 8, no local variable… (1 byte) Fat: Signature, Code Size, Stack Size… (14 bytes) 0xD0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x43, 0x00, 0x0A, 0x00, 0x01, 0x00 RVA 4 Bytes 0xD0200000 Points to the IL Code (More to come) Impl Flags 2 Bytes 0x0000 Click here… Flags 2 Bytes 0x9100 Click here… Name 2 Bytes 0x4300 Index in String Stream (#String) Signature 2 Bytes 0x0A00 Index in Blob Stream (#Blob) Param List 2 Bytes 0x0001 Index in the Parameter Table http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf bswapeax Method Def Table Method #1 (06000001) ------------------------------------------------------MethodName: PrintHelloWolrd (06000001) Flags : [Private] [Static] [HideBySig] [ReuseSlot] (00000091) RVA : 0x000020d0 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] ReturnType: Void No arguments. Signature : 00 00 01 Method #2 (06000002) ------------------------------------------------------MethodName: PrintHelloWolrd2 (06000002) Flags : [Private] [Static] [HideBySig] [ReuseSlot] (00000091) RVA : 0x000020e3 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] ReturnType: Void No arguments. Signature : 00 00 01 Method #3 (06000003) [ENTRYPOINT] ------------------------------------------------------MethodName: Main (06000003) Flags : [Private] [Static] [HideBySig] [ReuseSlot] (00000091) RVA : 0x000020f6 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] ReturnType: Void 1 Arguments Argument #1: SZArray String Signature : 00 01 01 1d 0e 1 Parameters (1) ParamToken : (08000001) Name : args flags: [none] (00000000) bswapeax IL Code (HelloWorld.exe) 2 RVA – @ 0x20D0 Flags (Static, Private…) ImplFlags (IL, managed…) Signature Parameter List PE Header Method Table 1 – PrintHelloWorld 2 – PrintHelloWorld2 3 – Main 4 - .ctor EntryPointToken : 0x06000003 1 3 4 Opcode 00 28 01 00 00 06 00 2A bswapeax Instruction nop call 0x06000001 nop ret Opcode Opcode 00 Instruction nop 28 01 00 00 06 call 0x06000001 00 nop 2A ret http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes_fields(v=vs.95).aspx Format Assembly Format Description 28 < T > call methodDesc Call the method described by methodDesc. The call instruction calls the method indicated by the method descriptor passed with the instruction. The method descriptor is a metadata token that indicates the method to call and the number, type, and order of the arguments that have been placed on the stack to be passed to that method as well as the calling convention to be used Easy to patch, we can change the metadata token in order to invoke another method, can be done with an hexadecimal editor. Eg. Convert 0x6000001 to 0x6000002 PrintHelloWorld to PrintHelloWorld2 bswapeax Easy… You said. Opcode 00 73 01 00 00 0A Instruction nop newobj 0xA000001 28 02 00 00 0A call 0x0A000002 00 nop 2A ret Table Relation You need to manipulate the metadata and not only the IL code What’s to be done: 1. Add an entry in the TypeRef 2. Add an entry in the MemberRef 3. Modify the IL Code of the main method All operations will impact the binary and for sure the PE Header (Section size, directory, RVA…) bswapeax Icon Source: http://www.gettyicons.com class Program { static void Main(string[] args) { new PrintLib().PrintHelloWolrd(); } } Live Attack Managed EXE static void Main() { Console.WriteLine(“Hello”); Console.WriteLine(“Goodbye”); } Native CPU Instructions Console static void WriteLine() JITCompiler static void WriteLine(string) JITCompiler function { 1. In the assembly that implements the type (Console), look up the method (WriteLine) being called in the metadata. 2. From the metadata, get the IL for this method. 3. Allocate a block of memory. 4. Compile the IL into native CPU instructions; the native code is saved in the memory allocated in step 3. 5. Modify the method’s entry in the Type’s table so that it now points to the memory block allocated in step 3. 6. Jump to the native code contained inside the memory block. } … bswapeax Opcode Instruction 00 nop 17 ldc.i4.1 0A 06 2A stloc.0 ldloc.0 ret Icon Source: http://www.gettyicons.com JITCompiler MSCore.dll Live Attack – Example public Boolean IsValidPassword(String encryptedPassword) { if (encryptedPassword.Equals("IRoNFZup0RbDw7heucGuRg==", StringComparison.InvariantCultureIgnoreCase) == true) { return true; } return false; } .method public hidebysig instance bool IsValidPassword(string encryptedPassword) cil managed // SIG: 20 01 02 0E { // Method begins at RVA 0x2050 // Code size 31 (0x1f) .maxstack 3 .locals init ([0] bool CS$1$0000, [1] bool CS$4$0001) IL_0000: /* 00 | */ nop IL_0001: /* 03 | */ ldarg.1 IL_0002: /* 72 | (70)000001 */ ldstr "IRoNFZup0RbDw7heucGuRg==" IL_0007: /* 19 | */ ldc.i4.3 IL_0008: /* 6F | (0A)000010 */ callvirt instance bool [mscorlib]System.String::Equals(string, valuetype [mscorlib]System.StringComparison) IL_000d: /* 16 | */ ldc.i4.0 IL_000e: /* FE01 | */ ceq IL_0010: /* 0B | */ stloc.1 IL_0011: /* 07 | */ ldloc.1 IL_0012: /* 2D | 05 */ brtrue.s IL_0019 IL_0014: /* 00 | */ nop IL_0015: /* 17 | */ ldc.i4.1 IL_0016: /* 0A | */ stloc.0 IL_0017: /* 2B | 04 */ br.s IL_001d IL_0019: /* 16 | */ ldc.i4.0 IL_001a: /* 0A | */ stloc.0 IL_001b: /* 2B | 00 */ br.s IL_001d IL_001d: /* 06 | */ ldloc.0 IL_001e: /* 2A | */ ret } // end of method Program::IsValidPassword bswapeax Opcode Instruction 00 nop 17 ldc.i4.1 0A 06 2A stloc.0 ldloc.0 ret Protected Code Obfuscation : In software development, obfuscation is the deliberate act of creating obfuscated code, i.e. source or machine code that is difficult for humans to understand. http://www.red-gate.com/products/dotnet-development/smartassembly VS What I have seen…. Unicode (eg… ☺.♦ Vs IsValidPassword) String Encryption (Inject a code for String Decoding Capture via a Library) PE Header Modification (Invalid number of data directories in NT Header !!! or SuppressIldasmAttribute or Multiple #GUID heaps) bswapeax Icon Source: http://www.gettyicons.com public bool (string ) { return .Equals(.(195), StringComparison.InvariantCultureIgnoreCase); } Avoid bad practice Do not think…. With this my software is secured Hashed (MD5, SHA, …) or Algorithm for public-key cryptography (RSA…)… Secure transport (HTTPS) Obfuscation is my security … Weakness are not in the usage of such good elements but how you use it !!!! Eg. Avoid Simple Types – IL Code attack Return bool eg. CheckPassword, IsValidPassword…. Return String eg. GetHash, GetEncryptedPassword…. Eg. Structure Types – Inject Assembly with the same signature Return a structure with some authorization Secure { Int : SessionCount; Int: MaxPlugin; … } …. bswapeax Check this out… Links Roslyn Project : http://msdn.microsoft.com/en-us/hh500769 Books Expert .NET 2.0 IL Assembler- Author : Serge LIDIN CLR via C# - Author Jeffrey Richter Tools Microsoft : ILDASM ILSpy : http://ilspy.net/ CFF : http://ntcore.com/exsuite.php .NET Reflector : http://www.reflector.net/ Reflexil : http://reflexil.net/ Cecil : http://www.mono-project.com/Cecil DigitalBodyGuard: http://www.digitalbodyguard.com/attacks.html bswapeax Icon Source: http://www.gettyicons.com Microsoft : http://msdn.microsoft.com/en-us/vstudio/hh341490.aspx http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes_fields(v=vs.95).aspx Questions Icon Source: http://www.gettyicons.com “Tell me and I'll forget; show me and I may remember; involve me and I'll understand.” bswapeax Method ImplFlags Back bswapeax Method Flags Back bswapeax String (String Stream) Back bswapeax Table Relations ModuleRef Table TypeSpec Table Drawing Source : .NET 2.0 IL Assembler (Serge Lidin) TypeRef Table MemberRef Table MethodSpec Table MethodImpl Table TypeDef Table Method Table Param Table Metadata tables related to method definition and referencing bswapeax Constant Table FieldMarshal Table Back