Monday, 5 December 2011

Security and MongoDB

The MongoDB Security Model has some scope for improvement.
  1. As default, Authentication is off. MongoDB is designed to run in a 'trusted' environment, depending on the network configuration to ensure the security of the environment.
  2. Pre v2 authentication is not supported within a sharded deployment.
  3. Once authenticated a user has full read-write to the entire DB. There is no concept of roles or groups or such like.
Now, I wanted to deploy with Security turned up to the max, so here I will present a practical example.
This is a typical set-up I'd use for my development environment; separate machines each running mongod.

Firstly, let's set up the replicaset.
On the primary we can define and run the replicaset config:

Nothing fancy here, all standard stuff. After a few minutes the dust settles and the primary and secondary identify themselves. You can check the status of the replicaset with:
Now, on each box in the replicaset you'll need to create a key (must be valid Base64 and 1K or less):
You can now bring down both instances. Either hit ctrl+c or do it the right way:

Now we can start each of the mongod instances with the keyFile:
Word of warning here. I spent a significant amount of time trying to set this up on v2.0.0 - yes I know it is a bit dumb to go with a x.0.0 version, but you'd think that something as basic/fundamental as this would be thoroughly tested. Well, suffice to say I ended up moving to the latest binary to get this basic functionality to work. It was annoying at the time, but it certainly made me read the available documentation multiple times.
So now on the primary we can create the admin user aka root, super...
As we have a replicaset these users will existing in admin and mydb on both instances.

This whole process should take about 5 minutes to configure provided you're using a stable, well tested version.
I got unlucky and wasted hours on a buggy version grappling with errors that I couldn't decipher, feeling a bit denvercoder9 (http://xkcd.com/979/).
I went through the pain so you don't have to...

Sunday, 4 December 2011

A simple guide to finding distinct array values in a MongoDB collection

So you want to find unique values within an array within a document in a collection? A reasonable request.
In ANSI SQL you'll be using DISTINCT, JOINS and GROUP BYs, stuff you're used to, but in the NoSQL realm your best bet is mapreduce.
It might seem a little bit like hard work, and probably a little intimidating at first, but it is certainly worth it; mapreduce is an extremely powerful tool.

Set up the collection, the map and reduce functions, and execute the mapreduce command:



But now you want to find unique values within an array within each document in an entire collection.


The map function in this example iterates over each of the items and emits the key/value of each array element.
The reduce function aggregates the key/value from each of the emits from the map function. In this example we're looking at unique keys and maintaining a count of the unique keys.
If you're looking to find the distinct array elements for a single document, simply specify the document index. For the entire collection, just leave the query out. *simples*

Saturday, 3 December 2011

Simple mongodb equivalents

After making a noob error today, I realised that some of the documentation could use a boost.

By default mongo returns the entire document.




All fields for the matched document will be returned

And in java




To return only certain fields, you need to let mongo know which ones you want



The will only return the fields meh and feh from the matched document

And in Java



You can also say 'all fields except for...'




This will return all the fields in the matched document expect for meh

And in Java


Wednesday, 12 January 2011

WPA2 Packet Capture

Viewing packets for users on a secure wireless access point is stupidly easy.

If you sit anywhere that has a Free Access Point, you can capture traffic from other users. This may be a coffee shop or juice bar, or whatever. You may think that this can only be done on Open Access Points. You'd be wrong in this thinking. This is no secret. You can capture packets from other users even if encryption is turned on. That is, if WEP, WPA or even the strongest WPA2 encryption is being employed. Seriously, this isn't new.

In the case of the coffee shop the operators will give you the wireless key for free. In other places they may charge you a small fee for the usage of the Access Point. It doesn't really matter if they give you the key or not tbh. I say this because it is pretty simple to snaffle the key. You can do this by driving by a house and sniffing for traffic for as short a time as a few seconds, and running some brute forcing offline. Anyhoo, this is off topic.

How to do it.

