Saturday, July 25, 2015

Making use of Grep, Cut & Sed -- An Anti-Theft Network Recon Script

After watching this video (which, by the way, is hilarious and worth checking out), I decided that I needed to write some kind of anti-theft bash script for my computers. Why bash? No other reason except it's one langauge that I'm confident enough speaking, and like that video, it too, is awesome. The basic scenario that I'd like to prepare for goes something like this:

Your computer gets stolen, and you really want it back. While you know that the computer is running an ssh server, and is listening on 0.0.0.0 for connections, you don't know what it's IP address will be whenever it gets plugged in to the WWW, or what kind of network topology you will have to hack through in order to connect to it. Of course, this logic assumes that the thief is not smart enough to wipe the system before putting it online. It also assumes that he does not have your sudo password, and perhaps even that you have the guest network account enabled, and/or your system boots into single user mode, as to lure the thief into testing out 'his' new computer. None of these assumptions are ideal, but perhaps if the computer that gets stolen exists in a shared computing environment where those conditions must be met, than this script could be helpful.

It's also worth noting that a few things have changed the days when that hacker in the video linked above had his box stolen, most importantly that 99% of all devices connected to the internet these days are behind some kind of firewall. So, there are a lot of variables to consider here...
In any case, let's assume all those conditions have been met, and you are sitting at home pulling you hair out, praying your computer's thief is a total idiot, and waiting for your beloved to phone_HOME()...

So, without spending too much time preparing for a very unlikely scenario, what information would you need in order to get a shell on your box and begin pwning the thief? First and foremost, you need an IP address. Sounds simple enough, but often times computers are not aware of what their public IP address is because they live on a LAN that does NAT to a local IP address. To solve this problem, we need a webserver that uses php to return the visitors IP address to an html page. Than your script can grab that IP with wget or curl, and send it back to you, the owner. This does the trick:

<?PHP
function getUserIP()
{
    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];

    if(filter_var($client, FILTER_VALIDATE_IP))
    {
        $ip = $client;
    }
    elseif(filter_var($forward, FILTER_VALIDATE_IP))
    {
        $ip = $forward;
    }
    else
    {
        $ip = $remote;
    }

    return $ip;
}

$user_ip = getUserIP();
echo $user_ip; // Output IP address
?>

This bit of php does nothing other than output the visiting client's IP address to the webpage in plain text, which is exactly what we need, no more and no less. I spun up a webserver and gave it the domain name ipreturn.tk, feel free to use it if you wish.

$ curl ipreturn.tk
 1.2.3.4

Perfect. Now that we've got the public facing IP of our perpetrators internet connection, perhaps it would be helpful to gather some more information about that host. This is where my all time favorite tool, Nmap, comes in to play:

#!/bin/bash

pubIP=$(curl ipreturn.tk)

pi_RESULTS=$(nmap -sV -A ${pubIP})
echo ${pi_RESULTS}


Parameter expansion is good stuff! Running this script will produce something like this:

Nmap scan report for 1.2.3.4
Host is up (0.063s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
53/tcp open  domain  dnsmasq 2.43rc3
22/tcp open  telnet    an old one


So now you have a little bit more information about your antagonist's internet connection. In this hypothetical example, the assailant has is running some kind of old telnet service, which should not be very difficult to exploit. But, wouldn't it be useful if we knew more about what lies on the other side of the network? To do that, first we need to find a way to grab the IP address from the output of ifconfig and either figure out the netmask as well, or just turn it into a a wildcard address and let nmap handle the rest. Originally, I tried something like this:

WlocIP=$(/sbin/ifconfig wlan0 | grep Mask | cut -d ':' -f2 | cut -d " " -f1)
ElocIP=$(/sbin/ifconfig eth0 | grep Mask | cut -d ':' -f2 | cut -d " " -f1)
ElocSN=$(echo ${ElocIP} | cut -d "." -f -3 | sed 's/$/.*/')
WlocSN=$(echo ${WlocIP} | cut -d "." -f -3 | sed 's/$/.*/')



function wifi_INFO(){
if [[ ${WlocIP} != "" ]]; then

    echo "<h3> Nmap results for wifi IP </h3>"
    echo "<pre>"
    nmap -sV -F ${WlocSN}
    echo "</pre>"
   
else
    echo "Wireless not available."
fi

}

function eth_INFO()}{
if [[ ${ElocIP} != "" ]]; then

    echo "<h3> Nmap results for wifi IP </h3>"
    echo "<pre>"
    nmap -sV -F ${WlocSN}
    echo "</pre>"
   
else
    echo "Ethernet not available."
fi

}

