Saturday, June 1, 2013

Not snort-related, but a good thing to know: How to tunnel VNC over SSH

So, this isn't strictly snort or autosnort related, but I figured I would post it anyhow. I primarily use SSH to manage my autosnort testing sensors in my virtual environment, but I also use vnc over SSH to manage my Attack system (A Kali Linux box -- was formerly Backtrack 5 r3) and thought I would share my experience on how to set up vnc server over SSH and have it look somewhat decent.

I've found a blog post here and a blog post there about how to tunnel VNC over ssh, but nothing really comprehensive. So I thought I'd share my knowledge on the bits of wisdom I've found strewn all over the net. If you have anything to contribute, or anything to add, please do so.

To begin, VNC is old and insecure; It encrypts absolutely nothing. This is why we're going to wrap it over SSH. In addition to a lack of encryption, VNC4's password functionality only allows 8-character passwords. This means the password can be broken fairly easily, even with a random password.

Tunneling VNC over SSH allows you to use stronger authentication (keys or huge long passwords, or both) in additional to the VNC password, setting up a basic form of multifactor authentication.

Most debian-based distro package sources include vnc server. It can be installed via:

apt-get install vnc4server

Afterwards, you will need to run vnc4server manually or vnc4passwd to specify a password for the current user for using VNC. again, the password can only be 8 chars long.

Additionally, in the user's .vnc folder (e.g. ~/.vnc or /home/[user]/.vnc/ ) is a file entitled xstartup

xstartup must be executable, and looks something like this:

# Uncomment the following two lines for normal desktop:
#exec /etc/X11/xinit/xinitrc

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources

#xsetroot -solid grey
#vncconfig -iconic &
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#x-window-manager &

 Change the file to look something like this:

# Uncomment the following two lines for normal desktop:

exec /etc/X11/xinit/xinitrc

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources

#xsetroot -solid grey
#vncconfig -iconic &
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#x-window-manager &
startx &;

if the .vnc directory doesn't exist, try running "vnc4server" to start up vnc. This should give you a .vnc directory and the file above. After starting it, immediately kill it via kill -9 or killall vnc4server.

Next, we need to make an init script to start up vnc at boot. I found this init script via

I've made some minor improvements, however. Copy these contents to /etc/init.d/vncserver:

# /etc/init.d/vnc4server
# Some things that run always

touch /var/lock/vnc4server

# Carry out specific functions when asked to by the system
case "$1" in

echo "Starting script vnc4server "
su root -c 'vnc4server -depth 24 -pixelformat RGB888 -localhost -geometry 1440x900 '

echo "Stopping script vnc4server"
su root -c 'killall Xvnc4'

echo "Usage: /etc/init.d/vnc4server {start|stop}"
exit 1


exit 0

The line that is doing the all the work of running the vnc server is this line:

 vnc4server -depth 24 -pixelformat RGB888 -localhost -geometry 1440x900

This line is essentially saying "start the vnc server with 24-bit color depth, with this RGB mapping and a resolution of 1440x900, and only allow it to listen on" (This last part is important! do not forget the -localhost line!) You can change the -geometry line to any resolution you wish, but I had to figure out the -depth and -pixelformat lines on my own, and mainly through trial and error.

next you'll have to make the file executable (chmod u+x /etc/init.d/vncserver)

after making the file executable, run:

update-rc.d vncserver defaults


update-rc.d vncserver start [runlevels you want the server to run on]

finally, the file make the xinitrc file executable. I've found that vnc won't work properly unless this file is executable:

chmod u+x /etc/X11/xinit/xinitrc

The higher the bit depth and resolution, the more packets you need to be able to push over the network (and your SSH tunnel) to keep things running smoothly. For this reason, I recommend that if you're going to use this configuration that it be over a high-speed link, or a local network. try changing the depth to 16, or making the resolution lower if you find the VNC session to be laggy.

So to summarize what we just did above we:

installed vnc4server

set up a vnc password for your user

made an init script for vnc4server

made all necessary preparations to host vnc4 server.

In this section I'll show you how to SSH tunnel to your VNC server either from windows or linux.

We'll start with windows. I use an awesome program called MRemoteNG for managing remote connectivity via a number of remote protocols -- VNC, RDP, SSH, .ICA (citrix), HTTP/HTTPS (xulrunner-- a bit buggy), etc. I can't stress how awesome MRemoteNG is for managing multiple connections. For those worried about having the app store connection information, it also allows you to encrypt the connection configuration files to keep your creds safe.

