Installing Consul Server on CentOS

A simple guide to deploying Consul Agent in Server mode on CentOS 7:
Consulcentos

Syntax: Any values in []’s should be replaced and the []’s not included.

First let’s do a yum update and grab a couple of extra packages!

yum -y update
yum -y install unzip wget

Next let’s download and unpack Consul and Consul Web UI (this will download 0.6.4, I recommend you check the Consul site for updated versions).

mkdir /tmp/bin
cd /tmp/bin
wget https://releases.hashicorp.com/consul/0.6.4/consul_0.6.4_linux_amd64.zip
wget https://releases.hashicorp.com/consul/0.6.4/consul_0.6.4_web_ui.zip
unzip consul_0.6.4_web_ui.zip
unzip consul_0.6.4_linux_amd64.zip
rm *.zip

Move Consul binaries and UI to appropriate folders and create config directories. Note I create both bootstrap and server config directories, the server config will be used in normal operation whilst the bootstrap will be used incase of cluster failure.

mkdir /var/consul
mkdir -p /home/consul/www
mkdir -p /etc/consul.d/{server,bootstrap}
mv consul /usr/local/bin/
mv index.html /home/consul/www/
mv static/ /home/consul/www/

Create startup config files:

touch /etc/consul.d/bootstrap/config.json /etc/consul.d/server/config.json

Server config.json example:

{
    "advertise_addr": "[SERVER IP]",
    "bind_addr": "[SERVER IP]",
    "domain": "[DOMAIN NAME]",
    "bootstrap_expect": 3,
    "server": true,
    "datacenter": "[DATACENTRE ID]",
    "data_dir": "/var/consul",
    "encrypt": "ENCRYPT KEY",
    "dns_config": {
        "allow_stale": true,
        "max_stale": "15s"
    },
    "retry_join": [
        "[LIST OF OTHER CONSUL SERVER IP's]",
        "[LIST OF OTHER CONSUL SERVER IP's]"
    ],
    "retry_interval": "10s",
    "retry_max": 100,
    "skip_leave_on_interrupt": true,
    "leave_on_terminate": false,
    "ports": {
        "dns": 53,
        "http": 80
    },
    "recursor": "[IP FOR FORWARD DNS LOOKUPS]",
    "ui_dir": "/home/consul/www",
    "rejoin_after_leave": true,
    "addresses": {
        "http": "0.0.0.0",
        "dns": "0.0.0.0"
    }
}

Bootstrap config.json example:

{
    "bootstrap": true,
    "server": true,
    "datacenter": "[DATACENTRE ID]",
    "data_dir": "/var/consul",
    "encrypt": "[ENCRYPT KEY]",
    "skip_leave_on_interrupt": true,
    "leave_on_terminate": false,
    "advertise_addr": "[SERVER IP]",
    "bind_addr": "[SERVER IP]",
    "domain": "[DOMAIN NAME]"

}

Configure consul agent to run as a service.

nano /etc/systemd/system/consul.service

[Unit]
Description=consul agent
Requires=network-online.target
After=network-online.target

[Service]
EnvironmentFile=-/etc/sysconfig/consul
Environment=GOMAXPROCS=2
Restart=on-failure
ExecStart=/usr/local/bin/consul agent -config-dir=/etc/consul.d/server -rejoin
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target

Start Service

systemctl start consul.service
systemctl enable consul

That’s it Consul agent is running in server mode. You should repeat the above process to build each server in your consul cluster, a minimum of 3 servers is recommenced for quorum, 5 is better.

Once you’ve built all your server nodes confirm Consul cluster status:

# consul members
Node             Address           Status  Type    Build  Protocol  DC
consul01   192.168.0.1:8301        alive   server  0.6.4  2         DCA
consul02   192.168.0.2:8301        alive   server  0.6.4  2         DCA
consul03   192.168.0.3:8301        alive   server  0.6.4  2         DCA

Let’s check the service status through the WebUI too:
consul
 
 
 
 
 
 
 
 
 
 
 
 
Looks good, let’s try DNS resolution with dig:

# dig consul.service.adambonny.com.

; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.3 <<>> consul.service.adambonny.com.
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42047
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;consul.service.adambonny.com. IN    A

;; ANSWER SECTION:
consul.service.adambonny.com. 0 IN   A       192.168.0.2
consul.service.adambonny.com. 0 IN   A       192.168.0.1
consul.service.adambonny.com. 0 IN   A       192.168.0.3

;; Query time: 1 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)

As you can see the consul service resolves to 3 A records one for each of our servers.

Hopefully your Consul cluster is working as expected too! Next we'll take a look at installing a Consul Client complete with a new service.

Cheers.

Automated ESXi service restarts using Plink

I needed to restart the ESXi management services each night for a few weeks and didn’t fancy logging in myself. Turns out you can do this easily using Plink.

