Top Banner
Software attacks Software attacks .NET security
59

Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Dec 25, 2015

Download

Documents

Aubrie Garrison
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Software attacks

.NET security

Page 2: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

The problem

• Buffer owerflow: one silly but very common bug

• Can allow a determined attacker to obtain control

• Components: building an application from third-party DLLs makes the problem even worse:– the attacker has lots of time to discover the

various gaps to be exploited in each DLL in use

– a bogus/malicious component could be used

Page 3: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

What we want

A user that runs a process constructed from components, wants to be sure that he is protected from malicious software.

=> Prevent buffer overflow with verification of managed code

=> Prevent execution of malicious software: Code access security (CAS)

Page 4: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

.NET

• CLR: Common Language Runtime• CTS: Common Type System• IL: Intermediate Language• Metadata:Self info about classes• Assembly: Code unit• Manifest: Description of assembly

Page 5: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

...

C#

Common Language Runtime

• At the heart of the .NET platform is a common language runtime engine and a base framework

VB

VC++

Common Language Runtime

JScript

GC

JITLoaderVerifier

...Native Code

Base framework classes

Data and XML classes

MSIL

XML Web Services

WebForms

WindowsForms

Page 6: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

MSIL• Every .NET language is not compiled to

machine code targeted to any specific CPU. Instead, the code generated by the compiler is a Microsoft intermediate language (MSIL)

• MSIL is much higher level than most CPU machine languages:– It understands object types– Has instructions that create and initialize objects– Calls to virtual methods on objects– Manipulate array elements directly– Instructions that raise and catch exceptions

Page 7: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

JITSourcecode

ClassLibraries

(IL &Metadata)

EXE/DLL(IL &

Metadata)

ManagedNativeCode

Compiler

Class Loader

JIT compilerW/ verification

Execution

Security checks

XMLSecuritypolicies

Stack walkPermission

demand

Call to anuncompiled

method

MSIL is not a bytecode: is JITed. The JIT compiler compiles methods on the fly, verifying code in the process

Page 8: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

JITfoo

call(…)foo.A

foo.B

jmpjmp

barcall(…)

bar.A

bar.B

jmpcall

Managed Code Blocks

push ebp; mov ebp, esp; …push ebp; … call bar.A

push ebp; … call bar.B

UniversalJIT Thunk

JIT compilerW/ verification

The stub code directs program execution to the JIT compiler.

When a method is called:

Once the JIT compiler has compiled the MSIL, the method's stub is replaced with the address of the compiled code.

From now, when this method is called, native code will execute

Page 9: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Metadata• The Microsoft .NET platform uses

metadata and assemblies to store information about components:– enabling cross-language programming – locate and load class types in the file– resolve method calls and field references– resolving the infamous DLL Hell problem

(SxS execution)– easy linking and loading of assemblies – easy versioning – reflection.

Page 10: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Metadata

Assembly

ModuleModule list Type list

Global methods

Foo

main

Methods

Fields

Properties

Events

MyFoo

Params

int a

The metadata hierarchy

class Foo { public void MyFoo() { ... }

}

public static void Main(string[] args) {...}

Page 11: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Assembly & Manifest• Metadata stored in assembly• Think of an assembly as a logical EXE or DLL• A manifest is a section of the assembly

which makes it self-describing• Each assembly has a 4-part name

– Friendly name– Version number– Culture setting– Public key (or public key token)

The public key forms the so called Strong Name of the assembly

MyLibrary, Version=1.0.24.0, Culture=neutral, PublicKeyToken=29989D7A39ACF230

BobsLibrary, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null

Metadata

IL

Assembly Manifest

list of dependent assemblies

PE File Format

4-part name

Resources

Page 12: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacksPhase I: Verification and

validation

• Even before checking if an assembly has the necessary permission to access a resource, it has to pass a set of rigorous checks

• Each related set of checks is called a validation

• Three major validation are made:– PE file format validation– Metadata validation– IL validation

• These check ensure that later security checks on assemblies are valid

Page 13: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

PE file format validation

• Assemblies are PE files• They contain a special slot (pointing to an

header with relevant addresses) + an unique x86 asm instruction (for old systems)– Donut virus

• Time of check: right after CLR initialization– All relevant addresses (Metadata location, IL

location, etc.) point inside the PE file– Ensures assembly isolation

