~$ skillshelf
← OverTheWire Bandit

Bandit 19 → 20: a command is not a menu

banditlinuxsetuidpermissions

The level hands you a setuid binary and tells you to work out how to use it. Understanding what setuid does is the easy half. The content of this level is in the other half: an assumption about what the program will accept.

the goal

To gain access to the next level, you should use the setuid binary in the homedirectory. Execute it without arguments to find out how to use it. The password for this level can be found in the usual place (/etc/bandit_pass), after you have used the setuid binary.

the approach

ls -la first, because the permission bits are the whole story here:

-rwsr-x---   1 bandit20 bandit19 14880 Jun 24 14:58 bandit20-do

Two things in that line. The s where the owner’s x should be — that’s the setuid bit. And the owner: bandit20. A setuid program runs with the identity of whoever owns the file rather than whoever launched it, so this one runs as bandit20 no matter that I’m bandit19. file confirms it in words:

bandit20-do: setuid ELF 32-bit LSB executable, Intel i386 ...

The 32-bit/i386 part is just ELF description and doesn’t lead anywhere. The useful word is setuid.

Running it bare, as the level instructs:

Run a command as another user.
  Example: ./bandit20-do whoami

Handing it the user you want to be doesn’t work:

./bandit20-do bandit20
env: 'bandit20': Permission denied

Wrong shape. It takes a command, not a username — so it dutifully went looking for a program called bandit20 to execute. Which one user it becomes isn’t mine to choose; that was decided by the owner column back in ls -l. The example from the usage line does work:

./bandit20-do whoami
bandit20

So the mechanism is proven. Meanwhile the direct route is closed, exactly as it should be:

cat bandit20
cat: bandit20: Permission denied

Both halves of the answer are now on screen, and the thing standing between them is reading that usage line as a menu — as though bandit20-do supported whoami and some short list of blessed commands, and the job were to find the entry that prints a file. It isn’t a menu. “Command” means any program with its arguments, exactly as you’d type it at a prompt; whoami is just the shortest possible demonstration.

The binary is a wrapper. You put the thing you already wanted inside it:

./bandit20-do cat /etc/bandit_pass/bandit20

The password comes straight back, redacted here.

the takeaway

Setuid attaches privilege to a program instead of to a person. The process carries two identities: the real UID (who launched it — still me) and the effective UID used for permission checks (the file’s owner). That’s how passwd lets you edit a root-only file, and how ping opens a raw socket without you being root. It’s a hole someone deliberately drilled through the permission system, which is why the interesting question about any setuid binary is always how much do I get to decide about what it does. This one lets you decide everything, which makes it less a tool than a door.

Permission denied answers “who is asking”, not “does this exist”. Same file, same cat, two different answers depending on the identity behind the process. When you hit it, the useful next question is about the caller, not the file.

Check what a program will actually accept before assuming it’s a fixed set. Nothing to do with setuid, and the most reusable of the three. A single example invocation turns into a whitelist in your head very easily. An example demonstrates the shape; it doesn’t enumerate the options.