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