But, there a couple problems with that approach. First of all, it's unlikely that the thief will be connected to both wireless and ethernet at the same time, so that will throw some sort of error. We also can't be sure that the name of the interface will be 'wlan0' or 'eth0', what is he is using his own wireless card or something? To get around that, we need to figure out exactly which NIC devices are online, and than grab the IP's and subnet's from there. For this, we need the help of for-loop magic:

INTFACES=$(/sbin/ifconfig -a | sed 's/[ \t].*//;/^\(lo\|\)$/d')
intIPS=$(for i in ${INTFACES}; do /sbin/ifconfig $i | grep Mask | cut -d ':' -f2 | cut -d " " -f1; done)


intSNS=$(for i in ${intIPS}; do echo $i | cut -d "." -f -3 | sed 's/$/.*/'; done)
sn_RESULTS=$(for i in ${intSNS}; do nmap -sV -F $i; done) 


echo ${sn_RESULTS}
192.168.1.*
10.0.0.*

This is much better. First, it grabs a list of all of the network interfaces that are up on the system (excluding the localhost), and stores it as a variable. Than it feeds that variable into the intIPS line, which utilizes some more grep & sed magic to print a list of each interface IP address. Finally, I had figure out a way to turn each IP address into a wildcard mask to feed to nmap (for example, turn 192.168.1.1 into 192.168.1.*). To do that, I had to study the sed manual for a while to figure out how to remove specific unknown characters from a regular expression and than replace them with something else:

for i in ${intIPS};
do echo $i | cut -d "." -f -3 | sed 's/$/.*/' 
done 

And wala, it works! Finally, we feed the list of subnets to scan to nmap, which gives us a lot of useful information about our nemisis's network enviroment:

