Sunday, September 21, 2014

A solution to prevent man-in-the-middle attacks

The balancing act between risk and trust with man-in-the-middle visibility is two fold:
  1. Corporate and Government networks need insight in to the data traversing their networks to protect them from advanced attacks, malicious insider threats, and inappropriate activities.
  2. End users want a certain level of privacy for trusted services, like banking, medical communications, and other sensitive traffic. There are some that will respond to this with “do not do personal things at work!” However, in our hyper-connected world where the lines between work and home are often heavily blurred, that draconic view is no longer valid. 
The solution today is to find an SSL man-in-the-middle solution that is policy based, something that will not decrypt sensitive traffic while decrypting everything else.  However, the problem with this is the end user has no visibility in to what that policy is and if their sensitive traffic was added to the exception list.  This is further complicated by the fact that once the root CA has been loaded in their browser there is no visual indication that this traffic will be intercepted.

To solve this problem and give end users the protections they want, I see a time coming when you will no longer need to use RSA or Diffie–Hellman to exchange keys beyond the initial account creation process with the service provider (if you went in to the brick-n-mortar facility then you would not even need that). Imagine if during the account creation process you could create a symmetric key with the provider along with some extra algorithm information for OTP randomness. You could then type that same key and OTP randomness in to a browser plugin for that site and never need to use standard SSL key exchanges again.  This would nullify all SSL man-in-the-middle attacks.

Given that it only takes one person with access to sensitive network traffic to cause problems, end users are hungry for solution to protect their privacy.

Saturday, September 20, 2014

Honey Roasted Almonds
















Source: Bret Jordan, modified from AllRecipes.com

Ingredients
  • Almonds, whole, shelled  -  3 Cups
  • Sugar, White  -  1/4 Cup
  • Salt, Kosher  -  1/2 Teaspoon
  • Honey  -  3 Tablespoons
  • Water  -  3 Tablespoons
  • Vegetable Oil  - 1 Tablespoon

Directions
  1.  Mix sugar and salt in a small bowl and scoop 1 tablespoon of that mixture in to large bowl (the tablespoon of sugar on the bottom helps keep them from sticking to the bowl).
  2.  Put honey, water, and oil in large sauce pan and set aside
  3.  Spread almonds in a single layer on a cookie sheet and place in cold oven
  4.  Set oven to 350 degrees, after 20 minutes remove almonds from the oven.  While in the oven stir every 4 minutes. As ovens vary, typically almonds are done when quite fragrant.  Watch them closely so they do not burn.
  5.  Just before the almonds are done, bring the sauce pan with the honey, water, and oil mixture to a boil, stirring frequently.  Once it boils turn down to med-low heat. (It should come to a boil very quickly.)
  6.  When the almonds are done, take them out of the oven and put them immediately in to the sauce pan with the hot liquid (do not let the almond cool first)
  7.  Cook the almonds and caramel sauce for about 5 minutes, stirring constantly.
  8.  Once all of the liquid is absorbed or completely caramelized dump the almonds in to the large bowl containing the sugar/salt mixture (see step 1).  
  9.  Slowly sprinkle the almonds with the remaining sugar/salt mixture while constantly tossing the almonds.
  10.  Spread almonds out on a piece of parchment paper to cool and dry.
  11.  Lightly sprinkle with some extra table salt.
  12.  Once dry (a few hours to over night) put in an air tight container, they will store for a few days.


Sunday, September 14, 2014

The Future of Protecting Corporate Data


Protecting corporate data in the future will be a lot harder than it is today using the current methodology and solutions of IPS, Next Generation Firewalls, DLP, and full packet capture. 

The reason for this is most corporate IT departments assume that when a user is at work they are using the corporate network (wired or Wi-Fi). This idea predicates that all protections for the network and its data be located on the link to the Internet service provider, the point at which data leaves or comes in to the network.

The reality is that users do not need to use the corporate network all of the time. With the migration to cloud services, users can actually access most of their corporate data from the LTE Cellular network on their device. This allows users to completely bypass the corporate network and all of the controls and visibility solutions that IT has deployed. 

There are many reasons why a user may choose to this:
1)   They honestly do not know the difference or forget to turn on Wi-Fi when they get to the office
2)   They want access to services that IT is currently blocking via the proxy or content filtering solution
3)   Their LTE connection is faster than the corporate internet connection