Install Backtrack4. This takes 30 minutes. It's easier to have BT4 as the host OS to be able to have all the tools to hand and to have the right access to the wireless interface. After this step it is as simple as a few commands.

Show the adapter config

iwconfig


Create a new interface in monitor mode

airmon-ng start wlan0


Now, can scans for available networks

airodump-ng mon0


Capture traffic on the Access Point in question

airdump-ng -c CHANNEL --bssid MAC_ADDRESS -w demo_capture mon0


Decrypt the captured packets.

airdecap-ng -e SSID_NAME -p PASSWORD_KEY demo_capture-01.cap


Open the decrypted packet capture in wireshark and follow any of the TCP streams that look interesting. You'll be surprised what you can find out.

Thursday, 4 November 2010

Hack a Master Padlock

Master 3 Barrel Combination Lock

Ever wanted to be able to show off to a friend that you could hack a padlock? Yeah me too. I started off making a shim as I thought I could use the piece of a coke can technique. It turns out I was trying too hard; I managed to open the lock without any tools or lock picking kit, just a bit or force and feel was required.




Set all the dials on the lock to 0 (zero).




Use your thumb to push up the hook. Hold this in place while you feel your way to the combination. Turn each of the dials, starting with the top dial slowly around. If you're applying enough force and your feel is sensitive enough, you'll notice that the dial will be significantly different when it hits a certain number.

Believe it of not, it's that easy, that is the number for dial. Seriously. Next move onto the dial down. The action is exactly the same as before. Repeat again for the last dial.



Bingo! Or 'House!', as they say in Bingo.

It is just as easy, and exactly the same method for the 4 dial combination lock. Well, when I say just as easy, I thought to begin with that same technique wouldn't work, but I'm rather stubborn and kept at it. The difference between the correct position and all the other positions of the dial are much more subtle on the 4 dial than the 3 dial.











The other (more) famous Master Combination lock hack.


You can change the number by:
  1. Unlocking the padlock
  2. Holding down the hook in the 90 degree position
  3. Setting a new number

Tuesday, 6 July 2010

Microsoft CA and Certificate chains

Introduction

I can't believe people struggle so much with this and why there isn't a free tool to convert certificates from a Microsoft CA (pfx to jks) and steps for creating the associated certificate chain.

Get the cert
Pull the certficate from the Microsoft CA and pull it from you browser.
  1. From the Microsoft issued certs list, install in IE. You get to this via the View the status of a pending certificate request link on the MS CA.
  2. Export in pfx format from IE. IE -> Tools -> Internet Options -> Content -> Certificates
  3. Select the certificate and Export
  4. 'Yes. export the private key' and select PKCS #12. Select all check boxes

Import the chain
  1. Download the CA certificate chain from the Microsoft CA
  2. Open the chain and export each part of the chain individually in DER format

Do the techie stuff

--Convert the pfx to jks using Jetty
java -classpath %JETTY_HOME%/jetty-6.1.1/lib/jetty-6.1.1.jar org.mortbay.jetty.security.PKCS12Import www.mysecuredomain.com.pfx www.mysecuredomain.com.jks

--Verify the key is there
keytool -list -keystore www.mysecuredomain.com.jks

--change the default alias to something more readable
keytool -storepass changeit -keystore www.mysecuredomain.com.jks -changealias -alias longunreadblealphanumericstring -destalias www.mysecuredomain.com

--convert the cer/der to pem
openssl x509 -inform der -in MyCompanyPrimaryRootCA.cer -out MyCompanyPrimaryRootCA.pem

openssl x509 -inform der -in MyCompanyServerAuthenticationPolicyCA.cer -out MyCompanyServerAuthenticationPolicyCA.pem

openssl x509 -inform der -in MyCompanyServerAuthenticationEnterpriseCA.cer -out MyCompanyServerAuthenticationEnterpriseCA.pem

--import the root cert and all other certificates in the chain. The trustcacerts arguement tells keytool that you want to import this as a trusted certificate.