Starting Nmap ( http://nmap.org )
Nmap scan report for router (10.0.0.1)
Host is up (0.063s latency).
Not shown: 98 closed ports
PORT   STATE SERVICE VERSION
53/tcp open  domain  dnsmasq 2.73rc4
80/tcp open  http    LuCI Lua http config


Starting Nmap ( http://nmap.org )
Nmap scan report for yourcomputer (10.0.0.101)
All ports on 10.0.0.101 are filtered (cause your smart)
Starting Nmap ( http://nmap.org )
Nmap scan report for felix (10.0.0.100)
(The 1640 ports scanned but not shown below are in state: closed)
PORT     STATE SERVICE    VERSION
21/tcp   open  ftp        WU-FTPD wu-2.6.1-20
22/tcp   open  ssh        OpenSSH 3.1p1 (protocol 1.99)
53/tcp   open  domain     ISC BIND 9.2.1
79/tcp   open  finger     Linux fingerd
111/tcp  open  rpcbind    2 (rpc #100000)
443/tcp  open  ssl/http   Apache httpd 2.0.39 ((Unix) mod_perl/1.99_04-dev)
515/tcp  open  printer
631/tcp  open  ipp        CUPS 1.1
953/tcp  open  rndc?
5000/tcp open  ssl/ftp    WU-FTPD wu-2.6.1-20
5001/tcp open  ssl/ssh    OpenSSH 3.1p1 (protocol 1.99)
5002/tcp open  ssl/domain ISC BIND 9.2.1
5003/tcp open  ssl/finger Linux fingerd
6000/tcp open  X11        (access denied)
8000/tcp open  http-proxy Junkbuster webproxy
8080/tcp open  http       Apache httpd 2.0.39 ((Unix) mod_perl/1.99_04-dev)
8081/tcp open  http       Apache httpd 2.0.39 ((Unix) mod_perl/1.99_04-dev)
Device type: general purpose
Running: Linux 2.4.X|2.5.X
OS details: Linux Kernel 2.4.0 - 2.5.20

Nmap finished: 1 IP address (1 host up) scanned in 42.494 seconds


In this case, the theif has at least one on his network that appears
to be very vulnerable (I borrowed this from nmap.org)
That will come in useful, but now we need a way to send this
information back home. This should also happen silently in the
background, and not leave any leftover files when it's done.
Originally I thought it may be a good idea to send all the gathered
information back home via email, but than I decided against that
because email is very insecure. It's possible to encrypt the message
with GPG before emailing it, but that has it's own issues too, like
you probably don't want your GPG key's password cached in memory
permantly if you can help it. The solution I decicided on was to send
it over SFTP to a server running SFTP in a chrooted enviroment,
protected by an RSA key:

function write_page(){
cat << _EOF_
<html>
<head>
<title>$TITLE</title>
</head>
<body bgcolor="black" text="white">
<h1>$TITLE</h1>
<p>$RIGHT_NOW</p>
<p><b> Local Subnet Scan Results: </b></p>
<pre>
${sn_RESULTS}
${pi_RESULTS}
</pre>
</body>
</html>
_EOF_
}
function phone_HOME(){
cd $workDIR
if [[ ! -f $workDIR/batch ]];then
cat << 'EOF' >> $workDIR/batch
put netenv*.html
EOF
fi
sftp -b batch $sftpUSER@$sftpHOST:/$sftpDIR
}

I figured I may as well have the output be in html format, in case someone did want to use email instead of sftp. To erase evidence of this script, I added the clean_UP function, with will delete the files left in /tmp with secure-delete if it's available, and if not than revert to normal 'rm'. Of course, this should probably also either be ran with the script command, or redirected to /dev/null, as not to leave any telltale error messages in the syslogs, like this:

netrecon > /dev/null 2>&1

So, putting it all together, this is the final script:


#!/bin/bash
#####################################################
# Bash Network Reconnaissance Script * Version 2.0  #                            
# DarkerEgo's Bash Snippets, GPL 2015               #
#####################################################
workDIR="/tmp/netrecon"
sftpUSER="user"
sftpHOST="remoteserver"
sftpDIR="some/directory"
OUTPUT="netenv.$(hostname).$(date +'%d-%m-%y').html"
TITLE="Bash Network Reconnaissance Results"
RIGHT_NOW=$(date +"%x %r %Z")
pubIP=$(curl ipreturn.tk)
#
INTFACES=$(/sbin/ifconfig -a | sed 's/[ \t].*//;/^\(lo\|\)$/d')
intIPS=$(for i in ${INTFACES}; do /sbin/ifconfig $i | grep Mask | cut -d ':' -f2 | cut -d " " -f1; done)
intSNS=$(for i in ${intIPS}; do echo $i | cut -d "." -f -3 | sed 's/$/.*/'; done)
sn_RESULTS=$(for i in ${intSNS}; do nmap -sV -F $i; done)
pi_RESULTS=(nmap -sV -A ${pubIP})
#
function prep_VARS(){
if [[ ! -d $workDIR ]];then
mkdir $workDIR
fi
if [[ -f $workDIR/$OUTPUT ]];then
srm $workDIR/$OUTPUT || rm $workDIR/$OUTPUT
fi
touch $workDIR/$OUTPUT
}
function write_page(){
cat << _EOF_
<html>
<head>
<title>$TITLE</title>
</head>
<body bgcolor="black" text="white">
<h1>$TITLE</h1>
<p>$RIGHT_NOW</p>
<p><b> Local Subnet Scan Results: </b></p>
<pre>
${sn_RESULTS}
${pi_RESULTS}
</pre>
</body>
</html>
_EOF_
}
function phone_HOME(){
cd $workDIR
if [[ ! -f $workDIR/batch ]];then
cat << 'EOF' >> $workDIR/batch
put netenv*.html
EOF
fi
sftp -b batch $sftpUSER@$sftpHOST:/$sftpDIR
}
function clean_UP(){
srm $workDIR/$OUTPUT || rm $workDIR/$OUTPUT
srm $workDIR/batch || rm $workDIR/batch
rmdir $workDIR
}
prep_VARS
write_page > $OUTPUT
phone_HOME
clean_UP
exit


And that is as much effort as I am going to put into that! By the way, I uploaded this to github as well, in case you'd like to pull it from there and avoid all those problems that the nasty windows style formatting can cause.

Edit: It might also be a good idea to also add a function that would ssh into your server for a few minutes upon each run, and do some reverse port forwarding so that you'd have a window to grab a shell that way. Or perhaps make it so that if the ip address changes, than the script would wait until the computer is idle for a few minutes, and than connect to your server over ssh, reverse forwarding back to your ssh port. Maybe I'll look into that and figure it out.

That's all for today.

Sunday, July 12, 2015

Bash Color Prompts

Last night I saw some old friends that I hadn't seen in years. It was a jolly reunion, and I drank way too much. Consequently, I've got a tad bit of a hangover, thus my brain is not functioning on par. It's also about 90 degrees here in [undeclared], USA today, so nobody feels like doing much of anything. To kill the time, figured I'd create some cool bash color prompts and post them.

This one is easy on the eyes and not too distracting.





export PS1="\[$(tput setaf 7)\]\u\[$(tput setaf 1)\]@\[$(tput setaf 7)\]\h\[$(tput setaf 6)\]:\[$(tput setaf 4)\]\W\[$(tput setaf 5)\]\\$ \[$(tput sgr0)\]"





user@yourbox:~$

But personally I prefer a very minimal colorized prompt, because (like it says in the .bashrc file already), it's distracting and the focus the of terminal ought to be more about the output than the prompt. However, a little itty bit of color never killed anyone:

export PS1="\[$(tput setaf 7)\]\u\[$(tput setaf 7)\]@\[$(tput setaf 7)\]\h\[$(tput setaf 2)\]:\[$(tput setaf 4)\]\W\[$(tput setaf 6)\]\[$(tput setaf 1)\]\\$\[$(tput setaf 6)\]\[$(tput sgr0)\]"

user@yourbox:~$

I think it's a nice touch.

For root accounts, I find it useful to add a bold red prompt to remind myself to not stay logged in as root as any longer than absolutely neccessary. Something like this:

export PS1="\[$(tput bold)\]\[$(tput setaf 7)\]\u\[$(tput setaf 5)\]@\[$(tput setaf 7)\]\h\[$(tput setaf 4)\]:\[$(tput setaf 1)\]\W\[$(tput setaf 1)\]\\$ \[$(tput sgr0)\]"

root@yourbox:~#

Another variation... 

export PS1="\[$(tput bold)\]\[$(tput setaf 7)\]\u\[$(tput setaf 1)\]@\[$(tput setaf 7)\]\h\[$(tput setaf 2)\]:\[$(tput setaf 4)\]\W\[$(tput setaf 6)\][\[$(tput setaf 1)\]\\$\[$(tput setaf 6)\]]\[$(tput sgr0)\]"

root@yourbox:~[#]

Oh yeah, rather than doing all this manually, there is this awesome website that has a bash prompt generator: https://www.kirsle.net/wizards/ps1.html#

Jeeze I've spent an hour doing this already. I guess that's all for today, folks.

Edit: I found the configuration I was looking for! This is much better, because the path is not colored as well, which is just plain annoying... For example..


user@host:~$/etc/default

... is just silly. This is what I was going for:

For user:

export PS1="\u@\h\[$(tput setaf 1)\]:\[$(tput setaf 7)\]\w\[$(tput setaf 2)\]$ \[$(tput sgr0)\]"


 you@yourbox:~$ cd /etc/default
 you@yourbox:/etc/default$

And a nice red prompt for root:

export PS1="\u@\h\w\[\e[36m\]:\[\e[m\]\[\e[31m\]\\$\[\e[m\] "

root@yourbox:#~ cd /etc/default

root@yourbox/etc/default:#
 
Much better.

Wednesday, July 8, 2015

Do VMs Provide a False Sense of Security?

I think I finally figured out how my computers keep getting hacked. This past year it's happened three or four times, forcing me to completely reinstall my system, and frustrating me to no end because I could not figure out what I was doing wrong, or not doing right. I'd like to think my security practices are pretty good. My friends consider them excessive and totally unnecessary (like when a guest needs the WiFi password and I'm like "ughhhh.... yeah....hold on.")

Until recently I never gave much though to the idea of securing Virtualbox. After all, the main reason I use VM's to begin with is so that I can run an insecure O.S. like Windows securely, inside a contained environment. Than I started playing around with Metasploit, and after a while I started to wonder what would happen if I migrated a meterpreter process to the vbox guest additions process on the guest. What would I be able to do from there? I don't know because I have not actually tried it, but it seems like that would be a good entry point for a hacker to break out of the VM and wreak havoc on the host. I started to think about how the vbox guest additions package works, and what it's capabilities are. It allows the guest machine to access 'shared folders' on the host, allows 'mouse integration', allows the guest to take advantage of the host system's GPU to improve graphics, and a lot of other things.

When you install it inside a VM, Virtualbox does not ask the user of the host computer for permission to access the resources provided. It does warn you that bad things could happen if you install the package, but if you import a VM that already has the guest additions package installed, than you won't even see that warning. So what is to prevent rogue software from interfacing with whatever server interprets commands from that package? Or what prevents a piece of malware present on the guest system from interfacing with the host system through a preinstalled guest additions package? What kind of safegaurds are in place to protect the host during a scenario like that? Virtualbox runs as root, and the program even has the setuid bit enabled by default.

Even without the guest add-ons program, Virtualbox can do a lot of interesting things with the host system, as is. It can create virtual network adapters that will grab their own IP address's from the host systems router, completely bypassing any NAT safeguards present on the host, allowing them direct access to your LAN. If you enable the USB integration feature and set the permissions, than Virtualbox can be configured to interact with any USB device connected to the host. On my computer, the webcam is actually connected through a USB controller, so that could be a scary situation indeed! These are just a couple hypothetical scenarios, but when I put all this together it seriously makes me wonder if Virtualbox is anything close to the safe sandbox for insecure systems that it's perceived to be. Than consider that if you are running Windows in a VM, you probably pirated it, as Windows does not officially support virtualization (afaik).

So what can be done about this pickle? Well, I am a big fan of chrooting untrustworthy software. For example, even though Firefox is an awesome browser, and one of the more secure ones, I still run it in a chroot because otherwise, the browser has access to anything that the user it's running as does. That means a compromised browser=a compromised system. Since client side web exploits are very common these days, I always run my browser in a chroot. I've been doing that a while now, and it's worked quite well, which brings me to the point... From now on I will only run VM's from inside a chroot, on a separate partition, and without the guest additions. A good App Armor policy should be able to prevent malware from talking to Virtualbox through the guest additions server.

If anyone has written or knows of a really good Virtualbox AA policy, please do comment and share it with me. That's all for now.

Wednesday, July 1, 2015

HackBox in the Cloud

You Never Know When You'll Need It

There's plenty of legit uses for a cloud based hackbox, penetration testing being the most prominent. While a Kali box on your home LAN is great for pentesting the local network, a Kali box in the cloud with a dedicated public IP address is a much more versatile tool. Sometimes it's easier to use the cloud box, even if I am working on the same network as my target due to local firewalls, NAT upstream issues, etc. But being able to ssh into your hackbox from your daily driver, from anywhere, is every bit as comfortable as it is priceless. I also bet many people overlook the security implications of leaving a pentest box like Kali running on your home network 24/7. If someone is able to compromise your home Kali box, you may find the damage will escalate quickly & in stylish fashion as that hacker uses your own tools against you. Yes, that has happened to me...

Building Your VPS -- Use Debian Wheezy!

A couple of posts ago I discussed the perks of taking advantage of the cheap & abundant virtualization available today, and of segregating your systems by task. Today we're going to talk about how to build a little "hackbox in the cloud", so to speak. It will be hosted on a relatively cheap VPS, yet provide most of the functionality of a physical Kali box. The system should be built from the Debian 7 kernel, enabling us to make use of the Kali Linux repositories. This will make your life about 1000x easier. Kali Linux is a straight pentesting distro with more security tools than I care to count, including metasploit, armitage, setoolkit, sqlmap, ettercap, wireshark, etc, blah. It is also completely based on Debian Wheezy, which means that we can turn any Wheezy system into a full blown angle of death with two or three lines of bash.

First you need to purchase a VPS that is running Debian Wheezy. I'd recommend Digital Ocean for this project if you are going to use the hackbox for legal whitehat activities, because D.O. is simply damn convenient & stable. I have never had even 1 second of downtime on any of my D.O. boxes. They also offer free Snapshots; meaning that you can rebuild your box with an image you created earlier when something breaks. This is a priceless feature, especially for this kind of project. The first thing I do after configuring a server is make a snapshot. As for the architecture, it's probably better to go with x64, simply because that allows us to compile both 32 and 64 bit binaries, something that can't effectively be done of a x86 system.

Graphic Desktop Environments

Before you build your VPS, decide whether you will be installing a desktop environment to use over VNC (tunnelled over ssh, of course). If so, than make sure you have at least 2G of ram. You can get away with running Openbox or Metacity on a server with 1G of ram, but you run the risk of program crashes because your system has ran out of memory, which is most inconvenient during a pentest! It will also be very slow once you start the X server. If you don't want a GUI, than 1G of ram will be more than enough. If you cheap out on yourself and go with the 512 MB ram package, than at least configure a large swap file, and do expect random system crashes.

It's also worth noting that tunnelling VNC over SSH can be really slow, especially if you are also behind a VPN or proxy. However, not tunnelling VNC over some type of SSL is like saying "Hey NSA -- Want a free live stream of my desktop?" To mitigate this problem, find a server that is geographically close to you, or tunnel your VNC through a VPN instead of SSH, which can be a lot faster depending on too many factors to list here (blowfish and AES-128 are two fast ciphers for this purpose).

In the end, GUI's on VPS servers kind of suck. I'd recommend doing the things which require a GUI on a local Virtual Machine instead. Besides, GUI's add tons of extra code, which introduces security vulnerabilities and requires a lot of extra precaution to deploy correctly.

Getting to It

After you've configured your sever, set up SSH, got your firewall running, optionally configured sudo, and performed a system update, it's time to add the Kali repositories to your sources.list:

deb http://http.kali.org/kali kali main non-free contrib
deb-src http://http.kali.org/kali kali main non-free contrib
deb http://security.kali.org/kali-security kali/updates main contrib non-free
deb-src http://security.kali.org/kali-security kali/updates main contrib non-free


You'll probably get an error about not having the GPG key when you run apt-get update, so add it than try again. You may be to install the package kali-archive-keyring to take care of that, or you may have to manually wget & import the key:

$ wget -q -O - https://www.kali.org/archive-key.asc | gpg --import


You should then check the fingerprint against the one listed on their site. After adding the sources and running an apt-get update && apt-get upgrade (but not an a dist-upgrade because that could break your Kali install) you can turn your Debian server into a near complete Kali system with this command:

 apt-get install kali-linux-full

That will install a lot of packages, and will take between 10 and 20 minutes to complete. If you opted to go with  a headless environment instead, you should probably install the packages you need individually instead, so that you don't end up with a bunch of useless extra code. Programs like metasploit, nmap, sqlmap, and tshark do not require a GUI to function, and can be installed via apt individually.

Metasploit is arguably the most useful program in a pentesters tool chest, so I'll briefly cover setting that up. You can clone it from git or grab it from apt, installation is pretty straightforward regardless of how you install it, but to ensure things go smoothly, I'd recommend doing things in this order:

apt-get -y install nmap metasploit postgresql
service postgresql start
service metasploit start
mfsconsole

Beautiful, isn't it? At this point you're pretty much good to go, but we've got a few more optimizations and tweaks to make. At some point your are going to need to open some ports for metasploit, so it's a good idea to write a 'reset' firewall script that you can later call on demand to close those ports. Normally I'd not recommend using UFW on a server, but because of it's sheer simplicity, and because your hackbox needs to be flexible (and can always be restored to it's original state provided you took a snapshot), UFW is not a bad choice in this situation.Write a quick script to reset the firewall after completing an exploit and save it as /usr/local/bin/firewall so it can be executed from anywhere, something like this:

#!/bin/bash
    # Need root.
    if [[ $EUID -ne 0 ]]; then
       echo "Got root?"
       exit 1
    fi


#First, define your SSH server's listening port:
   sshPORT=

   sshHOST=1.2.3.4
   primINT=eth0

   sshHOST=some.static.ip.addrs

   iptables -t nat -F #flusing iptables does not always reset these chains
   iptables -t mangle -F

   ufw reset

   ufw allow in on $primINT to any port $sshPORT proto tcp from $sshHOST

  ufw enable
  exit


If you want graphical desktop environment, than you need a way to access X. SSH does have native X forwarding, but to be honest, I've never used it. As I mentioned, you can use VNC and tunnel that over ssh. I've been using xtightvncserver, and tightvncviewer on the client side. The experience has not been great, but it works. For example, (unless I just don't know what I'm doing, which is possible) there does not seem to be a way to copy & paste text from or into the VNC window. Also, when I press the \/ arrow key out of habit to scroll through my command history, it does not work whatsoever. The < and > arrows work though... not sure what's with that situation. In any case, this is how you set it up [ Thanks & credit to the source for the excellent tutorial!] :

server$ apt-get update
server$ apt-get upgrade
server$ apt-get dist-upgrade 

(^It's always good to refresh your sources before installing anything.) The default Kali environment runs on gnome-classic, or "Metacity". I first tried doing this with openbox because it's lighter, but I had some configuration problems so I ended up going with good ol' trusty gnome:

server$ apt-get install gnome-desktop-environment 

(Assuming you're going to use tightvncserver: ) 

server$ apt-get install xfonts-100dpi xfonts-100dpi-transcoded xfonts-75dpi xfonts-75dpi-transcoded xfonts-base tightvncserver
 
Stop! Before you start the vncserver, I think it's a really good idea to create a separate user with limited privileges to run it. Anything graphical based tends to induce a lot of security issues, so take precautions. This way if someone manages to brute into your box, at least they will be presented with a somewhat limited shell.

server$ useradd -m limpriv
server$ usermod -s /bin/sh limpriv
server$ passwd limpriv (enter a strong password)
server$ su limpriv

And finally start the server, explicitly telling it to only accept connections from the localhost:

tightvncserver -localhost :1

Or from another account:

sudo su $USER -c '/usr/bin/tightvncserver -localhost :1'

At this point you'll be prompted to create a password to access vnc, so do that. If you want the VNC server to start up everytime you boot your box, create an init script. Here's a sample one to get you started. Now you need to create an ssh key for your limpriv user. I'll assume you know how to do that if you got this far. When you VNC into your box, you will be running as the limpriv user. From there, you can log into your privileged account, and than finally sudo or su to root. This adds a layer of protection, and is probably worth the effort. To start the connection:

client$ ssh -f -N -L 5901:localhost:5901 limpriv@hackbox 
client$ xtightvncviewer localhost:1

After entering your VNC password, a new window will appear with your remote desktop, with that old familiar black Kali desktop. Now you're ready to rock and roll. What you can do from here is only limited by your imagination and IQ level, I suppose. Just do the world a favour and use this gift of open source awesomeness for good rather than evil... You know the drill:

  • Think before you type
  • Respect other people's privacy
  • With great power comes great responsibility