Linux wget Command Cheat Sheet: Download, Automate, and Investigate Like a SOC Analyst
It's 2 a.m. and an alert fires on a Linux web server: a process owned by the web service account just ran wget and saved a file into /tmp. Is it an admin pulling a patch, or someone staging a second-stage tool? The only way to tell is to know exactly how wget behaves, what it leaves behind, and what normal use looks like.
wget ships with nearly every Linux distribution, which makes it valuable for administrators, incident responders, and threat intelligence teams. It also makes it a favorite for attackers who rely on tools already present on the host. This guide covers the commands you'll use daily, then shifts to the SOC and DFIR side: evidence handling, hash verification, and detection.
Table of Contents
- Basic Downloads and Custom File Names
- Resuming, Retrying, and Timeouts
- Bulk Downloads and Speed Control
- Authentication Without Leaking Credentials
- Headers, Redirects, and URL Checks
- Recursive Downloads and Mirroring
- TLS, Proxy, and IPv4/IPv6 Options
- wget in SOC and DFIR Workflows
- Detecting Suspicious wget Activity
- Shell Automation and Troubleshooting
- Expert Tips
- FAQ
Basic Downloads and Custom File Names
The simplest form is the one you'll type most often. Prefer HTTPS whenever the source supports it.
wget https://example.com/file.txt
What it does: downloads the file into the current directory. Expected output: a progress bar, resolved IP, HTTP status (200 OK), and the saved filename.
Control the output with these options:
wget -q https://example.com/file.txt # quiet, no normal output
wget -nv https://example.com/file.txt # fewer messages
wget -O newname.txt https://example.com/file.txt # custom filename
wget -O /tmp/archive.zip https://example.com/archive.zip # custom path
wget -O - https://example.com/file.txt # write to standard output
wget -O /dev/null https://example.com/file.txt # discard the body
wget --content-disposition https://example.com/download # use server-provided name
wget --trust-server-names https://example.com/redirect # use final redirected URL's name
One practical caution: --content-disposition and --trust-server-names let the server influence the local filename. On an investigation host, I'd rather force the name with -O so nothing unexpected lands on disk.
Resuming, Retrying, and Timeouts
Large downloads over unreliable links are where wget outperforms a browser. The -c flag continues a partial file instead of starting over.
wget -c https://example.com/largefile.zip
wget -c -O backup.zip https://example.com/largefile.zip
wget -c --tries=10 --waitretry=5 https://example.com/largefile.zip
Resuming depends on the server supporting HTTP range requests, and the partial file on disk must match the requested resource. If the remote file changed, you can end up with a corrupted merge, so verify the hash afterward.
For retry and timeout tuning:
wget -t 5 https://example.com/file.zip # retry up to 5 times
wget -t 0 https://example.com/file.zip # retry indefinitely
wget -T 30 https://example.com/file.zip # network timeout, 30 seconds
wget --dns-timeout=10 --connect-timeout=15 --read-timeout=30 https://example.com/file.zip
wget --retry-connrefused https://example.com/file.zip
wget --tries=5 --timeout=30 --waitretry=5 https://example.com/file.zip
Be careful with -t 0 in scripts. An endless retry loop against a dead host is a classic cause of runaway cron jobs.
Bulk Downloads and Speed Control
Put one URL per line in a file and feed it to wget:
wget -i urls.txt
wget -i urls.txt -nc # skip files that already exist
wget -i urls.txt -c # resume partial files
wget -i urls.txt -P /tmp/downloads # save into a directory
Note that wget -i urls.txt -O combined.txt writes every response into a single file rather than separate files. That's useful for concatenating IOC lists, but surprising if you expected individual downloads.
On shared networks or production servers, throttle your transfers so you don't saturate the link:
wget --limit-rate=200k https://example.com/largefile.zip
wget --wait=2 -i urls.txt
wget --wait=5 --random-wait -i urls.txt
Rate limiting applies to wget's own transfer and doesn't guarantee a fixed bandwidth allocation. Random waits also make your requests politer to the remote server.
Authentication Without Leaking Credentials
This is where many admins make mistakes. Passing a password directly on the command line works, but it can be exposed in shell history and in process listings visible to other users.
wget --user=username --ask-password https://example.com/private.zip
Safer approach: --ask-password prompts interactively. For automation, use a protected .netrc file:
# ~/.netrc
machine example.com
login username
password your_password
chmod 600 ~/.netrc
wget --netrc https://example.com/private.zip
wget --netrc-file=/path/to/custom.netrc https://example.com/private.zip
Never commit .netrc files or credentials to Git repositories. Secret-scanning findings in public repositories remain a common starting point for account compromise, so treat this as a baseline control for any enterprise security program.
Headers, Redirects, and URL Checks
wget can set request headers, send POST data, and inspect responses, which makes it a lightweight troubleshooting tool.
wget --header="Accept: application/json" https://example.com/api
wget --user-agent="Mozilla/5.0" https://example.com/
wget --referer="https://example.com/" https://example.com/file.zip
wget --post-data="user=admin&status=active" https://example.com/api
wget --method=PUT --body-data="status=active" https://example.com/api
wget --content-on-error https://example.com/resource
Support for --method and --body-data depends on your wget version, so check wget --version first. Avoid placing real bearer tokens directly in commands for the same history-exposure reasons described above.
To inspect responses without keeping the content:
wget --spider https://example.com/file.zip
wget --spider -S https://example.com/
wget -S -O /dev/null https://example.com/
wget --max-redirect=0 https://example.com/redirect
When to use it: --spider checks whether a URL responds, -S prints the server's response headers, and --max-redirect=0 stops at the first redirect so you can see where a link actually points. That's handy when triaging a suspicious shortened URL, though always do it from an isolated analysis host rather than your workstation.
Recursive Downloads and Mirroring
Recursive mode follows links. Used carelessly it can hammer a server or pull far more than intended, so set limits.
wget -r -l 2 -np https://example.com/docs/
wget -r -np -A "*.pdf,*.zip" https://example.com/docs/
wget -r -R "*.jpg,*.png" https://example.com/
wget -r -nd -P /tmp/site-download https://example.com/docs/
wget --accept-regex=".*\.pdf$" -r https://example.com/
wget --reject-regex=".*logout.*" -r https://example.com/
wget -r --domains=example.com,cdn.example.com https://example.com/
The -np flag prevents climbing to parent directories, -l sets depth, and -A/-R filter by extension. The --reject-regex example is a practical trick to avoid crawling logout links that would invalidate a session.
For a local browsable copy:
wget -m -k -p https://example.com/
wget -m -N -np https://example.com/docs/
Important: only mirror sites you're authorized to copy. Dynamic applications, authentication, robots rules, and JavaScript-rendered content can also prevent a complete mirror.
On file overwrite behavior, -nc skips files that already exist, while -N compares server timestamps and downloads only when the remote copy is newer. They are not interchangeable.
TLS, Proxy, and IPv4/IPv6 Options
By default wget verifies HTTPS certificates. When verification fails, resist the urge to bypass it.
wget --ca-certificate=/path/to/ca.pem https://example.com/file.zip
wget --secure-protocol=TLSv1_2 https://example.com/file.zip
wget --certificate=/path/to/client-cert.pem --private-key=/path/to/client-key.pem https://example.com/secure-file
The --no-check-certificate option disables verification and exposes the download to man-in-the-middle tampering. If you see it in a production script, flag it in your code review. Fix the underlying trust problem with --ca-certificate instead.
For proxies and IP versions:
wget -e use_proxy=yes -e https_proxy=http://127.0.0.1:8080 https://example.com/file.zip
wget --no-proxy https://example.com/file.zip
wget -4 https://example.com/file.zip
wget -6 https://example.com/file.zip
Switching between -4 and -6 is a fast way to tell whether a failure is an IPv6 connectivity problem, and --no-proxy helps isolate proxy issues.
wget in SOC and DFIR Workflows
Beyond convenience, wget fits evidence handling because it produces logs and predictable output. If you pull an authorized sample or IOC list from a trusted source, record everything about how you got it.
date -Is
wget -o evidence-download.log -O evidence.zip https://trusted.example.com/evidence.zip
sha256sum evidence.zip
stat evidence.zip
file evidence.zip
What each step gives you:
date -Isrecords the acquisition timestamp in ISO 8601 format.-o evidence-download.logpreserves the server interaction and download messages.sha256sumestablishes a hash for later integrity checks.statrecords size, permissions, and timestamps.fileidentifies the actual file type regardless of extension.
A sensible evidence-handling routine: record the source URL and time, keep the logs, hash the file, compare against an independently trusted hash if available, store it in a controlled location, and avoid executing untrusted files. Checksums only help when they come from a different trusted channel. A hash fetched from the same compromised location doesn't independently prove authenticity.
sha256sum -c SHA256SUMS
This verifies downloaded files against a trusted checksum list. Avoid MD5 for security verification.
To pull a throttled evidence download that won't disrupt production traffic:
wget --limit-rate=100k -c -O evidence.zip https://trusted.example.com/evidence.zip
Detecting Suspicious wget Activity
Because wget is legitimate and installed almost everywhere, defenders can't simply block it. MITRE ATT&CK describes this behavior as Ingress Tool Transfer (T1105): adversaries bringing tools onto a compromised system using whatever is available. Detection therefore depends on context, and that's where good endpoint detection and response tooling and SOC automation earn their keep.
Questions worth asking when wget appears in telemetry:
- Who ran it? A web server or database service account running wget is unusual and worth investigating.
- Where did it write? Output to
/tmp,/dev/shm, or hidden directories deserves scrutiny. - What came next? A download followed by
chmod +xand execution is a stronger signal than the download alone. - Where did it connect? Raw IP addresses, newly registered domains, or unusual ports stand out against baseline traffic.
- Quiet flags:
-q,-O -piped into a shell, or-bbackground mode can indicate an attempt to avoid notice, though admins use them legitimately too.
If your Linux hosts run auditd, a simple rule logs every wget execution so you can baseline it:
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/wget -k wget_exec
Add this to your audit rules, reload, and search with ausearch -k wget_exec. Adjust the binary path to match your distribution. Expect noise at first, so build an allowlist of approved admin hosts and package workflows before alerting on it.
Preventive controls that reduce risk without guaranteeing protection: restrict outbound internet access from servers to approved destinations, route egress through a monitored proxy, apply least privilege to service accounts, and keep wget updated. According to NVD, CVE-2024-38428 affected wget through version 1.24.4 in how it handled semicolons in URL userinfo, which could lead to a wrong host being contacted; always confirm affected versions against the current advisory and your distribution's package notes before acting.
Shell Automation and Troubleshooting
Simple loops make wget useful in scheduled jobs:
while read -r url; do
wget -q -c "$url" || echo "Failed: $url"
done < urls.txt
wget -q --spider https://example.com/ && echo "URL reachable"
The second command prints a message if wget's check succeeds. Remember that --spider tests URL behavior only. It is not a full application health check and doesn't prove a file is valid.
When a download fails, work through this sequence:
wget --debug https://example.com/file.zip
wget --server-response https://example.com/file.zip
wget --timeout=30 --tries=3 https://example.com/file.zip
wget --no-proxy https://example.com/file.zip
| Symptom | Typical Meaning |
| 403 Forbidden | Access denied by the server |
| 404 Not Found | Requested resource does not exist |
| 407 | Proxy authentication required |
| 429 | Rate limit may have been reached; slow down with --wait |
| 500 | Server-side error |
| TLS errors | Certificate, protocol, or trust problem |
| Connection refused | Remote host rejected the connection |
| DNS failure | Hostname could not be resolved |
To install wget if it's missing:
sudo apt update && sudo apt install wget # Debian / Ubuntu / Kali
sudo dnf install wget # Fedora / RHEL-based
sudo pacman -S wget # Arch
sudo zypper install wget # openSUSE
Expert Tips
- Always log evidence downloads with
-oand hash the result immediately. - Use
-Oto control filenames rather than trusting server-supplied names. - Prefer
--ask-passwordor achmod 600.netrcover inline passwords. - Run
--spider -Sto inspect suspicious links from an isolated analysis system. - Test
-4and-6separately before blaming the remote server. - Use
-bwith a log file so background downloads remain auditable (the default log iswget-log). - Never pipe downloaded content straight into a shell unless you fully trust and have verified the source.
- Baseline normal wget usage on your servers first, then alert on deviations.
Related Cybersecurity Topics You Should Explore
- Linux ss Command Cheat Sheet: Find Suspicious Connections Fast
- Linux netstat Command Cheat Sheet: Spot Suspicious Connections Fast
- Linux traceroute Command Cheat Sheet: Find Network Hops Fast (2026)
- Linux Ping Command Cheat Sheet (2026): Complete Guide
- Linux ifconfig Cheat Sheet: Commands, MTU, MAC & PROMISC
- Linux ip Command Cheat Sheet: Spot Rogue Routes & ARP Spoofing
- Linux Networking Commands Cheat Sheet: ip, ss, nmap (2026)
- SBI CyRIS Cybersecurity Centre of Excellence: Full Breakdown
- Linux pstree Command Cheat Sheet: Spot Suspicious Processes Fast
FAQ
What is the difference between wget and curl?
Both transfer data over network protocols. wget is built for downloading, including recursion, mirroring, and resuming. curl is more flexible for crafting individual requests and API testing.
How do I resume an interrupted wget download?
Run the same command with -c. The server must support range requests, and the partial file must match the remote resource.
Is --no-check-certificate safe?
No. It disables certificate verification and exposes you to man-in-the-middle attacks. Fix the trust issue with --ca-certificate instead.
How do I check a URL without downloading it?
Use wget --spider -S URL to see the status and headers without saving the response body.
Can wget be used maliciously?
Yes. Attackers can use it to transfer tools onto compromised hosts. Monitor the process owner, output paths, destinations, and follow-on execution rather than blocking the binary outright.
How do I verify a file I downloaded?
Calculate a SHA-256 hash with sha256sum and compare it to a checksum obtained from an independent, trusted source.
Does wget respect bandwidth limits exactly?
--limit-rate approximates the limit for wget's transfer but doesn't guarantee a fixed bandwidth allocation.
Conclusion
wget looks like a simple download tool, but in a SOC it's evidence collector, troubleshooting aid, automation building block, and potential indicator of compromise all at once. Learn its flags well enough to use it safely, then learn its footprint well enough to spot when someone else is using it against you. Build a baseline, log your own acquisitions, and verify what you download. That combination covers most of the real-world risk.
Analysis based on SOC monitoring and public threat intelligence review.
