Bandit 26 → 27: a setuid binary that runs as someone else
This is the payoff for the shell you fought for in 25 → 26. Sitting in bandit26’s
home is a single binary, bandit27-do, and its whole purpose is to run a command
as bandit27. The level is one command once you see what it’s for — and one
confusing dead end if you misread how it takes its argument.
the goal
Good job getting a shell! Now hurry and grab the password for bandit27!
The official page lists exactly one command you might need: ls. That’s the hint —
the tool you need is already in the directory, not in your head.
the approach
Start with ls -la, and read the permissions on the binary carefully:
ls -la
# -rwsr-x--- 1 bandit27 bandit26 14880 Jun 24 14:59 bandit27-do
Two things in that line are the whole level. The owner is bandit27, not you —
and where you’d expect an x in the owner’s execute slot there’s an s.
That’s the setuid bit: run this binary and it executes with the owner’s
privileges, not the caller’s. So bandit26 running bandit27-do gets bandit27’s
identity for the length of that command.
Run it bare to see how it wants to be called:
./bandit27-do
# Run a command as another user.
# Example: ./bandit27-do id
And confirm it actually elevates before trusting it:
./bandit27-do id
# uid=11026(bandit26) gid=11026(bandit26) euid=11027(bandit27) ...
That euid=11027(bandit27) is the proof — the command I passed ran with
bandit27’s effective identity.
The dead end worth flagging: “run a command as another user” reads as name the user, so the obvious thing is to pass one.
./bandit27-do bandit27
# env: 'bandit27': Permission denied
./bandit27-do 11027
# env: '11027': Permission denied
The env: '...': Permission denied is misleading — it’s not a privileges
problem. bandit27-do doesn’t take a user; the user is baked in. The argument
is the command to run, so ./bandit27-do bandit27 tried to execute a program
called bandit27, which doesn’t exist. The error really means “no such command.”
With that straightened out the fix is short — the id in the example is just a
placeholder command. Swap it for the command that reads bandit27’s password file —
the file only bandit27 can open:
./bandit27-do cat /etc/bandit_pass/bandit27
The password prints straight out (redacted here). Save it, then ssh in as
bandit27.
the takeaway
A setuid binary runs as its owner, not its caller. That s bit is a
permission boundary you’re allowed to cross: when a program you can execute is
owned by a user who can read something you can’t, the program is your read
primitive. This is the shape of a whole class of privilege escalations, not just
a Bandit gimmick — find a setuid binary, work out what command it’ll run for
you, and point it at what you’re locked out of.
And the smaller brick: read the tool’s own usage precisely. “Run a command as
another user” is easy to hear as “name the user.” The who is fixed; the what
is yours to choose. Passing the username looks reasonable and fails with an
env: ... Permission denied that has nothing to do with permissions.