How to automatically send a notification through email when someone logs in through SSH to server

Wow, that was a pretty log title.
I have been working a bit on setting upp vulnerable servers to play CTF with some friends. So I wanted to have a system where the server emails me every time someone successfully logs in to the server.

It requires two steps.
1. Setting up email on the server
2. Writing script that sends email upon SSH-login

Setting up email on the server

Email is sent through the Simple Mail Transfer Protocol. To make use of this protocal we need the program Simple SMTP(sSMTP).
In order to send an email directly from the server you need a domain-name. But I don’t have time for that, so instead I am going to relay the email through an account at gmail.com. From what I have seen online, this seems to be the most common solution for small projects like this.

So let’s download and install ssmtp.

sudo apt-get update
sudo apt-get install ssmtp

After we have installed ssmtp we need to do a bit of configuration.

sudo vim /etc/ssmtp/ssmtp.conf
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
#root=postmaster
root=myEmailAddress@gmail.com

# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named mail.domain.com
#mailhub=mail
mailhub=smtp.gmail.com:587

AuthUser=myEmailAddress@gmail.com
AuthPass=MyGmailPassword
UseTLS=YES
UseSTARTTLS=YES

# Where will the mail seem to come from?
#rewriteDomain=
rewriteDomain=gmail.com

# The full hostname
#hostname=MyMediaServer.home
hostname=localhost

# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=YES

Wow easy-peasy, now let’s send an email.

ssmtp myEmailAddress@gmail.com
To: blabla@gmail.com
From: myEmailAddress@gmail.com
Subject: Test
#ctr-d to send