To further complicate things, in the future I see a driver being written for Android and iOS that will allow per-application routing to either the Cellular Data Network or the internal Wi-Fi network, thus allowing some applications to talk to internal systems, while others to talk directly to the internet. 

It will be interesting to see how IT, security, and risk departments try to tackle this problem.  My guess is that it will first start with a draconic approach, then move to strict policy enforcement, and then finally where it should go, and that is private hybrid clouds with full identity and location aware networking. Each hybrid cloud instance will also need full reverse perimeter protections like IPS, Next Generation Firewalls, DLP, and full packet capture. It seems like the old Identity Engines had the right idea, they were just 10 years early. 

Tuesday, August 26, 2014

STIX and TAXII: On the road to becoming the de facto standard


The road to blissful cyber threat intelligence sharing often feels like a bumpy dirt track in a Wild West ghost town, but there’s hope on the horizon: A new language, designed to define and describe a broad swath of threat activity, is beginning to take shape. This language, known as STIX, and its transport method, called TAXII, offers security firms, industry, and government the promise of better and faster cyber threat intelligence sharing.

STIX and TAXII have been getting key support and backing from groups as diverse as the Department of Homeland Security, The MITRE Corporation, and members of various information security groups and vendors, including Blue Coat Systems. For the past 6 months, I have been heading up Blue Coat’s participation in this effort.

STIX (Structured Threat Information eXpression) is a language used to communicate a set of cyber threat intelligence idioms, including:

·      Threat Actors
·      Campaigns
·      Techniques, Tactics, and Procedures
·      Exploit Targets
·      Indicators
·      Incidents
·      Cyber-Observables
·      Courses of Action

TAXII (Trusted Automated eXchange of Indicator Information) is the preferred delivery mechanism for STIX data. Technically, TAXII is a lightweight XML-over-HTTP transport protocol, specifically designed to deliver STIX data. TAXII allows publishers to share STIX data with (and, optionally, get STIX data from) subscribers, or for peers to share STIX data with other peers.

The STIX and TAXII standards have matured well beyond their initial drafts and first release in 2013. In fact, major vendors are lining up to announce support and governments, incident responders and CERTs, the Financial Services Information Sharing and Analysis Center (FS-ISAC), and the Industrial Control Systems Information Sharing and Analysis Center (ICS-ISAC) (to name a few) have already started using STIX and TAXII in their production environments.

With all new technologies and community driven efforts, there inevitably comes a point when someone asks the question "when will this move to an official international standards body?" It is my opinion that moving right now to an international standards body would just inhibit development and slow down adoption. For the past two years, the amazing grassroots efforts of MITRE and DHS – with the help of FS-ISAC – have produced remarkable results.

In my opinion, four issues are slowing down the adoption of STIX and TAXII as the de facto standard:

Item 1: The absence of a hardened, full-featured, open source, Berkeley Software Distribution (BSD) licensed, TAXII server that end users, enterprises, and vendors can easily use and adapt for their needs. A project currently underway at FS-ISAC called Avalanche may solve this need, in the end. We need the TAXII equivalent of a FreeRADIUS server.  It would be nice if it were highly efficient, fully featured, and written in a compiled language for performance reasons.  

Item 2: Better support for creating and interpreting STIX packages. MITRE has done a lot of good work on creating and maintaining Python APIs, and there are some up and coming Java APIs. However, additional language support is needed; Hopefully, the community will create additional bindings. Part of the issue comes from the debate among contributors about the format that the data will eventually take: XML, JSON, or Cap'n Proto. In my experience, most academics love XML, and most developers ask for anything but XML.

Item 3: A fully featured, standalone GUI client or application – or a combination of the two – that will allow someone to manually create and/or understand STIX packages from their computer and/or mobile device. Even though you can publish STIX data via TAXII, I still see people posting cyber threat information on their Web site, FTP server, or via an RSS feed.  We really need a way of reading those packages and being able to update/change them and re-publish the results back in STIX format. It would be great if this GUI tool could also talk to a remote TAXII server and query it by asking "give me information you have about 'foo' and 'bar'". Having access to a tool like this would make it a lot easier for someone researching issues they see in their own network.   

