Wings of Hermes – Berin's Infosec Blog

Infosec the world and everything

I have just spent the arvo playing with IPv6 and brought up a tunnel using my web server as the tunnel endpoint in my network.

Next thing I know every machine on the network (OS X/Windows/Linux) have been allocated IPv6 addresses in the /56 network I requested from the broker.  Turns out I activated the routing functionality and all the machines on the network received a broadcast routing update.  IPv6 has a thing called stateless autoconfiguration that the devices then use to grab an IP address (based off the MAC address).

And because the tunnel goes through the firewall, everything is visible on the Internet (found a nice site that lets you port scan IPv6 addresses and verified).

As IPv6 becomes more available, I wonder how many people are going to find themselves opening up their network without realising it?  I wonder also if the bad guys have started scanning IPv6 address ranges – or is it still not worth the effort.  And if so – for how long.

Now playing with ip6tables before I bring that tunnel back up…..

I just upgraded from Glassfish 3.1 to 3.1.1 and all logging for my app below INFO (i.e. FINE/FINER/FINEST) stopped working.  Turns out there is a bug that normally expresses itself by stopping logging working altogether.  I think another symptom is glassfish starts to ignore logging if the level for the particular logger is set to FINE or below.

Anyway – fix seems to be to run the command:

asadmin set-log-levels com.sun.enterprise.server.logging.GFFileHandler=ALL

For more info see the 3.11 Release Notes

Well – JAAS and GlassFish. I naively assumed this would be easy to get to work. It’s not.

I started out by building a login module that extended AppservPasswordLoginModule and plugging it directly into login.conf. I then created a Realm that used it and continued on my merry way.

The moment I tried to extend beyond a simple user name and password (being passed through vi the j_security_check form) things broke down.

It turns out that the Realms in GlassFish don’t allow you to plug in “any” JAAS compliant LoginModule. In fact they seem to assume that any kind of authentication you want to do relies on username and password. That makes sense as the realm handles the user input, so if you want to deviate from that standard, you need to go outside what the realm can handle.

In the end, I ended up implementing a JSR 196 SAM (ServerAuthModule). This in turn was an interesting exercise – much of the stuff that GlassFish looks after for you in configuration now needs to be handled directly. For example detecting a not logged in user and redirecting to a login page and then redirecting back when the auth occurs. My SAM plugs direct into GlassFish and I no longer use the realm for those parts of the app with my customised authentication process.

Very interesting. But I now have a SAM that operates as a login bridge and calls a JAAS LoginModule implementation for my authentication.


Patrick Hogan has done a great project on GitHub – IOS Certificate Key and Trust Sample Project – that pulls together all the concepts for RSA key importing/exporting and handling. It’s used some of the code from my import and export posts + code from a few other places together with his own work. Great single place to go for guidance in this space.

Awesome! Wish I’d thought of it :) .


One of the biggest issues with security awareness is knowing what it is you are trying to achieve. It’s not enough to just run an awareness program – you have to be trying to drive an outcome.

Over a period of time I have defined in my own head a kind of CMM for security awareness. It’s something that helps me think about how mature is an organisation in its security awareness culture, which in turn helps me guide an awareness program to continually improve that culture.

It’s not really a CMM in the sense of measuring maturity process – it’s more looking at the output of all the awareness processes than measuring the processes themselves. But it’s a nice analogy that works for me.

A good CMM always has five levels (paraphrasing from the wikipedia article referenced above) :

 

  1. Initial – ad-hoc process
  2. Repeatable – Trying to do the same thing every time
  3. Defined - Documented as a standard business process
  4. Managed – Good metrics that measure success of the process
  5. Optimising – ongoing improvement

To make use of this, I try to put myself in the shoes of Fred Bloggs, some person in the organisation (not in the Information Security team) and I measure culture using statements to represent the way Fred is thinking:

  • Initial – “I know there is a security team and they’ll look after all that security stuff. I don’t need to do anything”.
  • Repeatable – “I’ll drag the information security person into this conversation – he/she will worry about the security requirements”.
  • Defined – “I know what the security requirements are, but I’ll drag the security team in anyway as they will do the ‘fighting’ for what is required”.
  • Managed – “I know the security requirements and I’ll fight for them because we need them. I’ll use the security team for final sign-off or where I have to escalate”.
  • Optimising – Security requirements are just inherent in everything people do.

Of course the above is quite a naive way of looking at things in some ways, but a key part of an awareness program is understanding where you are and what you are trying to achieve. By knowing roughly where your organisation culture sits and what you want to take it to, you can start to taylor your security awareness program to achieve that next step.

One last thing to note – different parts of an organisation will be at different levels, and probably should be. Having an IT team that is higher up the scale than the rest of the organisation might not be a bad place for the company you are looking at. And of course that’s another key part of awareness – understanding there are different messages and results that you want for different groups.


I was doing some reading on the distribute.it hack and stumbled onto a reference to a Risky Business podcast on probablistic risk assessments.

It’s a great argument as to why risk assessment does not work well in the information security space.  The basic thesis is you can’t assign a probability to a serious attacker.    We’ve built a whole risk model on the idea that we can assign a probability to various events – we treat risk in a malicous environment as we would in a "normal" environment.  We have a certain risk of machine failure therefore we have a similarly measurable risk on a malicious attacker and of course these two are not equivalent at all.

A great interview to listen to.

