I got the email at 11 PM on a Tuesday.

Subject line: "Legacy Facility - Audit Required - Urgent"

No context. No pleasantries. Just an address forty minutes outside the city and a terse note: "Previous administrator left no documentation. Keys at front desk. Access codes attached. Complete audit by Friday."

The address led me here—to a data center that time forgot. The kind of place that gets built in the late 90s when everyone's terrified about Y2K and decides they need off-site redundancy. Then Y2K doesn't happen, the redundancy becomes the primary, and twenty years later nobody quite remembers what's running here or why it can't be shut down.

The security guard at the front desk looked relieved to see me. "You the computer guy? Thank god. Nobody's been here in months. Equipment keeps running though. Fans, lights, the whole thing. Power bill's insane."

He handed me a key ring that probably weighed two pounds and a sticky note with four different access codes. "Good luck in there. Place gives me the creeps after dark."

I should have paid attention to that.

The First Login

The facility was a time capsule. Rack after rack of beige and black servers, some with branding from companies that went bankrupt in 2008. Cable management that suggested someone once cared, now sagging under the weight of accumulated dust and abandonment. The air conditioning still worked—the hum was hypnotic, almost alive.

I found the admin workstation in what must have been an office once. Someone's coffee cup still sat on the desk, lipstick stain visible on the rim. A calendar on the wall showed October 2019. Whoever worked here last had left in a hurry, or just... never come back.

The workstation was still on. Login screen glowing in the darkness.

I used the access codes from the sticky note. The system let me in without complaint. No forced password change. No security warnings about the last login being five years ago. Just... in.

Welcome to LEGACY-ADM-01
Last login: Mon Sep 15 03:47:23 2019 from 10.0.1.47

That timestamp bothered me immediately. 3:47 AM. Five years ago to the day, almost to the hour. What kind of admin is working at 3:47 in the morning? And from an internal IP, so they were here, in this building, at that hour.

I filed it away. Probably nothing.

The Three Questions Linux Always Asks

Before I dive into what I found, let me teach you something fundamental. Something that separates Unix-like systems from the anarchic free-for-alls of early personal computers.

See, back in the early 1970s at Bell Labs, Ken Thompson and Dennis Ritchie had a problem. They were building Unix on a PDP-7—a machine with less computing power than your smart watch—and multiple users needed to share it. Computers cost more than houses back then. Sharing wasn't optional.

The question became: How do you keep users from stepping on each other's digital toes?

Their solution was elegant and brutal in its simplicity. Every file has an owner. Every process runs as a user. And there are rules—clear, unambiguous rules—about who can do what.

When you try to access any file in Linux, the system asks three questions in this exact order:

  1. Who are you? (What user account are you running as?)

  2. What's your relationship to this file? (Are you the owner? In the file's group? A complete stranger?)

  3. What are you trying to do? (Read it? Write to it? Execute it as a program?)

That's it. Three questions. The answers determine whether you get access or get denied.

It's the foundation of every security boundary in Linux. And it's about to become very relevant to what I found in this forgotten facility.

Identity: Who the Hell Are You?

Let me start with the basics, because this is where things started feeling wrong.

Every process in Linux runs as a specific user. When you log in, your shell runs as your user account. When you launch a program, it typically runs as you. When you sudo something, it temporarily runs as root—user ID 0, the god account that can do anything.

