SANS Penetration Testing

Using Built-Ins to Explore a REALLY Restricted Shell

By Ed Skoudis and Josh Wright

Josh Wright and I were working on a project recently which involved a target machine with a really restricted shell environment. I'm not talking about a mere rbash with some limits on the executables we could access, but instead a shell so restricted we could not run any binaries at all, save for the shell itself. No ls... no cat... no netcat... we could access very little. It was some sort of ghastly chroot specter.

Still, Josh and I wanted to explore the target machine as much as we could given these shell restrictions. Of course we could have tried escaping our restricted shell (as Doug Stilwell describes in more detail here) and even doing privilege escalation, but before that, we wanted to just look around. Thankfully, we had many shell built-in capabilities we could rely on.

For the uninitiated, shell built-ins are features of the shell that don't rely on separate binaries in the system. For example, in bash, commands such as alias, printf, and echo are built-ins, which the shell can do itself, without calling a separate program. While some of these built-ins also have a binary of the same name (/bin/echo for example), your shell can rely on the built-in independently from the binary. Indeed, it can perform the task even if the binary isn't available. Turns out, you can do a whole lot with these shell built-ins.

A handy list of bash built-ins is available here, and can be quite an inspiration when faced with a task like that before Josh and me.

We started by looking around in the file system, using the following well-known trick as our rough "ls" equivalent:

$ echo *
file.txt

We then wanted to look at the contents of file.txt, so we ran:

$ while read line; do echo "$line"; done < file.txt
Hello World!
This is a nice file.
Happy Holidays!

We then wanted to search through a file to find a specific string, rather like grep:

$ while read line; do if [[ $line == *"nice"* ]]; then echo $line; fi; done < ./file.txt
This is a nice file.

Want a count of the number of lines in a file (rather like wc -l)? Use something like:

$ i=0; while read line; do i=$(($i+1)); done < ./file.txt; echo $i  
3

Want your UID number? You should try:

$ echo $UID
1024

Wanna do a whoami? If you have access to the world-readable /etc/passwd, you could build on what we saw above with:

$ while read line; do if [[ $line == *":x:$UID:"* ]]; then echo ${line%%:*}; fi; done < /etc/passwd
nobody

Those are just a few of the useful items we performed with built-ins. Got any more you'd like to share? Please do provide them in the comments below.

Thanks!

— Ed Skoudis & Josh Wright

3 Comments

Posted December 9, 2014 at 10:10 AM | Permalink | Reply

Mike Peters

Check for readable files:
for x in `echo /sbin/*`; do if [ -r $x ]; then echo $x; fi; done
Replace -r with -x or -w to check for executable or writeable permissions or to check for block devices:
for x in `echo /dev/*`; do if [ -b $x ]; then echo $x; fi; done
Full list of available tests here ''" http://tldp.org/LDP/abs/html/fto.html

Posted December 9, 2014 at 11:34 AM | Permalink | Reply

Ed Skoudis

Awesome, Mike. I could see how that would come in handy. Thank you. Got any more? Anyone else have any more?

Posted December 10, 2014 at 3:46 AM | Permalink | Reply

John H Long Jr

Greetings Ed. Enjoying the nice rainy Nor'easter we're having in NJ?
Here's one, given access to the /proc file system and the existence of the comm file that will list the running process:
read -a PROCS

Post a Comment - Cancel Reply






Captcha


* Indicates a required field.