Of course, that didn’t work.
So i checked the log-file: cat /var/log/mail.log
Where I found this error:
Mar 31 17:13:25 ctf sSMTP[19275]: Authorization failed (534 5.7.14 https://support.google.com/mail/answer/78754 j8sm4704154qhj.19 – gsmtp)

So I started googeling it, and this answer lead me to this answer from google. That answer led me to this page: https://g.co/allowaccess, which lets you allow access from other apps.

And now it is working.

Okay. So now any user on the server can read the config file (/etc/ssmtp/ssmtp.conf). Which includes out password, so that it not optimal. So let’s set the file permission so that only root can read the file.

chmod 700 /etc/ssmtp/ssmtp.conf

Now you can check to see if other users can read the file or not.

#Granted that you are root
su userName
cat /etc/ssmtp/ssmtp.conf
#should output: cat: /etc/ssmtp/ssmtp.conf: Permission denied

There are many other email clients out there. Mailx, mutt and sendmail are some.

Check hos is loggin in

So how do we know if someone has logged in through ssh to out server?

My initial though was to parse the ssh-logfile and then run a cron-job that would check it every 10 minutes or so. But after some googleing I soon discovered that there is a much better way to solve the problem. This SO-answer provided a great solution.

First we create the bash-script and put it in /etc/ssh/login-notify.sh. This script is pretty straight-forward. We set the sender and recipient in each variable. And then we have an if-statement that returns true if anything except close_session happens. And then we use mailx to send the email.

#!/bin/sh

# Change these two lines:
sender="sender-address@example.com"
recipient="notify-address@example.org"

if [ "$PAM_TYPE" != "close_session" ]; then
    host="`hostname`"
    subject="SSH Login: $PAM_USER from $PAM_RHOST on $host"
    # Message to send, e.g. the current environment variables.
    message="`env`"
    echo "$message" | mailx -r "$sender" -s "$subject" "$recipient"
fi

Then we need to make it executable:

chmod +x /etc/ssh/login-notify.sh

You then add the following line the file: /etc/pam.d/sshd

#/etc/pam.d/sshd
session optional pam_exec.so seteuid /etc/ssh/login-notify.sh

Notice that is says:

# SELinux needs to be the first session rule.  This ensures that any
# lingering context has been cleared.  Without this it is possible that a
# module could execute code in the wrong domain.

So it is probably a good idead to add the above code after this paragraph.

So, who the hell is PAM? Well, PAM stands for Pluggable Authentifacion Modules, and is basically the program in charge of stuff that regards authentication. If we check:

ls /etc/pam.d

These are the config-files for the programs that uses pam. chsh, cron, newuser, passwd, login, sshd, and some others. Here you can really configure these programs down to details. For more about PAM check out this excellent resource.

Fundamental git commands

View changes in a file

To view changes in a file in git you just use the command:

git diff path/to/file.js

It happens that whitespace is showed. Which shows almost everything as changed. To solve this, add the -b flag.

git diff -b path/to/file

Discard changes in an unstaged file

Every now and then Git shows that I have edited a file, but when I run git diff I can see that I have added and removed the same line. I think this happens if I add a line and then remove it. So basically nothing has changed (and I haven’t actually edited the file, just opened it). I think it is better to discard the h2>changes to that the commit does not get cluttered with files that we actually haven’t modified. So in order to discard the changes from git I use the following command:

git checkout -- app/config/rest.js

This is the recommended command from git, and it shows when we run git status.

Create new branch

There are two ways.

#Create a branch
git branch nameOfBranch
#Create a branch and switch to it
git checkout -b nameOfBranch

Remove branch

If the branch is merged you can use the command:

git branch -d myBranch

If it is not merged you have to use:

git branch -D myBranch

Remove remote branch

git push origin --delete the_remote_branch

Switch branch without committing

So if you have made some changes in a branch and then switch branch without committing the changes git will automatically merge those branches. Which might not be what you want. But you might not feel ready to commit the changes.
So how do you switch branch without having to merge the branches and without having to commit the changes?
The answer is: stash.
So, let’s say you have made changes that you haven’t committed or added but want to switch branch. You just use the following command:

//Branch: testBranch
git stash
git checkout master
//Make some changes or whatever you wanted to do
git checkout testBranch
git stash pop

And now you are back and can keep working on your branch.

Check out this for a better understanding of how to use git stash:
https://git-scm.com/book/en/v2/Git-Tools-Stashing-and-Cleaning

Create a new remote branch

So let’s say that you have a master-branch and you want to create a development-branch.

First you create your branch locally

git checkout -b development

Then you push it to your remote repo

git push -u origin development

View commit log

So let’s say you have made some commits. And then you want to see what those commits were. You can’t run

git diff

. So instead you can run

git log -p

This will show you the difference in each commit.

Install Burp Suite on Ubuntu 14.04

Burp Suite is a program that contains many features related to web security. It contains a proxy server that let’s the user intercept and manipulate communication between the client/browser and the server. It lets the user manipulate data before it is sent to the server. It also contains a lot of other features.

In order to get Burp Suite up and running on Ubuntu 14.04 (and probably other Ubuntu-versions as well) we first need to make sure we have Java-installed. You can check that by running the following command in the terminal:

java -version

Your terminal should respond with the version, for example:
java version “1.7.0_95”
If you don’t have java installed make sure to install it. Here is a guide.
Okay, now go ahead and download Burp SUite from the Portswiggers website.
Once it is downloaded you just move it to wherever you want to have it.
I had to change the file permission in order to execute it as a normal user.

chmod +x burpsuite_free_v1.6.32.jar
./burpsuite_free_v1.6.32.jar

Configure with Chrome

In order to get burp suite to act as a proxy you need to configure your web browser, to pass all traffic through burp. In Firefox I think this is done through some settings in the browser, but Chrome picks up the settings from the computer itself. If you, in Chrome, go to Preferences/Advanced Settings/Network/Change Proxy Settings you will receive this note:

“When running Google Chrome under a supported desktop environment, the system proxy settings will be used. However, either your system is not supported or there was a problem launching your system configuration.

But you can still configure via the command line. Please see man google-chrome-stable for more information on flags and environment variables.”

So, in order to get the proxy set up correctly we have to open up System Settings, it can be done through the Unity Dash or with the command:

unity-control-center

In System Settings we open up Network, then we choose manual and add for HTTP Proxy 127.0.0.1, with port 8080.

Now you can go ahead and launch Burp Suite. Then click on Proxy and make sure that Intercept is on. Now you can visit any http-website. You will notice that the page will not load. That means that burp suite is working as it should, and that it has intercepted the http-request. Now we can change whatever parameters in the http-header that we want to change. And when you are done you just click Forward. If you don’t want to intercept the traffic any more you just turn intercept off.

This is far from a perfect solution, but it works. But in order to use your browser without Burp Suite you have to turn off the Proxy in the System Settings/network.

Configure with HTTPS

At the moment you are only able to intercept http-traffic. But these days less and less websites run without ssl. So let’s configure Burp Suite to be able to intercept https traffic.
First go to System Settings/Network/Network Proxy/Manual there you add: 127.0.0.1 with port 8080 at the HTTPS-Proxy field.
Now open Burp Suite and go to Proxy and turn intercept on. Now go visit https://portswigger.net. You will now get an error message saying that the traffic is not secure. That is because Chrome knows that Burp is intercepting the traffic and it gives you a warning. For us it is no big deal because we know what is provoking it, but if you get that while you are surfing at a café or on some other open network you should assume that someone is monitoring your traffic.
Anyways, click on the little lock next to the cross-over HTTPS. Click on Certificate information, and then export the certificate so some place on your computer.
Now open up Preferences in Chrome and then scroll down to advanced settings, there you will find HTTPS/SSL Manage Exceptions. Click on it and the click on Authorities, then import. Then you just import the certificate and you are done.
Now Burp Suite should work on HTTPS-web pages.

Running it on localhost

So, you want to try out Burp on a project that you are working on on your local computer. Burp does not initially work on localhost (your Internal IP-address). But that is easy to fix.
You just have to add it to your hosts file.
On ubuntu that means you have to do the following:

#Get your internal ip-address:
ifconfig
#Edit your hosts-file
sudo vim /etc/hosts
#Now you add your internal ip and give it a name.
192.168.1.123    myprojekt.dev

You can name it whatever you like. Remember that you have to have a tab between the ip and name. It cannot be spaces.
Now you just go to myprojekt.dev in your browser. If you are running it on a specific port just add the port in the browser, not in the hosts-file (because that won’t work). So just go to: myprojekt.dev:8080 (or whatever port you use).

C – variables, data-types and format-characters

Okay, so let’s talk a bit about data-types in C. Coming from JavaScript this might be a bit confusing. In JavaScript you have few data-types (in comparison with C), six primitiv data-types: Null, Undefined, String, Number, Booleon, Symbol, and the data-type Object. JavaScript is a loosely-typed or dynamic language. This means that you don’t have to define what type of data a variable will be.

For example, all of these data-types are different, but we just define them as variables, without specifying which types.

var text = "I am a string";
var digit = 42;
var float = 4.2;

But in C that does not work.

So why do we need to define what type of variable/data-type we are going to use? Because that specifies the amount of space used in the storage, and how the bit-pattern is interpreted. So different data-types occupy different amount of storage. The minimum amount of memory we can manage in C is 1 byte.

Here are the different fundamental data-types and the space they take up (taken from here):

Character types
char – 1 byte – -128 to 127 or 0 to 255
unsigned char – 1 byte – 0 to 255
signed char – 1 byte – -128 to 127

Integer types
int – 2 or 4 bytes – -32,768 to 32,767 or -2,147,483,648 to 2,147,483,647
unsigned int – 2 or 4 bytes – 0 to 65,535 or 0 to 4,294,967,295
short – 2 bytes – -32,768 to 32,767
unsigned short – 2 bytes – 0 to 65,535
long – 4 bytes – -2,147,483,648 to 2,147,483,647
unsigned long – 4 bytes – 0 to 4,294,967,295

Float types
float – 4 byte – 1.2E-38 to 3.4E+38 – 6 decimal places
double – 8 byte – 2.3E-308 to 1.7E+308 – 15 decimal places
Because doubles take up double the space, 8 byte we can fit in more decimals in it.
long double – 10 byte – 3.4E-4932 to 1.1E+4932 – 19 decimal places

Well, that is a bit complicated. A better way to understand it to understand the following as basic variables:
int – integer.
float – decimal number.
double – more precise decimal number.
char – a single character.
void – valueless special purpose type.

These basic variables can be defined more precisely using size qualifiers, sign qualifiers or const qualifier.

The size qualifier alters the size of the variable by using the keywords long and short. The int variable is 2-4 bytes, but if long is used with it the size becomes 4-8 bytes.
int == 2-4 bytes
short int == 2 bytes
long int == 4-8 bytes

Sign qualifiers define if a variable can hold positive or negative values.
unsigned int;
Can only hold 0 or positive values.
A variable is by default signed. So that is not needed to add.

Const qualifier
A const keywords makes a variable constant, so that it can not be changed.

It’s interesting to note here that C does not have the concept of strings. Just characters. A string in C is just an array of characters.
But in order to find out the size of a data-type or a variable you can use the built-in sizeof-function. Here is an example:

#include <stdio.h>
#include <limits.h>

int main(){
  int test = 8;
  printf("Storage-size of a an int: %zu \n", sizeof(test));
  return 0;
}

So, the format to create variables in C is the following:
type name = value;

#include <stdio.h>

int main(){
  // This is an integer
  // Format character: %d as in digit
  int age = 10;
  printf("This is the integer: %d\n", age);

  // This is a floating point
  // Format character: %f as in float
  float floating_point = 10.33;
  printf("This is the decimal_number %f\n", floating_point);

  // This is also a floating point, but much bigger.
  // Format character: also %f as in float
  double kinda_big_number = 44444.333233;
  printf("This is a big floating point: %f\n", kinda_big_number);

  // This is a character
  // Format character: %c as in character
  // Notice that a single character is written with only single-quotation-marks
  char one_character = 'H';
  printf("This is one character: %c\n", one_character);

  // This is a string
  // Format character: %s as in string
  char several_characters[] = "hello world";
  printf("This is a string: %s\n", several_characters);
  return 0;
}

Compile and run a C program

I have been programming in JavaScript now for a while, and I feel like it would be useful to learn a second language. One that is a bit closer to the machine, to learn a bit more about the computer. So I have settled on C.

C was developed in by Dennis Richie between 1969 and 1973, while he was working at AT&T Bell Labs. It was designed to be a general-purpose, high-level language that provide low-level access to memory. C is great because it produces efficient and fast programs. It can handle low-level activities, and do it almost as fast as assembly code. The language was developed closely together with the operating system Unix, and Unix was written in C. And it can be compiled on many different platforms. Linux OS, MySQL and NodeJS are some of the programs written in C. It is also the root of many other languages. Example of languages that have borrow from C are: C++, D, Go, Rust, Java, JavaScript, Limbo, LPC, C#, Objective-C, Perl, PHP, Python, Verilog.

Okay, so C seems like a useful language to learn. Let’s get started.
The first thing we need to know is that in order to run C-code we first need to compile it. That mean we translate the code to an executable file, so that the computer understands it, and is able to run it. This basically mean that we translate the code to machine-code (assembly-code is basically the human-readable representation of machine-code) to be able to talk directly to the CPU. JavaScript is sometimes categorized as a interpreted language, but when used with for example Googles V8 Engine (that powers Node and Chrome) the JS-code is compiled straight to machine-code on the spot. It uses Just-in-time Compilation. The difference between V8 and Rheno (the mozilla JS-compiler) is that V8 does not produce any intermediate code, or bytecode. For more on the V8 click here. Okay, so that was bit of a detour. Let’s get back on track.

Unlike JavaScript that is run in Node we have quite a few different options on which compiler we want to to use to compile our C-code.

I am going to use the

make

program in linux. Make is a program that uses the GCC compiler. Even though the text CC pops up when you compile with make, CC usually points to GCC (Gnu compilation collection).

Anyways, let’s get started to write and compile our first program.

hello-world.c

#include &amp;lt;stdio.h&amp;gt;
int main()
{
    printf(&amp;quot;hello, world\n&amp;quot;);
    getchar();
    return 0;
}

Okej, so we got the standard “hello world”-program written. Now it is time to compile and run it.
In the dir where you have your hello-world.c-file run the command:

make hello-world

Notice that we don’t include the .c ending.
You will now have an executable know as hello-world, it can be run with the following command:

./hello-world

Let’s look at the code.
First we do an #include. This is basically the same as a require in Node. We import the functions from the stdio.h module/library. stdio stands for Standard Input Output. So yeah, we gain access to the printf- (output), and getchar-function (input). This code is usually called preprocessor command.
The int main creates the main function, and we are saying that it will return an integer, hence the int. Every c-program includes a main function. The operating system that runs the program will first look for the main-function, and start there. So all other functions will derive from main.

printf is the standard print-function that prints to the console, and getchar takes input from the user through the console. In the end we return with 0. 0 mean success.

There is not that much new stuff coming from JS. We write the function code inside of curly-brackets, and we end with semi-colon. A major difference between JS and C here is that it is easy to break the C-code, just omit the semi-colon and it will throw an error, and it will not be able to compile, and you will not be able to execute your program.