keytool -storepass changeit -keystore www.mysecuredomain.com.jks -import -v -noprompt -trustcacerts -alias MyComanyPrimaryRootCA -file MyComanyPrimaryRootCA.pem

keytool -storepass changeit -keystore www.mysecuredomain.com.jks -import -v -noprompt -trustcacerts -alias MyComanyServerAuthenticationPolicyCA -file MyComanyServerAuthenticationPolicyCA.pem

keytool -storepass changeit -keystore www.mysecuredomain.com.jks -import -v -noprompt -trustcacerts -alias MyComanyServerAuthenticationEnterpriseCA -file MyComanyServerAuthenticationEnterpriseCA.pem

--Check the chain length
keytool -v -list -keystore www.mysecuredomain.com.jks | grep chain
Enter keystore password: changeit
Certificate chain length: 4

--Check the certificates for the chain are all present
keytool -list -keystore www.mysecuredomain.com.jks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 4 entries

mycompanyserverauthenticationenterpriseca, DateStamp, trustedCertEntry,
Certificate fingerprint (MD5): MD5String
mycompanyprimaryrootca, DateStamp, trustedCertEntry,
Certificate fingerprint (MD5): MD5String
mycompanyserverauthenticationpolicyca, DateStamp, trustedCertEntry,
Certificate fingerprint (MD5): MD5String
www.mysecuredomain.com, DateStamp, PrivateKeyEntry,
Certificate fingerprint (MD5): MD5String

Importing the root CA
Import Root CA into browser - you only need the root to be installed in the truststore, or the trusted certificate authorities.
  1. Firefox :: Certificate Manager -> Authorities -> Import...
  2. IE :: Certificates -> Trusted Root Certification Authorities -> Import...
  3. Chrome :: Certificates -> Trusted Root Certification Authorities -> Import...
Happy days.

Monday, 21 June 2010

Passwords

Passwords are now so everyday that remembering a dozen or so long, complex password doesn't phase anyone. But why do passwords have to be so long and so complex? Well, you don't want to bad guys to be able to guess it or to apply brute force to 'crack' it and gain access to your private data, do you?

There are many factors that influence the strength of a password and each of those factors used together can help protect your credentials and thus your data. If you're still in doubt over the knowledge your users have around protecting their password and their password strength, then you can always educate them.

  • Show them your password policy and explain to them why it is how it is.
  • Explain to them the pitfalls of clicking on links in emails.
  • Explain installing random software can be invasive and dangerous.
  • Provide links to tools that can help them generate a strong password, or to essays or research papers. Or spend a day writing your own, summarising all the facts important to your business.

This post is designed to be a guide to how to help you decide how to implement safe storage of passwords. It is not meant to be complete one-size-fits-all policy document, though it could be used as a basis for creating a password policy specific to your needs. I've also attempted to give some positive and negative impacts for each area.

Length, or "size is important"

Password length is the most important factor in password strength. Forget entropy, make your password as long as you can. Many policies enforce a minimum length of mixed case, numbers and special characters, and some even impose a maximum length.

The minimum length is important, but please make it longer than 8, which is extremely common. I don't understand why anyone would want to restrict the maximum length of your password. At the end of the day the resultant hash is of a fixed length, so longer user passwords won't have any negative impact on storage concerns. Provide a large characters set from which to chose the password but there is no real need to force a user to use the upper/lower/numeric/special characters.

+ve longer passwords increase complexity, slowing down any brute force attack

-ve the longer the password the more likely it will be to be forgotten by the user resulting in more password resets which could result in more helpdesk calls.
-ve a user not being able to log in at a given time could impact time sensitive sales


Lifetime, or "all change please"

