The Linux ln Command Explained: How Hackers Abuse Symlinks (And How SOC Teams Catch Them)
In late 2022, a mid-sized fintech company in Texas noticed something strange during a routine log review. A cron job that had been quietly backing up configuration files for years suddenly started dumping the contents of /etc/shadow into a world-readable directory. No malware signature triggered. No antivirus alert fired. The root cause, once the incident response team dug in, was almost embarrassingly simple: an attacker had replaced a harmless file with a symbolic link pointing to a sensitive system file, and the backup script — running as root — followed that link without question.
This is the story of the humble ln command. Most Linux tutorials treat it as a beginner-level file management tool. In the real world of SOC operations and penetration testing, ln sits at the intersection of legitimate system administration and one of the sneakiest privilege escalation techniques around: symlink attacks. If you work in security, understand this command properly, or attackers will understand it better than you do.
Table of Contents
- What Is the ln Command, Really?
- Hard Links vs Symbolic Links: The Security-Relevant Difference
- Complete ln Command Reference (With Real Use Cases)
- Real-World Attack Scenario: Symlink Race Conditions
- Key Indicators and Log Artifacts to Watch For
- Detection Techniques for Blue Teams
- Prevention Strategies for SOC and SysAdmin Teams
- Expert Tips From the Field
- Related Articles Worth Reading
- FAQ: Common Questions About ln and Symlink Security
- Conclusion
What Is the ln Command, Really?
On the surface, ln is nothing more than a way to create links between files on a Linux or Unix system. Instead of duplicating data, a link lets multiple filenames point to the same underlying content, or lets a shortcut point to another file's location entirely. Developers use it to manage shared libraries. SysAdmins use it to organize configuration files. Docker images use it internally for versioning binaries like /usr/bin/python3.
But every tool that touches the filesystem is also a tool an attacker can weaponize. Symbolic links, in particular, are involved in a well-documented class of vulnerabilities called symlink attacks (also known as symlink race conditions or TOCTOU — Time-of-Check to Time-of-Use — bugs). These have shown up in CVEs against everything from antivirus engines to backup utilities to container runtimes, because privileged processes that write to predictable file paths without checking whether those paths are actually links are a goldmine for local privilege escalation.
Hard Links vs Symbolic Links: The Security-Relevant Difference
This distinction matters more than most tutorials let on, because it changes your entire threat model.
A hard link is a second directory entry pointing to the exact same inode as the original file. There is no "original" and "copy" — they are indistinguishable, share the same permissions, and the underlying data isn't deleted until every hard link to it is removed. Hard links cannot cross filesystem boundaries and cannot point to directories, which limits their abuse potential somewhat, but they are still used in exploits that rely on file persistence tricks (for example, preserving access to a file even after the "original" is deleted, which can confuse forensic timeline analysis).
A symbolic link (symlink) is a separate, tiny file that simply contains a path pointing somewhere else. The kernel resolves that path at access time. This is exactly what makes symlinks dangerous in privileged contexts: a process with root permissions that writes to /tmp/app.log without verifying it's a real file — rather than a symlink an attacker planted pointing to /etc/passwd or /etc/cron.d/ — can be tricked into overwriting or leaking data it was never supposed to touch.
Complete ln Command Reference (With Real Use Cases)
Below is a practitioner's breakdown of every major ln variation, what it does, when you'd realistically use it, and what output to expect.
Create a Hard Link
ln file link
What it does: Creates a second filename ("link") pointing to the same inode as "file." When to use it: Useful for deduplication or preserving file access even if the original name gets deleted or renamed. Expected output: No output on success; running ls -li afterward shows both filenames sharing an identical inode number.
Create a Symbolic Link
ln -s file link
What it does: Creates a soft link — a pointer file — referencing "file." When to use it: Common in software deployment, versioning binaries, and organizing shared configs. Expected output: A new file appears; ls -l shows it with an arrow notation pointing to the target.
Create a Shortcut in the Home Directory
ln -s /path/file ~/shortcut
What it does: Places a symlink shortcut inside the user's home folder pointing to a file elsewhere on the system. When to use it: Handy for quick access to deeply nested project files or shared resources. Expected output: A shortcut file visible in the home directory listing.
Force Update a Symbolic Link
ln -sf newfile link
What it does: Overwrites an existing symlink, repointing it to a new target without manual deletion first. When to use it: Common in deployment scripts that swap "current release" symlinks during blue-green deployments. Security note: This is exactly the flag pattern attackers abuse in automated scripts — if an attacker can control "link," a forced overwrite can redirect trusted automation toward malicious files.
Show Symbolic Link Target
ls -l
What it does: Lists directory contents, showing symlinks with their target using "-> " notation. When to use it: The very first command any investigator should run when auditing a suspicious directory. Expected output: Lines like lrwxrwxrwx 1 user user 8 Jul 30 shortcut -> /etc/passwd — an immediate red flag if seen in an unexpected location.
Display Symlink Target
readlink link
What it does: Prints exactly where a symlink points. When to use it: Scripting-friendly alternative to parsing ls -l output during automated audits. Expected output: A single path string.
Create a Symbolic Link to a Directory
ln -s /path/directory mydirlink
What it does: Points a symlink at an entire directory rather than a single file. When to use it: Useful for organizing large data volumes or mount points. Security note: Directory symlinks are frequently abused in web server misconfigurations, allowing directory traversal outside the intended web root if FollowSymLinks is enabled without restriction.
Create a Hard Link Using an Absolute Path
ln /home/user/file.txt hardlink.txt
What it does: Creates a hard link using a fully qualified path rather than a relative one. When to use it: Best practice in scripts to avoid ambiguity about the working directory.
Create a Symbolic Link Using an Absolute Path
ln -s /home/user/file.txt softlink.txt
What it does: Same as above, but for a symlink. When to use it: Recommended in production environments where relative paths could break if a script's working directory changes.
Create a Symbolic Link Using a Relative Path
ln -s ../file.txt link.txt
What it does: Creates a symlink relative to the current directory. Security note: Relative symlinks are commonly used in "dotfile" repositories and dev environments, but they're also a favorite in malware persistence chains because they can be portable across compromised hosts with similar directory structures.
Create a Symbolic Link With Verbose Output
ln -sv file.txt link.txt
What it does: Same as a normal symlink creation but prints confirmation of the action. When to use it: Preferred in provisioning scripts and Ansible playbooks where visibility into every filesystem change matters for auditability.
Create a Backup Before Replacing
ln -sfb newfile link
What it does: Forces a symlink replacement but keeps a backup of the previous link (usually with a tilde suffix). When to use it: Safer alternative to -f alone in production systems, since it preserves forensic evidence of what a symlink pointed to before it changed — genuinely valuable during incident response.
Prevent Overwriting an Existing Link
ln -sn file.txt link
What it does: Treats an existing symlink as a normal file for overwrite purposes rather than silently following it, avoiding accidental redirection. Security relevance: This flag exists specifically because of the symlink-following problem described earlier in this article — it's one of the few built-in defenses against symlink confusion baked into the command itself.
Show Inode Numbers of Links
ls -li
What it does: Lists files along with their inode numbers. When to use it: The definitive way to confirm whether two filenames are truly hard-linked (same inode) versus just similarly named.
Compare Hard Links
stat file link
What it does: Displays detailed metadata for both files side by side, confirming shared inode, link count, and timestamps. When to use it: Standard step in forensic file analysis when investigating potential file tampering.
Display Detailed Link Information
stat link
What it does: Shows full metadata — permissions, owner, timestamps, inode, and link count — for a single file or symlink. Expected output: A structured block revealing whether "link" is a regular file, symlink, or hard-linked entry.
Find All Symbolic Links
find /path -type l
What it does: Recursively searches a directory tree for every symbolic link. When to use it: One of the most important commands in this entire list for security auditing — this is how you sweep a compromised or suspicious server for planted symlinks pointing to sensitive files.
Delete a Symbolic Link
rm link
What it does: Removes the symlink pointer itself, leaving the target file completely untouched. Common mistake: Junior admins sometimes panic and try to rm -rf what they think is a directory, not realizing it's a symlink to something they didn't intend to delete — always check with ls -l first.
Delete a Hard Link
rm hardlink.txt
What it does: Removes one filename reference; the underlying data survives as long as at least one other hard link (or open file handle) still references it. Forensic note: This is why deleted files can sometimes still be recovered from a live system's memory or via other hard links, even after "rm" appears to succeed.
Verify the Symbolic Link
readlink -f link
What it does: Resolves a symlink all the way down to its final, absolute target — following chains of nested symlinks if necessary. When to use it: Critical during incident response when attackers stack multiple symlinks to obscure where a file chain actually leads.
Real-World Attack Scenario: Symlink Race Conditions
Symlink attacks typically follow a predictable pattern, and understanding this pattern is what separates a SOC analyst who can explain a root-cause finding from one who just closes the ticket.
Picture a scheduled maintenance script running as root that writes temporary output to a fixed, predictable filename like /tmp/status.log. A local attacker with low-privilege shell access — perhaps from a compromised web application account — watches for that script's execution window. Just before the script writes to the file, the attacker deletes any existing file at that path and replaces it with a symlink pointing to /etc/passwd or a cron directory. If the script doesn't validate the file type before writing, the root process ends up overwriting or corrupting a sensitive system file, effectively handing the attacker a path to privilege escalation or persistence.
This exact class of bug has appeared repeatedly in real CVEs — from container runtimes mishandling mount paths to backup and logging utilities that trusted world-writable temp directories. It's a textbook example of a Time-of-Check-to-Time-of-Use (TOCTOU) vulnerability, and it's why security-conscious code never assumes a file path is safe just because it "should" be a regular file.
Key Indicators and Log Artifacts to Watch For
- Unexpected symlinks appearing in
/tmp,/var/tmp, or shared world-writable directories - Symlinks pointing to sensitive files such as
/etc/shadow,/etc/passwd, SSH authorized_keys files, or cron directories - Audit logs (via
auditd) showing repeatedsymlink()orunlink()syscalls from a low-privilege user account in a short time window - File integrity monitoring alerts flagging a regular file that has been replaced by a symlink
- Cron or scheduled task logs showing permission errors or unexpected file modification timestamps on system files right after a maintenance job ran
Detection Techniques for Blue Teams
Effective detection here isn't about a single magic alert — it's a layered approach:
- Audit rules: Configure
auditdto logsymlinkandunlinksyscalls in sensitive directories like/etc,/tmp, and application data folders. - File integrity monitoring (FIM): Tools like Tripwire, AIDE, or OSSEC/Wazuh should flag any regular file that suddenly becomes a symlink, or any symlink pointing outside its expected directory tree.
- Scheduled sweeps: Run
find / -type l -newer /var/log/lastcheckstyle jobs to catch newly created symlinks since the last audit baseline. - Behavioral correlation: Pair symlink creation events with the process that later accessed that path — a root-owned cron job writing to a path that was recently converted to a symlink by a non-root user is a near-certain indicator of attempted privilege escalation.
Prevention Strategies for SOC and SysAdmin Teams
- Avoid writing privileged process output to predictable, world-writable paths — use randomly generated temp filenames or dedicated, restricted directories instead.
- Use
O_NOFOLLOWin application code (or its equivalent) so file operations fail if the target turns out to be a symlink. - Set the sticky bit on shared temp directories (
/tmpshould already have this by default) to prevent users from deleting files they don't own. - Prefer
ln -snin your own automation scripts to avoid accidentally following an existing symlink during updates. - Disable
FollowSymLinksin web server configurations unless explicitly required, and scope it narrowly withSymLinksIfOwnerMatchwhere possible. - Bake symlink sweeps into routine hardening checks, not just incident response playbooks — catching a planted symlink during a weekly audit is far cheaper than catching it after a breach.
Expert Tips From the Field
- When investigating a suspicious directory, always run
ls -libefore touching anything — inode numbers tell you the real story that filenames can hide. - Don't trust
rm -rfblindly on a path you haven't verified withstatfirst; deleting through a symlink to a directory can have very different consequences than deleting the directory itself. - During incident response, always chain
readlink -fon suspicious links — attackers sometimes nest three or four symlinks deep specifically to slow down manual investigation. - If you manage CI/CD pipelines, audit every
ln -sfcall in your deployment scripts — a compromised build agent that can control the "link" argument is a classic path to supply-chain style tampering.
Related Cybersecurity Topics You Should Explore
- NVIDIA BlueField Flaw Lets Hackers Hijack Cloud Servers
- NGINX Buffer Overflow (CVE-2026-42533): Patch Before It's Exploited
- Windows 11 Finally Fixes Its Slowest File Deletion Problem
- Microsoft Just Killed the Fake KMS Server Trick for Good
- GitLab RCE Bug: How a Simple Notebook Diff Gave Attackers Root
- PentesterFlow: The AI Tool That Hacks Like a Human
- Bash History Forensics: A SOC Analyst's Real Breach Story
- Bing Images Bug Let Hackers Run Code as SYSTEM — Here's How
- Dolphin X Malware: New AI Stealer Hits 300+ Apps
- Google Now Unlocks Accounts With a Selfie — Here's the Catch
- Notepad++ Under Attack: Fake Plugin Hides Malware
- RefluXFS: The Silent Linux Bug Giving Hackers Root Access
FAQ: Common Questions About ln and Symlink Security
Q1: Is the ln command itself dangerous?
No — ln is a completely standard, safe utility. The risk comes from how privileged processes and scripts handle the links it creates, not from the command itself.
Q2: Can hard links cross filesystems?
No. Hard links must reside on the same filesystem as their target because they reference an inode directly, which is filesystem-specific.
Q3: Why do attackers prefer symlinks over hard links for exploitation?
Symlinks can point anywhere, including across filesystems and to directories, and they're resolved at access time — giving attackers a flexible way to redirect a trusted process toward a target of their choosing.
Q4: How do I quickly audit a server for suspicious symlinks?
Run find / -type l combined with filters for world-writable directories, and compare results against your baseline file integrity monitoring data.
Q5: Does deleting a symlink delete the original file?
No. rm link only removes the pointer file; the target it referenced remains completely untouched.
Q6: What's the difference between readlink and readlink -f?
readlink shows the immediate target of a symlink, while readlink -f resolves the entire chain down to the final absolute path, even through nested symlinks.
Q7: Are symlink attacks still relevant in modern, containerized environments?
Yes — container runtimes, volume mounts, and orchestration tooling have all had documented symlink-related CVEs, since the underlying filesystem behavior hasn't fundamentally changed.
Conclusion
The ln command looks unremarkable in a beginner's cheat sheet, but for anyone working in a SOC, incident response team, or penetration testing role, it represents a genuine intersection of everyday system administration and a well-documented attack surface. Understanding hard links versus symbolic links, knowing exactly how to audit and verify them, and recognizing the signs of a symlink race condition isn't academic trivia — it's the kind of practical knowledge that turns a routine log anomaly into a properly diagnosed root cause instead of an unresolved mystery. Master this command the way an attacker would, and you'll be far better equipped to defend against the way they actually use it.