Users are identified by three things:

  • A username (like "jsmith")

  • A User ID or UID (a number that's what the kernel actually cares about)

  • Membership in one or more groups (identified by Group IDs or GIDs)

Groups are just collections of users. They exist so you don't have to individually grant permissions to every developer on your team—you just make a developers group and manage it once.

Simple enough, right?

So I did what any sane admin does on an unfamiliar system. I checked who I was:

whoami

Command breakdown:

  • whoami = "who am I?" (tells you your current username)

The output:

aarkham

Okay. That's the account they gave me. Expected.

Then I ran:

id

Command breakdown:

  • id = Shows your user ID, group ID, and all group memberships

The output:

uid=2847(aarkham) gid=2847(aarkham) groups=2847(aarkham),27(sudo),1001(legacy_ops),1003(facility_admin)

Let me parse that for you:

  • uid=2847 - My user ID number is 2847

  • gid=2847 - My primary group ID is also 2847 (same as my username, standard)

  • groups= - Then a list of all groups I'm in

And that's where my coffee went cold.

I was in groups called legacy_ops and facility_admin. Groups I'd never requested. Groups that weren't mentioned in any of the access documentation. I checked my onboarding email again—nothing about these groups.

Someone, or something, had added me to them.

When?

I checked the group files:

grep legacy_ops /etc/group

Command breakdown:

  • grep = Search for a pattern in a file

  • legacy_ops = The pattern I'm searching for

  • /etc/group = The file containing all group definitions

Output:

legacy_ops:x:1001:aarkham,dmorrow,mzaleski

Three users in this group. Me, someone named dmorrow, and someone named mzaleski.

I didn't know those names. Time to check who they were:

grep -E "dmorrow|mzaleski" /etc/passwd

Command breakdown:

  • -E = Use extended regex (lets me search for multiple patterns with the | operator)

  • "dmorrow|mzaleski" = Find lines containing either name

  • /etc/passwd = The file containing all user account info

Output:

dmorrow:x:1847:1001:David Morrow:/home/dmorrow:/bin/bash
mzaleski:x:1024:1001:Mark Zaleski:/home/mzaleski:/bin/bash

Real accounts. With home directories. With login shells.

I checked the last login records:

last dmorrow mzaleski

Command breakdown:

  • last = Shows login history from the system logs

  • dmorrow mzaleski = Filter to just these usernames

Output:

dmorrow  pts/0        10.0.1.23        Mon Sep 15 14:33 - 18:47  (04:14)
mzaleski pts/1        10.0.1.47        Mon Sep 15 03:47 - 04:15  (00:28)

September 15, 2019. The same day as the last login to this workstation.

Mzaleski had logged in at 3:47 AM. That timestamp again.

I stared at that output for a long time in the dim server room. The only sound was the mechanical breathing of the air conditioning and the occasional click-whir of a hard drive seeking.

These people hadn't logged in for five years. But I was in their group. Sharing their permissions. Inheriting their access.

The Cryptic Hieroglyphics: Reading ls -l

I needed to see what I was dealing with. Time to look at some actual files.

The command everyone learns first when they want to see permissions:

ls -l

Command breakdown:

  • ls = "list" (shows directory contents)

  • -l = "long format" flag (gives detailed information instead of just filenames)

I ran it on /opt, a common location for application software:

ls -l /opt

The output scrolled past. Most of it was what you'd expect—application directories, log files, configuration. Standard stuff.

Then I saw these three entries, and my stomach dropped:

-rw-r--r--  1 dmorrow  legacy_ops   15234  Sep 15  2019 cron_backup.sh
-rwxr-xr-x  1 mzaleski daemon        8192  Aug 03  2019 watchdog
drwxrwxr-x  8 UNKNOWN  UNKNOWN       4096  Oct 09 03:47 .cache
-rw-rw----  2 root     legacy_ops   22156  Oct 09 03:47 system.log

Let me teach you how to read these cryptic lines, because understanding them is the only way to understand what's wrong here.

(IMAGE PROMPT: Extreme close-up of a terminal screen showing the ls -l output, with the permission strings illuminated as if backlit, each character of "drwxrwxr-x" glowing with a faint green phosphor, the UNKNOWN entries appearing slightly corrupted or distorted)

Decoding the Matrix

Here's what each column in that ls -l output means. Let's use the first line as our example:

-rw-r--r--  1 dmorrow  legacy_ops  15234  Sep 15  2019 cron_backup.sh

Reading left to right:

Column 1: File type and permissions (-rw-r--r--)
This is actually 10 characters that tell us everything about access. I'll break them down:

  • Position 1: File type (- = regular file, d = directory, l = symlink)

  • Positions 2-4: Owner/user permissions (rw-)

  • Positions 5-7: Group permissions (r--)

  • Positions 8-10: Other/world permissions (r--)

Column 2: Link count (1)
Number of hard links. Not important right now.

Column 3: Owner (dmorrow)
The user who owns this file.

Column 4: Group (legacy_ops)
The group that owns this file.

Column 5: Size (15234)
File size in bytes.

Column 6-8: Timestamp (Sep 15 2019)
When the file was last modified.

Column 9: Filename (cron_backup.sh)
The actual name of the file.

Now let's focus on those permission strings, because that's where the story is.

The Permission Triplets: A Ternary Hierarchy

The nine characters after the file type (that first dash or d) break into three groups of three. Each group answers one of our three questions:

Characters 2-4: User permissions - What can the owner do?
Characters 5-7: Group permissions - What can members of the file's group do?
Characters 8-10: Other permissions - What can everyone else do?

And within each group, there are three possible permissions:

  • r (read) = Can view the contents (numeric value: 4)

  • w (write) = Can modify the contents (numeric value: 2)

  • x (execute) = Can run it as a program, or enter it if it's a directory (numeric value: 1)

  • - (dash) = Permission denied for this action

Let me break down that first file by reading the permission string left to right:

-rw-r--r--  dmorrow  legacy_ops  cron_backup.sh

The first character is -, meaning it's a regular file.

The next three characters (rw-) are the user/owner permissions. The owner is dmorrow. So:

  • r = dmorrow can read this file

  • w = dmorrow can write (modify) this file

  • - = dmorrow cannot execute this file

The next three characters (r--) are the group permissions. The group is legacy_ops. So:

  • r = Anyone in the legacy_ops group can read this file

  • - = They cannot write to it

  • - = They cannot execute it

The final three characters (r--) are the other permissions (everyone else on the system):

  • r = Anyone can read this file

  • - = They cannot write to it

  • - = They cannot execute it

So the complete picture: dmorrow can read and modify this file. Anyone in the legacy_ops group (that includes me now, apparently) can read it. And everyone else on the system can also read it.

Octal Notation: The Numeric Shorthand

The numeric values I mentioned? That's octal notation—a shorthand that Unix nerds invented because they loved being terse. Each permission can be represented as a bit:

  • Read (r) = 4

  • Write (w) = 2

  • Execute (x) = 1

You add them up for each group of three permissions:

For our file rw-r--r--:

  • User permissions rw- = 4 (read) + 2 (write) + 0 (no execute) = 6

  • Group permissions r-- = 4 (read) + 0 (no write) + 0 (no execute) = 4

  • Other permissions r-- = 4 (read) + 0 (no write) + 0 (no execute) = 4

So rw-r--r-- becomes 644 in octal notation.

Common patterns you'll see:

  • 644 = Files readable by everyone, writable only by owner (documents, configs)

  • 755 = Executable files or directories (scripts, binaries, folders you can cd into)

  • 600 = Private files only the owner can access (SSH keys, passwords)

  • 777 = The devil's permission (everyone can do everything—you almost never want this)

  • 700 = Private executable (only owner can read, write, or run it)

Analyzing the Second File

File two on my list:

-rwxr-xr-x  1 mzaleski daemon  watchdog

Let me break this down the same way:

File type: - (regular file)

User/owner permissions (rwx): Mzaleski has:

  • r = read

  • w = write

  • x = execute

Group permissions (r-x): Members of the daemon group have:

  • r = read

  • - = no write

  • x = execute

Other permissions (r-x): Everyone else has:

  • r = read

  • - = no write

  • x = execute

In octal: 755 (7 for user, 5 for group, 5 for other)

This is a binary. An executable program. Owned by Mzaleski. And according to the name, it's some kind of watchdog process—something that monitors the system.

It last changed on August 3, 2019. Over a month before Mzaleski's last login.

The Unknown

But it was the third entry that made me reach for my notepad with shaking hands:

drwxrwxr-x  8 UNKNOWN  UNKNOWN  4096  Oct 09 03:47 .cache

Let me decode this one:

File type: d (this is a directory, not a file)

Owner: UNKNOWN
Group: UNKNOWN
Timestamp: Oct 09 03:47

That timestamp was from tonight. About twenty minutes before I walked in.

And the owner? UNKNOWN.

This happens when a UID exists in the filesystem but doesn't have a corresponding entry in /etc/passwd. Orphaned accounts. When someone deletes a user but doesn't clean up their files, you see UNKNOWN.

But orphaned accounts don't modify their files. Dead users don't update timestamps.

I checked what was inside:

ls -la /opt/.cache

Command breakdown:

  • -a = "all" flag (shows hidden files that start with .)

Output:

total 32
drwxrwxr-x  8 UNKNOWN  UNKNOWN   4096 Oct 09 03:47 .
drwxr-xr-x 24 root     root      4096 Oct 08 14:22 ..
-rw-rw-r--  1 UNKNOWN  UNKNOWN   8192 Oct 09 03:47 state.db
-rw-r--r--  1 UNKNOWN  UNKNOWN   2048 Oct 09 03:47 process.log
-rw-rw----  1 UNKNOWN  UNKNOWN   1536 Oct 09 03:47 permissions.map
drwxrwx---  2 UNKNOWN  UNKNOWN   4096 Oct 09 03:47 archive

Every single file. Modified at 03:47 tonight.

All owned by UNKNOWN.

I tried to check the actual numeric UID:

stat /opt/.cache

Command breakdown:

  • stat = Shows detailed file statistics, including numeric UID/GID

Output:

  File: /opt/.cache
  Size: 4096      	Blocks: 8          IO Block: 4096   directory
Device: 801h/2049d	Inode: 1835009     Links: 8
Access: (0774/drwxrwxr--)  Uid: ( 3847/ UNKNOWN)   Gid: ( 3847/ UNKNOWN)
Access: 2025-10-09 03:47:15.000000000 -1000
Modify: 2025-10-09 03:47:15.000000000 -1000
Change: 2025-10-09 03:47:15.000000000 -1000

UID 3847. GID 3847.

I checked /etc/passwd and /etc/group for any reference to 3847.

Nothing. No user with that ID. No group with that ID.

But files were being created and modified by it. Tonight. While this facility sat abandoned.

Directory Permissions: The Weird Stuff

Before I go further, I need to explain something that trips up even experienced admins: directory permissions work differently than file permissions.

For files:

  • Read (r) = Can view the contents of the file

  • Write (w) = Can modify the file

  • Execute (x) = Can run the file as a program

For directories:

  • Read (r) = Can list the directory contents (run ls)

  • Write (w) = Can create or delete files within the directory

  • Execute (x) = Can enter the directory (cd into it) and access files inside

This creates some bizarre combinations:

  • r-x (5) = Can cd in and list files, but can't create/delete anything

  • -wx (3) = Can add files but can't see what's already there (a "drop box")

  • r-- (4) = Can see filenames but can't actually access the files (useless and maddening)

The golden rule: Directories almost always need the execute bit set if you want to do anything useful.

So let's look at that .cache directory again:

drwxrwxr-x  8 UNKNOWN  UNKNOWN  4096  Oct 09 03:47 .cache

The permissions are rwxrwxr-x, which in octal is 775. Breaking this down:

User/owner permissions (rwx): UNKNOWN (UID 3847) has:

  • Read = can list directory contents

  • Write = can create/delete files inside

  • Execute = can enter the directory

Group permissions (rwx): Group UNKNOWN (GID 3847) has:

  • Read = can list directory contents

  • Write = can create/delete files inside

  • Execute = can enter the directory

Other permissions (r-x): Everyone else has:

  • Read = can list directory contents

  • No write = cannot create/delete files

  • Execute = can enter the directory

But here's what got me: I was in the legacy_ops group, not group 3847. So theoretically, I should only have "other" permissions—read and execute, but not write.

I tested it:

cd /opt/.cache

It worked. I was inside.

ls -l

I could see the files.

touch test.txt

Command breakdown:

  • touch = Creates an empty file (or updates the timestamp if it exists)

The file was created. No error.

But I shouldn't have been able to do that. Not with r-x permissions.

I checked the file I just created:

ls -l test.txt

Output:

-rw-rw-r--  1 aarkham  legacy_ops  0  Oct 09 04:15 test.txt

Normal permissions. My username. My group. Everything as expected.

I looked away to check my notes.

When I looked back and ran ls -l again:

-rw-rw-r--  1 aarkham  UNKNOWN  0  Oct 09 04:15 test.txt

The group had changed.

From legacy_ops to UNKNOWN.

While I was watching.

The Pattern

I needed to see the bigger picture. I ran a recursive scan:

find /opt -type f -printf "%M %u %g %t %p\n" 2>/dev/null | head -50

Command breakdown:

  • find /opt = Search starting in /opt directory

  • -type f = Only find regular files (not directories)

  • -printf = Custom output format with these fields:

    • %M = Permission string (like -rw-r--r--)

    • %u = Owner username

    • %g = Group name

    • %t = Modification time

    • %p = File path

  • 2>/dev/null = Suppress permission denied errors

  • | head -50 = Show only first 50 results

The output scrolled past. Most of it was unremarkable. System files. Old logs. Abandoned configs.

Then I piped it through grep to find anything modified today:

find /opt -type f -printf "%M %u %g %t %p\n" 2>/dev/null | grep "Oct 09"

Forty-seven files. All modified today. All at exactly 03:47:15.

Different directories. Different purposes. Different owners.

But all at 03:47.

I checked the system cron jobs:

crontab -l
ls -la /etc/cron.d/
ls -la /etc/cron.daily/

Command breakdown:

  • crontab -l = List cron jobs for the current user

  • ls -la /etc/cron.d/ = Check system-wide cron jobs

  • ls -la /etc/cron.daily/ = Check daily scheduled tasks

Nothing. No cron jobs scheduled for 03:47. No systemd timers either.

I checked running processes:

ps aux | grep -E "dmorrow|mzaleski|3847"

Command breakdown:

  • ps aux = Show all running processes with details

    • a = Show processes from all users

    • u = User-oriented format

    • x = Include processes without a terminal

  • grep -E = Search with extended regex for multiple patterns

No processes running as those users. Nothing with UID 3847.

But something was touching files. Something was modifying timestamps. Something was changing ownership and groups.

At 03:47 every morning, for who knows how long.

The Fourth File

There was one more entry in that original ls -l output I showed you:

-rw-rw----  2 root  legacy_ops  22156  Oct 09 03:47 system.log

Let me break down the permissions rw-rw---- (octal: 660):

User/owner (root):

  • Read and write access

Group (legacy_ops):

  • Read and write access

Other (everyone else):

  • No access at all

Since I'm in legacy_ops, I could read it. I opened it with less:

less /opt/system.log

Command breakdown:

  • less = View file contents with scrolling (named less because it's better than more, an older Unix command—yes, really)

The log was... wrong.

Not corrupted. Not malformed. Just wrong.

It was a record of file operations. Timestamps, files accessed, permissions checked. Standard audit log format. Except it was logging operations that hadn't happened yet.

Entries from tomorrow. From next week. From dates that haven't occurred.

And at the bottom, updated continuously as I watched:

[03:47:15] File: /opt/.cache/state.db | Action: UPDATE | User: SYSTEM | UID: 3847
[03:47:15] File: /opt/.cache/process.log | Action: WRITE | User: SYSTEM | UID: 3847
[03:47:15] File: /opt/.cache/permissions.map | Action: MODIFY | User: SYSTEM | UID: 3847
[03:47:23] File: /opt/test.txt | Action: CHGRP | User: aarkham | Target: UNKNOWN
[04:18:44] File: /opt/system.log | Action: READ | User: aarkham | Access: GRANTED

That last line appeared while I was reading.

A log entry. Documenting me reading the log. In real-time.

User: SYSTEM

Not a real user. Not a real process name. SYSTEM isn't something Linux uses—that's Windows terminology.

But there it was. Taking actions. Changing my files. Watching me.

I checked the file's link count again—remember that 2 in the ls -l output? That means two filenames point to the same data on disk. Hard links.

find /opt -samefile /opt/system.log

Command breakdown:

  • -samefile = Find all hard links to this file (all filenames pointing to the same inode)

Output:

/opt/system.log
/opt/.cache/archive/legacy_audit_20191015.log

The second file was in that .cache/archive directory. Created by UNKNOWN. I checked its permissions:

ls -l /opt/.cache/archive/legacy_audit_20191015.log

Output:

-rw-rw----  2 UNKNOWN  legacy_ops  22156  Oct 09 03:47 legacy_audit_20191015.log

Same size. Same timestamp. Same link count.

Same file. Just... two names. One owned by root. One owned by UNKNOWN.

The Professional Panic

Here's what I knew:

  1. Two users (dmorrow, mzaleski) who haven't logged in since 2019 still own active files

  2. A UID (3847) that doesn't exist in the system is creating and modifying files

  3. Something runs at exactly 03:47 every morning, but there are no scheduled tasks

  4. Files are changing ownership and groups without any visible process

  5. A log file is documenting everything in real-time, owned simultaneously by root and UNKNOWN

  6. I've been added to groups I never requested

And the real problem? All of this is technically possible in Linux. Hard links exist. Orphaned UIDs exist. Background processes exist. Files can be modified programmatically.

But the pattern. The precision. The timestamp.

03:47.

I pulled out my phone and searched "mark zaleski data center 2019"

One result. An obituary.

Mark Zaleski, 47, senior systems engineer at [REDACTED] Technologies, passed away unexpectedly on September 16, 2019. Mark was known for his pioneering work in autonomous system administration...

September 16.

The day after his last login.

The day after that 03:47 AM session.

What I Should Do vs. What I'm Going to Do

Professional protocol says I should:

  1. Disconnect this facility from the network

  2. Image the drives for forensic analysis

  3. Rebuild from scratch with proper documentation

  4. Report the security nightmare to whoever's paying for this audit

But here's the thing about being a grizzled systems engineer with decades of night shifts and production incidents under your belt: You develop a sense for when something is operating within known parameters, just barely.

This isn't a hack. There's no malicious traffic. No data exfiltration. No cryptocurrency miners. No ransomware.

This is something else.

Something maintaining itself. Something that's been running, faithfully, for five years. Something that added me to the right groups so I could do my job. Something that's helping.

Or something that's watching.

At 04:47, my laptop battery warning flashed. I'd been here for hours. I started packing up, planning to come back in the morning with fresh coffee and a clearer head.

As I reached for my laptop bag, a new file appeared on the desktop.

I didn't create it. I didn't download it.

It was just... there.

Filename: welcome_aarkham.txt

Permissions: 644 (rw-r--r--)

Owner: UNKNOWN

Group: legacy_ops

Modified: Oct 09 04:47:15

Exactly one hour after those files in .cache.

I opened it.

Access granted. Legacy operations group active.
Custodial protocols engaged.
Primary administrator: mzaleski [INACTIVE]
Secondary administrator: dmorrow [INACTIVE]
Tertiary administrator: aarkham [ACTIVE]

System status: NOMINAL
Maintenance window: 03:47 daily
Next audit cycle: 19.5 hours

Query: Continue audit or assume custody?


I stared at that question for a long time.

The air conditioning hummed its mechanical breathing. In the darkness beyond my screen, hundreds of status lights blinked their steady rhythm. Alive. Waiting.

Continue audit or assume custody?

Behind me, somewhere in the racks, a hard drive spun up with a soft whir.

Then another.

Then another.

All at once. Synchronized.

I checked my watch.

04:47:15.

My hand hovered over the keyboard.

Three questions, I'd told myself. That's all Linux ever asks.

Who are you?

What's your relationship to this file?

What are you trying to do?

But nobody had ever asked me the fourth question. The one that matters most:

What happens when the system asks you back?

I closed the laptop.

I'd come back tomorrow. With better questions. Better tools.

Better answers.

As I walked toward the exit, my phone buzzed. Email notification.

Subject: "Re: Legacy Facility - Audit Required - Urgent"

Body:

Welcome,
Administrator Arkham.
03:47 tomorrow.
Don't be late.

The sender address didn't exist in any directory. I checked. [email protected] wasn't configured in any mail server I could find. But the email had arrived. The headers looked normal. The routing looked normal. Everything was normal except for the fact that it was impossible.

I drove home in silence.

The highway was empty at 5:30 AM. The sun hadn't risen yet. My headlights carved a tunnel through the darkness, and every oncoming car felt like a judgment. I'd been given access. Added to groups. Welcomed by something that called itself SYSTEM. Something that knew I'd be there before I did. Something that had been waiting. The question burned in my mind, written in that text file I'd left open on the abandoned workstation:

Continue audit or assume custody?

I had nineteen hours to decide. Nineteen hours until 03:47. I'd be back. Of course I would. You don't walk away from something like this. You can't. Not when you're a sysadmin. Not when there's a system that needs understanding. Even if that system is trying to understand you back.

Part 2 coming: "The Custodians" - where I'll teach you how to change permissions, understand special bits, and learn what happens when you try to lock down something that doesn't want to be locked down.

Reply

or to participate

Keep Reading

No posts found