You should impose a maximum lifetime of a password. You could implement expiration such that after a given period of time you prompt the user to change their password. You could do this at login, or you could send them a mail prompting them to change their password, maybe providing a link to the reset page.
It may be worth adding historical knowledge of passwords used. When a user is prompted to change their password according to the lifetime policy the new password should not match any of the previous passwords used for the account. This eliminates the possibility of a stolen password database where the passwords have been expired and thus becoming stale, to then becoming valid again.

+ve any leaked password DB would only have a finite lifetime as the passwords would be stale after a given period of time
+ve informing the user to change their password may increase customer confidence and show you take security seriously.

-ve implementation of an expiration mechanism would have to be coded, which takes time and resource
-ve nagging the user may have a negative impact on user experience


Lockout, or "add some treacle"

It is quite common for hackers to brute force a live system. Obviously you've already implement a set of rules that will alert you to such attempts, along with your detection of cross-site scripting monitoring and alerting. You can take a couple of approaches here. You can lock accounts after a specified number of failed login attempts. Any account that has been locked out would require administrative intervention to re-enable the account.

+ve this will quickly stop any brute force attempts

-ve calls to helpdesk have a cost attributed to them, businesses are in business to make money

An alternative is to add some treacle. After a given number of failed attempts, apply a pause, a delay until the next login attempt can be made.

+ve slows the brute force attempt down


Salting, or "pass the salt"

Appending a salt to the password prior to applying the hash function has the effect of lengthening the password. You should generate a different salt for each password. If you can store the salt in a separate database, then great, that will slow a brute force attempt on a leaked database and storing salts in a different databases reduces the likelihood of the hash and the salt being stolen at the same time. Added the salt slows down the hash brute force, it may even take so long that the password has gone stale by the time it is cracked. There is no harm in rotating salts each time the user logs in. This could be implemented a an asynchronously (thus not affecting the user experience) strengthening the argument for storing the salt in a different database to the hash; if the theft of the two databases is not synchronised, then the hacker doesn't have the expected salt for a given user.  You can always append an additional, option application salt. This adds one more pieces to the puzzle that the attack must solve.  Store this somewhere that the salt, the final hash or the algorithm is not stored, thus requiring the attack to gain access to additional systems.

+ve slows down a brute force attempt


Key strengthening, or "stretch, and relax"

Employ a form of key stretching will strengthen any given password. Key stretching, by design executes slowly; introducing a delay to the hashing process introduces the same delay in the brute forcing process.

+ve hacker needs to know how the algorithm is implemented, and for that they would need access to source code
+ve significantly slows down any brute forcing

-ve slowing down the password verification _could_ impact user experience when logging in
initialise key
loop 100,000
        key = hash(key + password + salt)

Why hash all 3? This reduces the chances of collisions


Cryptographic functions, or "don't make a hash of it"

Choose your hashing function you probably want to use SHA-2, though judging by the rate of hash function breakage, you'll want to ensure you can quickly and easily upgrade to the latest SHA implementation; so prepare for SHA-3.


Complexity indicator, or "a show of strength"

It is always good to give your users a visual indication of how strong their password is. You can add a graphical indicator on the registration page and on password reset page. Though I would not retrospectively send my users an email telling them that they must change their password as it has found to be under strength. This would give the impression that somehow you have visibility of it.


I (don't) want to do whatever common people do

Common passwords have been collated for years. For example, 123456 was the #1 common password for years. There are multiple sources where you can download lists for the top 100, 1,000, 10,000, 100,000 passwords. Use one of these lists to ensure your users don't.


Sensible storage, or "Cover me, I need back up!"

Back up source code which will contain the algorithm, the per password salt, application salt and the resultant hash in isolation. There is no point is keeping them all separate in production if you then back themup to the same location. If you can, encrypt your back up.


Summary

There are many ways to increase the strength of passwords at rest and how you influence and educate your users in choosing strong passwords in the first place. There is no one right way and no one size fits all.
  • Educate your users/customers about secure passwords, they'll thank you for it.
  • Weigh up what is the right solution for your requirements.
  • Leave comments/suggestions/advice below (-;