Security Challenge: "Star Hacks, Episode V: The Empire Hacks Back" by Raul Sileswalker (www.raulsiles.com) Acks: Thanks to Eric and Monica for being as you are! Life is terrific with you! (This is the first one where Eric is just a few meters far from the keyboard ;-)) In order to solve this month security challenge I mainly used the WMIC tool [3]. It is a command-line tool to pull and push OS data via the Windows Management Instrumentation (WMI) management interface [1][2]. WMI is a complex interface that allows to manage several thousands internal Windows OS settings. WMI includes its own WMI Query Language, WQL, a subset of ANSI SQL (WMI + SQL = WQL) [4]. The tool, WMIC, is available on Win XP Pro and Windows 2003 and interacts with the OS using WMI and WQL. Most of the actions for this challenge deal with processes, therefore the "wmic process /?" command provides the different actions and options available to manage OS processes. Prior to trying to answer the challenge questions, it is well worth to clarify that as a consious incident handler Jedi, I programmed my R2D2 droid to always generate forensic traces of all the actions it runs. This audit trail is crucial for situations where an incident finishes as a case in the Galatic Republic court of law. For simplicity and clarity the logging option has not been included in the commands below, but R2D2 includes in every WMIC execution the "/record:" option, specifying a different file for each command, such as: C:\> wmic /record:log_0.xml process list brief C:\> wmic /record:log_1.xml process where name='cmd.exe' The log file contains the command executed, when it was executed and the results obtained, all in XML format. It's time to use my Jedi Kung Fu skills to advise R2D2 how to fight the Vader Bots: 1) How can R2D2 kill all of the processes named “vaderbot.exe” with a single command? Jedi: "R2, use the Windows wmic command-line tool to kill all the processes named “vaderbot.exe”." "That's easy! Remember how we did when repairing our X-wing starfighter last week." R2D2: "Beep Beeeep Beeeep Beep" [I'll use a WQL sentence using a "where" clause and the "name" field in an equal to condition.] After confirming it, R2D2 executed the following command killing all the ten “vaderbot.exe” processes running on the Windows 2003 Server controlling the Falcon's hyper drive: C:\>wmic process where name='vaderbot.exe' delete Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="500" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="1000" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="1500" Instance deletion successful. ... Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="5000" Instance deletion successful. C:\> C3PO: "R2, this is like the "killall -9 vaderbot.exe" command on my FALCON-Linux box." R2D2: "Beep Beep Beep" [These protocol droids... they're always thinking in open-source terms.] 2) Unfortunately, as the last vaderbot.exe process is about to be killed, it spawns a group of new Vader Bot processes, but each with a new name, called “vaderbot0.exe”, “vaderbot1.exe”, “vaderbot2.exe”, and so on up to “vaderbot9”. How can you kill all of these processes based on their process name in one command? C3P0: "Oooohhh! The last one has launched ten new processes, each of them with a different name." Jedi: "R2, use a simple regular expression this time to match the last number for all the new "vaderbotX.exe" processes." R2D2: "Beeeepp Beeeep Beep" [I'll use the same WQL sentence using a "where" clause but this time with the "like" operator.] R2D2 executed the following command killing all the ten “vaderbotX.exe” processes running on the Windows 2003 Server: C:\>wmic process where "name like 'vaderbot[0-9].exe'" delete Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="6000" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="6001" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="6002" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="6003" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="6004" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="6005" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="6006" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="6007" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="6008" Instance deletion successful. Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="6009" Instance deletion successful. C:\> C3P0: "R2, you always surprise me with your Windows knowledge!" 3) Unfortunately, as the last Vader Bot numbered process (“vaderbot9”) is about to be killed, it generates a whole bunch of new Vader Bot processes, with apparently random names, such as QnV5I.exe, ENvdW.exe, 50ZXI.exe, gSGFj.exe, ayBSZ.exe, WxvYW.exe, RlZCw.exe, gUGxl.exe, YXNlI.exe, and finally, Q==.exe. How can you kill all of these processes in one command without knowing their Process IDs? C3P0: "Oooooh, my god! This is getting worse and worse." In order to solve this situation, the Jedi got the advise from his master. Yoda: "Raul, the differences and relationships between the processes you need to find." Jedi: "R2, let me thing about this! All the new 10 processes use a name with a length of 5 characters, and it seems that 3 of them are always uppercase. Mmmmmm...". R2D2: "Beeeeeep Beep" [I'm afraid the last process doesn't follow this rule.] Jedi: "R2, you're rigth! It seems we cannot use the name to kill them all in one command (and Ed does not allow us to use their process ids ;-))." Jedi: "I need to find another relationship between them..." After two seconds of reflection, the Jedi figured out he need his best Jedi Kung Fu skills. He still remember the lessons learnt from the Yoda master: Yoda: "The WQL language and the internal OS kernel structures you need to master." Jedi: "All processes have been spawned by the previous "vaderbot9.exe" process, therefore, although we don't know their process ids (PIDs), their parent process id (PPID) must be the same for all them. The PPID field for all them should contain the id value of the last process we killed before, that is, 6009". In the previous question you can validate that the WMIC output diplays the PID of every process terminated. That's how the Jedi knew 6009 is the key number. Another way of getting this information would have been using the following WMIC command that allows to list basic information for all the "vaderbotX.exe" process in question 2: C:\>wmic process where "name like 'vaderbot[0-9].exe'" list brief HandleCount Name Priority ProcessId ThreadCount WorkingSetSize 31 vaderbot0.exe 8 6000 1 356352 31 vaderbot1.exe 8 6001 1 356352 31 vaderbot2.exe 8 6002 1 356352 31 vaderbot3.exe 8 6003 1 356352 31 vaderbot4.exe 8 6004 1 356352 31 vaderbot5.exe 8 6005 1 356352 31 vaderbot6.exe 8 6006 1 356352 31 vaderbot7.exe 8 6007 1 356352 31 vaderbot8.exe 8 6008 1 356352 31 vaderbot9.exe 8 6009 1 356352 C:\> Jedi: "R2, prior to kill them all, let's double-check that the PPID is the same for all them. Generate a detailed view of all the processes with a PPID of 6009." C:\>wmic process where ParentProcessId=6009 Caption CommandLine CreationClassName CreationDate CSCreationClassName CSName Description ExecutablePath ExecutionState Handle HandleCount InstallDate KernelModeTime MaximumWorkingSetSize MinimumWorkingSetSize Name OSCreationClassName OSName OtherOperationCount OtherTransferCount PageFaults PageFileUsage ParentProcessId PeakPageFileUsage PeakVirtualSize PeakWorkingSetSize Priority PrivatePageCount ProcessId QuotaNonPagedPoolUsage QuotaPagedPoolUsage QuotaPeakNonPagedPoolUsage QuotaPeakPagedPoolUsage ReadOperationCount ReadTransferCount SessionId Status TerminationDate ThreadCount UserModeTime VirtualSize WindowsVersion WorkingSetSize WriteOperationCount WriteTransferCount QnV5I.exe QnV5I.exe Win32_Process 20060429024010.113804+120 Win32_ComputerSystem FALCON-2003 QnV5I.exe C:\Temp\QnV5I.exe 1076 32 500720 1413120 204800 QnV5I.exe Win32_OperatingSystem Microsoft Windows XP Professional|C:\WINDOWS|\Device\Harddisk0\Partition1 338 112780 886 1200128 6009 1200128 3347 6608 3461120 8 1200128 7000 2640 31468 3712 34864 2 2217 0 1 200288 32473088 5.1.2600 3461120 0 0 ... Q==.exe Q==.exe Win32_Process 20060429024030.723440+120 Win32_ComputerSystem FALCON-2003 Q==.exe C:\Temp\Q==.exe 4048 31 500720 1413120 204800 Q==.exe Win32_OperatingSystem Microsoft Windows XP Professional|C:\WINDOWS|\Device\Harddisk0\Partition1 106 500 840 1118208 6009 1118208 3347 6608 3158016 8 1118208 7009 2520 30420 3392 34864 0 0 0 1 100144 31399936 5.1.2600 3149824 0 0 C:\> C3P0: "Ooohhh, what's that. Me, being a protocol droid, and I cannot understand this dialect. What are all these numbers? Why is a partition reflected in each process line? Why the last number is alwasy 0?" Jedi: "C3P0, don't worry, this is not the output you're looking for." ;-) Jedi: "R2, run a simplified version of this command to filter by specific attributes. Let's just get the very basic ones." R2 run the following command providing a user friendly output C3P0 was confortable with: C:\>wmic process where ParentProcessId=6009 get Caption,Name,ParentProcessId,ProcessId Caption Name ParentProcessId ProcessId QnV5I.exe QnV5I.exe 6009 7000 ENvdW.exe ENvdW.exe 6009 7001 ... Q==.exe Q==.exe 6009 7009 C:\> Another way of getting a clear and parseable output of the full detailed view is by using the "C:\>wmic process where ParentProcessId=6009 list full" command. It displays one field per line. Jedi: "R2, this execution is critical, so use the "/interactive:on" command-line switch to confirm the termination of all these randomly named processes". R2 then executed the next command following the Jedi wise recommendation: C:\>wmic process where ParentProcessId=6009 delete /interactive:on Delete '\\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="7000"' (Y/N/?)? y Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="7000" Instance deletion successful. Delete '\\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="7001"' (Y/N/?)? y Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="7001" Instance deletion successful. ... Delete '\\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="7009"' (Y/N/?)? y Deleting instance \\FALCON-2003\ROOT\CIMV2:Win32_Process.Handle="7009" Instance deletion successful. C:\> C3P0: "R2, you did it! You're my hero!" 4) And yes again unfortunately, as the last apparently random-named bot process is about to be killed, it generates one more process for Vader Bot, named smss.exe. How can you kill this final Vader Bot process in a single command without knowing its Process ID? Again, for this difficult task, the Jedy turn to the wise advice of his masters (in plural): Yoda: "Remember, your scripting Fu skills you must use. The process relationships and differences the key are." Obi-Wan: "Raul, find these two processes differences and let the force be with you!" Although till now Han Solo and Chewbacca were busy getting rid of some Imperial Stormtroopers, they came back to the scene in the last and decisive moment: Han: "Hey boy, tell your droid not to kill the real smss.exe process or the hyper drive will be the least of our worries. If the good smss.exe disapears I won't be able to control the Millennium Falcon at all and you will meet your father beforehand." Chewy: "OOOuuuugghhhhhh!". [Han I agree, I'm tired of fixing all the time what these two droids break.] In this relaxed and friendly environment, the Jedi recommended R2 to list all the processes called "smss.exe". R2 executed the following command: C:\>wmic process where name="smss.exe" list brief HandleCount Name Priority ProcessId ThreadCount WorkingSetSize 21 smss.exe 11 1024 3 114688 39 smss.exe 8 7500 1 356352 C:\> From the brief output above he could not derive much information so, he tried to get all the details about these processes: C:\>wmic process where name="smss.exe" Caption CommandLine CreationClassName CreationDate CSCreationClassName CSName Description ExecutablePath ExecutionState Handle HandleCount InstallDate KernelModeTime MaximumWorkingSetSize MinimumWorkingSetSize Name OSCreationClassName OSName OtherOperationCount OtherTransferCount PageFaults PageFileUsage ParentProcessId PeakPageFile Usage PeakVirtualSize PeakWorkingSetSize Priority PrivatePageCount ProcessId QuotaNonPagedPoolUsage QuotaPagedPoolUsage QuotaPeakNonPagedPoolUsage QuotaPeakPagedPoolUsage ReadOperationCount ReadTransferCount SessionId Status TerminationDate ThreadCount UserModeTime VirtualSize WindowsVersion WorkingSetSize WriteOperationCount WriteTransferCount smss.exe \SystemRoot\System32\smss.exe Win32_Process 20060401200719.966750+120 Win32_ComputerSystem FALCON-2003 smss.exe C:\WINDOWS\System32\smss.exe 1024 21 29842912 1413120 204800 smss.exe Win32_OperatingSystem Microsoft Windows XP Professional|C:\WINDOWS|\Device\Harddisk0\Partition1 456 22062 259 172032 4 1716224 12345344 479232 11 172032 1024 640 5248 1752 13328 43 22686 0 3 100144 3891200 5.1.2600 114688 4 4 smss.exe "C:\Temp\smss.exe" Win32_Process 20060429025311.116832+120 Win32_ComputerSystem FALCON-2003 smss.exe C:\Temp\smss.exe 7500 39 400576 1413120 204800 smss.exe Win32_OperatingSystem Microsoft Windows XP Professional|C:\WINDOWS|\Device\Harddisk0\Partition1 139 536 7009 1404928 2580 1404928 39038976 3637248 8 1404928 7500 2920 33296 3312 3979 2 0 0 0 1 300432 35909632 5.1.2600 356352 0 0 C:\> The Jedi tried to figure out what fields could help to differentiate the two processes. Although in this case, for example, the path from where each process was executed is different, this information canot be used always to discriminate which is the good and the bad process. The bad one could have been run from "\SystemRoot\System32\" too. In this type of scenario, multiple fields can be used, such as binary paths or memory fingerprints, like the process size in memory. The WMIC process help (wmic process list /? OR wmic process get /?) provides the different list formats and fields available. Jedi: "I need to find a way of differentiate both processes in any situation." Han: "Hey boy, it seems you have lot of fields to choose from." Jedi: "Yes, that's the problem! Ok, we know that the bad smss.exe process have been launched by the last randomly named process just a few minutes ago, therefore, its creation time must be very recent compared with the smss.exe system process, that is launched when the OS boots." Jedi: "R2, simplify the output above using the WMIC GET command showing the creation date." C:\>wmic process where name="smss.exe" get CommandLine,Name,CreationDate CommandLine CreationDate Name \SystemRoot\System32\smss.exe 20060401200719.966750+120 smss.exe "C:\Temp\smss.exe" 20060429025311.116832+120 smss.exe C:\> Jedi: "Let's see, the first of the two processes has a creation date of 20060401200719.966750+120. The format used is YYYYMMDDHHMMSS.mmmmmm+min", so... this is the 1st of April 2006, around 20:07. I can't believe this! This Windows box has been running for almost one month without rebooting. Amazing!" Jedi: "And the second smss.exe process has a creation date of 20060429025311.116832+120, that's just 7 minutes ago (29th of April 2006, around 2:53). I'm wondering why incidents tend to occur late at night. I'm always sleepy! Neither Yoda nor Obi-Wan told me about the difficulties of being an incident handler Jedi..." Jedi: "Therefore, based on the creation date it seems prety obvious that the bad one is the second process. R2, terminate it based on the creation date. Use a condition value equal to the exact second creation date." R2, following the Jedi instructions executed the following command, successfully killing the malicious process: C:\>wmic process where CreationDate='20060429025311.116832+120' delete Deleting instance \\RSILES-HP\ROOT\CIMV2:Win32_Process.Handle="7500" Instance deletion successful. C:\> The field used by the Jedi is just one way of discriminating different proccesses that look similar. The method used seems to be a very accurate technique if the processes where clearly started in separate time periods, specially based on the accurancy provided by this timestamp field; up to thousands of milliseconds. c3P0: "Great! That's all! There are no new malicious processes in the system!" Jedi: "R2, before calling it a day, let's remove the account created by the Vader Bot out of the system. Use the same WMIC method to clean it up." R2D2: "Beeeeeeep Beep Beep Beeeep Beep" [That's all folks! This is my last WMIC command for today, although I still prefer the net command ;-)!] And finally, R2 listed and removed the Darth account under the "vader" username, member of the admin group: C:\>wmic useraccount where name='vader' AccountType Caption Description Disabled Domain FullName InstallDate LocalAccount Lockout Name PasswordChangeable PasswordExpires PasswordRequired SID SIDType Status 512 FALCON-2003\vader FALSE FALCON Darth TRUE FALSE vader TRUE TRUE TRUE S-1-5-21-3335374247-4020222366-1500430415-1014 1 OK C:\> He used the old "net" tool instead of the corresponding WMIC command (wmic useraccount where name='vader' delete) simply to show that there are other commands in Windows apart from WMIC, although at this point it could seem unbelievable ;-) C:\>net user vader /DELETE The command completed successfully. C:\> 5) Finally, instead of spawning separate processes, the Vader Bot could have used other techniques to survive on the machine, continuing to run in light of R2D2’s process-killing assault. Please describe techniques for malware (or even non-malicious code) to continue running without having to spawn new processes. In order to be as stealthy as possible, some malware specimens use code injection techniques instead of spawning new OS processes that can be easily detected by the administrator or an HIDS. These injection methods do not create a separate process, so all the attacker's actions live inside the victim process. They are based on the fact that the basic execution unit in today's computers architectures is the thread; one process is made of multiple threads or execution units. The metasploit framework [5] provides several payloads that take advantage of this code injection capabilities. We are going to use this tool as the reference in the following paragraphs mainly because it implements the latest cutting-edge hiding execution tricks. The first Metasploit payload that implemented these techniques was the "Windows VNC Server DLL inject" [6]. This payload works by exploiting a remote vulnerable process and injects a DLL implementing a VNC server. Therefore, it provides GUI access to the desktop of the exploited system. Another similar generic payload available on Metasploit is the "Win32 DLL Injection Payload" [7], capable of injecting any custom DLL into memory and starts a new thread in the victim process. This DLL injection concept was extended by a new Metasploit general-purpose module called the Meterpreter [8]. It allows to load and interact accross the network with DLLs injected in the exploited process. Its main feature is that it provides a built-in command-line interpreter that can be extended through new customized DLLs in real-time. Finally, the new Metasploit 3.0 release, still in alpha version, will include in-memory process migration capabilities. The Meterpreter will be able to move from the initial victim process to a different process in memory, injecting its code wherever the attacker indicates it to. This will improve the malware stealthiness and will difficult R2D2 to shutdown future Vader Bots ;-) Fortunately from an incident handler perspective, the newly added malicious functionality increases the payload size, and in most cases the process memory fingerprint could be used to identify strage behaviours and compromises. Unfortunately, there are solutions already available that overcome this detection mechanism, such as the Syscall Proxy concept implemented in the Core Impact penetration testing commercial tool [9]. The Syscall Proxy is a small stub inserted on the victim machine (or inside another process in the future :-)) to execute system calls on the victim machine's kernel. The requests are received through the network from the attacker's machine. All these implementations apply to Windows, as in the Millenium Falcon case, but there are similar tools for other OS, such as the Metasploit "Impurity ELF Injection" [10]. It implements a method of loading and executing a new Linux ELF executable in-memory. DLL injection is an easy and flexible way of adding new code to an already running process that do not require to modify the current in-memory process code. This method is typically also used by user-mode rootkits. To sum up this section, code injection is the method that allows executing code within the address space of another existent process. Apart from DLL injection there are other techniques for injection, such as direct code injection and remote subclassing, described at [15] and implemented in the InjLib library [16]. Apart from that, rootkits [11] (we'll focus on Windows) implement methods to control the execution of new code and hide running processes. This could be considered a valid response to this question given the fact that, from the administrator point of view, no new processes are spawned in the system; all the attacker's processes are completely hidden at the user or kernel level. There are several techniques to implement these process hidding capabilities, such as IAT and SSDT hooking, virtual memory tricks or DKOM tricks [12]. Besides, there are other techniques used by kernel-mode rootkits focused on executing code in a system without requiring new processes. Kernel based rootkits are commonly implemented in Windows through device drivers, running at the highest OS priviledge level, called ring zero. An example is the kernel mode IRCbot [13]. This POC denotes that Darth Vader should attract new Siths to program more advanced bots, like this one, with the goal of increasing the capabilities of the dark side of the force against the Jedis. Directly related with the rootkit world, although it is not considered a rootkit, is the Stealth by Design (SbD) concept [14]. This malware uses the concept of short-life processes that are not hidden but can be hardly detected. Its goal is, again, to disappear from the incident handler sight. The saga continues... still with some unanswered questions, such as how R2 knew that Vader himself had used his bot to kill the hyperdrive.exe process? ;-) Raul Siles - REFERENCES: [1] "Windows Management Instrumentation (WMI)". MSDN. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/anch_wmi.asp [2] "WMI reference". MSDN. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_reference.asp [3] "WMIC". MSDN. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmic.asp [4] "WQL". MSDN. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/querying_with_wql.asp http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wql_sql_for_wmi.asp [5] Metasploit. H. D. Moore. http://www.metasploit.com [6] "NC Server DLL Injection". Metasploit. H. D. Moore. http://www.metasploit.com/projects/Framework/docs/userguide/node52.html [7] "Win32 DLL Injection Payloads". Metasploit. H. D. Moore. http://www.metasploit.com/projects/Framework/docs/userguide/node51.html [8] "The Metasploit Meterpreter". Metasploit. H. D. Moore. http://www.metasploit.com/projects/Framework/docs/meterpreter.pdf [9] "Syscall Proxying - Simulating remote execution". Maximiliano Caceres. http://www1.corest.com/files/files/11/SyscallProxying.pdf [10] "Impurity ELF Injection". Metasploit. H. D. Moore. http://www.metasploit.com/projects/Framework/docs/userguide/node48.html [11] Windows rootkits. Greg Hollund. http://www.rootkit.com [12] "Windows rootkits of 2005, part one". James Butler, Sherri Sparks. http://www.securityfocus.com/infocus/1850 [13] "Kernel Mode Ircbot". tibbar. http://tibbar.blog.co.uk/2006/04/06/kernel_mode_ircbot~708256 [14] "Rootkit Hunting vs. Compromise Detection". Joanna Rutkowska. http://invisiblethings.org/papers/rutkowska_bhfederal2006.ppt [15] "Three Ways to Inject Your Code into Another Process". Robert Kuster. http://www.codeproject.com/threads/winspy.asp [16] "InjLib". Antonio Feijao . http://www.codeproject.com/library/InjLib.asp