Summary
From SQL Injection to Infrastructure-Level RCE: A PostgreSQL Superuser Compromise Imagine finding a backdoor that gives you absolute superuser access to a state infrastructure network, documenting the exploit chain perfectly, and submitting it—only to be met with total bureaucratic silence. While auditing a financial management web portal (vsswb ), I discovered a single unparameterized parameter that ultimately resulted in unauthenticated Remote Code Execution (RCE). This is the technical walkthrough of the exploit chain.
- The Entry Point The vulnerable endpoint was responsible for processing the pJobNumber parameter. vss00CvStatusData.php Appending a single quote (’ ) immediately triggered a raw PostgreSQL error: pg_query(): Query failed: ERROR: unterminated quoted string at or near ”## order by wcs.fdate ;” Observation User-controlled input was being directly concatenated into a SQL statement without parameterization.
- Fingerprinting the Database Using UNION SELECT with NULL placeholders to align the three-column query structure, I extracted the PostgreSQL version and execution context. curl -k -s “https://[TARGET_URL]/vsswb/vss00CvStatusData.php?pAction=LoadTypeCombo&pJobNumber=nonexistent’+UNION+SELECT+NULL,version(),current_user—&pSelection=1” Response: [ { “wbid”: null, “job”: “PostgreSQL 13.1, compiled by Visual C++ build 1914, 64-bit”, “wodetails”: “postgres” } ] Finding The web application connected directly as the native PostgreSQL postgres account. Get Gokul’s stories in your inbox Join Medium for free to get updates from this writer. This is the database superuser, effectively eliminating privilege boundaries.
- Mass Data Exposure With superuser privileges, PostgreSQL system catalogs became fully accessible. Enumeration quickly revealed employee records stored in: public.vss01tpemployee The table contained personally identifiable information (PII), including employee names, PAN numbers, and financial records.