Bypassing Shell Restrictions

by Malvineous

I recently obtained a device that you could login to via SSH, but once connected you were left in an extremely locked down shell.

The purpose of this article is not to explain how to get around the restrictions on this particular device, but to hopefully show some of the thinking involved in working around the limitations that were imposed.

When connecting to the device, it is quickly apparent that it is running a fairly ordinary shell, but many of the commands have been disabled:

Dell Remote Access Controller 5 (DRAC 5)
Firmware Version 1.40 (Build 08.08.22)
$ echo
echo: not found
$ cat
cat: not found
$ ls
ls: not found
$ blah
-sh: blah: not found
$ sh
$

The eagle-eyed will have noticed that valid (but disabled) commands like echo produce a different error message to truly invalid commands like blah.  This gives us a hint that the commands are not locked down by normal means; there's probably some custom code in the shell that blocks certain commands early on (so maybe we can find a weakness in this).

The last command also reveals that we can reinvoke the shell, but does that tell us anything useful?

$ sh --help
BusyBox v1.00 (2008.08.22-17:37+0000) multi-call binary
No help available.

Aha!  The shell is BusyBox.

But without any core commands, you might think it is impossible to do anything useful.  However, there is a surprise:

$ /bin/ec*
echo: not found

The shell still performs wildcard expansion!  How could this be used?

$ /bin/*
[: missing ]

At first confusing, this reveals that the * is being expanded to a list of filenames in the /bin directory, with the first one being the [ command.  This is then executed, resulting in an error message.

We have now discovered one filename on this locked down system.  But if wildcard expansion is still enabled, what else is?

$ $PATH
-sh: .:/bin:/usr/bin: not found
$ $USER
-sh: racuser: not found
$ $PWD
-sh: /var/home/racuser: Permission denied

Environment variables!

Using $PWD, we at least know where on the system we are, even though the cd command doesn't work, so we can't move around.  Because there is no echo command, we can't display anything, but here we are trying to execute the contents of the variable instead.

Since the contents are not a valid command, we get an error - but the shell is kind enough to tell us what the offending command was, giving us a rudimentary equivalent to the disabled echo command.

Can we do anything useful with this?  Let's try changing the prompt:

$ PS1=/*
$ PS1=/* sh
/* echo
echo: not found
/*

It seems we can't just change variables in-place, but we can execute commands with changed variables.

Here we reinvoke the shell with a modified environment, which causes the prompt to change.

Unfortunately, just not in the expected way!  It seems wildcard expansion doesn't work with environment variables.

However, reinvoking the shell in a modified way has given me an idea...

$ sh < /etc/passwd
sh: root::0:0:root:/root:/bin/sh: not found
sh: daemon:x:1:1:daemon:/usr/sbin:/bin/sh: not found
sh: bin:x:2:2:bin:/bin:/bin/sh: not found
sh: sys:x:3:3:sys:/dev:/bin/sh: not found
sh: sync:x:4:100:sync:/bin:/bin/sync: not found
sh: mail:x:8:8:mail:/var/spool/mail:/bin/sh: not found
...

Aha!

When a file is redirected like this, the contents of the file are passed to the shell as if it had all been typed in on the command line by the user.  Since each line is obviously an invalid command, our rudimentary echo command comes to the rescue and we can see the file contents.

We now have a method to display the contents of files, just like the disabled cat command!

$ sh < /etc/shadow
-sh: cannot open /etc/shadow: Permission denied

Well, perhaps not every file.

But this requires that we know the filenames already.  What if we don't?

Trying out some more commands reveals that those related to flow control are still enabled (if/then/else, etc.).

This means a for loop can be used to do something with a list of words, like you might get out of a wildcard expansion...

$ for i in /*; do $i; done
-sh: /bin: Permission denied
-sh: /dev: Permission denied
-sh: /etc: Permission denied
...

What this does is make use of the for loop to run a command against every file in the list.

We are using our rudimentary echo command again (attempting to run something) to see each name in the list.  Thanks to this, we now have a way of listing files on the system without the ls command.

Unfortunately, after much experimentation, that's as far as I got!

I was able to copy files off the device via its serial port (by redirecting a file into a communication command, like viewing /etc/passwd above), but in the end I found it much easier to download the device's firmware and extract the filesystem images.

Browsing through these revealed some hidden commands which removed the restrictions.

But I hope this article provokes some thought about how you can use things in unusual ways to get around whatever nonsensical restrictions might be imposed upon you!

Big raspberry to (((Dell))) for using GPL code in the device's firmware, but making sure the source code released cannot be compiled.

Return to $2600 Index