This is a loaded nail gun left on the bench, not a sniper rifle that can hit every host by itself
CVE-2014-6271 is the original Shellshock bug: GNU Bash imports function definitions from environment variables and, in vulnerable builds, keeps parsing attacker-controlled text that follows the function body. In plain English, if some exposed service copies untrusted input into an environment variable and then launches Bash, the attacker can turn that hop into command execution. The vulnerable range is Bash through 4.3, but the first fix was incomplete, so truly safe builds are the vendor backports or later patch levels that also address CVE-2014-7169 and the follow-on parser issues.
The vendor's 9.8/CRITICAL score is technically fair for the exposed subset, but it overstates enterprise-wide reachability. Bash is not a network service. The exploit chain usually needs a second product or feature in front of it: CGI on Apache, forced-command SSH workflows, DHCP hooks, embedded web admin panels, or another component that bridges attacker input into Bash. That dependency is the main friction. Still, KEV status, trivial exploitation, and a long tail of forgotten appliances keep this firmly out of the backlog.
4 steps from start to impact.
Find a Bash-backed trust boundary
mod_cgi/mod_cgid, embedded web interfaces, SSH ForceCommand, and some DHCP client hooks. Tools like Nmap http-shellshock NSE or simple header fuzzing with curl are enough to validate candidate targets.- A vulnerable Bash build is installed
- A reachable service passes attacker-controlled data into environment variables
- The service is exposed remotely or reachable from the attacker's position
- Most enterprise Linux hosts have Bash installed but do not expose a CGI or equivalent Bash bridge
- Modern reverse proxies, WAFs, and app stacks often terminate requests before legacy CGI is involved
- Many vulnerable systems left today are niche appliances rather than general server fleets
Send a crafted environment payload
- Input reaches a header, variable, or field that the target component exports to the process environment
- No upstream filter normalizes or blocks the payload
- Many modern stacks no longer use classic CGI at all
- Simple signature-based filtering often catches stock payloads, though it will not stop all variants
- Some internet-facing products use
dashor another shell instead of Bash
() { :;}; patterns; evasive variants and non-HTTP paths reduce signature reliability.Bash parses past the function and executes attacker code
- The installed Bash build is still vulnerable to the original bug or only partially patched
- The invoked program actually launches Bash during request handling
- A lot of Linux fleet patching years ago removed this from mainstream server images
- The original 6271-only patch was incomplete, so version-string checks can be misleading without behavioral testing
httpd, apache2, lighttpd, sshd, or CGI wrappers; package scanners alone may misclassify backported builds.Pivot from service user to business impact
- The compromised service account has useful local privileges, secrets, or network reach
- Outbound access or lateral paths exist
- Least-privilege service accounts, network segmentation, and egress controls contain the blast radius
- EDR, NGFW, and anomaly detection often catch the second-stage tooling even if the initial exploit lands
curl/wget, unusual child processes, and lateral movement telemetry.The supporting signals.
| In-the-wild status | Yes. Exploitation was observed within hours of disclosure, with Cisco Talos, CERT, and others documenting active attacks and botnet activity. |
|---|---|
| KEV status | CISA KEV listed; known exploited date shown by CISA is 2022-01-28 on the catalog entry. |
| Proof-of-concept availability | Abundant and low-skill. Public exploit paths include Nmap http-shellshock, Metasploit Shellshock modules, and trivial curl header payloads. |
| EPSS | 0.9422 (user-supplied), which is extremely high and consistent with long-lived opportunistic exploitation; percentile was not independently verified here. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — accurate for an exposed vulnerable path, but it assumes the attacker can actually reach a Bash-import boundary. |
| Affected versions | GNU Bash through 4.3; the initial fix for CVE-2014-6271 was incomplete, so environments patched only to that first state remained exposed via CVE-2014-7169. |
| Fixed versions | Do not trust a generic bash 4.x check. Use vendor-backported packages or patch levels that include both 6271 and 7169 fixes; examples include Ubuntu 4.3-7ubuntu1.1 for 14.04 and Debian 4.2+dfsg-0.1+deb7u1 for wheezy. |
| Exposure reality | The exposed population is narrower than the CVSS implies because Bash itself is not remotely reachable. Real exposure is concentrated in legacy CGI, embedded admin panels, forced-command SSH workflows, and neglected appliances. |
| Scanning and noise | This remains classic internet background radiation: defenders can still find scanners, tooling, and tag support for Shellshock-style activity in products like GreyNoise, while Nmap maintains a dedicated detection script. |
| Discovery and disclosure | Disclosed 2014-09-24; widely attributed to Stéphane Chazelas. |
noisgate verdict.
The decisive factor is reachability friction: Bash is everywhere, but remotely exploitable Bash paths are not. KEV listing and mass exploitation evidence keep this high, yet the requirement for a second exposed component between the internet and Bash stops it from being enterprise-wide critical on every host with /bin/bash.
Why this verdict
- Downgrade for reachability: the attacker position is often *unauthenticated remote*, but only if a separate service like CGI, SSH forced-command, or appliance glue code passes input into Bash. That sharply reduces the fraction of real enterprise hosts that are actually one packet away from RCE.
- Not every Bash install is exposed: a workstation, internal server, or container image with Bash installed is not the same thing as an internet-exploitable target. The vendor CVSS treats the reachable case, while defenders need to prioritize the exposed subset.
- KEV and real-world exploitation push it back up: the exploit is trivial, public, and historically wormable, with active exploitation evidence and CISA KEV status. That means any externally reachable legacy path is still an easy win for attackers.
- Blast radius is workload-dependent: successful exploitation usually lands as the calling service account first. High impact is common, but full environment compromise is not automatic and depends on local privilege, secrets, and lateral movement opportunities.
Why not higher?
This is not higher because the vulnerable component is usually indirect. The attack chain commonly requires legacy CGI or another trust-boundary bridge, and many modern enterprise stacks never expose that bridge externally. A CVSS 9.8 makes sense for the subset that is reachable, but not for every Linux asset with Bash installed.
Why not lower?
This is not lower because the exploit is cheap, famous, KEV-listed, and still useful against neglected internet-facing assets. One forgotten appliance, old CGI app, or embedded admin page can turn this into immediate command execution with very little attacker effort.
What to do — in priority order.
- Block exposed CGI and legacy admin paths — Put reverse-proxy, WAF, ACL, or firewall controls in front of known
cgi-binpaths and embedded web interfaces immediately, within hours because this CVE is KEV-listed. This directly removes the most common remote trust boundary into Bash while patching catches up. - Hunt for Bash as a child of network services — Use EDR or audit telemetry to alert on
bash,sh,curl,wget,perl, orpythonspawned byhttpd,apache2,nginxhelpers,lighttpd,sshd, or appliance web daemons. Deploy within hours for exposed systems, then keep it in place through the HIGH remediation window. - Segment and restrict egress from internet-facing Linux and appliances — Limit outbound package fetches and lateral movement from web tiers and network appliances so a successful Shellshock hit cannot immediately pull second-stage payloads or pivot. Apply to exposed assets within hours because active exploitation evidence overrides the normal mitigation timetable.
- Inventory Bash behind services, not just packages — Prioritize systems where Bash is actually invoked by web, SSH, DHCP, or management workflows; package presence alone will drown you in false urgency. Build that inventory in the first pass and complete it well inside the HIGH remediation window.
- Blindly patching only assets with a
bashpackage match without checking exposure; that treats every Linux box like an internet-facing CGI server and wastes your queue. - Relying on WAF signatures alone; stock
() { :;};payloads are easy to catch, but alternate delivery paths and non-HTTP vectors bypass that assumption. - Trusting simple version-string checks; distro backports and the incomplete initial 6271 fix make behavioral verification more reliable than naive
bash --versionparsing.
Crowdsourced verification payload.
Run this on the target host itself as a local check. Invoke it with bash ./check-shellshock.sh; no root is required, but you need permission to execute the local bash binary. The script performs behavioral tests for the original Shellshock parser bug and the immediate incomplete-fix follow-up, then prints VULNERABLE, PATCHED, or UNKNOWN.
#!/usr/bin/env bash
# check-shellshock.sh
# Behavioral verifier for CVE-2014-6271 and the immediate incomplete-fix follow-up (CVE-2014-7169).
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN
set -u
if ! command -v bash >/dev/null 2>&1; then
echo "UNKNOWN: bash not found"
exit 2
fi
TMPDIR_LOCAL="${TMPDIR:-/tmp}"
probe_file="${TMPDIR_LOCAL%/}/shellshock_test_$$"
rm -f "$probe_file"
# Test for CVE-2014-6271: vulnerable systems print the injected marker before 'safe'.
out1="$({ env 'x=() { :;}; echo VULN6271' bash -c 'echo safe'; } 2>&1)"
# Test for the incomplete initial fix / CVE-2014-7169 behavior.
out2="$({ env 'x=() { (a)=>\\' bash -c 'echo date' ; } 2>&1)"
file_created=0
if [ -e echo ]; then
file_created=1
rm -f echo
fi
vuln=0
unknown=0
if printf '%s\n' "$out1" | grep -q '^VULN6271$'; then
vuln=1
fi
if [ "$file_created" -eq 1 ]; then
vuln=1
fi
# Sanity guard: if bash invocation failed unexpectedly, mark unknown unless already vulnerable.
if ! printf '%s\n' "$out1" | grep -q 'safe'; then
unknown=1
fi
if [ "$vuln" -eq 1 ]; then
echo "VULNERABLE"
exit 1
fi
if [ "$unknown" -eq 1 ]; then
echo "UNKNOWN"
exit 2
fi
echo "PATCHED"
exit 0
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.