Grab a copy from here. Then simply setup a scheduled task to run Plink using the following options:

plink.exe [ESXi Hostname] -batch -ssh -l [username] -pw [password] "services.sh restart"

This will cause Plink to open an SSH session to the ESXi host and execute the services.sh restart command.

Cheers!

How to Identify an Unknown Hash

Hash Identifier logoContinuing the theme of hashes lets look at how we can use the “Hash Identifier” tool to determine which algorithm was used to generate a hash.

You can download the tool from here, you’ll also need Python which you can get from here.

Test Hashes:

The plan is to pass the following four hashes through HashID to see how accurate its suggestions are. The test hashes have been generated using four separate algorithms which are revealed in the results.

62163b3694fff97209c48ccc195e04f9e40fff1893fad83275739ba394003dfc
e0734de7a4e8bdb219f3d4935a1c64cc
0ed43e25f742ee0c49d33f9c519fb164ce14866497c3e414c8d95b5ac23525dd54566565bd77f7c3dcf22ad19020092
e209583a1dba302441c9abe5ea6eac6b8
$H$9x8cOSfMfr202yHvWuU/oKdJcBSrLM1

Running Hash Identifier:

Running HashID gives the following prompt:

Hash ID

Let’s paste in the hashes and see what suggestions we get:

-------------------------------------------------------------------------
 HASH: 62163b3694fff97209c48ccc195e04f9e40fff1893fad83275739ba394003dfc

Possible Hashs:
[+] SHA-256
[+] Haval-256
-------------------------------------------------------------------------
HASH: e0734de7a4e8bdb219f3d4935a1c64cc

Possible Hashs:
[+] MD5
[+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username)))
-------------------------------------------------------------------------
HASH: 0ed43e25f742ee0c49d33f9c519fb164ce14866497c3e414c8d95b5ac23525dd54566565b
d77f7c3dcf22ad19020092e209583a1dba302441c9abe5ea6eac6b8

Possible Hashs:
[+] SHA-512
[+] Whirlpool
------------------------------------------------------------------------- 
HASH: $H$9x8cOSfMfr202yHvWuU/oKdJcBSrLM1 

Possible Hashs: 
[+] MD5(phpBB3)

Results:

Hash: 62163b3694fff97209c48ccc195e04f9e40fff1893fad83275739ba394003dfc
HashID Suggestions: SHA-256 or Haval-256
Algoritum Used: SHA-256

Hash: e0734de7a4e8bdb219f3d4935a1c64cc
HashID SuggestionsMD5 or Domain Cached Credentials – MD4(MD4(($pass)).(strtolower($username)))
Algoritum Used: MD5

Hash: 0ed43e25f742ee0c49d33f9c519fb164ce14866497c3e414c8d95b5ac23525dd54566565bd77f7c3dcf22ad19020092
e209583a1dba302441c9abe5ea6eac6b8
HashID Suggestions: SHA-512 or Whirlpool
Algoritum Used: Whirlpool

Hash: $H$9x8cOSfMfr202yHvWuU/oKdJcBSrLM1
HashID Suggestion: MD5(phpBB3)
Algoritum Used: MD5(phpBB3)

As you can see HashID successfully guessed all 4 hashes!

Unfortunately its guesses do get a little more wild when given more exotic hashes but in general it’s a great starting point.

-Cheers

How to Retrieve a Linux Account Password using oclHashcat

hashcatPasswords are regularly stored in the form of “hashes”. Hashes are the result of passing a plain text password through a hashing algorithm. There are many different algorithms and sometimes a password will be passed through a chosen algorithm multiple times. The most important trait of hashing is that its a one-way process, meaning you can’t convert the output hash back into the original plain text, even if you know which algorithm was used.

The common way to retrieve a password from a hash is to identify the algorithm used and then run a list of words through the same algorithm until a duplicate hash is produced. This is known as a ‘dictionary attack’. It’s also possible to ‘brute force’ a hash, where you simply attempt every possible combination of characters until a match is found. Typically however, a dictionary attack will prove more time efficient, due to people habitually using weak word-based passwords.

Human nature aside, the main factor in how fast a hash can be cracked is the computing power you have available for the task. The obvious solution here is to use an on-demand distributed computing platform, such as Amazons’ EC2.  However, as discussed by Errata Security, it is arguably more cost efficient to use ‘off the shelf’ gaming GPUs. Of course this isn’t really suprising, people have been using GPU’s for folding and bitcoin farming for ages now. So the only question left now is how? This is where oclHashcat comes in. It allows us to use most modern AMD or nVIDIA cards to process hashes, using the same command line syntax as the original CPU based hashcat.

In this guide we will retrieve a Linux account password by running the associated user’s hash through oclHashcat.

