~$ skillshelf
← OverTheWire Bandit

Bandit 26 → 27: a setuid binary that runs as someone else

banditlinuxsetuidprivilege-escalation

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.