Item 4: My personal wish item is an analytics tool for the cyber threat data itself.  Once you start collecting large repositories (millions of indicators or bigger) of STIX data.  As repositories of indicators increase in size, it becomes difficult to see the big picture. Imagine having the ability to run some sort of analytics tool on top of your cyber threat intelligence data to make sense of it all: Something that can build correlations while visually helping you research and understand the threat data you have. I could see someone taking a tool like this and overlaying their own traffic to answer interesting questions like 'what types of threat data are actually found in my network?’ and ‘what other entities are seeing the same types of data?' (said another way, 'what threat feeds are the most relevant for my network?').

With every user that jumps on board, every vendor that comes to the table, and—as owners of large cyber threat data decide to play—everyone wins and becomes more secure. As a result, that deserted bumpy road of cyber threat intelligence sharing in the middle of a Wild West ghost town will no longer be deserted, and will become a smooth paved boulevard of information exchange.

Eventually, STIX and TAXII will evolve into the de facto standard because it is the first standard collaboratively created by the people that actually WANT to share and WILL share critical cyber threat intelligence.

Thursday, July 10, 2014

How to assign ACLs to Cisco VPN user via RADIUS

While setting up per user ACLs in RADIUS for my VPN users I noticed some issues with current on-line documentation. I am using a Cisco ASA 9.2(2) as the VPN concentrator and FreeRADIUS 3.0.2 as the RADIUS server.  In the RADIUS users file you need to add your ACLs in this manner:

testuser1  Cleartext-Password := "testme"
   Cisco-AVPair = "ip:inacl#101=permit ip any 192.168.1.0 255.255.255.0",
   Cisco-AVPair += "ip:inacl#102=deny ip any any",
   Service-Type = Framed-User,
   Framed-Protocol = PPP,
   Framed-IP-Address = 192.168.255.97,
   Framed-IP-Netmask = 255.255.255.0,
   Reply-Message = "This is a test message"


You should notice the use of "ip:inacl" not "ip.inacl" as most current on-line documentation suggests.  Also, make sure you use "+=" for every line other than the first. 

Thursday, July 3, 2014

Cisco AnyConnect Secure Mobility Client Authentication Errors

I recently ran in to a problem where I would get the dreaded "User not authorized for AnyConnect Client access, contact your administrator" error message from my Cisco ASA running version 9.2(2) when trying to connect to the VPN service (IPSec, IKEv2).  The really frustrating part was my Mac could connect just fine, but my Windows VM would not. After some research I figured out what the fundamental problem was and what was causing it.

The main issue was the AnyConnect Client Profile was not getting downloaded to the Windows machine. The reason my Mac worked, is I had successfully downloaded it at some point and it was cached. On Windows 7 you can find the file in the following directory:
C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Profile>

On Mac you can find the same profille in:
/opt/cisco/anyconnect/profile->

The reason it was not getting downloaded is I had turned off the SSL Access configuration in the AnyConnect Connection Profiles interface section, since I was not using it.  You turn this back on, and viola it works. So if you are getting the dreaded error, check to see if you have your AnyConnect Client Profile first.

Tuesday, April 29, 2014

Working With Golang Array Slices

In the Go language a Slice is equivalent to the way a Perl/Python developer might think of an Array.  Yes, there is an actual Array under the covers of a Slice, but you cannot do much with them. So in Go, most people works with a Slice.  So if you are new to Go and coming from Perl/Python or the like, when you think you want an Array, you really want a Slice.  

Example
package main

import (
 "fmt"
)