Getting Started!

First, lets download a copy of the oclHastcat archive from hashcat.net. In the archive you’ll find several different versions of the hashcat application. These are to cater for different OS’s and hardware. Use the BIN files for Linux or the EXE’s for Windows, then choose between CUDA for NVIDIA or OCL for AMD.

oclhashcat versions

I’ll be using cudaHashcat64.exe, as I have a GeForce 660Ti and am running Windows 7 64bit.

Before we can run oclHashcat we need to complete three steps:

1. Add some working files and folders for oclHashcat to use:

  • a folder for the wordlists
  • a file to contain the hashes to be cracked
  • a file for the output recovered passwords

Here’s a screenshot of my oclHashcat directory with the newly added files and folders. You can name yours anything, but for this example I’ll use “wordlists”, “hashes.txt” and “recovered.txt”:

hashcat_d

2. Add word lists to the wordlists folder.

Unsurprisingly, word lists are simply plain-text lists of words, the more the better. A quick Google search will find you plenty, just place them all in your wordlists folder. For the sake of this example I’m going to use a small wordlist of just 500 words. If you want to follow along with this example then you can download my wordlist here.

3. Find a hash and place it in the hashes.txt file.

I’ll be using a hashed Linux password retrieved from the shadow file. The shadow file contains the hashed passwords of all the user accounts on the system and is normally located at /etc/shadow. Alternatively,  in older versions of Linux, you might find the hashes in the passwd file. Below is the shadow file entry for the user “adambonny.com”:

adambonny.com:$1$j8d78ThV$AJwVDt8fyGGzGVBg7xWP2/:16182:0:99999:7::

The entry is divided into several sections separated by colons, for details on the purpose of each section see here. We’re after the hash which is the second part:

$1$j8d78ThV$AJwVDt8fyGGzGVBg7xWP2/

The hash is made up of three parts separated by $’s:

$ 1 $ j8d78ThV $ j8d78ThV$AJwVDt8fyGGzGVBg7xWP2/

1 defines which hashing algorithm was used, as per the crypt3 man page; $1$ is MD5 ; $2a$ is Blowfish; $2y$ is Blowfish, with correct handling of 8-bit chars; $5$ is SHA-256 and $6$ is SHA-512. So in our case MD5 was used.

j8d78ThV is the the clear text salt. This is a random string that’s used to encode the plain text password before it’s run through the hashing algorithm.  Adding a salt to the password adds randomisation which makes it much harder to crack the hash via a dictionary attack and renders precomputed hash lists (aka rainbow tables) useless. As an additional side effect, adding a salt also prevents the creation of identical hashes where duplicate passwords are used. Fortunately for us, the salts are stored in plain text so we can feed them straight to oclHashcat, negating their advantages.

j8d78ThV$AJwVDt8fyGGzGVBg7xWP2/ is the hash itself i.e. the output received when running the salt + clear text password through the MD5  algorithm.

Copy the complete hash with all three parts into the hashes.txt file.

hash

Running oclHashcat

Based on everything we’ve discovered here’s the complete oclHastcat command we’ll use:

cudaHashcat64.exe -m 500 -a 0 hashes.txt F:\oclHashcat-1.01\wordlists -o recovered.txt

Lets break that down:

-m 500 The -m flag defines the hash type, we already established that the hash was a linux based md5 so I’ve chosen 500 which is used for: md5crypt, MD5(Unix), FreeBSD MD5, Cisco-IOS MD5. For a list of all the available  oclHashcat hash types and example hashes see here.

-a 0 the -a flag defines the attack type, in this case we are using a “straight” word list attack so I’ve chosen 0.

hashes.txt defines the file that contains our hashes.

F:\oclHashcat-1.01\wordlists defines our word lists directory.

-o recovered.txt defines our output file for recovered passwords.

 Let’s run it!

F:\oclHashcat-1.01>cudaHashcat64.exe -m 500 -a 0 hashes.txt F:\oclHashcat-1.01\wordlists -o recovered.txt
cudaHashcat v1.01 starting...

Hashes: 1 total, 1 unique salts, 1 unique digests
Bitmaps: 8 bits, 256 entries, 0x000000ff mask, 1024 bytes
Rules: 1
Applicable Optimizers:
* Zero-Byte
* Single-Hash
* Single-Salt
Watchdog: Temperature abort trigger set to 90c
Watchdog: Temperature retain trigger set to 80c
Device #1: GeForce GTX 660 Ti, 3072MB, 1124Mhz, 7MCU
Device #1: Kernel ./kernels/4318/m0500.sm_30.64.ptx
Device #1: Kernel ./kernels/4318/bzero.64.ptx