I read No pic, no fly plan for airports in The Age yesterday with a small amount of dismay.  It’s always frustrating to see security measures that seem to be more about the appearance of security rather than the reality, and which will negatively impact the users (or travellers in this case).

I’m really not sure how having to produce a photo ID will really slow down the determined criminal or terrorist. I’m pretty sure it’s not going to give them pause for thought.

And as for signing a stat-dec if you don’t have ID – what does that achieve?

I do like the idea of getting a newborn to sign a stat dec tho….

Very belatedly I’ve been looking into the Stuxnet worm. Interesting new world we find ourselves in. This thing was surgical – not only damaging the equipment but hiding its footsteps.

The question you have to ask though is if this is the one we know about – how many are out there that we don’t?


So following from my post on exporting a public key from an iPhone into java, here is some sample code for going the other way.

It follows the same logic as exporting the key but in reverse. (It starts with decoding the Base64 piece as the app I am working on always passes data in encoded format.)

Once it’s base 64 decoded it strips the ASN.1 encoding associated with the OID and sequence encoding that generally prepends the RSA key data. That leaves it with just the large numbers that make up the public key.

The key loading parts are heavily based on the Crypto example provided by Apple. It’s not been extensively tested, but it works with the few keys I’ve thrown at it. (refString is just a string constant I define elsewhere that identifies the key in the key store.)

Let me know what you find that’s wrong! I’d also be interested in knowing how to do this without saving the key as a persistent reference. I didn’t have time to work out how to do that part (assuming it’s possible).

- (BOOL) setPublicKey: (NSString *) keyAsBase64 {

    /* First decode the Base64 string */
    Base64 * b64 = [[Base64 alloc] init];
    NSData * rawFormattedKey = [b64 base64decode:[keyAsBase64 UTF8String] length:[keyAsBase64 length]];

    /* Now strip the uncessary ASN encoding guff at the start */
    unsigned char * bytes = (unsigned char *)[rawFormattedKey bytes];
    size_t bytesLen = [rawFormattedKey length];

    /* Strip the initial stuff */
    size_t i = 0;
    if (bytes[i++] != 0x30)
        return FALSE;

    /* Skip size bytes */
    if (bytes[i] > 0x80)
        i += bytes[i] - 0x80 + 1;
    else
        i++;

    if (i >= bytesLen)
        return FALSE;

    if (bytes[i] != 0x30)
        return FALSE;

    /* Skip OID */
    i += 15;

    if (i >= bytesLen - 2)
        return FALSE;

    if (bytes[i++] != 0x03)
        return FALSE;

    /* Skip length and null */
    if (bytes[i] > 0x80)
        i += bytes[i] - 0x80 + 1;
    else
        i++;

    if (i >= bytesLen)
        return FALSE;

    if (bytes[i++] != 0x00)
        return FALSE;

    if (i >= bytesLen)
        return FALSE;

    /* Here we go! */
    NSData * extractedKey = [NSData dataWithBytes:&bytes[i] length:bytesLen - i];

    /* Load as a key ref */
    OSStatus error = noErr;
    CFTypeRef persistPeer = NULL;

    NSData * refTag = [[NSData alloc] initWithBytes:refString length:strlen(refString)];
    NSMutableDictionary * keyAttr = [[NSMutableDictionary alloc] init];

    [keyAttr setObject:(id)kSecClassKey forKey:(id)kSecClass];
    [keyAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
    [keyAttr setObject:refTag forKey:(id)kSecAttrApplicationTag]; 

    /* First we delete any current keys */
    error = SecItemDelete((CFDictionaryRef) keyAttr);

    [keyAttr setObject:extractedKey forKey:(id)kSecValueData];
    [keyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnPersistentRef];

    error = SecItemAdd((CFDictionaryRef) keyAttr, (CFTypeRef *)&persistPeer);

    if (persistPeer == nil || ( error != noErr && error != errSecDuplicateItem)) {
        NSLog(@"Problem adding public key to keychain");
        return FALSE;
    }

    CFRelease(persistPeer);

    publicKeyRef = nil;

    /* Now we extract the real ref */
    [keyAttr removeAllObjects];
    /*
    [keyAttr setObject:(id)persistPeer forKey:(id)kSecValuePersistentRef];
    [keyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef];
    */
    [keyAttr setObject:(id)kSecClassKey forKey:(id)kSecClass];
    [keyAttr setObject:refTag forKey:(id)kSecAttrApplicationTag];
    [keyAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
    [keyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef];

    // Get the persistent key reference.
    error = SecItemCopyMatching((CFDictionaryRef)keyAttr, (CFTypeRef *)&publicKeyRef);    

    if (publicKeyRef == nil || ( error != noErr && error != errSecDuplicateItem)) {
        NSLog(@"Error retrieving public key reference from chain");
        return FALSE;
    }

    return TRUE;
}


I was forwarded an article today from the BBC news website - Zurich Insurance fined £2.3m over customers’ data loss .  It’s a fairly standard article about a financial institution being fined for  losing customer data.

What really struck me though was a comment in the article from the FSA – “Firms across the financial sector would do well to look at the details of this case and learn from the mistakes that Zurich UK made…“.  That’s true.  But what concerns me is the real focus on fincos with this stuff.  There are so many other companies now holding our private data – and in many cases they are holding more than the financial institutions do.

Shouldn’t we be maturing this argument now to extend beyond financial institutions?  There should a duty of care for any company holding my data.  Financials can lead the way – but we need to hold other companies accountable as well.