Blog
Nginx and Secure SSL Configuration
It turns out that it is kind of tricky to get a perfect high security SSL configuration. I will give you configuration options and I will explain the reasons for which they are chosen.
SSL Versions
SSLv2
is insecure and you also need to disable SSLv3
, as TLS 1.0
suffers a downgrade attack, allowing an attacker to force a connection to use SSLv3
and therefore disable forward secrecy. SSLv3
also allows exploiting the POODLE attack which is another reason to disable it.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
Ciphersuite
The cipher suites that provide the best Forward Secrecy are the ones that use an ephemeral form of the Diffie-Hellman key exchange. The main disadvantage is their overhead which is improved by using their elliptic curve variants.
The following options are recommended by the Mozilla Foundation. If you are not looking for backwards compatibility the following is the recommended modern configuration that is compatible with: Firefox 27, Chrome 22, IE 11, Opera 14 and Safari 7.
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK";
For services that don't need compatibility with legacy clients (WinXP), but need to support a wide range of clients, the following less recommended configuration is compatible with: Firefox 1, Chrome 1, IE 7, Opera 5 and Safari 1.
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
And finally if for some crazy reason you would really like to support legacy systems like Windows XP and Internet Explorer 6, this is the NOT RECOMMENDED ciphersuite which will work with all clients back to Windows XP/IE6. It should only be used as a last resort.
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
Forward Secrecy and DHE Parameters
Forward Secrecy is a property of a secure communication that guarantees that even if an attacker gets a hold of the server's private key he would not be able to decrypt any past recorded communications. This is done by performing a Diffie-Hellman key exchange, which guarantees that the symmetric key of a communication (session key) is never transmitted over the connection and cannot be acquired from a third party. Because this key is only used for a limited amount of time it is called Ephemeral. The server's private key is then used to sign the negotiated session key and thus protecting from a MITM attack, which a standard Diffie-Hellman key exchange is vulnerable to. Nginx relies on an input parameters from OpenSSL for the Ephemeral Diffie-Hellman (DHE), but the OpenSSL defaults only provide a 1024-bit key for the key-exchange. Since often you will be using a 2048-bit certificate (or higher), DHE clients will use a weaker key-exchange than non-ephemeral DH clients. To set a stronger DHE parameter we generate an 4096-bit key and supply it to Nginx:
cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096
And then in your Nginx configuration:
ssl_dhparam /etc/ssl/certs/dhparam.pem;
Additional Options
When choosing a cipher during an SSL or TLS handshake, normally the client's preference is used. If this directive is enabled, the server's preference will be used instead.
ssl_prefer_server_ciphers on;
SSL operations consume a lot of CPU resources. They can be optimised in the following way:
- On a multiprocessor system there should be several workers and no less than the number of available CPUs. This can easily be solved with:
worker_processes auto;
- The most CPU intensive operation is the SSL handshake. To minimise the number of these operations you could enable keepalive connections so multiple request can be send over the same connection and to reuse SSL session parameters and avoid SSL handshakes for subsequent connections.
http {
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
keepalive_timeout 70;
}
}
An extra level of security can be achieved by enabling HTTP Strict Transport Security (HSTS). This is done by appending an extra header to each response signalling the browser that content from this domain should always be loaded via HTTPS.
server {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
Testing your SSL configuration
The SSL Labs have an excellent tool for testing you server configuration. I would highly recommend doing that after you've set up your server. If you get an A
, then you are good to go!
Regular Expression Cheat Sheet
Every time I had to go to the lovely Rubular just to take a look at their Regex Quick Reference, I thought of composing a list of my own, a bit more detailed though. There are a dozen Regex hacks that I keep forgetting that are really useful and I have to look them up every time.
Well, hopefully with this list that won't have to happen again. And if you think of something that is missing, please leave a comment and I will add it.
Revision 4 (Each revision extends the article with new hacks. I'll bump the number whenever I add something new)
Skip and go to Hacks
TL;DR {
Basic Regex Reference
Regex |
Description |
Regex |
Description |
Regex |
Description |
[abc] |
A single character of: a, b, or c |
. |
Any single character |
(...) |
Capture everything enclosed |
^ |
Start of line |
\s |
Any whitespace character |
(a|b) |
a or b |
[^abc] |
Any single character except: a, b, or c |
\S |
Any non-whitespace character |
a? |
Zero or one of a |
$ |
End of line |
\d |
Any digit |
a* |
Zero or more of a |
[a-z] |
Any single character in the range a-z |
\D |
Any non-digit |
a+ |
One or more of a |
\A |
Start of string |
\w |
Any word character (letter, number, underscore) |
a{3} |
Exactly 3 of a |
[a-zA-Z] |
Any single character in the range a-z or A-Z |
\W |
Any non-word character |
a{3,} |
3 or more of a |
\z |
End of string |
\b |
Any word boundary |
a{3,6} |
Between 3 and 6 of a |
Groups & Modifiers (Options)
Syntax |
Meaning |
(foo) |
Capture everything enclosed |
(?:foo) |
Group, but do not capture |
(?=foo) |
Lookahead |
(?<=foo) |
Lookbehind |
(?!foo) |
Negative Lookahead |
(?<!foo) |
Negative Lookbehind |
}
Hacks
Match everything until a sequence
Looking at the groups reference above, you can do that with a lookahead expression, like so:
/.+?(?=foo)/
This will match everything until the string foo
.
To capture everything until foo, you can use the following:
/(.+?)(?=foo)/
Make sure you include the ?
in the first capture group or otherwise that will result in an empty capture group at the end.
Capture everything until an optional sequence
Because Regex engines are greedy, what I showed above wont work with just adding an optional modifier to it (?
). Instead you should do this:
(.+?)(?:foo|$)
This will capture both abc
and abcfoo
.
Greediness vs. Laziness
By default Regex is greedy. It would try to match as much as possible when you use operators like +
or *
. But sometimes you might only need to match more than one but as few as possible. This could be done by switching from Greedy mode to Lazy mode and is achieved by just adding a ?
to the multiple operator like: +?
or *?
. This feature of Regex is called Possessive Quantifiers.
Here is a detailed example matching the string abbbbbc
:
- The regex:
a(b+)
would match abbbbb
with the first capture group being bbbbb
.
- The regex:
a(b+?)
would match ab
with the first capture group being b
.
Now a bit more interesting
- The regex:
a(b+)(b+)c
would match abbbbbc
with the first capture group being bbbb
and the second being b
.
- The regex:
a(b+?)(b+)c
would match abbbbbc
with the first capture group being b
and the second being bbbb
See how that reversed the order of the matches. Because greediness and laziness change the order in which permutations are tried, they can change the overall match. However, they do not change the fact that the regex engine will backtrack to try all possible permutations of the regular expression in case no match can be found. Possessive quantifiers are a way to prevent the regex engine from trying all permutations. This is useful for performance reasons. You can also use possessive quantifiers to eliminate certain matches.
P.S. This article could have been called: Harry Potter and the Power of Regex
Proxying Traffic through a DNS relay
There are cases in which the connection you have to the internet only allows DNS packets or traffic needs to be concealed. In those cases when an Internet connection is really required, one way to do that is through DNS relays.
How it works?
What essentially is going on is that instead of sending normal packets to the internet you are encoding your packets in DNS requests and sending those instead. You do need a special kind of DNS server that understands these modified DNS requests and responds appropriately. Of course owning a domain name is an absolute requirement for this and the shorter the domain is, the more space you have for channelling data. This is so because a full domain name cannot exceed 253 characters and thus your request cannot contain more that 253 - length(domain)
. There are some additional limitations to that, though.
Iodine
Iodine is a very powerful utility that enables you to tunnel IPv4 data through a DNS server. Iodine runs on Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD and Windows.
To try it out you will need to set up an iodined
server.
First you need to set up a domain name to use with iodine. It has to be as short as possible for example: i.example.com
.
Set up two DNS records. An A
record pointing to your server and an NS
record pointing to your A
record, like this:
A iodine.example.com 1.2.3.4 7200
NS i.example.com iodine.example.com 7200
Once you are ready you will need to set up the iodined
(Iodine Daemon) on your server. This is done with the following command:
iodined -f -c -P secretpassword 172.16.0.1 i.example.com
Not that 172.16.0.1
is the local address on which the server will appear when connecting through the tunnel.
Once you are ready it is simply a matter of running iodine
and giving it your server domain name to create the tunnel:
iodine -f -P secretpassword i.example.com
At this point of time you have a tunnel with DNS packets to your target server. This means that you will be able to access you server but nothing else. But if you want to use it as an Internet relay you could simply set up a proxy and use the tunnel for all kinds of data.
There are several methods to do this. You can either set up a VPN and route your traffic through the VPN or use an SSH proxy. Or even though not recommended, since your traffic won't be sent over a secure channel, but still worth mentioning are setting up an HTTP proxy on your server or setting up a route through your tunnel and configuring your server to do NAT.
After all the easiest (and secure) way to send your traffic over the tunnel is setting up an SSH proxy. This actually is pretty straight forward. All you need to do is run the following command and login to your server:
ssh user@172.16.0.1 -D 1234
This will create a SOCKS
proxy listening on localhost:1234
and you can configure either your computer to use it from the network settings or just your browser. There are plenty of tutorials on how to do that.
I definitely advise you to experiment with the -T
, -L
and -M
arguments to establish the most efficient configuration and get lower latency and higher bandwidth. See the man page for details.
It does not provide a very high speed. Actually the speed of the connection can sometimes be really slow, depending on the network and the ping to your server, but iodine is a really powerful tool that can connect you to the internet even when there is no other way.
UPDATE:
Hacktag iodined
server
Now we give you the #hacktag iodined
server available for free. You can connect to it with the following command:
iodine -f -P strongholdfreefallmonkey i.hacktag.uk
ssh -n ihacktag@172.16.0.1 -D 1234 # The password is the same
If you like it and/or use it often and you would like this service to stay online and be 99.9% available, please consider donating a small amount so we can get a proper server to host our iodined
.
This entire article was created and uploaded using iodine
.
How more secure could RSA be?
Breaking an RSA-10 key (meaning an RSA key 10 bits long), requires that you try every prime number in the range of 2 to 100. There are 25 of those, meaning that the security of RSA-10 is about equivalent to a 5-bit symmetric cipher. Doubling that, going to RSA-20 means that to crack it, you need to try every prime number in the range of 2 to 1000. There are 168 of those so the security of RSA-20 is equivalent to about an 8-bit symmetric cipher. Doubling the key length did not give us the security we naively expected. Each subsequent bit adds to the security of the key but always less than the preceding bit. Thus we quickly reach a point of diminishing returns after which every bit adds so little that it is almost negligible.
That point is reached around RSA-2048 and adding more bits to that doesn't make much difference. For comparison, RSA-2048 gives about 112 bits of security and RSA-3072 gives roughly 128 bits of security.
When someone someone asks you whether it is worth using RSA-4096, the only added security compared to RSA-2048 is about 28 bits, meaning a total of 140 bits.
If you need more security than what RSA-2048 offers, consider using Elliptic Curve cryptography rather than using RSA with an ever increasing key length.
So how more secure could RSA be?
And the answer is: not much more secure.
Creative Commons
We truly believe that sharing, not only software but any kind of content/data in general, should be a human right. And from now all of the content on this website is provided under the terms of the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License unless otherwise stated.
Below is a brief description of what the license covers, but is not a substitute for the license.
This simply means that you are free to copy and redistribute the content of the website in any medium or format as long as you give as appropriate credit and provide a link to the license. You may not use any of the materials on the website for commercial purposes. You are free to remix, transform or build upon the material, but you man not distribute copies of the modified material.
This is done so we respect your right of sharing we believe in and you respect our right as copyright holders.
Content on the website and content we link to may be distributed under different license which will be explicitly stated.
Linux Cheat Sheet
This is a really useful list of bash one-liners for Linux and Unix so you can save those 5 minutes of time googling. This is for all the people who need a simple short snippet they can paste into bash
, or fish
for that matter, but might need some modifications.
I will add new snippets whenever I stumble upon something more interesting.
Revision 8 (Each revision extends the article with new commands. I'll bump the number whenever I add something new)
Generic
Generate a secure random password
There are many methods to perform this task. I am just going to mention my favourites.
This one uses the very useful dd command. On OS X
you will need to lose the -w 0
from the base64
command.
dd if=/dev/urandom bs=1 count=33 2>/dev/null | base64
This uses openssl’s rand function, which may not be installed on your system. Good thing there are other examples, right?
openssl rand -base64 16
# To strip the equal signs at the end
openssl rand -base64 16 | head -c${1:-16}
Wait for internet connection
This will pause your script until there is network connection available. Really useful in some particular situations like boot time scripts, especially on machines relying on a WiFi connection.
for i in {1..50}; do ping -c1 google.com &> /dev/null && break; done
List IP Addresses on all interfaces
This will list all IP Addresses of all interfaces connected to the system. You can use it in an espionage script to report it's current location on the internet.
ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d’/'
Webserver from current directory
If for some reason you would like to start a webserver from the current directory downwards, here is a single line snippet thar does the job:
python -m SimpleHTTPServer 8080
Linux
Disable Root Password Login
usermod -p '!' root
Creating a Swap file
This creates a swap file located at /swapfile
with the correct permissions and size specified in MB (The example demonstrates the creation of 512MB swap file).
dd if=/dev/zero of=/swapfile bs=1M count=512
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
Increasing the space in /tmp
As with any other tmpfs
, increasing the size of the /tmp
with no data loss is just a matter of a simple remount.
mount -o remount,size=6G tmpfs /tmp
Creating a user
useradd -m -G wheel -s /bin/bash username
Some explanation:
- The
-m
argument creates a home folder at: /home/user/
with the correct permissions.
-G
sets a supplementary group for the user. wheel
is the administrative group on Debian systems.
- You can set the primary group of the user with the
-g
argument, but leaving it empty would create a group with the same name as the user, which is the preferred method of creating users. Using a single default group is not recommended on multi-user systems, because the default group will by default always have write access to any files the user create.
-s
Sets the default shell for that user.
- The last argument is the user name.
Deleting a user
userdel user
You can add the -r
option to remove the user's home directory and mail spool.
Adding an existing user to a group
usermod -a -G group user
gpasswd -a user group
Removing a user from a group
gpasswd -d user group
deluser user group
Checking process listening on a port
lsof -i :port
lsof -i tcp:port
lsof -i udp:port
Where port
is the port number.
OpenSSL
Generate a keypair
openssl genrsa -out private_key.pem 4096
openssl rsa -pubout -in private_key.pem -out public_key.pem
Generate a CSR
openssl req -key private_key.pem -new -out certificate_request.csr
Encrypt an RSA private key
openssl rsa -des3 -in private_key.pem -out encrypted_private_key.pem
The -des3
tells openssl to encrypt the key with DES3
.
Remove the encryption from an RSA private key
openssl rsa -in server.key.org -out server.key
Encrypt a file
Symmetric encryption
openssl aes-256-cbc -salt -in file.txt -out file.txt.enc
A few notes here:
* You can use -a
if you want your output to be in base64
. This is useful if you would like to read it with a text editor or paste it in an email.
* -salt
makes the encryption stronger. You are advised to use it.
* This uses symmetric encryption and you will be prompted for a password.
Asymmetric encryption
1. Generate a 256bit (32 byte) random key
openssl rand -base64 32 > key.bin
2. Encrypt the key
openssl rsautl -encrypt -inkey public_key.pem -pubin -in key.bin -out key.bin.enc
3. Encrypt the file
openssl enc -aes-256-cbc -salt -in file.txt -out file.txt.enc -pass file:./key.bin
Note that you shouldn't encrypt the entire file with asymmetric encryption. That is too slow and inefficient. Instead you encrypt a 256bit key with which you encrypt the file. So when you are sending the encrypted file, you should send both the encrypted key and the encrypted file.
This procedure is slightly simpler when using PGP.
Decrypt a file
Symmetric encryption
openssl aes-256-cbc -d -in file.txt.enc -out file.txt
Again use -a
if the input was encoded with base64
.
Asymmetric encryption
1. Decrypt the key
openssl rsautl -decrypt -inkey private_key.pem -in key.bin.enc -out key.bin
2. Decrypt the file
openssl enc -d -aes-256-cbc -in file.txt.enc -out file.txt -pass file:./key.bin
Networking
Changing your MAC address
While this is somewhat trivial, I would still like to mention it. Primarily because not many people are used to the new Linux ip
utility.
You might need sudo
for all of the commands.
Using ifconfig
(Older Linux distros and Mac OS X)
ifconfig # to list all interfaces
ifconfig interface ether 00:00:00:00:DD
Using the new ip
utility (Modern Linux distros like Arch)
ip link # To list interfaces and current configuration OR
ip link show interface # to list a specific interface.
ip link set dev interface address 00:00:00:00:DD
Note 1: You might have to turn of your interface before changing you address. This could be done with:
ifconfig interface up/down
ip link set dev interface up/down
Note 2: You have to substitute interface
with your interface name. That is usually en*
on Linux and OSX or wlan*
for WiFi networks or the new wlp****
.
Nmap
Simple Port Scan
nmap -v host # -v is for verbosity
nmap -PN 192.168.1.1 # Scans a host protected by a firewall
nmap -6 2607:f0d0:1002:51::4 # Scan an IPv6 host/address
Nmap Network Scan
Some of the arguments showed here could be used in the Port scan mode.
nmap -sP 192.168.1.0/24 # Scan a network and find out which servers and devices are up and running
nmap 192.168.1.1-20 -sA # Find out whether the host is protected by a Firewall
nmap 192.168.1.* -A # with OS and version detection
nmap 192.168.1.0/24 --exclude 192.168.1.5 # Excluding specific hosts
The Hacktag Project
Welcome to #hacktag!
We created this website in order to share the multiple projects we work on, our research, the interesting things we found out and the things we invented.
I hope you find it useful.
If for some reason you would like to ask us a question, feel free to go to the contacts section and leave us a message.
Kind Regards,
The Hacktag Team