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
}




 

Wednesday, April 23, 2014

Creating Snapshots in Linux / MacOSX

Here is a script I wrote back in the 1999 time frame to perform daily, weekly, monthly snapshots of critical directories.  This scripts is designed for filesystems that support the notion of hard links, aka Linux and MacOSX. (The Windows filesystems do not support hard links and thus this will not work on Windows).

This script is usually called from /etc/crontab and requires that you have rsync installed on the system.  At the top of the actual script code is a section that you will need to update to specify where you want the backups to go and what directories you want to backup.



#!/usr/bin/perl
#
#
####################################################################
# Ideas taken from Mike's handy rotating-filesystem-snapshot       #
# utility, http://www.mikerubel.org/computers/rsync_snapshots/     #
# and from code written by Eric Ross                               #
####################################################################
#
####################################################################
# This program is not guaranteed to work at all, and by using this #
# program you release the author of any an all liability.          #
#                                                                  #
# You may use this program so long as this notice, disclaimer and  #
# comment box remain intact and unchanged.                         #
#                                                                  #
# Please send me all bugs and patches.                             #
#                                                                  #
# Written by Bret Jordan                                           #
# jordan at open1x littledot org                                   #
####################################################################
#
#
#
# Example /etc/crontab
# Every night at 1:01 make rsync copy and then give plenty of time before snapshots
# 01 1  * * *     root  /local/bin/snapshot rsync
#
# Every night at 2:01 make snapshots
# 01 2  * * *     root  /local/bin/snapshot snap 7 daily
#
# Every Sunday Morning at 3:01 make weekly snapshot
# 01 3  * * 7     root  /local/bin/snapshot snap 4 weekly
#
# First day of every month at 4:01 make monthly snapshot
# 01 4  1 * *     root  /local/bin/snapshot snap 12 monthly


use 5.8.8;
use strict;
use warnings;

our $VERSION = "0.02";
$VERSION = eval $VERSION;

my $sType = shift;
my $iHistoryLength = shift; 
my $sFreq = shift;


########################
# BEGIN THINGS TO UPDATE

my $sSnapDir = "/backups/snapshots";
my $sCurrentBackupDir = "$sSnapDir/backup.current";
my @aDirsToBackup = qw (/data/home/);

# END THIGNS TO UPDATE
########################


unless ($sType eq "rsync" || $sType eq "snap")
{ &ShowSyntax(); }


if ($sType eq "snap")
{
    unless ($iHistoryLength =~ /^\d+$/) 
    { &ShowSyntax(); }

    unless ($sFreq eq "hourly" || $sFreq eq "daily" || $sFreq eq "weekly" || $sFreq eq "monthly") 
    { &ShowSyntax(); }
}


sub ShowSyntax
{
    print "Please run command with ./snapshot <rsync snap=""> <historylength> <freq name="">\n";
    print "Example: ./snapshot 7 daily\n";
    print "Example: ./snapshot 24 hourly\n";
    die;
}

# Lets make sure we are running at root
unless ( $< == 0 ) { die "This program must be run as root\n"; }

# Do we have write access to the snap directory?
unless ( -w $sSnapDir ) { die "This user does not have write access to $sSnapDir\n"; }


if ($sType eq "rsync") 
{
    #----------------------------------------
    # Rsync Command
    #----------------------------------------
    #-a = archive mode which is -rlptgoD (no -H,-A,-X)
    #
    #-r = recurse in to directories
    #-l = copy symlinks as symlinks
    #-p = preserve permissions
    #-t = preserve modification times
    #-g = preserve group
    #-o = preserve owner
    #-D = preserve device files and special files

    foreach (@aDirsToBackup) { system("rsync -vax --delete $_ $sCurrentBackupDir"); }

    # Touch the directory so the date time is right
    system("touch $sCurrentBackupDir");
}
elsif ($sType eq "snap")
{
    # Step 1: Delete oldest snap shot and increase the age of the rest
    my $i = $iHistoryLength;
    while ($i > 0)
    {
    my $sCurrentDir = "$sSnapDir/backup.$sFreq.$i";

    # If index equals the max length of the history, then delete that directory
    if ( $i == $iHistoryLength ) { system ("rm -rf $sCurrentDir"); }
    else 
    {  
        my $j = $i + 1;
        my $sNewDir = "$sSnapDir/backup.$sFreq.$j";
        if ( -d $sCurrentDir ) { system ("mv $sCurrentDir $sNewDir"); }
    }
    $i--;
    }

    # Step 2: Make a hard link from the backup.current to backup.daily.1
    unless ( -d $sCurrentBackupDir ) { die "The current backup directory does not exist\n"; }
    system("cp -al $sSnapDir/backup.current $sSnapDir/backup.$sFreq.1");
}



Thursday, April 10, 2014

Heartbleed-ing on the inside

It is alarming to me how many vendors have not yet produced a patch for the OpenSSL issue, even days after it was released. Some vendors have taken the stance and said, "you should not have the management/configuration interface be public facing". This mindset follows the escargot model of security from the 1990s and is not an acceptable solution.

The idea of having just a hard and crunchy firewall perimeter while maintaining a soft and chewy inside is dangerous. Please remember that when a system in the organization is compromised, it can, and often does, give a remote user (threat actor) access to the inside network. When this happens the predictive and preventive security tools that you spent so much money on are not going to help you when all your trusted servers are effectively wide open to the internal network.