Download and Install MRemoteNG. Open it up and click Tools::Options:: and click advanced. Click "Launch Putty"

Here is where we're going to configure the portforwarding settings. Under Category, go down to Connections, click the plus sign on SSH, then click tunnels.

This page looks confusing, but it's really simple.

The only things you need to modify are

Source Port: set this to any arbitrary port number you want. Doesn't really matter. Just remember what it is. If you can't remember, you can always come back to this page.

For destination type this in exactly:

The more intrepid may ask "uh.. why am I putting localhost in as the destination?"

Because this is localhost on the REMOTE server (e.g. the system where VNC is listening on loopback ( only. So what this tunnel is saying is:

"After this user has successfully authenticated to me, have the client open up source port:[source port you choose]. If you get a connection on [source port you chose], funnel it over port 22. When it reaches the remote end, connect it to where the VNC server is listening."

Save your putty session by scrolling up, clicking on sessions, putting in a name under "saved sessions" then clicking save. Afterwards, you can close putty.

You'll need to create two mremoteng sessions here:

the first Mremote session, select ssh version tool as the protocol, enter the IP address (user name and/or password if you want) and under PuTTY session, click the drop down and save the session you made.

the second Mremote session, you'll choose VNC as the protocol. Enter the IP address "" and the source port that you entered when you created the putty session above. For the password, enter the password you entered when you ran vnc4passwd or vnc4server previously.

Next, double click on your ssh session in mremoteng, then double click on your localhost VNC session. You should have your remote system's desktop.

If you're doing this over Linux, it's not that much harder to do. Make sure your linux  connecting to the remote SSH (and VNC) server has an ssh client and a vncviewer application of some sort.

Open up a terminal window and type:

ssh -L 5901:localhost:5901 username@[hostname/ipaddress]

The -L line above is the secret sauce and works exactly the same as the what the putty session does:

[Source Port to listen on locally]:[target remote ip address]:[remote port to connect to]

So we tell SSH to open a listener on 5901 if your local workstation gets a connection on 5901, forward it over the SSH connection and send it to 5901 on the remote server's loopback address.

Next, just tell your vnc client to connect to and you're done.

Note: Some of the more intrepid among you may notice that there's now a listener on 6001/tcp. I've searched long and hard for the reasoning behind this. 6001/tcp is the default port for the first X server screen to use when X is told to listen for remote X client connections.

Some of you are probably freaking out. you don't want your server to allow connections to X windows. Don't freak out just yet; Sure enough, if you get NMAP scanned, NMAP will say the port is open. Netcat will connect and promptly get dropped. PuTTY RAW sessions stay open (probably because the remote X server has no idea what the heck the PuTTY RAW session is trying to do.) No remote X clients will be able to connect to the x server. While you are on your vnc session, If you type "xhost" in a terminal window "access control enabled, only authorized clients can connect" should be the response you get. In the olden days, way before even my time, No one thought to tunnel X over SSH. so they would use xhost to authorize remote users to connect to that system's X windows server. The format was usually xhost +{ip address} to allow a remote ip address to connect to your X server. Even more common was for most to just type xhost + (no ip address). This is the same as saying "Allow anyone to connect to my X server". You can probably imagine why this isn't a good idea.

So why am I telling you about this? Because by default, your X server (the one that VNC uses), for some stupid reason  has your X11 X windows server listen on 6001/tcp. From what googling I've done, there's no reason for this, and there's no way to configure X (without modifying the source code) to just listen on localhost. I've tried to find a solution that isn't "turn on your firewall, or just configure firewall rules to block it." That's a work-around, not a solution (A viable work-around, by the way, but not the point.) and I haven't find any (other than the just a firewall rule)

For those of you who aren't firewall gurus, you're in luck. by default, xhost doesn't authorize ANY remote users at all to connect to your X server. That means, as soon as anyone tries to connect to your X server, the session is dropped by X's own authorization system. The bottom line is: Don't freak out; no one is allowed to connect to it. You're safe. But if you know how to make X listen on only, I'd be very interested...

Final Note: On some sshd servers, TCP Forwarding is disabled. TCP forwarding is the magic by which all this tunneling happens. Meaning if it's disabled, then none of this works. Check /etc/ssh/sshd_config if you see the line "AllowTcpForwarding no" it means tcp forward is turned off. Conversely, if it is set to yes, then you're good to go. If you don't see this line in your sshd_config file, then you're good to go as well. It's implicitly allowed by default.


No comments:

Post a Comment