Page 14: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Metadata validation

• As we saw, metadata is a set of linked tables

• Metadata is used for many crucial functions (recall for example load of types)– Structural validation (the table structure must

adhere some standards)– Ex: field table pointing to a buffer (data section)– Semantic validation (rules of the CLR: type

invariants, type relatinons)– Ex: subclass B of A cannot be A superclass

• They are done before metadata is used (i.e. before IL validation)

Page 15: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

IL validation & verification

• As we saw, IL is not executed but compiled on a method basis

• Before compiling a method, IL is validated• Then, it is verified

– Native code has direct memory access and can subvert isolation

– Type contracts can be broken (C-style casts, access to private members…)

• JIT checks that IL is not used in a way it can generate unsafe native code

Page 16: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

IL validation

• Bytes in the IL stream are all valid IL instructions

• All jumps are inside the same method

Page 17: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacksIL verification: Ensuring

type safetyclass Account { private: long balance; }; void useAccount(Account* a) { // use pointer arithmetic to index // into the object wherever we like! ((long*)a)[1] = MAX_LONG; }

• By using pointers and unsafe casts, the attacker is able to access and modify private members of a class

• There is no runtime protection against this in unmanaged code.

• The CLR detects this sort of type system abuse during just-in-time (JIT) compilation (unsafe pointer arithmetic in this particular case) and raise an exception.

• A buffer overflow is another example of a type system violation: the CLR closes all of these holes by ensuring the type safety of all code

The CLR verify all code before running it

Page 18: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Ensuring type safetypublic SecurityInfo{ private bool fullyTrusted; public bool IsFullyTrusted() { return (fullyTrusted); } public static SecurityInfo GetSecurityInfo (Assembly a) {...} }

public SpoofSecurityInfo{ public bool fullyTrusted;}

Main() { SecurityInfo si = SecurityInfo.GetSecurityInfo(System.GetMyAssembly()); SpoofSecurityInfo sp = si; spoof.fullyTrusted = true; //do nasty things}

call class SecurityInfo SecurityInfo::GetSecurityInfo(class Assembly);stloc si //store the retval (top of stack) in sildloc si //put si on top of the stackstloc sp //put top of stack in sp TYPE UNSAFE!!

The previous code will not compile, however could be possible to write corresponding IL:

The JIT werification will not allow stloc sp to

execute!!

Page 19: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Ensuring type safetypublic SpoofSecurityInfo{ public bool fullyTrusted;}

Main() { SecurityInfo si = SecurityInfo.GetSecurityInfo(System.GetMyAssembly()); bool* pb = (si + 4); *pb = true; //do nasty things}

ldloc si //load si on top of stackldc.i4 4 //load 4 on top of stackadd //add the top 2 operandstloc pb //store top of stack back in pb UNSAFEldloc pb //load pb on top of stackldc.i4 1 //load true constant stind.i1 //*pb = true

The previous code will not compile, however could be possible to write corresponding IL:

The JIT verification will not allow stloc sp to execute!!

Type unsafe IL breaks the CLR type system

Page 20: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Type safety• The common language runtime ensures type

safety by combining strong typing in the metadata with strong typing in the MSIL (local variables and stack slots).

• This permit to automatically verifying the type safety of programs written in MSIL.

• By default, all code compiled by the JIT is validated before beign JITed.– The CLR does not allow any assembly with type unsafe IL to

run, with the exception of Full Trusted assemblies

• Not all safe code may be verifiable with existing technology => but code emitted by .NET compilers is always verifiable

Page 21: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Summary

PE file validation

Metadata validation

don’t run malicious code before validation

IL validation

correct metadata (no bogus methods/classes)

CAS

type contracts not broken

IL verification

file not corrupted

Page 22: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Security models

• Traditional OS security provides isolation and access control based on user accounts.

• This is useful for organizations, but assumes that all code is equally trustworthy.

• This assumption is broken by the increasing reliance on mobile code (Web services and components, e-mail attachments, …)

• There is a need for more granular control of application behavior.

Page 23: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

User-based security model

• Programs have the same rights of the user who executes them, so they can do all the things a user can do– Often users didn’t even know what a program

can do!

• Too many users run as administrator, too many programs require admin settings to install and run– Even when a program is executed with

standard rights, the same concept holds!

Page 24: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacksUser-based security model

exampleall the program used by these users have access to this folder

Windows explorer may have the right to access %WINDIR%\system32

But letting a spyware-filled-P2P-client access them is not very wise…

Word may have the right to access my documents folder

Page 25: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Role-based security• Evolution of User-based security• Often used in business applications/3-tier

applications (business logic)• Windows 2000 introduces role-based security

for to COM+ components, .NET and Web services

• You can:– define roles – define the tasks those roles can perform– nest roles to inherit characteristics from other roles– define application groups– use scripts to modify permissions dynamically

Page 26: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacksRole-based security

example• A system to manage a company library• Make a list of the sensitive operations:

– Read catalog – Place hold (for self or another) – Check out book – Check in book – Add book to inventory – Remove book from inventory – Read patron history (for self or another)

• Some operations sensitive to information that you'll only have at run time (read a patron's history => the user is trying to access his own history or that of someone else?)

Page 27: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Roles and tasks

Browse catalogPlace holdRead history

Browse catalogPlace holdRead historyCheck out bookCheck in book

Browse catalogPlace holdRead historyCheck out bookCheck in bookAdd book to inventoryRemove book from inventory

Customer Clerk Manager

Page 28: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacksCode-based security

model

• Authenticate code, not the user running it => Code identity

• Authorize code, not the user => security policies an permission sets

• Enforce code authorization => CAS

Page 29: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Evidences

• Code identity is based on evidences• Using evidences, security policy can control the

privileges granted to an application• Eight types of evidences:

– ApplicationDirectory: From what directory was this assembly executed?

– Site: From what site was this assembly downloaded?– URL: Which is the URL of origin of this assembly?– Zone: From what zone was this assembly obtained?– Hash: What’s the hash of this assembly?– StrongName: What's the strong name of this assembly?– Publisher: Who signed this assembly?

Page 30: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Code Identity

• There are only two ways for execute code: – through the class loader – through interoperability services

• Both of these are services provided by the CLR and are part of the security perimeter

• The class loader maintains information about the source of every class that it loads

• The class loader provides some of the evidence upon which code identity is based

Page 31: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Strong names

Metadata

Intermediate Language

Assembly ManifestFriendly Name: MyLibrary

Version: 1.0.24.0

Culture:neutral

Public Key: (full 128-byte value)

Reference list of dependent assemblies

Digital Signature

// AssemblyInfo.csusing System.Reflection;

[assembly: AssemblyKeyFile(@"..\..\AcmeCorp.snk")]

DLL tampering and replacement creates security hole

Public key token + digital signature (= Strong Name) guarantees tamper proof

Digital signature built from private key and assembly file hash

CLR authenticates digital signature with strong name verification

Page 32: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Strong names• sn.exe -k PublicPrivateKeyFile.snk • The compiler digitally signs an assembly:

– calculates a cryptographic digest (hash) of the assembly– encrypts the compile-time digest using the 1.024-bit private

key from your public-private key pair file. – compiler stores this encrypted compile-time digest into

assembly

• When the .NET loader loads an assembly: – calculates a cryptographic digest (hash) of the assembly– extracts the encrypted compile-time digest from the assembly– extracts the public key for the assembly– uses the public key to decrypt the compile-time digest– compares the runtime digest to the decrypted compile-time

digest– if they are not equal, something or someone has modified the

it since you compiled it; the runtime fails to load the assembly

Page 33: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Strong names

• Strong Names during developement cycle:– Build the assembly with delay signing enabled– Enable strong name verification skipping for the

assembly (sn.exe -Vr)– Debug and test the assembly– Obfuscate the assembly– Debug and test the obfuscated version– Delay sign the assembly (sn.exe -R).

Page 34: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

If the strong name is not present, or is not correct…

…the main method is not fired!

StrongNameSignatureVerification

__int32 STDMETHODCALLTYPE _CorExeMain2(PBYTE pUnmappedPE, DWORD cUnmappedPE, LPWSTR pImageNameIn, LPWSTR pLoadersFileName, LPWSTR pCmdLine) { PEFile *pFile = NULL; HRESULT hr = E_FAIL;

if (!StrongNameSignatureVerification(pImageNameIn, SN_INFLAG_INSTALL|SN_INFLAG_ALL_ACCESS|SN_INFLAG_RUNTIME, NULL) && StrongNameErrorInfo() != (DWORD) CORSEC_E_MISSING_STRONGNAME) { LOG((LF_ALL, LL_INFO10, "Program exiting due to strong name verification failure\n")); return -1; }

//...

if (SUCCEEDED(hr)) { hr = SystemDomain::ExecuteMainMethod(pFile, pImageNameIn); }

//exit EEShutDown(FALSE); SafeExitProcess(GetLatchedExitCode()); return (GetLatchedExitCode());}

Page 35: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacksAuthorization &

Enforcement

• They are highly coupled• Security decisions

– Coded in software (dynamic, hardcoded)

– Declared in assemblies (declarative security)

– Inserted in Security Policy (static, configurable)

Page 36: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Setting permission

• The CLR discover permissions by gathering evidences from the assembly and giving the answers to the security policy manager, which converts them into permissions.

• However, often we may want to restrict the set of permissions based on policy at runtime. Let’s see an example.

Page 37: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Runtime security request

• Imagine an highly trusted assemblies calling to a user-provided script. The assembly invoking the script might want to restrict the effective permissions before making the call

• Need for a dynamic permission set management: – PermissionSet– Demand– Deny and RevertDeny, – PermitOnly and RevertPermitOnly – Assert

Page 38: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Demanding permission

using System.Security.Permissions; public class MyFileAccessor { public MyFileAccessor(String path, bool readOnly) { path = MakeFullPath(path); // helper fcn FileIOPermissionAccess desiredAccess = readOnly ? FileIOPermissionAccess.Read : FileIOPermissionAccess.AllAccess; FileIOPermission p = new FileIOPermission(desiredAccess, path); p.Demand(); // ••• open the file } // ••• }

•Create an object that represents the permission (in this case, access to a file)

•Demand that permission. •The system look at the permissions of the caller• If the caller doesn't have this particular permission, Demand

throws a SecurityException.

Page 39: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Luring attack

Mscorlib.dll

FileStream

Assembly2.dll

FileReader

Assembly4

BadComponent

Assembly3.exe

MyComponent

Local drive

Local drive

InternetIf Assembly2 is fully trusted, Assembly4 could use it to circumvent protection

Making someone other do the dirty work for you.

Rather than forcing each middleman component to do its own access checks to avoid this situation, the CLR uses a technique called Stack Walk

Page 40: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Finds that the Internet permission set does not contain FileIO permission,

Internet.Contains(FileIO) = falseFullTrust.Contains(FileIO) = true

Finds that FileReader::read() has this permission

Stack walkThe CLR verifies that every caller in the call chain has the permissions demanded.

Call Stack                             Grant               Requires===================================================================================

Assembly4.exe

BadComponent::Main()

Assembly4.exe!BadComponent::Main()      Internet            Execution

Assembly2.dll

FileReader::read()

Assembly2.dll!FileReader::read()            FullTrust           Environment, FileIO

Mscorlib.dll

FileStream::.ctor()

mscorlib.dll!System.IO.FileStream::.ctor()  FullTrust           FileIO

Raise a SecurityException.

The FileStream constructor does its demand for FileIOPermission

Page 41: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Stack walkWhen the local component Assembly3.exe

uses FileReader to read a file, it will be given access because all asseblies in the call chain are local.

However, when BadComponent attempts to use FileReader, FileStream calls Demand, the CLR walks up the stack and discover that one of the callers in the call chain don't have the requisite permissions: Demand will throw a SecurityException.

Page 42: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

If Calculate tries to:-access files anywhere in the two sensitive directories, -access an environment variable,-access the contents of the clipboard,(or if any components that Calculate uses internally tries to do any of these things)

when the CLR walks the stack to check access, it notes that a stack frame denies these permissions and so denies the request

Setting permissions (Deny)

using System.Security.Permissions; using System.Security;

public interface IUserPluggableAlgorithm { int Calculate(int a, int b); }

// code snippet that uses the algorithm PermissionSet ps = new PermissionSet(); ps.AddPermission(new FileIOPermission( FileIOPermissionAccess.AllAccess, "c:\\sensitiveStuff")); ps.AddPermission(new FileIOPermission( FileIOPermissionAccess.AllAccess, "c:\\moreSensitiveStuff")); ps.AddPermission(new EnvironmentPermission( PermissionState.Unrestricted)); ps.AddPermission(new UIPermission( PermissionState.Unrestricted)); ps.Deny(); // deny these permissions

int result = a.Calculate(42, 64); CodeAccessPermission.RevertDeny(); // ••• continue doing work

Recall the case of a trusted assembly calling to a user-provided script.This code places extra restrictions in the current stack frame.

Page 43: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Denies.Contains(FileIO) = true

Finds that this permission is in the Deny set

Permission set and Stack walk

Call Stack                             Grant          Requires Denies========================================================================================

MyApp.exe

MyApp::Main()

MyApp.exe!MyApp::Main()      FullTrust      -

custom.dll

IUserPluggableAlgorithm::calculate()

custom.dll! IUserPluggableAlgorithm::calculate() FullTrust      - FileIO, ...

Mscorlib.dll

FileStream::.ctor()

mscorlib.dll!System.IO.FileStream::.ctor()   FullTrust      FileIO FileIO, ...

Raise a SecurityException.

The FileStream constructor does its demand for FileIOPermission

ps.Deny()

FileIO, ...

Page 44: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Assert

using System; using System.IO; public class ErrorLogger { public static void Log(string s) { const string fname = "c:\\temp\\errlog.txt"; FileStream logStream = new FileStream(fname, FileMode.Append, FileAccess.Write); StreamWriter logWriter = new StreamWriter(logStream); logWriter.Write(s); logWriter.Close(); logStream.Close(); } }

Suppose to have the following class

ErrorLogger is safer than MyFileAccessor when used by arbitrary components.But the stack-walking mechanism doesn't know this: when the FileStream constructor demands permissions of its callers, the demand will fail unless every caller in the chain has the FileIOPermission demanded.

Page 45: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Assert

• If ErrorLogger class was installed locally, and its assembly is granted full access to the file system by the code access security policy.

• But this class was designed to provide service to other assemblies, some of which aren't granted permissions to write to the local file system!

• This impediment can be removed by having ErrorLogger assert its own authority to write to the log file.

Page 46: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

When the stack walk reaches that stack frame, it will consider the asserted permissions satisfied.

Assert a file IO permission before using the FileStream.

Assert

public class ErrorLogger2 { public static void Log(String s) { const String fname = "c:\\temp\\errlog.txt"; FileIOPermission p = new FileIOPermission( FileIOPermissionAccess.Append, fname); p.Assert(); FileStream logStream = new FileStream(fname, FileMode.Append, FileAccess.Write); StreamWriter logWriter = new StreamWriter(logStream); //... } }

You can only assert permissions that your assembly has been granted!

ErrorLogger installed as a local component is granted full access to the FileIO.

Page 47: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Assert and Stack walk

Now, when the FileStream constructor demands FileIO permission it is going to check Log(), find that it has permission, then hit the wall that the Assert put up, and goes no further up the stack. (FOR THAT permission!)

Call Stack                             Grant               Requires===================================================================================mscorlib.dll!System.IO.FileStream::.ctor()  FullTrust           FileIOErrorLogger2::Log()            FullTrust           Environment, FileIO-------------------------Assert(Environment, FileIO)-------------------------------Assembly4.exe!BadComponent::Main()      Internet            Execution

Since Log() is opening a very specific file, and since I've done a full security review on its code, I've decided to enable this scenario. 

I can do that by calling Assert() for Environment and FileIO permission in Log(), which will create a situation like the following:

Stack call Stack walk

Page 48: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Declarative Security• This powerful mechanism allows you to insert

code access security checks into your code by annotating classes, fields, or methods.

• The declarations are encoded in the assembly metadata and are enforced by the .NET security system.

[FileIOPermission(SecurityAction.Demand, UnmanagedCode = true)] void aMethod() { ... }

Page 49: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Security policy

• Permissions are assigned on a per-assembly basis by the Class Loader in the CLR. The steps are:– Gather evidence– Present evidence to security policy – discover assigned permission set

• It is possible to fine-tune permission set based on assembly requirements

Page 50: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Evaluating Security Policy

• To discover the permission set assigned to that assembly, a graph is traversed.

• The root node is really just a starting place for the traversal:– it matches all code – by default refers to the permission set named Nothing,

which contains no permissions.

• The traversal of the graph is governed by a couple of rules. – if a parent node doesn't match, none of its children are

tested for matches – each node can also have the Exclusive attribute, that

influence the traversal: only the permission set for that particular node will be used

Page 51: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Evaluating Security Policy

Zone:MyComputer

ps:permission1

Zone:Internet

ps:permission2

URL:http://.com/*

ps:permission3

Publisher:Microsoft

ps:permission4

Publisher:ACME Corp

ps:permission3

Publisher:ACME Corp

ps:permission4

All code

ps:nothing

Resulting permission set

permission1

permission3

Page 52: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Evaluating Security Policy

• There is more than one graph: – a machine policy level, – a user policy level, – an application domain policy level,

• They are evaluated in that order. • The resulting set is the

intersection of the sets discovered during the traversal of the three graphs

Page 53: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

AppDomains• Last enforcement technique, independent from

permissions• An AppDomain is conceptually similar to a process,

but has a much lighter weight. • When a process hosts the CLR, it always has a

default AppDomain where all managed types are loaded.

• By creating multiple AppDomains, types in one AppDomain cannot liberaly access types in any other AppDomains. – Sharing references between AppDomains requires the use

of remoting. If A and B are in separate AppDomains and A want to access B objects, B has to pass a reference to A.

– A can't poke around without being invited.

Page 54: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Attacks Against CAS • Misuse of Assert • Unmanaged code security permissions:

– Permission to call unmanaged code, it can bypass all CAS

– no permission to the file system, but allowed to call into unmanaged code => call to the Win32 API

– No protection if an attacker executes unmanaged code as admin

• Permission escalation by change of location:– Assembly used from Internet => low permissions – Convince the victim to install a copy of the

assembly on his machine => permission escalation

Page 55: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

Attacks Against CAS

• Fully trusted assembly– Can cross AppDomain boundaries– Can pass over IStackWalk.Deny with new PermissionSet( PermissionState.Unrestricted).Assert();

– Can access private members (via Reflection) by turning off JIT checks SecurityManager.SecurityEnabled = false;

• Remember the principle of least privilege, and design and code with it in mind.

Page 56: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

The old new thing

• How an .exe assembly get turned into code? • _CorExeMain2 starts the process

– verifies the signature on the assembly (StrongNameSignatureVerification)

– gets the execution engine (EE) ready (CoInitializeEE )

• EEStartup starts up all supporting services - garbage collector,- JIT- thread pool manager.

– SystemDomain::ExecuteMainMethod makes the Class Loder load an JIT the application main method

Page 57: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

The old new thing__int32 STDMETHODCALLTYPE _CorExeMain2(PBYTE pUnmappedPE, DWORD cUnmappedPE, LPWSTR pImageNameIn, LPWSTR pLoadersFileName, LPWSTR pCmdLine) { PEFile *pFile = NULL; HRESULT hr = E_FAIL;

if (!StrongNameSignatureVerification(pImageNameIn, SN_INFLAG_INSTALL|SN_INFLAG_ALL_ACCESS|SN_INFLAG_RUNTIME, NULL) && StrongNameErrorInfo() != (DWORD) CORSEC_E_MISSING_STRONGNAME) { LOG((LF_ALL, LL_INFO10, "Program exiting due to strong name verification failure\n")); return -1; }

//...

if (SUCCEEDED(hr)) { hr = SystemDomain::ExecuteMainMethod(pFile, pImageNameIn); }

//exit EEShutDown(FALSE); SafeExitProcess(GetLatchedExitCode()); return (GetLatchedExitCode());}

Remember?

Page 58: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks

The old new thing

• This is unmanaged, native code. Here we are going to attack: API patching of – RegQueryValueEx– RegOpenKeyEx

• Recall delay signing and sn.exe -Vr• Insert via API patch a bogus voice in HKLM\

Software\Microsoft\StrongName\Verification

• This makes the CLR skip StrongName verification for our assembly => tampering

• Microsoft did a number of things to avoid this situation, but a way can be found

Page 59: Software attacks.NET security. Software attacks The problem Buffer owerflow: one silly but very common bug Can allow a determined attacker to obtain control.

Software attacks