Posts tagged ssh

use strace to snoop on ssh sessions
posted on 2016-09-12 00:17

To snoop on another running SSH session, these oneliners come in handy.

  1. use w to find out which session you want to have a look at
  2. ps aux|grep pts to find out the PID
  3. replace the PID in the scripts below


Tested on 6.8:

strace -p PID -e trace=write 2>&1 | grep --line-buffered -o '".*[^"]"' | sed -e 's/^"//' -e 's/"$//'


Tested on jessie / 8:

strace -p PID -e write 2>&1 | grep --line-buffered -e '^write(7' | grep --line-buffered -o '".*[^"]"' | sed -e 's/^"//' -e 's/"$//'
ssh vpn howto
posted on 2016-05-29 12:38

To create a permanent tunnel via ssh between two hosts, some configuration has to be done on each side of the tunnel, so it gets automatically created once the tunnel interface is gotten up.

This tutorial is debian-specific.


  • a keypair gets created on client side, for the sole purpose of activating the tunnel
  • server network config is extended by an additional tun interface and a routing rule
  • authorized_hosts on the server is modified to activate the tunnel and the tun interface on the server side
  • client network config gets added a tun interface and routing rule
  • once the client tun interface gets brought up, an ssh connection gets established to the server, the servers tun interface is brought up, too, and the tunnel is in place



ssh-keygen -t rsa -b 4096 -f ~/.ssh/sshvpn

server side

Allow tunnelling in /etc/ssh/sshd_config:

PermitTunnel point-to-point

Save and exit, and service ssh restart.

Make ip forwarding available persistently, so it will be there across reboots:

echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf

Enable ip forwarding just for the current session:

sysctl net.ipv4.ip_forward=1

Add to /etc/network/interfaces:

manual tun99
iface tun99 inet static
    up ip r a via dev tun0

client side

manual tun98
iface tun98 inet static
pre-up ssh -i /home/sjas/.ssh/sshvpn -M -S /var/run/sshvpn -f -w 98:99 sjas@ true
    pre-up sleep 5
up ip r a dev tun0


Starting the tunnel, on client-side:

ifup tun0

Stopping the tunnel, on client-side:

ifdown tun0
SSH: tunnel and port-forwarding howto
posted on 2015-07-10 07:56:07

To create ssh tunnels there are a lot of explanations out there, and the most are not worth much. Let's see if I can do better.

some facts against common misconceptions


A tunnel involves only two endpoints.

Ok, fair enough. But you need to specify minimum three host locations for a working tunnel.

Where two can point to the same machine, just from different views.

