~$ skillshelf
← OverTheWire Bandit

Bandit 32 → 33: the shell that uppercases you

banditlinuxrestricted-shellsetuid

“After all this git stuff, it’s time for another escape” is the entire level page, and it’s accurate. Log in and there’s no bash — there’s something that takes whatever I type, shifts it to uppercase, and runs that. ls goes out as LS and comes back not found. Every command I know is lowercase, and so is every path I need.

the goal

After all this git stuff, it’s time for another escape. Good luck!

Two commands listed, sh and man. That’s the whole page.

the approach

what’s actually running

One file in home, uppershell:

file uppershell
uppershell: setuid ELF 32-bit LSB executable, dynamically linked,
interpreter /lib/ld-linux.so.2, not stripped

Two things worth reading off that. setuid — it runs with elevated privileges rather than mine, which is how it gets to sit between me and my own keyboard no matter who logs in. And ELF executable — it’s compiled, so there’s no script to open and read. That route was closed before I tried it.

strings uppershell

Plenty of output, and it confirmed the suspicion: the thing spawns a shell and shifts input to uppercase on the way through. Good as confirmation, useless as a lever. I now knew exactly how the trap worked and was no closer to being outside it.

the actual problem

Stated plainly: every character I type arrives uppercased. Not a permissions problem, not a missing binary. The password lives at /etc/bandit_pass/bandit33 and there is no way to type that path.

So the question stops being “what command do I run” and becomes “where is there lowercase text that didn’t come from my keyboard?”

$0

$0 is the name of the current shell. Two characters, neither with a case to shift, so it goes through the filter untouched — and what it expands to is a lowercase string the shell was already holding.

Typing it gave me a working shell. From inside that:

echo $0
sh
echo $0 | cat
sh

Lowercase both times, and the second one is the confirmation: the trap mangles what I type, not what flows through a pipe. $0 was never typed — it’s a lowercase string already in memory, and it survives.

reading the file

With a shell that would accept a command, I put the read through $0 itself, so the command text came from the shell rather than from the keyboard:

$0 -c 'cat /etc/bandit_pass/bandit33'

Password, redacted here as <password>.

the takeaway

A filter only controls the channel it sits on. The uppercaser owns my keystrokes and nothing else. $0 held sh in lowercase before I ever logged in, so reflecting it back hands me a string the filter never touched. When input is being mangled, stop hunting for a command you can type and start looking for values the program is already holding.

Two smaller ones:

file first, every time. One command said setuid, compiled, not a script — which killed “read the source” immediately and told me the binary runs as someone other than me. Same setuid idea as 26 → 27, except here it’s the thing standing in my way rather than the thing helping me.

strings confirms; it doesn’t solve. It explained the mechanism precisely and moved me nowhere. Understanding how a trap works and having a lever against it are different things, and it’s easy to spend a while mistaking the first for the second.


That’s the end of the trail. Level 33 is the last one — the official page for bandit34 says it doesn’t exist yet — so this is where the chapter stops.