DEV Community

Cover image for The Day My Linux Server Started Distributing Windows Malware
Jerry Satpathy
Jerry Satpathy

Posted on

The Day My Linux Server Started Distributing Windows Malware

Here's a Minimal & Practical Guide to Server Hygiene

If you run a server long enough, you will eventually open a directory, spot a file you don't recognise, and think: “I did not put this here.”

I had my "moment" during the React2shell (CVE-2025-55182) outbreak. I found a file named Agtisx.exe sitting in a temp folder. A Windows executable on a Linux box is a red flag big enough to cover a stadium.

It wasn't just a stray file; it was the payload for a campaign turning my infrastructure into a distribution hub to infect Windows servers. My clean server had become a staging ground for someone else’s war.

This guide exists so that the moment becomes mildly interesting instead of emotionally devastating. We aren't aiming for "military-grade" complexity. We want clean, boring, predictable systems that let you sleep at night.

Boring Predictable Systems

1. SSH: Make Logging In Aggressively Boring

If logging into your server feels exciting, you’ve already failed. Your job isn't to defeat "hackers"; it’s to make your server so unrewarding that they move on to someone else.

Your config file at (/etc/ssh/sshd_config) should at the very least enforce:

  • Key-based login only. No passwords.
  • No root login. Force a standard user.
  • Minimal attempts. Give them three tries, then kick them.
#Edit /etc/ssh/sshd_config with these settings:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
MaxAuthTries 3
Enter fullscreen mode Exit fullscreen mode

Why it works: Bots love low-hanging fruit (passwords and root). They hate keys and effort. Be the effort.

2. Keys & Secret Rotation is Hygiene, Not Panic

SSH keys live forever unless you actively rotate them. They sit on old laptops, archived backups, CI machines you no longer use, and devices you forgot ever had access.

Environment variables behave the same way.

Once a secret exists, it tends to spread. It gets copied into .env files, pasted into dashboards, shared with teammates, backed up, and sometimes logged by mistake. Over time, you stop remembering where it lives, but it still works.

Rotating keys and secrets is not a response to an incident. It is routine maintenance. It limits the damage of forgotten access and reduces the blast radius of mistakes.

If you are thinking, “But nothing bad happened,” that is exactly the point. Rotation is what keeps it that way.

3. The Local Firewall: Trust but Verify

Even if your cloud provider has a "Security Group," run a local firewall. It’s your second line of defence against human error—specifically, your own misclicks.

The Rule: Expose SSH, HTTP, HTTPS, and your specific app ports. Block everything else.

# Example using UFW (Uncomplicated Firewall)
sudo ufw default deny incoming
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
Enter fullscreen mode Exit fullscreen mode

4. Fail2ban: Outsource the Annoyance

Brute-force attempts are a fact of life. You aren't being targeted; you just exist. Fail2ban watches your logs and quietly jails IPs that behave poorly.

# Check status of blocked IPs
sudo fail2ban-client status sshd
Enter fullscreen mode Exit fullscreen mode

5. Audit Your Services

Malware loves persistence, and persistence loves services. Run this command:

systemctl list-unit-files --state=enabled
Enter fullscreen mode Exit fullscreen mode

Ask one question for every line: “Do I know why this is here?”

If the answer is No: Investigate.
If the answer is still No: Disable it.

6. The Post-Moment Forensic Routine

When you find a file like Agtisx.exe, don't just delete it. You need to know how it got there.

Step 1: Check the Metadata

Before deleting, look at the file's "birth certificate":

stat Agtisx.exe
Enter fullscreen mode Exit fullscreen mode

This tells you the exact second it was created (Birth) or modified. Note the timestamp.

Step 2: Check Permissions and Ownership

Who "owns" the malware?

ls -la Agtisx.exe
Enter fullscreen mode Exit fullscreen mode

Owned by www-data? Your web app was the entry point (e.g., React2shell).
Owned by root?This implies privilege escalation.

Step 3: Confirm via Logs

Match the stat timestamp against your logs:

# Search web logs for activity around the 'stat' timestamp
grep "2025-02-04 10:30" /var/log/nginx/access.log
Enter fullscreen mode Exit fullscreen mode

7. Recovery: The "Burn It Down" Philosophy

Once a server is compromised enough to host attack payloads, you can rarely trust the OS again.

  1. Snapshot the evidence: Save logs and the malware sample to an isolated folder.
  2. Rotate everything:
    • SSH Keys: Generate new ones; revoke all old ones.
    • Secrets: Change DB passwords, API keys, and .env files.
  3. Delete the instance: Terminate the server. Do not try to "clean" it.
  4. Redeploy Fresh: Provision a new instance, apply your "Boring Config," and patch the vulnerability (e.g., update React) before going live.

8. Predictability Beats Fancy Tools

Your server should only talk to places you expect. Check your active connections:

ss -antp
Enter fullscreen mode Exit fullscreen mode

Normal: Web traffic, database connections, updates.
Not Normal: Random IPs, unknown processes, strange ports.

9. File Hygiene: Stop the Clutter

Your server is not a downloads folder. Make sure to check if there are

  • No random binaries in home directories.
  • No world-writable directories.
  • No executable permissions unless required.
# Find world-writable directories
find / -xdev -type d \( -perm -0002 -a ! -perm -1000 \) -print
Enter fullscreen mode Exit fullscreen mode

10. Backups: The Disaster Circuit-Breaker

Backups don’t prevent incidents; they prevent disasters. They turn a "compromise" into a "recovery."

The Golden Rule: If the thought of restoring your server feels scary, your backups aren't finished yet.

Clean Predictable Systems
The Goal

A clean server has:

  1. A few ways in.
  2. A few things are running.
  3. Few places to hide.
  4. Predictable behaviour.

The best compliment a professional server can receive is: “Nothing interesting happened today.”

The goal is to build for boredom & to Sleep better.
And as always Happy Coding!

Top comments (0)