Which is your local host (or at least it's port), the gateway (the machine which will be the other tunnel endpoint) and the machine you are targetting. localhost, if the target/destination host is the same machine as the gateway host.

More on that later, if this does not make sense yet.


Another misconception which is often prevalent: "How do I get the server port so I can access it locally?"

Actually the direction may seem unnatural:
Things depend on the source host, where the request (of whichever protocol being used) will originate.


There exist directions, which is what the -L and -R flags are for.


The order in which the ssh arguments are specified can actually be changed. And changed it is quite easier to grok.

tunnel 101

This is basic tunnelling knowledge, where SSH tunnels differ from SSL/IPSEC VPNs comments will indicate so.

Tunnelling connects non-routable networks with each other. (This is the case when one or both sites are behind a NAT.)

A tunnel is created between two enpoints, often called gateways. Encrypted pipes are created for securing traffic by crypting packets between the endpoints.

On each side, other hosts can be reached. Depending on the tunnel type, you may or may not have access to the remote gateway. (SSH lets you access the remote gateway, with an IPSEC VPN (virtual private network) where application and endpoint run on the same box you are in for some trouble. It works, but is ugly to do so.)

You also have to specify the hosts behind the endpoint. This can happen via subnets, or you can specify single hosts. (With SSH we will specify only single hosts here, no networks. Further only one side behind the tunnel has to be specified, the other side's host 'behind' the tunnel endpoint, is always located on the same machine as the gateway in question. The tunnel, it being of local or remotely forwarded port type, lets you specify the host not being locate on the gateway. Don't worry, this will come later with a better explanation.)

On general VPN's:
If you would not specify the local and remote network, how could the remote party possibly know to which ip packets should have to be directed, after the data packets exit the tunnel? (For SSH as already stated, only one host, either remote or local, which is not located on a gateway, can be specified. The other 'end' outside of the tunnel endpoint, lies always on the the gateway.)

ssh tunneling howtos


A regular ssh tunnel is like the above mentioned tunnels, except that the gatways and the networks after the ends (/32 networks to be exact) reside on the same host (read: the gateway). This guide assumes that you already know how to do this, its the basic ssh <hostname-or-ip> stuff.

chained tunnels

To connect to a remote host, but hopping over a few other hosts in the process, simply chain the tunnels:

ssh <host1> ssh <host2> ssh <host3>

Since you will want proper terminals, use the -t flag when doing so. And use -A if you need agent forwarding, when wanting to copy files between hosts directly.

ssh -t -A <host1> ssh -t -A <host2> ssh -A <host3>

This chaining stuff will also work for port forwardings described below, but you really have to watch your ports, so things fit together.

local tunnelling / port forwarding

-L will forward a port on your side of the tunnel to a host on the other one. That way you can reach over into the remote network.

The first use case here will be 'local' tunneling with the -L flag. The port specified on the local site will be forwarded to the remote site. This will be done so the webinterface of a remote NAS behind a router with NAT will be made externally accessible. NAS means Network Attached Storage, a small data server consuming not much energy providing file-level data.

For this to work, the router has to be configured such that it does port forwarding of requests on its port 12345 to the ssh host you want to connect to, by knowing its IP and the port on which the ssh server on this machine runs. (Usually on port 22.)

Usually you see specifications like this one:

ssh -L 1337: <user>@<domain-or-ip> -p12435

Easier to grasp should be this:

ssh <domain-or-ip> -l <user> -p 12345 -L localhost:1337:

You ssh to the host at <domain-or-ip>, with the user specified by -l as <user> on port specified with -p which is 12345. The port only has to be specified if SSH is not running on standard port 22. This is the gateway part.

Then you pass the information from on the local and the remote host, connected via a :.

localhost is the bind address, on which the SSH server instance is running, and 1337 is the port which will be used for accessing the webinterface. Which is what you have to type into your browser. (https://localhost:1337) If it were running with a different bind address, you'd have to use this one here, but then I likely would not have to tell you that. :) localhost does not have to be specified, this is done just for illustration purposes.

What another bindaddress does, is allowing others to use the tunnel if GatewayPorts is enabled on the local SSH server. See man sshd_config for more info. is the ip of the NAS system on the remote network behind the remote gateway and the port where the webserver is running on there.

remote tunneling / port forwarding

-R will forward a port from the remote site to your side of the tunnel. That way hosts from your network can be reached remotely.

Going along with the example above, from within the LAN where the NAS is located:

ssh <domain-or-ip> -l <user> -p 12345 -R localhost:1337:

Here <domain-or-ip> -l <user> -p 12345 is again the gateway information for the remote machine. Depending on -L or -R the local or remote port (and bindaddress!) are specified.

localhost here talks about the bindaddress on the remote server. If it is explicitly set, ssh's GatewayPorts directive/option has to be enabled on the server's /etc/ssh/sshd_config. is just the location of the NAS again.

tunnel chains with port forwardings

A local example:

ssh -t <host1> -L 1337:localhost:1337 ssh -t <host2> -L 1337:localhost:1337 ssh <host3> -L 1337:

Local browser can reach the far far away NAS via https://localhost:1337, which is on the same network as <host3>. If the NAS were SSH accessible, the complete path could be encrypted. Since we can't (at least in my made up example), we will hop from <host3> to it at its IP, and this is the only part of the connection, that cannot be encrypted. (This is just provided for educational purposes, such complex setups are usually unlikely in sane reality.)

Use -t for all hops prior to the last one.

a tunnel in a tunnel - port forwarding for ssh to reach locally bound services

This is for services bound to the loopback / interface, and which are thus only locally available:

ssh <host1> -L 1336:<host2>:22
ssh localhost -p 1336 -L 1337:localhost:3306

NAS is again a bad example here, as usually these boxes do not have ssh daemons installed/running.

What we did above was simply building a tunnel to the host we want to hop onto, and then creating the port forward by connecting to the locally existing SSH tunnel. This may be useful for remote connections to mysql instances that usually can just be reached locally.

Usually I have no use for this, but it might come in handy some day.

dynamic tunnelling

To create a SOCKS proxy via SSH:

ssh <domain-or-ip> -l <user> -p 12345 -D

Here a specific bindaddress was used (, which is our local ip within our LAN. Do you remember the Gatewayports thing?). Any host connecing to our ssh tunnel running on port 1337 will straight be forwarded to the remote gateway.

The application has to know how to handle SOCKS connections, else this will not work.

To keep up with our NAS example, I'd do:

ssh <domain-or-ip> -l <user> -p 12345 -D 1337

Then set up my web browser to use a SOCKS proxy, with address localhost (since no bindaddress was given, unlike in the prior example) and port 1337.

Afterwards can be entered into the adressbar and the NAS is reachable. Just keep in mind, that other Websites will not work.


When having to use software which is unaware of SOCKS proxies, the Point-to-Point Protocol (PPP) comes to help.

Also this is a poor man's VPN, when used to transfer all traffic through it and not just a sole host or network.

Since I have not had this put to use yet, I cannot write much about it.

So far:

  • Routing may be an issue and thus reaching DNS servers, when its just used to partially tunnel network connections.
  • When tunnelling everything, OSPF (open-shortest-path-first, a routing protocol) can be used to fix this, as I read, see the second link for more info.
  • Well, here are the links.

One link was on BSD, but I guess this helps with enlightenment. The shortest howto is the last one from the Arch wiki. Best may be the second one.

Linux: website migration guide
posted on 2015-06-19 19:53:32

Migrating a website can be a tedious task, if you have problems keeping several things at once inside your head. This aims to solve this problem by presenting some proper guidelines.

Here we have a standard dynamic website with a mysql backend, served through an apache httpd.

For other databases/webservers the steps may differ in particular, but essentially this is the same theory everytime.

Mailmigration will as of now not be a part of this here, since it's gonna be long enough anyway.

Read this completely prior, as alternative ways are suggested sometimes.


This part is almost the most important, actual copying is usually not that hard if you know what you are doing. It's often harder to remember everything.

Before we start, the server can serve data of three kinds which are handled all the same way.

web data, just copy the website code
database, copy the database dump file
emails, copy the mailfiles

The server is accessed via the globally available...:


Basically these are the things you have to copy/adjust so things will go smooth.


open questions

Putting most of these questions plus the answers to them into a spreadsheed is not the worst idea. Maybe I will come up with a shell one-liner to create a .csv later.

Also it is helpful if you are able to do FXP (transfer files from one host directly to the other, without temporary saving the data/files locally), if you do not have SSH access.

  • server access via ssh is possible?

  • ssh works via key? or password only?

  • root account? (a lot of this guide assumes root privileges, I might have missed points there are no alternatives)

  • if not, do you have all necessary account credentials for all folders etc.?


  • if no ssh, do you have ftp credentials?

  • do the credentials actually work?

  • do you get a database dump you can transfer? (If you cannot access the server, you can't make a dump.)

  • are the folder accurately named?

  • how BIG is the webfolder? (so how long will copying take?)

  • which database management system is used? (i.e. mysql or postgres)

  • database credentials for it are?

  • what is the database the site is using actually called?

  • just how BIG is the database? (and so how long will copying take?)

  • what domains are pointing to the server?

  • are these actually active?

  • and can you change the DNS RR?

  • what are the DNS TTL times?

  • is mailing configured?

  • don't forget the DNS MX RR/RR's while at the last point

DNS: aquiring information active resource records

For finding out about the dns, if you have several virtual hosts on the same machine, try grepping them all there.

When having an apache, grep all vhost files for ServerName and ServerAlias. Here's a kind-of snippet, which will work if your apache vhost configs are in default locations and indented:

\grep -e '^\s\+Server' /etc/apache2/sites-enabled/*

This shows only active sites, check sites-available if you have to migrate sites which are currently turned off, too.

The resulting list, if sanitized, can be piped on the shell and used with something like host/nslookup/echo + dig +short, to easily check which domains are still running. Check all the records, not just the A/AAAA (quad-A is ipv4, single-A is ipv4) records, also MX and whatever is set. If the exit code is non-zero, no dns anymore and less work for you. Providing a script here would not help much, since you should know what you are doing here anyway and it would most likely not help you much.

and maybe prepare the webserver, too

In case the apache config is, lets say, 'adventurous', do apache2ctl -S (Debian/Ubuntu) or httpd -S to see which domains are hosted, and in which file these are defined. Then search there for ServerName/ServerAlias directives.

If the webserver happens to have all vhosts defined in one huge file (which ist just... very not great), remove the configuration and place them into a separated file. In Debian-based Linuces you can use a2ensite <vhost-config-filename> / a2dissite <vhost-config-filename> to enable/disable single websites easily. On Redhat-based ones you create the symlinks to the configfolder apache is configured to load manually and delete them also by hand. (This isn't any different from what a2en/dissite do.) All this only for the sites you want to migrate.

Of course, you can just comment out the information on your vhosts from the config, but just... don't.

For other webservers all this is different, of course, but you get the idea.

DNS: get the domains and the website together, information-wise

Refer to the website via its main link. (apache ServerName from above.) But make sure to note all other aliases there, too. (apache ServerAlias from above.) Since you can only migrate one site after another, this helps to keep track. Write all this down, each alias in another row. Maybe put the inactive ones into an extra column there, too. Could be that these should be prolonged again, or were incorrectly set. (I.e. it did not point to the webserver when you checked.)

Write the set TTL into the next column, along with the current date. (Usually TTL is 86400, which means 24 hours, which is exactly how long it will take until your change to 1800 seconds becomes finally active. If the TTL was longer than 86400 for whatever reason, note that into your list, too!)

DNS: lower TTL the day before the migration

After having created a list and checked which domains are currently active, set the default TTL time to 1800. (Just don't go below, 30 mins are short while you do the migration. Also the registrar might prefer you not to.)

DNS: plan b in case you have dozens of websites to migrate

If you have A LOT of websites that should go from one server to the next, try migrating and testing everything (via entries in the hosts file). Then switch the ip's of the servers with each other. That way no dns changes are needed (except if you have dead domains), because this shit can become tedious, too.

TBD / todo

Nothing more here now, until i am motivated again to write more stuff up.

vim: remote editing of files
posted on 2015-04-21 10:24:10

In general, this will do:

vim scp://remoteuser@server.tld//path/to/document


vim scp://

The important part is the double slash after the domain, in case you specify absolute paths.

To not having to fiddle with passwords, create a .netrc file in your home folder containing entries like this one:

machine login yourlogin password "yoursecret"

Some more tricks can be found here, where this is initially from.

If vim tells something about 'buftype' and that it cannot save, issue this command prior to saving from within vim:

:se buftype=
ssh for remote backups
posted on 2015-03-09 12:32:56

To backup a system's file, usually you employ scp. This is fine, as long as you want to backup only regular files.

If you want to backup non-regular files, this won't work and you will need ssh.


tar cvJ <folder> | ssh -T -c blowfish -e none <user>@<host> "cat > /backup.tar."

Here are some hacks contained within:

  1. -T to prevent allocation of a pseudo-terminal so redirection works
  2. -cblowfish to not use 3DES encryption, which is faster
  3. -enone so no escape sequence is used. That way the transfer can not kill the connection if <escapesequence>. is found. (Usually it is this one: ~.)

If this stuff is not done, your transfer may or may not work.

Thanks to Jan Engelhardt of for this gem.

sshd: show ssh logins and fails
posted on 2015-03-05 11:13:00


To show all successful login attempts on a debian-based system:

cat /var/log/secure | grep 'sshd.*opened'

Same for RHEL:

cat /var/log/auth.log | grep 'sshd.*opened'



cat /var/log/auth.log | grep 'sshd.*Invalid'


cat /var/log/secure | grep 'sshd.*Invalid'
fritzbox: install ssh server
posted on 2015-02-22 17:38:27

After having enabled the telnet access to your fritz box, which involves a phone connected to the device and dialing a number as described here, connect to its ip:

connect via telnet

[jl@jerrylee ~]% telnet                                               
Connected to
Escape character is '^]'.

BusyBox v1.20.2 (2014-09-26 13:25:19 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

ermittle die aktuelle TTY
tty is "/dev/pts/0"
Console Ausgaben auf dieses Terminal umgelenkt
disable start/stop characters and flowcontrol

check architecture

Depending on the architecuture of the fritzbox cpu, you need a different binary. Older fritzboxes had mipsel cpu's whereas newer ones have mips ones. You may find this here helpful. Later this check is integrated into the install script, so no real need to bother with it now.

install overview

Several steps are needed, to achieve what is desired: (is automated in next section)

  1. set a root password

  2. copy the hashed password

  3. check cpu architecture

  4. install appropriate dropbear ssh server, depending on the platform


actual installation

From there on, do these steps: (tried to make these foolproof by using absolute paths)

cd /var
chmod 755 /var/cfg_dropbear

In case you wondered what this 'spblinux' distro is, this is what the sourceforge page tells:

    modular mini distribution running completely in RAM
    can be booted from USB
    based on Busybox and Midnight Commander
    optional with DirectFB and (since version 2.1) Mozilla
    it is possible to create/modify own modules inside SPB:Linux.
Krypton Walkthrough
posted on 2015-01-22 03:24:30 is just as much fun as bandit or leviathan, which I covered in earlier posts here or here.


Just go and have a look at the bandit post mentioned above


Here is what I have found by now.

level 0

[root@jerrylee /home/jl]# echo "S1JZUFRPTklTR1JFQVQ=" | base64 -d

This is only locally.

level 1

Here you have to login with 'krypton1'. In case you have already been on the server, you can see this here:

leviathan7@melinda:~$ grep krypton /etc/passwd
krypton1:x:8001:8001:krypton level 1:/home/krypton1:/bin/bash
krypton2:x:8002:8002:krypton level 2:/home/krypton2:/bin/bash
krypton3:x:8003:8003:krypton level 3:/home/krypton3:/bin/bash
krypton4:x:8004:8004:krypton level 4:/home/krypton4:/bin/bash
krypton5:x:8005:8005:krypton level 5:/home/krypton5:/bin/bash
krypton6:x:8006:8006:krypton level 6:/home/krypton6:/bin/bash
krypton7:x:8007:8007:krypton level 7:/home/krypton7:/bin/bash

So, after connecting first lets see where our file is:

krypton1@melinda:~$ find / -iname '*krypton2*' | less

In less, do again the &krypton2 + Enter trick:

& (END)

krypton1@melinda:~$ cat /games/krypton/krypton1/krypton2 | tr 'A-Za-z' 'N-ZA-Mn-za-m' LEVEL TWO PASSWORD ROTTEN ### level 2 krypton2@melinda:~$ ls -lah total 20K
drwxr-xr-x   2 root root 4.0K Nov 14 10:32 .
drwxr-xr-x 167 root root 4.0K Jan 12 17:44 ..
-rw-r--r--   1 root root  220 Apr  9  2014 .bash_logout
-rw-r--r--   1 root root 3.6K Apr  9  2014 .bashrc
-rw-r--r--   1 root root  675 Apr  9  2014 .profile
krypton2@melinda:~$ cd /games/krypton/
krypton2@melinda:/games/krypton$ ls
krypton1  krypton2  krypton3  krypton4  krypton5  krypton6
krypton2@melinda:/games/krypton$ cd krypton2
krypton2@melinda:/games/krypton/krypton2$ ls -lah
total 15K
drwxr-xr-x 2 root     root     1.0K Nov 14 10:32 .
drwxr-xr-x 8 root     root     1.0K Nov 14 10:32 ..
-rw-r----- 1 krypton2 krypton2 1.1K Nov 14 10:32 README
-rwsr-x--- 1 krypton3 krypton2 8.8K Nov 14 10:32 encrypt
-rw-r----- 1 krypton3 krypton3   27 Nov 14 10:32 keyfile.dat
-rw-r----- 1 krypton2 krypton2   13 Nov 14 10:32 krypton3

So far, so nice. But the encrypt file does not work due to file permissions, it seems.

Lets hack up a really, really whacky bash script:


## basically this converts the chars to their ascii code and back
## this is likely not the best solution, but everything else would have been even worse

## first read the file contents into an array
while read -n1 j
    current[$a]=$(LC_CTYPE=C printf '%d ' "'$j")
done < <( cat ./krypton3 )## HERE PROCESS SUBSTITUTION IS NEEDED!

## now iterate over the array we created and increment each item by 1
for i in {1..25}
    echo "OFFSET BY "${i}
    for l in $(seq 1 $((a-1)))
        ## here is the most important part:
        ## since 'A' is 65 in ascii, substract 64
        ## such that 'A' becomes '1', and 'Z' becomes '26'
        ## then increment by one, take the modulo 26
        ## (else you have numbers bigger than 26)
        ## and aftwards add 64, so the ascii conversion can take place again
        ## the 'mod 26' trick works since we assume the pw is written in CAPSLOCK
        current[$l]=$(( $(( $((  $(( current[$l] - 64 )) + 1 )) % 26 )) + 64 ))

    ## now print the current result by iterating again and converting to characters again
    for ((b=0; b<${#current[@]}; b++))
        printf "\x$(printf %x ${current[$b]})"

Uah, this was ugly. I did that just as a proof of concept, use a proper scripting language in case you want to do it yourself. But I disgress.

Lets just use this monster as a one-liner:

krypton2@melinda:/games/krypton/krypton2$ a=0; while read -n1 j; do ((a++)); current[$a]=$(LC_CTYPE=C printf '%d ' "'$j"); done < <( cat ./krypton3 ); for i in {1..25}; do echo "OFFSET BY "${i}; for l in $(seq 1 $((a-1))); do current[$l]=$(( $(( $((  $(( current[$l] - 64 )) + 1 )) % 26 )) + 64 )); done; for ((b=0; b<${#current[@]}; b++)); do printf "\x$(printf %x ${current[$b]})"; done; echo; echo; done

























Looks like offset '14' is our winner:


This would have been quite easier if the encrypter just worked...

level 3

krypton3@melinda:~$ ls -alhF
total 20K
drwxr-xr-x   2 root root 4.0K Nov 14 10:32 ./
drwxr-xr-x 167 root root 4.0K Jan 12 17:44 ../
-rw-r--r--   1 root root  220 Apr  9  2014 .bash_logout
-rw-r--r--   1 root root 3.6K Apr  9  2014 .bashrc
-rw-r--r--   1 root root  675 Apr  9  2014 .profile
krypton3@melinda:~$ cd /games/krypton/krypton
krypton1/ krypton2/ krypton3/ krypton4/ krypton5/ krypton6/
krypton3@melinda:~$ cd /games/krypton/krypton3
krypton3@melinda:/games/krypton/krypton3$ ls -lah
total 12K
drwxr-xr-x 2 root     root     1.0K Nov 14 10:32 .
drwxr-xr-x 8 root     root     1.0K Nov 14 10:32 ..
-rw-r----- 1 krypton3 krypton3   56 Nov 14 10:32 HINT1
-rw-r----- 1 krypton3 krypton3   37 Nov 14 10:32 HINT2
-rw-r----- 1 krypton3 krypton3  785 Nov 14 10:32 README
-rw-r----- 1 krypton3 krypton3 1.6K Nov 14 10:32 found1
-rw-r----- 1 krypton3 krypton3 2.1K Nov 14 10:32 found2
-rw-r----- 1 krypton3 krypton3  560 Nov 14 10:32 found3
-rw-r----- 1 krypton3 krypton3   42 Nov 14 10:32 krypton4

Using the contents of 'found1' to 'found3' with frequency analysis tools found on the web, I can get this: (the last column / line is the frequency in english language from most to fewest)

 s : 155 s : 243 s : 58   |    e
 c : 107 q : 186 q : 48   |    t
 q : 106 j : 158 j : 41   |    a
 j : 102 n : 135 g : 35   |    o
 u : 100 u : 130 c : 34   |    i
 b : 87  b : 129 n : 31   |    n
 g : 81  d : 119 b : 30   |    s
 n : 74  g : 111 u : 27   |    h
 d : 69  c : 86  d : 22   |    r
 z : 57  w : 66  v : 21   |    d
 v : 56  z : 59  z : 16   |    l
 w : 47  v : 53  w : 16   |    c
 y : 42  m : 45  e : 13   |    u
 t : 32  t : 37  m : 12   |    m
 x : 29  e : 34  k : 12   |    w
 m : 29  y : 33  x : 9    |    f
 l : 27  x : 33  y : 9    |    g
 k : 25  k : 30  a : 9    |    y
 a : 20  l : 27  t : 6    |    p
 e : 17  a : 26  l : 6    |    b
 f : 11  i : 14  f : 5    |    v
 o : 7   f : 12  i : 3    |    k
 h : 2   o : 3   o : 2    |    j
 i : 2   h : 2   p : 1    |    x
 r : 1   r : 2   r : 1    |    q
 p : 0   p : 1   h : 0    |    z



Using this on the server:

krypton3@melinda:/games/krypton/krypton3$ cat krypton4 | tr [SCQJUBGNDZVWYTXMLKAEFOHIRP] [ETAOINSHRDLCUMWFGYPBVKJXQZ]
krypton3@melinda:/games/krypton/krypton3$ cat krypton4 | tr [SCQJUBGNDZVWYTXMLKAEFOHIRP] [ETAOINSHRDLCUMWFGYPBVKJXQZ]; echo
krypton3@melinda:/games/krypton/krypton3$ cat krypton4 | tr [SQJNUBDGCWZVMTEYXKLAIFOHRP] [ETAOINSHRDLCUMWFGYPBVKJXQZ]; echo
krypton3@melinda:/games/krypton/krypton3$ cat krypton4 | tr [SQJGCNBUDVZWEMKXYATLFIOPRH] [ETAOINSHRDLCUMWFGYPBVKJXQZ]; echo

Well, this could be better. But by now I lost my motivation, so this stops here. If I will continue, the following steps will be put up here into this post.

Leviathan Walkthrough
posted on 2015-01-22 01:38:57 is just as much fun as bandit, which I covered in eralier post here.


Just go and have a look at the bandit post mentioned above


Here is what I have found by now.

level 0

leviathan0@melinda:~$ ls -alh
total 24K
drwxr-xr-x   3 root       root       4.0K Nov 14 10:32 .
drwxr-xr-x 167 root       root       4.0K Jan 12 17:44 ..
drwxr-x---   2 leviathan1 leviathan0 4.0K Nov 14 10:32 .backup
-rw-r--r--   1 root       root        220 Apr  9  2014 .bash_logout
-rw-r--r--   1 root       root       3.6K Apr  9  2014 .bashrc
-rw-r--r--   1 root       root        675 Apr  9  2014 .profile
leviathan0@melinda:~$ cd .backup/
leviathan0@melinda:~/.backup$ ls -alh
total 140K
drwxr-x--- 2 leviathan1 leviathan0 4.0K Nov 14 10:32 .
drwxr-xr-x 3 root       root       4.0K Nov 14 10:32 ..
-rw-r----- 1 leviathan1 leviathan0 131K Nov 14 10:32 bookmarks.html
leviathan0@melinda:~/.backup$ grep leviathan1 *
<DT><A HREF=" | This will be fixed later, the password for leviathan1 is rioGegei8m" ADD_DATE="1155384634" LAST_CHARSET="ISO-8859-1" ID="rdf:#$2wIU71">password to leviathan1</A>

pw is rioGegei8m, as can be seen in the last line.

level 1

ltrace for tracing libraries is the key here.

leviathan1@melinda:~$ ls -alhF
total 28K
drwxr-xr-x   2 root       root       4.0K Nov 14 10:32 ./
drwxr-xr-x 167 root       root       4.0K Jan 12 17:44 ../
-rw-r--r--   1 root       root        220 Apr  9  2014 .bash_logout
-rw-r--r--   1 root       root       3.6K Apr  9  2014 .bashrc
-rw-r--r--   1 root       root        675 Apr  9  2014 .profile
-r-sr-x---   1 leviathan2 leviathan1 7.4K Nov 14 10:32 check*
leviathan1@melinda:~$ ./check 

Wrong password, Good Bye ...
leviathan1@melinda:~$ ltrace ./check 
__libc_start_main(0x804852d, 1, 0xffffd784, 0x80485f0 <unfinished ...>
printf("password: ")                             = 10
getchar(0x8048680, 47, 0x804a000, 0x8048642password: 
)     = 10
getchar(0x8048680, 47, 0x804a000, 0x8048642
)     = 10
getchar(0x8048680, 47, 0x804a000, 0x8048642
)     = 10
strcmp("\n\n\n", "sex")                          = -1
puts("Wrong password, Good Bye ..."Wrong password, Good Bye ...
)             = 29
+++ exited (status 0) +++
leviathan1@melinda:~$ ./check
password: sex
$ id
uid=12001(leviathan1) gid=12001(leviathan1) euid=12002(leviathan2) groups=12002(leviathan2),12001(leviathan1)
$ cd /                  
$ pwd
$ find . -iname "*leviathan*2*" | less

Then in less, use & to show just lines matching your search content, and type leviathan2 and hit enter, which will give you this:

& (END)


$ cat ./etc/leviathan_pass/leviathan2

level 2


leviathan2@melinda:~$ ls -alh
total 28K
drwxr-xr-x   2 root       root       4.0K Nov 14 10:32 .
drwxr-xr-x 167 root       root       4.0K Jan 12 17:44 ..
-rw-r--r--   1 root       root        220 Apr  9  2014 .bash_logout
-rw-r--r--   1 root       root       3.6K Apr  9  2014 .bashrc
-rw-r--r--   1 root       root        675 Apr  9  2014 .profile
-r-sr-x---   1 leviathan3 leviathan2 7.4K Nov 14 10:32 printfile
leviathan2@melinda:~$ ./printfile 
*** File Printer ***
Usage: ./printfile filename
leviathan2@melinda:~$ mkdir -p /tmp/sjas/
leviathan2@melinda:~$ ln -s /etc/leviathan_pass/leviathan3 /tmp/sjas/lvl2
leviathan2@melinda:~$ ls -alh /tmp/sjas/lvl2 
lrwxrwxrwx 1 leviathan2 leviathan2 30 Jan 22 01:15 /tmp/sjas/lvl2 -> /etc/leviathan_pass/leviathan3
leviathan2@melinda:~$ touch /tmp/sjas/asdf\ lvl2
leviathan2@melinda:~$ ./printfile /tmp/sjas/lvl2\ asdf 
You cant have that file...
leviathan2@melinda:~$ touch /tmp/sjas/lvl2\ asdf
leviathan2@melinda:~$ ./printfile /tmp/sjas/lvl2\ asdf
/bin/cat: asdf: No such file or directory

And we get the password: Ahdiemoo1j

This is a security flaw. But neither strace nor this here...

leviathan2@melinda:~$ ltrace ./printfile /tmp/sjas/lvl2\ asdf
__libc_start_main(0x804852d, 2, 0xffffd754, 0x8048600 <unfinished ...>
access("/tmp/sjas/lvl2 asdf", 4)                 = 0
snprintf("/bin/cat /tmp/sjas/lvl2 asdf", 511, "/bin/cat %s", "/tmp/sjas/lvl2 asdf") = 28
system("/bin/cat /tmp/sjas/lvl2 asdf"/bin/cat: /tmp/sjas/lvl2: Permission denied
/bin/cat: asdf: No such file or directory
 <no return ...>
 --- SIGCHLD (Child exited) ---
 <... system resumed> )                           = 256
 +++ exited (status 0) +++

... helped my understanding much.

By using the space in the filename, this works. If used only the link, it wouldn't work. I cannot tell you more, since I googled this as I wasn't smart enough to figure this out by myself.

See for more info, if you happen to program C.

level 3

 1  leviathan3@melinda:~$ ls -alh
 2  total 28K
 3  drwxr-xr-x   2 root       root       4.0K Nov 14 10:32 .
 4  drwxr-xr-x 167 root       root       4.0K Jan 12 17:44 ..
 5  -rw-r--r--   1 root       root        220 Apr  9  2014 .bash_logout
 6  -rw-r--r--   1 root       root       3.6K Apr  9  2014 .bashrc
 7  -rw-r--r--   1 root       root        675 Apr  9  2014 .profile
 8  -r-sr-x---   1 leviathan4 leviathan3 7.4K Nov 14 10:32 level3
 9  leviathan3@melinda:~$ ./level3 
10  Enter the password> 
11  bzzzzzzzzap. WRONG
12  leviathan3@melinda:~$ ltrace ./level3 
13  __libc_start_main(0x8048450, 1, 0xffffd784, 0x8048600 <unfinished ...>
14  __printf_chk(1, 0x80486ca, 0x804860b, 0xf7fca000) = 20
15  fgets(Enter the password>                
16  "\n", 256, 0xf7fcac20)                     = 0xffffd5bc
17  puts("bzzzzzzzzap. WRONG"bzzzzzzzzap. WRONG
18  )                       = 19
19  +++ exited (status 0) +++
20  leviathan3@melinda:~$ strings ./level3 
21  /lib/
23  _IO_stdin_used
24  __printf_chk
25  puts
26  __stack_chk_fail
27  stdin
28  fgets
29  system
30  __libc_start_main
31  __gmon_start__
32  GLIBC_2.3.4
33  GLIBC_2.4
34  GLIBC_2.0
35  PTRhp
36  QVhP
37  [^_]
38  snlprintf
39  [You've got shell]!
40  /bin/sh
41  bzzzzzzzzap. WRONG
42  Enter the password> 
43  ;*2$",
44  secret
45  leviathan3@melinda:~$ ./level3 
46  Enter the password> snlprintf
47  [You've got shell]!
48  $ id
49  uid=12003(leviathan3) gid=12003(leviathan3) euid=12004(leviathan4) groups=12004(leviathan4),12003(leviathan3)
50  $ cat /etc/leviathan_pass/leviathan4
51  vuH0coox6m

Line 37 should be the if-clause or something, 38 the string to test against. Line 39 and 40 are the branch for true whereas 41 is the branch for false?

So much for some wild guesswork.

level 4

leviathan4@melinda:~$ ls -lahF
total 24K
drwxr-xr-x   3 root root       4.0K Nov 14 10:32 ./
drwxr-xr-x 167 root root       4.0K Jan 12 17:44 ../
-rw-r--r--   1 root root        220 Apr  9  2014 .bash_logout
-rw-r--r--   1 root root       3.6K Apr  9  2014 .bashrc
-rw-r--r--   1 root root        675 Apr  9  2014 .profile
dr-xr-x---   2 root leviathan4 4.0K Nov 14 10:32 .trash/
leviathan4@melinda:~$ cd .trash/
leviathan4@melinda:~/.trash$ ls -lahF
total 16K
dr-xr-x--- 2 root       leviathan4 4.0K Nov 14 10:32 ./
drwxr-xr-x 3 root       root       4.0K Nov 14 10:32 ../
-r-sr-x--- 1 leviathan5 leviathan4 7.3K Nov 14 10:32 bin*
leviathan4@melinda:~/.trash$ ./bin 
01010100 01101001 01110100 01101000 00110100 01100011 01101111 01101011 01100101 01101001 00001010 
leviathan4@melinda:~/.trash$ ltrace ./bin 
__libc_start_main(0x80484cd, 1, 0xffffd754, 0x80485c0 <unfinished ...>
fopen("/etc/leviathan_pass/leviathan5", "r")      = 0
+++ exited (status 255) +++
leviathan4@melinda:~/.trash$ for i in `./bin`; do echo "ibase=2;$i" | bc; done
leviathan4@melinda:~/.trash$ for i in `./bin`; do j=$(echo "ibase=2;$i" | bc); printf "\x$(printf %x $j)"; done

This was some ugly stuff at the end. Once you see the binary values, and converting them to decimals, the numbers look like ascii character numbers. The decoding printf statement is from

level 5

leviathan5@melinda:~$ ls -lahF
total 28K
drwxr-xr-x   2 root       root       4.0K Nov 14 10:32 ./
drwxr-xr-x 167 root       root       4.0K Jan 12 17:44 ../
-rw-r--r--   1 root       root        220 Apr  9  2014 .bash_logout
-rw-r--r--   1 root       root       3.6K Apr  9  2014 .bashrc
-rw-r--r--   1 root       root        675 Apr  9  2014 .profile
-r-sr-x---   1 leviathan6 leviathan5 7.5K Nov 14 10:32 leviathan5*
leviathan5@melinda:~$ ./leviathan5 
Cannot find /tmp/file.log
leviathan5@melinda:~$ ltrace ./leviathan5 
__libc_start_main(0x80485ed, 1, 0xffffd774, 0x8048690 <unfinished ...>
fopen("/tmp/file.log", "r")                      = 0
puts("Cannot find /tmp/file.log"Cannot find /tmp/file.log
)                = 26
exit(-1 <no return ...>
+++ exited (status 255) +++
leviathan5@melinda:~$ ln -s /etc/leviathan_pass/leviathan6 /tmp/file.log
leviathan5@melinda:~$ ./leviathan5 

No explanation here, as this one was rather easy.

level 6

leviathan6@melinda:~$ ls -lahF
total 28K
drwxr-xr-x   2 root       root       4.0K Nov 14 10:32 ./
drwxr-xr-x 167 root       root       4.0K Jan 12 17:44 ../
-rw-r--r--   1 root       root        220 Apr  9  2014 .bash_logout
-rw-r--r--   1 root       root       3.6K Apr  9  2014 .bashrc
-rw-r--r--   1 root       root        675 Apr  9  2014 .profile
-r-sr-x---   1 leviathan7 leviathan6 7.4K Nov 14 10:32 leviathan6*
leviathan6@melinda:~$ ./leviathan6 
usage: ./leviathan6 <4 digit code>
leviathan6@melinda:~$ ltrace ./leviathan6 
__libc_start_main(0x804850d, 1, 0xffffd774, 0x8048590 <unfinished ...>
printf("usage: %s <4 digit code>\n", "./leviathan6"usage: ./leviathan6 <4 digit code>
) = 35
exit(-1 <no return ...>
+++ exited (status 255) +++
leviathan6@melinda:~$ for i in `seq 0000 9999`; do echo $i; ./leviathan6 $i; done

... this takes a while.

$ cat /etc/leviathan_pass/leviathan7

Bruteforcing this with a bash one-liner is the easiest option to find '7123'. Cat the PW file once you have the leviathan7 shell and you are done.

level 7

leviathan7@melinda:~$ ls -lahF
total 24K
drwxr-xr-x   2 root       root       4.0K Nov 14 10:32 ./
drwxr-xr-x 167 root       root       4.0K Jan 12 17:44 ../
-rw-r--r--   1 root       root        220 Apr  9  2014 .bash_logout
-rw-r--r--   1 root       root       3.6K Apr  9  2014 .bashrc
-rw-r--r--   1 root       root        675 Apr  9  2014 .profile
-r--r-----   1 leviathan7 leviathan7  178 Nov 14 10:32 CONGRATULATIONS
leviathan7@melinda:~$ cat CONGRATULATIONS 
Well Done, you seem to have used a *nix system before, now try something more serious.
(Please don't post writeups, solutions or spoilers about the games on the web. Thank you!)


create SSH session via a proxy server
posted on 2014-11-24 00:23:16

If i want to connect from my computer via my workstation at work to another computer, this is how it is done:

ssh -t work_station ssh another_computer

work_station and another_computer in the above example are either IP's or aliases in the ~/.ssh/config file.

If there are more hops in between your destination workstation and your local computer, just add these via -t hop1 -t hop2 etc. into the line above.

Bandit Walkthrough
posted on 2014-08-30 11:39:32 is quite some fun, in case you are a linux user. You might even learn a trick or two along the way.


Helpful may be, to create a ssh host shortcut either in ~/.ssh/config or a DNS shortcut in /etc/hosts for the banditlabs url:

Host asdf

That way you can access the server via ssh <username>@asdf.


These are the solutions I found so far:

level 0

Connect via ssh bandit0@asdf if you made the shortcut like above. Else use ssh

bandit0@melinda:~$ ls
bandit0@melinda:~$ cat readme 

level 1

Now connect via ssh bandit1@asdf if you made the shortcut like above. Else use ssh

bandit1@melinda:~$ ls
bandit1@melinda:~$ cat ./- 

level 2

You should by now know which username to use to connnect to the server for the next level... ;)

bandit2@melinda:~$ ls
spaces in this filename
bandit2@melinda:~$ cat spaces\ in\ this\ filename 

Just use Tab for auto-completion in the shell and avoid typing...

level 3

bandit3@melinda:~$ cd inhere/
bandit3@melinda:~/inhere$ ls -a
.  ..  .hidden
bandit3@melinda:~/inhere$ cat .hidden 

level 4

bandit4@melinda:~$ cd inhere/
bandit4@melinda:~/inhere$ ls
-file00  -file02  -file04  -file06  -file08
-file01  -file03  -file05  -file07  -file09
bandit4@melinda:~/inhere$ file ./*
./-file00: data
./-file01: data
./-file02: Non-ISO extended-ASCII text, with no line terminators
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: Non-ISO extended-ASCII text
bandit4@melinda:~/inhere$ cat ./-file07

level 5

bandit5@melinda:~$ find inhere/ -size 1033c \! -executable
bandit5@melinda:~$ cat inhere/maybehere07/.file2

level 6

bandit6@melinda:~$ find / -user bandit7 -group bandit6 -size 33c 2>/dev/null
bandit6@melinda:~$ cat /var/lib/dpkg/info/bandit7.password 

level 7

bandit7@melinda:~$ grep millionth data.txt 
millionth   cvX2JJa4CFALtqS87jk27qwqGhBM9plV

level 8

bandit8@melinda:~$ cat data.txt | sort | uniq -u

level 9

bandit9@melinda:~$ strings data.txt | grep ^=
========== the
========== is
========== truKLdjsbJ5g7yyJ2X2R0o3a5HQJFuLk
bandit9@melinda:~$ strings data.txt | grep ==
========== the
,========== passwordc
========== is
========== truKLdjsbJ5g7yyJ2X2R0o3a5HQJFuLk

level 10

bandit10@melinda:~$ base64 -d data.txt 
The password is IFukwKGsFW8MOq3IRFqrxE1hxTNEbUPR

level 11

bandit11@melinda:~$ cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m'          
The password is 5Te8Y4drgCRfCx8ugdwuEX8KFC6k2EUu

level 12

This is a longer one... I inserted extra newlines for better readability this time.

bandit12@melinda:~$ l

bandit12@melinda:~$ mkdir /tmp/sjas/ && cp data.txt /tmp/sjas

bandit12@melinda:~$ cd /tmp/sjas

bandit12@melinda:/tmp/sjas$ l

bandit12@melinda:/tmp/sjas$ cat data.txt 
0000000: 1f8b 0808 d095 b051 0203 6461 7461 322e  .......Q..data2.
0000010: 6269 6e00 013a 02c5 fd42 5a68 3931 4159  bin..:...BZh91AY
0000020: 2653 5915 d9db 2800 0017 7fff ff5d f6ea  &SY...(......]..
0000030: e98b bff6 ff7f ffbf fce3 f7fa a3fb badb  ................
0000040: f3e9 f873 b7ff fcff cffb 7bff b001 3b35  ...s......{...;5
0000050: b080 d000 0000 0000 1ea0 f534 3400 0d00  ...........44...
0000060: d1a1 a1a1 a006 8680 0006 9ea0 6868 68f4  ............hhh.
0000070: 81b5 0d34 d0c2 0d0d 3d13 47a4 cd44 01a1  ...4....=.G..D..
0000080: a007 a801 a000 d1a0 d00d 0034 0640 1ea3  ...........4.@..
0000090: 4c99 0000 d034 d1b5 3201 a0d1 a06d 4003  L....4..2....m@.
00000a0: d403 351a 00f4 2347 a801 9348 1a7a 8034  ..5...#G...H.z.4
00000b0: d340 0000 0006 690d 0000 0340 0d3d 46d1  .@....i....@.=F.
00000c0: 341a 7a86 8190 1a1a 1a34 347a 8d00 001a  4.z......44z....
00000d0: 6468 d006 8001 0403 0081 e752 1ca1 324a  dh.........R..2J
00000e0: 2d8d 2082 b927 606a 8dc4 4407 d0eb 1428  -. ..'`j..D....(
00000f0: 8782 7c75 29f4 19d4 3b6a 1f7e 147f 5636  ..|u)...;j.~..V6
0000100: 0183 4dbf 9a5d 968c 7340 d299 dd22 3024  ..M..]..s@..."0$
0000110: 8ecc 1ffe 92b3 101b ca86 20bd 47f2 7958  .......... .G.yX
0000120: 7d40 d62a 1dc8 8697 d109 66ae 1549 39df  }@.*......f..I9.
0000130: 95e2 2dad 4990 b250 9a0b f842 0ade e4fb  ..-.I..P...B....
0000140: 2717 ba73 0a60 9048 c4db 851b db3c 0e4d  '..s.`.H.....<.M
0000150: 9d04 a542 3d98 a411 65b8 116f 0710 19e3  ...B=...e..o....
0000160: 210a 11d4 b9bc 5227 c02e f8ac fab6 f541  !.....R'.......A
0000170: f934 9619 a951 6654 8482 4fd2 9ce7 af09  .4...QfT..O.....
0000180: 0ed5 e29c 3482 e515 3882 07b5 8a2b 02e7  ....4...8....+..
0000190: 5357 2cd5 c071 3d10 546c d9e2 aa49 a75c  SW,..q=.Tl...I.\
00001a0: 2ada f467 469d 4464 c20e f8f0 17d3 271d  *..gF.Dd......'.
00001b0: e3c6 ac3a 9f96 d17f 897c 04bf c445 d6bc  ...:.....|...E..
00001c0: a706 16b0 34bf 2f1b 3419 9eea 5d5a f7c0  ....4./.4...]Z..
00001d0: 1ce4 5477 832b 2258 6b29 55ec 2155 2e66  ..Tw.+"Xk)U.!U.f
00001e0: 2ad1 81d1 edd0 22fe 0f6c 9172 b0d2 3b93  *....."..l.r..;.
00001f0: 42b3 079e 8013 c6ef 1425 82fe a53b 1898  B........%...;..
0000200: c9b5 2111 5c53 eb19 6142 a8b6 480a a8eb  ..!.\S..aB..H...
0000210: 439e b18f 9269 890e dcec da54 614c 4eba  C....i.....TaLN.
0000220: fe8c 5c10 6586 1321 680b 9896 fdee b1d5  ..\.e..!h.......
0000230: 8e68 d49a 11d4 868d 7e82 3238 4e13 dd44  .h......~.28N..D
0000240: 9ad4 0081 b138 f17f e2ee 48a7 0a12 02bb  .....8....H.....
0000250: 3b65 0018 d921 743a 0200 00              ;e...!t:...

bandit12@melinda:/tmp/sjas$ file data.txt 
data.txt: ASCII text

bandit12@melinda:/tmp/sjas$ xxd -r data.txt data1

bandit12@melinda:/tmp/sjas$ file data1
data1: gzip compressed data, was "data2.bin", from Unix, last modified: Thu Jun  6 13:59:44 2013, max compression

bandit12@melinda:/tmp/sjas$ mv data1 data1.gz

bandit12@melinda:/tmp/sjas$ gzip -d data1.gz 

bandit12@melinda:/tmp/sjas$ l
data.txt  data1

bandit12@melinda:/tmp/sjas$ mv data1 data2.bin

bandit12@melinda:/tmp/sjas$ file data2.bin 
data2.bin: bzip2 compressed data, block size = 900k

bandit12@melinda:/tmp/sjas$ bzip2 -d data2.bin
bzip2: Can't guess original name for data2.bin -- using data2.bin.out

bandit12@melinda:/tmp/sjas$ l
data.txt  data2.bin.out

bandit12@melinda:/tmp/sjas$ file data2.bin.out 
data2.bin.out: gzip compressed data, was "data4.bin", from Unix, last modified: Thu Jun  6 13:59:43 2013, max compression

bandit12@melinda:/tmp/sjas$ gzip -d -S .out data2.bin.out 

bandit12@melinda:/tmp/sjas$ l
data.txt  data2.bin

bandit12@melinda:/tmp/sjas$ file data2.bin. 
data2.bin.: POSIX tar archive (GNU)

bandit12@melinda:/tmp/sjas$ tar -xvf data2.bin 

bandit12@melinda:/tmp/sjas$ l
data.txt  data2.bin  data5.bin

bandit12@melinda:/tmp/sjas$ file data5.bin 
data5.bin: POSIX tar archive (GNU)

bandit12@melinda:/tmp/sjas$ tar -xvf data5.bin 

bandit12@melinda:/tmp/sjas$ file data6.bin 
data6.bin: bzip2 compressed data, block size = 900k

bandit12@melinda:/tmp/sjas$ bzip2 -d data6.bin
bzip2: Can't guess original name for data6.bin -- using data6.bin.out

bandit12@melinda:/tmp/sjas$ file data6.bin.out     
data6.bin.out: POSIX tar archive (GNU)

bandit12@melinda:/tmp/sjas$ tar xf data6.bin.out 

bandit12@melinda:/tmp/sjas$ l
data.txt  data2.bin  data5.bin  data6.bin.out  data8.bin

bandit12@melinda:/tmp/sjas$ file data8.bin 
data8.bin: gzip compressed data, was "data9.bin", from Unix, last modified: Thu Jun  6 13:59:43 2013, max compression

bandit12@melinda:/tmp/sjas$ gzip -d -S .bin data8.bin

bandit12@melinda:/tmp/sjas$ l
data.txt  data2.bin  data5.bin  data6.bin.out  data8

bandit12@melinda:/tmp/sjas$ file data8 
data8: ASCII text

bandit12@melinda:/tmp/sjas$ cat data8 
The password is 8ZjyCRiBWFYkneahHwxCv3wb2a1ORpYL

Finally it's over...

level 13

This time all the console output is shown:

I connect to host asdf as I made the aforementioned shortcut in ~/.ssh/config.

[sjas@beckett /tmp]% ssh bandit13@asdf                                         

This is the OverTheWire game server. More information on

Please note that wargame usernames are no longer level<X>, but wargamename<X>
e.g. vortex4, semtex2, ...

Note: at this moment, blacksun and drifter are not available.'s password: 
Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.15.4-x86_64-linode45 x86_64)

 * Documentation:

Welcome to the OverTheWire games machine !

Please read /README.txt for more information on how to play the levels
on this gameserver.

  System information disabled due to load higher than 8.0

11 packages can be updated.
8 updates are security updates.

New release '14.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

*** System restart required ***

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

bandit13@melinda:~$ l
bandit13@melinda:~$ logout
Connection to closed.
[sjas@beckett /tmp]% scp bandit13@asdf:sshkey.private .                        

This is the OverTheWire game server. More information on

Please note that wargame usernames are no longer level<X>, but wargamename<X>
e.g. vortex4, semtex2, ...

Note: at this moment, blacksun and drifter are not available.'s password: 
sshkey.private                                100% 1679     1.6KB/s   00:00    
[sjas@beckett /tmp]%

All here is to do is to download the ssh private key to your local machine. I moved it to /tmp since I will not need anymore after the levels. It this were different, I'd have placed it into my ~/.ssh folder.

level 14

Now the private key from level 13 is to be put to use. The next levels are to be passed on the server, connected as bandit14, anyway.

The pass the keyfile to ssh, use -i, if it should not use ~/.ssh/id_rsa or ~/.ssh/id_dsa

Also the complete output is shown here.

[sjas@beckett /tmp]% ssh -i /tmp/sshkey.private bandit14@asdf                  

This is the OverTheWire game server. More information on

Please note that wargame usernames are no longer level<X>, but wargamename<X>
e.g. vortex4, semtex2, ...

Note: at this moment, blacksun and drifter are not available.

Permissions 0640 for '/tmp/sshkey.private' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /tmp/sshkey.private's password: 

[sjas@beckett /tmp]% chmod 600 /tmp/sshkey.private                             
[sjas@beckett /tmp]% ssh -i /tmp/sshkey.private bandit14@asdf                  

This is the OverTheWire game server. More information on

Please note that wargame usernames are no longer level<X>, but wargamename<X>
e.g. vortex4, semtex2, ...

Note: at this moment, blacksun and drifter are not available.

Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.15.4-x86_64-linode45 x86_64)

 * Documentation:

Welcome to the OverTheWire games machine !

Please read /README.txt for more information on how to play the levels
on this gameserver.

System information disabled due to load higher than 8.0

11 packages can be updated.
8 updates are security updates.

New release '14.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

*** System restart required ***

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

bandit14@melinda:~$ cat /etc/bandit_pass/bandit14

chmod is used to fix permissions that were off. ssh expects RW access to the key only being possible by the owner, no other rights.

level 15

localhost? On my own computer?

[sjas@beckett /tmp]% telnet localhost 30000                                    
telnet: connect to address Connection refused

Not so. How on the remote server?

[sjas@beckett /tmp]% telnet 9000                   

Won't work from a remote server, most likely due to firewall rules. So Ctrl-C for ending the connection try and retry from on the server:

[sjas@beckett /tmp]% ssh -i /tmp/sshkey.private bandit14@asdf                   

bandit14@melinda:~$ telnet localhost 30000
Connected to localhost.
Escape character is '^]'.

Connection closed by foreign host.

nc (netcat) works, too:

bandit14@melinda:~$ nc localhost 30000


level 16

First try:

bandit14@melinda:~$ openssl s_client -connect localhost:30001
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1
Certificate chain
 0 s:/CN=localhost
Server certificate
No client certificate CA names sent
SSL handshake has read 1272 bytes and written 363 bytes
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
    Protocol  : SSLv3
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 162F69EE481BEE8FF1AC7CCBA304284F7C7A6AF9C35743D0272D285514D8226D
    Master-Key: 6CDD3BC45858C00FF59DD8E0C872AC96769EAC33574BD56590AA0B0A32C1DA309F32FF8C38B10AB6AFD58D44AF3CB767
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1409415184
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
read R BLOCK

Ok, lets give the manpage a try? (man s_client)

       If a connection is established with an SSL server then any data
       received from the server is displayed and any key presses will be sent
       to the server. When used interactively (which means neither -quiet nor
       -ign_eof have been given), the session will be renegotiated if the line
       begins with an R, and if the line begins with a Q or if end of file is
       reached, the connection will be closed down.

Awww, lets just try -quiet...

bandit14@melinda:~$ openssl s_client -connect localhost:30001 -quiet
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1



level 17

First lets do a simple portscan:

bandit14@melinda:~$ nmap -PN localhost

Starting Nmap 5.21 ( ) at 2014-08-30 16:28 UTC
Nmap scan report for localhost (
Host is up (0.0011s latency).
Not shown: 994 closed ports
22/tcp    open  ssh
80/tcp    open  http
113/tcp   open  auth
443/tcp   open  https
3306/tcp  open  mysql
30000/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 0.30 seconds

Bummer. But that's due to nmap only scanning the first 30000 ports. See:

bandit14@melinda:~$ nmap -p 30000-32000 localhost

Starting Nmap 5.21 ( ) at 2014-08-30 16:41 UTC
Nmap scan report for localhost (
Host is up (0.00086s latency).
Not shown: 1994 closed ports
30000/tcp open  unknown
30001/tcp open  unknown
31046/tcp open  unknown
31518/tcp open  unknown
31691/tcp open  unknown
31790/tcp open  unknown
31960/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 0.54 seconds

30001 wasn't shown in the first scan.

Since we know the port is between 31000 and 32000, so it's one of these:

  • 31046
  • 31518
  • 31691
  • 31790
  • 31960

This can be programmatically tried by nmap, too, but I am an amateur, so I will try them by hand. It's just that five ports.

bandit14@melinda:~$ openssl s_client -quiet -connect localhost:31046
140737354065568:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:749:

bandit14@melinda:~$ openssl s_client -quiet -connect localhost:31518
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1

bandit14@melinda:~$ openssl s_client -quiet -connect localhost:31691 
140737354065568:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:749:
bandit14@melinda:~$ openssl s_client -quiet -connect localhost:31790
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1


Well, this looks like ssh privatekey? :)

For fun the last port:

bandit14@melinda:~$ openssl s_client -quiet -connect localhost:31960
140737354065568:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:749:

By the way:
-PN flag used in the first scan is for skipping the host discovery stage. Use it, if you know for sure that the host is up.

level 18

The desctiption was a bit off, since there was no password. 'Just' a private key.

Anyway, copy the content of the private key and put it into a new key file.

I created a new file in /tmp/newkey. Opened it in my editor of choice (vim), pasted everything between the delimiters into it:


    and the garbage between 
         included, too


... and save it.

If you have a microsoft-based operating system and fuck up the line endings due to copy paste, you're to blame (CRLF instead of just LF.).

If all was done accordingly, it will work as can be seen here. Of course, I forgot chmod 600 on the keyfile once again.

[sjas@beckett /tmp]% ssh -i /tmp/newkey bandit17@asdf                          

This is the OverTheWire game server. More information on

Please note that wargame usernames are no longer level<X>, but wargamename<X>
e.g. vortex4, semtex2, ...

Note: at this moment, blacksun and drifter are not available.

Permissions 0664 for '/tmp/newkey' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /tmp/newkey's password: 

[sjas@beckett /tmp]% chmod 600 newkey                                          
[sjas@beckett /tmp]% ssh -i /tmp/newkey bandit17@asdf

. (this time I omitted the servers welcome message........)


After having this out of the way, there are options to solve this:

diff wasn't mentioned, but is the easiest by far:

bandit17@melinda:~$ diff passwords.old 
< PRjrhDcANrVM6em57fPnFp4Tcq8gvwzK
> kfBf3eYk5BPBRzwjqutbbfE887SVc5Yd

It shows the differences between two files.

42c42 tells, line 42 in the first file got changed to line 42 in the second file, and thus is the new password.

Another solution:

bandit17@melinda:~$ TEMP=`cat`; for i in $TEMP; do grep $i passwords.old > /dev/null; if [ $? -ne 0 ]; then echo $i; fi; done

Explaining this, because there's helpful stuff in there:

 1      TEMP=`cat`
 2      for i in $TEMP
 3      do 
 4          grep $i passwords.old > /dev/null
 5          if [ $? -ne 0 ]
 6          then 
 7              echo $i
 8          fi
 9      done
  1. assign the new variable TEMP the contents of ''
  2. for loop, index i, running through contents of temp
  3. start of body of for loop
  4. grep for finding matches. exit code 0 if yes, exit code 1 if no match found. The grep output was streamed to /dev/null, because the output is of no importance to us.
  5. if clause, checking if no match was found. $? returns return code of last command that was run. -ne is 'not equal'.
  6. start of if body
  7. echo the currently tested string, which is our winner
  8. return to escape the loop as soon as we found our match
  9. end of if body
  10. end of body of for loop

level 19

Execute the cat from your localhost to run on the server and return the results. To do so simply append the command you want to the ssh call.

[sjas@beckett /tmp]% ssh bandit18@asdf cat readme                              

This is the OverTheWire game server. More information on

Please note that wargame usernames are no longer level<X>, but wargamename<X>
e.g. vortex4, semtex2, ...

Note: at this moment, blacksun and drifter are not available.'s password: 

level 20

bandit19@melinda:~$ ll /etc/bandit_pass/
total 108
drwxr-xr-x   2 root     root     4096 Jun 27  2013 ./
drwxr-xr-x 109 root     root     4096 Aug 30 10:57 ../
-r--------   1 bandit0  bandit0     8 Jun  6  2013 bandit0
-r--------   1 bandit1  bandit1    33 Jun  6  2013 bandit1
-r--------   1 bandit10 bandit10   33 Jun  6  2013 bandit10
-r--------   1 bandit11 bandit11   33 Jun  6  2013 bandit11
-r--------   1 bandit12 bandit12   33 Jun  6  2013 bandit12
-r--------   1 bandit13 bandit13   33 Jun  6  2013 bandit13
-r--------   1 bandit14 bandit14   33 Jun  6  2013 bandit14
-r--------   1 bandit15 bandit15   33 Jun 27  2013 bandit15
-r--------   1 bandit16 bandit16   33 Jun  6  2013 bandit16
-r--------   1 bandit17 bandit17   33 Jun  6  2013 bandit17
-r--------   1 bandit18 bandit18   33 Jun  6  2013 bandit18
-r--------   1 bandit19 bandit19   33 Jun  6  2013 bandit19
-r--------   1 bandit2  bandit2    33 Jun  6  2013 bandit2
-r--------   1 bandit20 bandit20   33 Jun  6  2013 bandit20
-r--------   1 bandit21 bandit21   33 Jun  6  2013 bandit21
-r--------   1 bandit22 bandit22   33 Jun  6  2013 bandit22
-r--------   1 bandit23 bandit23   33 Jun  6  2013 bandit23
-r--------   1 bandit24 bandit24   33 Jun  6  2013 bandit24
-r--------   1 bandit3  bandit3    33 Jun  6  2013 bandit3
-r--------   1 bandit4  bandit4    33 Jun  6  2013 bandit4
-r--------   1 bandit5  bandit5    33 Jun  6  2013 bandit5
-r--------   1 bandit6  bandit6    33 Jun  6  2013 bandit6
-r--------   1 bandit7  bandit7    33 Jun  6  2013 bandit7
-r--------   1 bandit8  bandit8    33 Jun  6  2013 bandit8
-r--------   1 bandit9  bandit9    33 Jun  6  2013 bandit9

Since we need the pass for bandit20...

bandit19@melinda:~$ ls -ln /etc/bandit_pass/bandit20 
-r-------- 1 11020 11020 33 Jun  6  2013 /etc/bandit_pass/bandit20

but really only bandit20 can read it.

So what's up with the binary?

bandit19@melinda:~$ whoami
bandit19@melinda:~$ id
uid=11019(bandit19) gid=11019(bandit19) groups=11019(bandit19)
bandit19@melinda:~$ ./bandit20-do whoami
bandit19@melinda:~$ ./bandit20-do id    
uid=11019(bandit19) gid=11019(bandit19) euid=11020(bandit20) groups=11020(bandit20),11019(bandit19)

Niiice. And so...

bandit19@melinda:~$ ./bandit20-do cat /etc/bandit_pass/bandit20 

level 21

For this one, you have to open two shells, with which you connect to the server:

On the first one, open a netcat server on a free port. (ss -a, to look up which ports are in use, nc -l <port> to run it.)

On the second shell, connect with the SUID binary to the netcatserver. (./suconnect <port used before with netcat>)

Once connected, send the password from the last level from the server (via first shell).

FIRST SHELL: (there arrives the new pw!)

bandit20@melinda:~$ nc -l 54545


bandit20@melinda:~$ ./suconnect 54545
Read: GbKksEFF4yrVs6il55v6gwY5aVje5f0j
Password matches, sending next password

Et voila.

level 22

First lets see what cronjobs are defined in /etc/cron.d. For better readability, I let the filename be printed in yellow.

bandit21@melinda:/etc/cron.d$ for i in *; do echo $'\e[1;33m'$i$'\e[0m'; cat $i; done
@reboot root /vulnbot/ start boobiesbot
# Regular cron jobs for the cron-apt package
# Every night at 4 o'clock.
0 4 * * *   root    test -x /usr/sbin/cron-apt && /usr/sbin/cron-apt
# Every hour.
# 0 *   * * *   root    test -x /usr/sbin/cron-apt && /usr/sbin/cron-apt /etc/cron-apt/config2
# Every five minutes.
# */5 * * * *   root    test -x /usr/sbin/cron-apt && /usr/sbin/cron-apt /etc/cron-apt/config2
* * * * * bandit22 /usr/bin/ &> /dev/null
* * * * * bandit23 /usr/bin/  &> /dev/null
* * * * * bandit24 /usr/bin/ &> /dev/null
@reboot eloi0 /eloi/eloi0/
@reboot eloi1 /eloi/eloi1/
@reboot root /vulnbot/ start hintbot
cat: manpage3_resetpw_job: Permission denied
*/30 * * * * root /root/scripts/
* * * * * root /root/scripts/
*/30 * * * * root /root/scripts/
cat: natas25_cleanup: Permission denied
cat: natas26_cleanup: Permission denied
# /etc/cron.d/php5: crontab fragment for php5
#  This purges session files older than X, where X is defined in seconds
#  as the largest value of session.gc_maxlifetime from all your php.ini
#  files, or 24 minutes if not defined.  See /usr/lib/php5/maxlifetime

# Look for and purge old sessions every 30 minutes
09,39 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete
@reboot root /semtex/semtex0 24000 /semtex/semtex0.data32
@reboot root /semtex/semtex0 24001 /semtex/semtex0.data64
@reboot root /semtex/semtex0 24002 /semtex/semtex0.datappc
@reboot root /semtex/semtex10 24019
@reboot root /semtex/semtex12.authd 24012 /semtex/
@reboot root /semtex/semtex12.reader 24013 /semtex/
@reboot root /semtex/semtex5 24027
@reboot root /semtex/semtex6
@reboot root /semtex/semtex8 /semtex/ /semtex/
@reboot root /semtex/semtex9.fshell /semtex/
@reboot root /semtex/semtex9.i2t -f /semtex/
# The first element of the path is a directory where the debian-sa1
# script is located

# Activity reports every 10 minutes everyday
5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1

# Additional run at 23:59 to rotate the statistics file
59 23 * * * root command -v debian-sa1 > /dev/null && debian-sa1 60 2
@reboot root /vortex/vortex0
@reboot root /vortex/vortex20
# @reboot root /vulnbot/ start vulnbot0
# @reboot root /vulnbot/ start vulnbot1

Looks like cronjob_bandit22 is the way to go.

bandit21@melinda:/etc/cron.d$ cat cronjob_bandit22 
* * * * * bandit22 /usr/bin/ &> /dev/null

Now we know which script gets executed every minute. (* * * * *)

bandit21@melinda:/etc/cron.d$ cat /usr/bin/ 
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv

Well, lets check the rights and the content of these files from the script...

bandit21@melinda:/etc/cron.d$ ll /etc/bandit_pass/bandit22
-r-------- 1 bandit22 bandit22 33 Jun  6  2013 /etc/bandit_pass/bandit22

No luck, no read access for us.

bandit21@melinda:/etc/cron.d$ ll /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
-rw-r--r-- 1 bandit22 bandit22 33 Aug 30 19:32 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv

But here...

bandit21@melinda:/etc/cron.d$ cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv

level 23

bandit22@melinda:~$ cd /etc/cron.d
bandit22@melinda:/etc/cron.d$ ll
total 128
drwxr-xr-x   2 root root 4096 Jul 22 13:40 ./
drwxr-xr-x 109 root root 4096 Aug 30 10:57 ../
-rw-r--r--   1 root root  102 Apr  2  2012 .placeholder
-rw-r--r--   1 root root   52 Oct 22  2013 boobiesbot-check
-rw-r--r--   1 root root  355 Nov 18  2011 cron-apt
-rw-r--r--   1 root root   61 Jun  6  2013 cronjob_bandit22
-rw-r--r--   1 root root   62 Jun  6  2013 cronjob_bandit23
-rw-r--r--   1 root root   61 Jun  6  2013 cronjob_bandit24
-rw-r--r--   1 root root   35 Jun  6  2013 eloi0
-rw-r--r--   1 root root   35 Jun  6  2013 eloi1
-rw-r--r--   1 root root   49 Jul  3 14:13 hintbot-check
-rw-------   1 root root  233 Jun  6  2013 manpage3_resetpw_job
-rw-r--r--   1 root root   51 Jul 12 15:57 melinda-stats
-rw-r--r--   1 root root   54 Sep 30  2013 natas-session-toucher
-rw-r--r--   1 root root   49 Sep 30  2013 natas-stats
-r--r-----   1 root root   47 Sep 30  2013 natas25_cleanup
-r--r-----   1 root root   45 Jul 22 13:40 natas26_cleanup
-rw-r--r--   1 root root  544 Mar 11  2013 php5
-rw-r--r--   1 root root   58 Jun  6  2013 semtex0-32
-rw-r--r--   1 root root   58 Jun  6  2013 semtex0-64
-rw-r--r--   1 root root   59 Jun  6  2013 semtex0-ppc
-rw-r--r--   1 root root   36 Jun  6  2013 semtex10
-rw-r--r--   1 root root  143 Jun  6  2013 semtex12
-rw-r--r--   1 root root   35 Jun  6  2013 semtex5
-rw-r--r--   1 root root   29 Jun  6  2013 semtex6
-rw-r--r--   1 root root   96 Jun  6  2013 semtex8
-rw-r--r--   1 root root  134 Jun  6  2013 semtex9
-rw-r--r--   1 root root  396 Dec 16  2011 sysstat
-rw-r--r--   1 root root   29 Jun  6  2013 vortex0
-rw-r--r--   1 root root   30 Jul  2  2013 vortex20
-rw-r--r--   1 root root   52 Jul  3 13:41 vulnbot0-check
-rw-r--r--   1 root root   52 Jul  3 13:41 vulnbot1-check
bandit22@melinda:/etc/cron.d$ cat cronjob_bandit23
* * * * * bandit23 /usr/bin/  &> /dev/null

Oh, another cronjob running every minute.

bandit22@melinda:/etc/cron.d$ ll /usr/bin/ 
-rwxr-x--- 1 bandit23 bandit22 211 Jun  6  2013 /usr/bin/*

Running a script, for which our group just happens to have execute permission, too.

bandit22@melinda:/etc/cron.d$ cat /usr/bin/ 

mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)

echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"

cat /etc/bandit_pass/$myname > /tmp/$mytarget

And the script just further happens to copy something into /tmp, again. Granting read permissions to everyone in the process.

This tells us different things.

  • We can run the script ourselves. But this won't help us.
  • The path where the file is stored lies under /tmp and the filename is generated.
  • If we knew the filename, we'd have the pw.

So let's do the line with the filename creation by hand:

bandit22@melinda:/etc/cron.d$ echo I am user bandit23 | md5sum | cut -d' ' -f1

Which is the filename. Since i am not overly into copy-typing:

bandit22@melinda:/etc/cron.d$ cat /tmp/`echo I am user bandit23 | md5sum | cut -d' ' -f1`

level 24

level 25

This one is not prepared yet. It's over for now.

/ \
SSH debugging
posted on 2014-08-26 16:40:50

When debugging SSH connections, or rather their connection establishment mishaps, check the logs:





Usually this does suffice. If not, increase the Log Level in /etc/ssh/sshd_config.

ssh tricks links
posted on 2014-07-31 11:30:59

Really nice articles and comments:

SSH multiplexing
posted on 2014-07-27 11:59:57

SSH creates a new connection, upon each new session you are trying to establish. Every time time the SSH handshake has to be repeated.

Wait, what?

Ok again: If you want to connect to another server with four terminals simultaneously, you will establish four SSH connections. Why not reuse the connection for all sessions, so the handshake becomes obsolete?

SSH provides this:
A control master connection is created, which will in turn be used by the other session initiations. (The latter are not control masters, of course.)

Easy, add this to your ~/.ssh/config:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/conn-%u-%r@%h:%p
    ControlPersist 600

And it will be enabled for all the connections you make (Host *). Also there is no need to specify session/connection type (auto).

The path to the control socket can be freely specified via the ControlPath directive, too.

%u = local user
%r = remote user
%h = remote host
%p = port

600 are 600 seconds, for which timespan the master connections stays open without getting any input.

To spot the difference:

[sjas@beckett ~/.ssh]% time ssh date
Sun Jul 27 01:02:01 CEST 2014
ssh date  0.16s user 0.03s system 14% cpu 1.282 total
[sjas@beckett ~/.ssh]% time ssh date
Sun Jul 27 01:02:05 CEST 2014
ssh date  0.02s user 0.01s system 14% cpu 0.204 total
[sjas@beckett ~/.ssh]% time ssh date
Sun Jul 27 01:02:06 CEST 2014
ssh date  0.01s user 0.02s system 14% cpu 0.217 total
[sjas@beckett ~/.ssh]%

See how the time to run the complete command (date on the remote machine via ssh, measured by time) decreases?

From 0.16s to 0.01s/0.02s, it will stay like that. (As long as the socket is kept open.) It feels just so much nicer.

Cygwin sshd
posted on 2014-07-06 18:31:27

To set up ssh access on a windows box via cygwin, do yourself a favor and read the oracle docs:

VirtualBox SSH access
posted on 2014-07-05 19:08:08

When using virtual machines with VirtualBox, it can be helpful to have proper SSH access configured.

Theory up front

Virtualbox networking modes and Host Adapters

Since most people have trouble figuring this one out on themselves, some basics before, in case you do not just use 'NAT Mode'.

'Bridge Mode' of virtual box maps the physical NIC (network interface card) of your host OS (operating system) to the VNIC / virtual networking interface card / virtual adapter of your VM (virtual machine). That way all traffic is passed from extern to the VM directly, transparently to to the host OS. It will not have to fiddle with any packets flowing between VM and the/an internet.

'Host-only Mode' works on an IF (interface) of the host OS, similarily to the loopback device which is used by linux in case you have network-based application (i.e. TCP/IP based) running locally, on the localhost. The loopback interface sports the famous address but it can have any one from the subnet, which spans up to actually. Also you can have several loopback interfaces, in case you want to run several webservers locally and all on port 80. (I just made that example up from the top of my head, to provide a more plastic explanation, but I disgress.) The virtualbox Host-only adapter works similar in that, that virtualbox will use the virtual adapter to transfer all traffic among the vm's through this adapter.

There can be quite a bit more said, but just head over to the VirtualBox Manual and do the reading yourself, I am about to becoming lazy as this post grows quite a bit longer than I ever intented it to.

Virtual NIC's of the VM

This are the actual network cards being present in your virtual system.

To have internet as well as communication between host and guest (or among guests), you have to setup a two NIC's. To have two NIC's, you have to enable those in the settings of your VM, that is what the 'Adapter 1' to 'Adapter 4' tabs in the Network settings of the VM in question are for.

Short answer, if you do not have a NIC, you cannot assign ip's to it.

Of course, in the real world you can set several ip addresses on one NIC. Although I have not tried this, I doubt it to work since the VNIC's that virtualbox provides are different to each other, depending on the mode which they are set to I bet.

Actual IP configuration of the guest

Once the VNIC is enabled for your VM (which is like you just built in a physicalNIC into your desktop), you can configure it so linux will know about it.

So first you have to create a new entry in the networking config, followed by an ip configuration you make.

This should have you covered on the basics (so you got at least a small idea what you are actually doing next.), hopefully this will serve you good.

Without more words, easiest the ssh setup is done like this:

Setup VirtualBox

  1. Open the settings page of the VM in question from within virtualbox.
  2. Menupoint Network >> Tab Adapter 2.
  3. Checkbox Enable Network Adapter to create a new virtual Network Interface Card (NIC).
  4. Set 'Attached to:' to Host-only Adapter. The name of the adapter is not of interest, there just has to exist a vbox specific one already. If this is not the case, go to your virtualbox preferences (the ones of the hypervisor, not the ones of the individual vm's), choose "Network" in the left frame and then the tab "Host-only Networks". Add a network and edit the newly created adapter if you need a specific ip network or DHCP.
  5. Start the VM, and open a shell.
  6. $ ip addr and hit enter.
  7. Maybe you already have an ip then, otherwise you will have to set up networking with the ip network that is used in the vbox adapter in step 4. The one is a likely network, in case you did not change the default settings in step 4.
  8. Depending on if you have a RHEL-based distro in use (RHEL, CentOS, Fedora, ...), or Debian-based (Ubuntu, Debian), this step varies.

Setup guest VM, possibility one: static networking (recommended)


Open /etc/sysconfig/network-scripts/ifcfg-eth1 (Or whatever IF you looked up in step 6.) with root privileges and add the following code:


Fix IPADDR and DEVICE to the values in step 6.


Open /etc/network/interfaces as root and change/add this:

allow-hotplug eth1
iface eth1 inet static

As with the RHEL part, fix IF and IP accordingly, if these differ in step 6.

Setup guest VM, possibility two: dynamic networking (not recommended)

After you have set the additional NIC in your guest OS as described below, run ifup eth to activate the new interface and do dhclient eth1 afterwards to get an ip address from the dhcp server.


Open /etc/sysconfig/network-scripts/ifcfg-eth1 (Or whatever IF you looked up in step 6.) with root privileges and add the following code:



Open /etc/network/interfaces as root and change/add this:

allow-hotplug eth1
iface eth1 inet dhcp


For easiest usage, add a shorthand on your host OS into your ssh config. (/home/<username>/.ssh/config) If the file does not exist, create it.

Add this:

Host vbox
    User root #change this to the user as which you want to login
    StrictHostKeyChecking no

Which will make it possible to connect like this from your host OS:

$ ssh vbox

The strict hostkey check was turned off since you certainly know the machine you are connecting to and do not care when you use another vm with the same setting. (Which has very likely a different hostname.)

Of course, this step happens to be of little use if you use just DHCP ip's. Static network adresses are preferred as they will stay the same and you will not have to fix the config if you use several hosts and ip's get mixed up.

Editing remote files in local vim
posted on 2014-05-14 14:39:09

If you have a highly configured vim that you hold dearly and love to bits, and you have to edit a lot of remote files, try vim-over-ssh. scp is used to transfer files, and there is a slight delay, but it does work awesome.


vim scp://<user>@<host>//<path/to/file>

Note the double slashes // after the hostname. These are used so the absolute path to your file can be specified.

ssh key forwarding
posted on 2014-04-28 18:26:53

To enable ssh key forwarding on startup, use these in .bashrc or .zshrc:

eval $(ssh-agent|grep -v echo)
ssh-add > /dev/null

This has supressed output, and will work next time you login a new shell.

Further you have to have set these in your ssh config.

# Mind the indentation!
Host *
    ForwardAgent yes
    StrictHostkeyChecking no

    # if you want, try these
    User root
    VisualHostkeyChecking yes

User root is the user that will be used, if the username is omitted with the ssh command, and you do not want to use the current user on your machine. VisualHostkeyChecking shows the graphical fingerprint of the machine you are connecting to.

On Linux, for system-wide changes these go into /etc/ssh_config. If you just want to change for a specific user, just change the /home/<username>/.ssh/config file.

User specific changes on windows go into C:\Users\<username>\.ssh\config IIRC.

scp properly explained
posted on 2013-11-16 17:05:03

scp is handy when transferring files from one host to another while being in a shell. How else to transfer stuff without using FTP or a kind of version control? Of course there are other alternatives, but scp's advantage is that it is widely available, does not need any kind of setup on the other host (As long as you have access to your other box, that is.) and has encrypted traffic. Also no GUI, mounting of USB sticks etc. pp. is needed. Sounds great.

The syntax looks like this, higlevel:


Or lower level and a little more concrete:

scp <src-user>@<src-host>:/dir/file <dst-user>@<dst-host>:/dir/file

src is shorthand for 'source', dst for 'destination', in case you wondered. Of course there are flags and parameter settings that can be used. But using man scp yourself is not rocket science. :o)

To specify working scp calls it is helpful to properly understand the user@host:file syntax. If your current use case is to copy a file from the host you are currently on, user@src-host can be omitted. Just the filename (and its path if you are not in the same directory on the shell) is needed. user is the username of the system user on the machine in question. This is the user with which you'd log into the remote machine. If passwords are needed, the system will promt you to enter them.

If you have setup SSH keys properly, and are in the same folder as the file you want to transfer, a call could look like this:

scp example.txt <dst-host>:

<dst-host> is either a valid IP or a domain name pointing to the IP.

Here are several things omitted:

  1. The <src-user>, the user on the machine you are currently logged on, and <src-host>, the address of the current host you are on.
  2. The file path and file name at the destination.

So the file will be put in the homefolder of the user that is used on the remote machine. (This is the folder entry of the user entry, to look it up use grep <username> /etc/passwd on the remote machine, in case it is not /home/<username>.)

The colon in the example above MUST NOT be omitted.

Else nothing will be copied to the remote address. You will not an error message, since linux thinks the destination address you specified is a file name, and the file is copied locally.

If you want to specify a certain folder on the remote host, either use the full path, or specify it in relation to the users home directory.


## file on server will be '/home/sjas/.ssh/asdf.txt'
scp file.txt 123.123.123:.ssh/asdf.txt

## file on server will be '/tmp/file.txt'
scp file.txt

So long. Maybe as a last note that there is the -r flag, so you can copy whole directories and not just files.

This blog covers .csv, .htaccess, .pfx, .vmx, /etc/crypttab, /etc/network/interfaces, /etc/sudoers, /proc, 10.04, 14.04, AS, ASA, ControlPanel, DS1054Z, GPT, HWR, Hyper-V, IPSEC, KVM, LSI, LVM, LXC, MBR, MTU, MegaCli, PHP, PKI, R, RAID, S.M.A.R.T., SNMP, SSD, SSL, TLS, TRIM, VEEAM, VMware, VServer, VirtualBox, Virtuozzo, XenServer, acpi, adaptec, algorithm, ansible, apache, apachebench, apple, arcconf, arch, architecture, areca, arping, asa, asdm, awk, backup, bandit, bar, bash, benchmarking, binding, bitrate, blackarmor, blowfish, bochs, bond, bonding, booknotes, bootable, bsd, btrfs, buffer, c-states, cache, caching, ccl, centos, certificate, certtool, cgdisk, cheatsheet, chrome, chroot, cisco, clamav, cli, clp, clush, cluster, coleslaw, colorscheme, common lisp, console, container, containers, controller, cron, cryptsetup, csync2, cu, cups, cygwin, d-states, database, date, db2, dcfldd, dcim, dd, debian, debug, debugger, debugging, decimal, desktop, df, dhclient, dhcp, diff, dig, display manager, dm-crypt, dmesg, dmidecode, dns, docker, dos, drivers, dtrace, dtrace4linux, du, dynamictracing, e2fsck, eBPF, ebook, efi, egrep, emacs, encoding, env, error, ess, esx, esxcli, esxi, ethtool, evil, expect, exportfs, factory reset, factory_reset, factoryreset, fail2ban, fbsd, fedora, file, filesystem, find, fio, firewall, firmware, fish, flashrom, forensics, free, freebsd, freedos, fritzbox, fsck, fstrim, ftp, ftps, g-states, gentoo, ghostscript, git, git-filter-branch, github, gitolite, gnutls, gradle, grep, grml, grub, grub2, guacamole, hardware, haskell, hdd, hdparm, hellowor, hex, hexdump, history, howto, htop, htpasswd, http, httpd, https, i3, icmp, ifenslave, iftop, iis, imagemagick, imap, imaps, init, innoDB, inodes, intel, ioncube, ios, iostat, ip, iperf, iphone, ipmi, ipmitool, iproute2, ipsec, iptables, ipv6, irc, irssi, iw, iwconfig, iwlist, iwlwifi, jailbreak, jails, java, javascript, javaws, js, juniper, junit, kali, kde, kemp, kernel, keyremap, kill, kpartx, krypton, lacp, lamp, languages, ldap, ldapsearch, less, leviathan, liero, lightning, links, linux, linuxin3months, lisp, list, livedisk, lmctfy, loadbalancing, locale, log, logrotate, looback, loopback, losetup, lsblk, lsi, lsof, lsusb, lsyncd, luks, lvextend, lvm, lvm2, lvreduce, lxc, lxde, macbook, macro, magento, mailclient, mailing, mailq, manpages, markdown, mbr, mdadm, megacli, micro sd, microsoft, minicom, mkfs, mktemp, mod_pagespeed, mod_proxy, modbus, modprobe, mount, mouse, movement, mpstat, multitasking, myISAM, mysql, mysql 5.7, mysql workbench, mysqlcheck, mysqldump, nagios, nas, nat, nc, netfilter, networking, nfs, nginx, nmap, nocaps, nodejs, numberingsystem, numbers, od, onyx, opcode-cache, openVZ, openlierox, openssl, openvpn, openvswitch, openwrt, oracle linux, org-mode, os, oscilloscope, overview, parallel, parameter expansion, parted, partitioning, passwd, patch, pdf, performance, pfsense, php, php7, phpmyadmin, pi, pidgin, pidstat, pins, pkill, plesk, plugin, posix, postfix, postfixadmin, postgres, postgresql, poudriere, powershell, preview, profiling, prompt, proxmox, ps, puppet, pv, pvecm, pvresize, python, qemu, qemu-img, qm, qmrestore, quicklisp, r, racktables, raid, raspberry pi, raspberrypi, raspbian, rbpi, rdp, redhat, redirect, registry, requirements, resize2fs, rewrite, rewrites, rhel, rigol, roccat, routing, rs0485, rs232, rsync, s-states, s_client, samba, sar, sata, sbcl, scite, scp, screen, scripting, seafile, seagate, security, sed, serial, serial port, setup, sftp, sg300, shell, shopware, shortcuts, showmount, signals, slattach, slip, slow-query-log, smbclient, snmpget, snmpwalk, software RAID, software raid, softwareraid, sophos, spacemacs, spam, specification, speedport, spi, sqlite, squid, ssd, ssh, ssh-add, sshd, ssl, stats, storage, strace, stronswan, su, submodules, subzone, sudo, sudoers, sup, swaks, swap, switch, switching, synaptics, synergy, sysfs, systemd, systemtap, tar, tcpdump, tcsh, tee, telnet, terminal, terminator, testdisk, testing, throughput, tmux, todo, tomcat, top, tput, trafficshaping, ttl, tuning, tunnel, tunneling, typo3, uboot, ubuntu, ubuntu 16.04, udev, uefi, ulimit, uname, unetbootin, unit testing, upstart, uptime, usb, usbstick, utf8, utm, utm 220, ux305, vcs, vgchange, vim, vimdiff, virtualbox, virtualization, visual studio code, vlan, vmstat, vmware, vnc, vncviewer, voltage, vpn, vsphere, vzdump, w, w701, wakeonlan, wargames, web, webdav, weechat, wget, whois, wicd, wifi, windowmanager, windows, wine, wireshark, wpa, wpa_passphrase, wpa_supplicant, x2x, xfce, xfreerdp, xmodem, xterm, xxd, yum, zones, zsh

View posts from 2017-02, 2017-01, 2016-12, 2016-11, 2016-10, 2016-09, 2016-08, 2016-07, 2016-06, 2016-05, 2016-04, 2016-03, 2016-02, 2016-01, 2015-12, 2015-11, 2015-10, 2015-09, 2015-08, 2015-07, 2015-06, 2015-05, 2015-04, 2015-03, 2015-02, 2015-01, 2014-12, 2014-11, 2014-10, 2014-09, 2014-08, 2014-07, 2014-06, 2014-05, 2014-04, 2014-03, 2014-01, 2013-12, 2013-11, 2013-10

Unless otherwise credited all material Creative Commons License by sjas