func main() {
 
 // This is how you would declare and initialize a Slice at the same time.
 var aSliceOfStrings1 = []string{"a", "b", "c"}
 fmt.Println(aSliceOfStrings1[1])
 // This will print "b"


 // This is a shorthand way of declaring and initializing a Slice at the same time.
 aSliceOfStrings2 := []string{"c", "d",}
 fmt.Println(aSliceOfStrings2[1])
 // This will print "d" 

 
 // To create a slice but not initialize it you would use the make function.  This allows to define the
 // size and the optional capacity (defaults to length) at the same time.
 aSliceOfStrings3 := make([]string, 5, 10)
 aSliceOfStrings3[0] = "a"
 aSliceOfStrings3[1] = "b"
 aSliceOfStrings3[2] = "c"
 aSliceOfStrings3[3] = "d"
 aSliceOfStrings3[4] = "e"
 fmt.Println(aSliceOfStrings3[0])
 // This will print "a"


 // Append a Slice with more data
 aSliceOfStrings3 = append(aSliceOfStrings3, "f", "g", "h")
 fmt.Println(aSliceOfStrings3[6])
 // This will print "g"

 // Get the length and capacity of a Slice
 l := len(aSliceOfStrings3)
 fmt.Println("Length: ", l)
 // This will print "Length: 8"

 c := cap(aSliceOfStrings3)
 fmt.Println("Capacity: ", c)
 // This will print "Capacity: 10"

 // Copy an element of a Slice
 i := aSliceOfStrings3[1]
 fmt.Println(i)
 // This will print "b"


 // Copy part of a Slice in to another Slice, end needs to be what you want + 1 so if we want [2:4] we need to say [2:5]
 // You can also say [:] to mean the entire Slice. 
 // [:2] means the start of the Slice to the second element. 
 // And [2:] to mean from the second element to the end of the Slice.
 anotherSliceOfStrings1 := aSliceOfStrings3[2:5]
 fmt.Println("Length: ", len(anotherSliceOfStrings1))
 fmt.Println("Capacity: ", cap(anotherSliceOfStrings1))
 fmt.Println(anotherSliceOfStrings1[0])
 fmt.Println(anotherSliceOfStrings1[2])
 // This will print "Length: 3"
 // This will print "Capacity: 8" since we removed the first 2 elements of the original Slice
 // This will print "c" and "e"

 anotherSliceOfStrings2 := aSliceOfStrings3[:2]
 fmt.Println("Length: ", len(anotherSliceOfStrings2))
 fmt.Println("Capacity: ", cap(anotherSliceOfStrings2))
 fmt.Println(anotherSliceOfStrings2[0])
 fmt.Println(anotherSliceOfStrings2[1])
 // This will print "Length: 2"
 // This will print "Capacity: 10" the start of the Slice did not change so the capacity is the same
 // This will print "a" and "b" 

 anotherSliceOfStrings3 := aSliceOfStrings3[4:]
 fmt.Println("Length: ", len(anotherSliceOfStrings3))
 fmt.Println("Capacity: ", cap(anotherSliceOfStrings3))
 fmt.Println(anotherSliceOfStrings3[0])
 fmt.Println(anotherSliceOfStrings3[1])
 // This will print "Length: 4"
 // This will print "Capacity: 6" the start of the Slice changed so the capacity did as well
 // This will print "e" and "f"
}




Passing Slices to Functions
It's important to understand that even though a slice contains a pointer, it is really a value that under the covers is a struct value holding a pointer and a length. It is not a pointer to a struct. 

This matters when you pass a Slice to a function.  When you pass a Slice to a function you can modify the values in the Slice in the function and they will keep, however,  you can not modify the header (aka the length and capacity) as the header was passed by value not as a pointer.  If you want to modify the header, then you need to pass the Slice as a pointer not as a value.    You pass a Slice as a pointer by preceding it with an “&”.  Here is an example to replicate the "shift" function in Perl.

package main

import ("fmt")

var DEBUG int = 0

// This function tries to replicate the shift function in Perl by removing the first
// element of an slice and returning it
func Shift (pToSlice *[]string) string {
    sValue := (*pToSlice)[0]
    if DEBUG == 1 {
        fmt.Println("The slice before the shift: ",  *pToSlice)
    }
    *pToSlice = (*pToSlice)[1:len(*pToSlice)]
    
    if DEBUG == 1 {
        fmt.Println("The slice after the shift: ",  *pToSlice)
    }
    return sValue    
}


func main() {
    var a = []string{"1", "2", "3", "4"}
    for i := range a {
        fmt.Println(a[i])
    }
    // This will print 1, 2, 3, 4


    test := Shift(&a)
    fmt.Println("This is the shifted value: ", test)
    // This will print 1


    test2 := Shift(&a)
    fmt.Println("This is the shifted value: ", test2)
    // This will print 2
    
    for i := range a {
        fmt.Println(a[i])
    } 
    // This will print 3, 4
}