Session.Name...: cudaHashcat
Status.........: Exhausted
Input.Mode.....: File (F:\oclHashcat-1.01\wordlists/wordlist.txt)
Hash.Target....: $1$j8d78ThV$AJwVDt8fyGGzGVBg7xWP2/
Hash.Type......: md5crypt, MD5(Unix), FreeBSD MD5, Cisco-IOS MD5
Time.Started...: Wed Apr 23 10:05:32 2014 (1 sec)
Time.Estimated.: 0 secs
Speed.GPU.#1...:   120.6 kH/s
Recovered......: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts
Progress.......: 8100/8100 (100.00%)
Rejected.......: 0/8100 (0.00%)
HWMon.GPU.#1...:  0% Util, 45c Temp, 1080rpm Fan

Started: Wed Apr 23 10:05:32 2014
Stopped: Wed Apr 23 10:05:33 2014

It ran correctly. Unfortunately though, we were not able to recover the password. It looks like we might need more words. First though lets try modifying the words we already have. Currently our wordlist contains simple words such as “symmetric”. It does not account for any variants such as “symmetric101”.

We can configure oclHashcat to account for additional variants by changing our attack type to hybrid dictionary + mask (-a 6). This attack type allows us to combine our wordlists with a mask. A mask may contain any number of the following five variables:

  • ?l attempts every combination of a-z
  • ?u attempts every combination of A-Z
  • ?d attempts every combination of 0-9
  • ?s attempts every combination of special characters
  • ?a attempts every combination of a-z, A-Z, 0-9 and special characters.

So as an example, below is our original oclHashcat command modified to support a hybrid dictionary + mask attack:

cudaHashcat64.exe -m 500 -a 6 hashes.txt F:\oclHashcat-1.01\wordlists ?d?d -o recovered.txt

In this instance the mask ?d?d forces oclHashcat to make 100 attempts for each word. The attempts would be in the format:

symmetric00
symmetric01
symmetric02
...
symmetric99

So, with this extra knowledge lets try cracking our hash again. Here’s the new command we’ll use:

cudaHashcat64.exe -m 500 -a 6 hashes.txt F:\oclHashcat-1.01\wordlists ?a -o recovered.txt

This will attempt all our original words again, this time suffixed with every possible number, letter and special character combination. Note that unmasked words will not be attempted when a mask is specified. So, for example, ‘symmetric@’ will be attempted but ‘symmetric’ will not.

F:\oclHashcat-1.01>cudaHashcat64.exe -m 500 -a 6 -i hashes.txt F:\oclHashcat-1.01\wordlists ?a -o recovered.txt
cudaHashcat v1.01 starting...

Hashes: 1 total, 1 unique salts, 1 unique digests
Bitmaps: 8 bits, 256 entries, 0x000000ff mask, 1024 bytes
Applicable Optimizers:
* Zero-Byte
* Single-Hash
* Single-Salt
Watchdog: Temperature abort trigger set to 90c
Watchdog: Temperature retain trigger set to 80c
Device #1: GeForce GTX 660 Ti, 3072MB, 1124Mhz, 7MCU
Device #1: Kernel ./kernels/4318/m0500.sm_30.64.ptx
Device #1: Kernel ./kernels/4318/markov_le_v2.64.ptx
Device #1: Kernel ./kernels/4318/bzero.64.ptx

Session.Name...: cudaHashcat
Status.........: Cracked
Input.Base.....: File (F:\oclHashcat-1.01\wordlists/wordlist.txt)
Input.Mod......: Mask (?a) [1]
Hash.Target....: $1$j8d78ThV$AJwVDt8fyGGzGVBg7xWP2/
Hash.Type......: md5crypt, MD5(Unix), FreeBSD MD5, Cisco-IOS MD5
Time.Started...: Thu Apr 24 20:49:06 2014 (1 sec)
Speed.GPU.#1...: 649.2 kH/s
Recovered......: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.......: 769595/769595 (100.00%)
Rejected.......: 0/769595 (0.00%)
HWMon.GPU.#1...: 0% Util, 50c Temp, 1080rpm Fan

Started: Thu Apr 24 20:49:06 2014
Stopped: Thu Apr 24 20:49:08 2014

Success! We recovered the plain text from the hash, but, before we check the recovered.txt file lets take a look at the above output. This time you can see an extra line was added ‘Input.Mod’ where our Mask is shown, also note how many extra words our single ?a mask generated. Our wordlist contained a mere 8100 words, applying the mask resulted in 769595 words. Fortunately we were able to process 649,000 hashes per second so the extra workload didn’t take too long. Don’t forget that more complex masks or stronger hashing algorithms will decrease your recovery speed, so use mask’s wisely.

Lets take a look at our recovered password:

 recovered_txt

The password was ‘insecure1’, lets try logging in to the system to confirm it is correct…

login

It worked, the recovered password was correct!

I hope this has been helpful!

– Cheers