Retrieving TippingPoint Reports in .NET

From SoftLayer Development Network Wiki

Jump to: navigation, search
The information in this guide is deprecated. Please read out C# and Visual Basic .NET guides for HOW-TOs and examples. Thanks!

As with our first .NET example this TippingPoint reporting tool uses Visual Studio's Web Reference technology to interact with our API's SOAP service. If you're new to working with C#, Visual Studio, and Web References then please read the article Implementing SOAP in .NET before continuing.

Our last .NET API example introduced you to querying the API from Visual Studio using Web References to make a simple console bandwidth monitor. This example delves into the SoftLayer TippingPoint network IDS logs and queries the SoftLayer_Network_TippingPointReporting service to generate a comma-separated values (CSV) file with a simple report containing the number of attacks your account and your subnets have received over a given period of time. To shake things up a little we're going to accept your API username and api key as program arguments. This way you don't have to hard code your authentication credentials into your API application and can distribute this program to other SoftLayer users.

This example also takes optional program arguments to report the up to a certain number of attacks, the number of minutes from the current time to retrieve attack logs for, and the path to save the CSV report to. If the user doesn't specify these then the program uses default values of 5 attacks, 60 minutes, and the "\SoftLayer" directory relative to the directory that the program is run from.

If you want to skip our analysis you can download the Visual Studio solution for this report. Also, if you don't want to bother with coding, but want to use this report tool you can download the compiled executable. Remember that you must have the latest .NET runtime libraries installed in order to run this program. You can download them from your system's Windows Update feature or from the Mono Project if you use a non-Microsoft operating system.


Contents

The Report Header

The SoftLayer_Network_TippingPointReporting service's methods are varied enough that we can make a useful CSV report header with an overall attack count per datacenter and for your account as a whole. The getMainStatistics method can get this information for us. This method returns a SoftLayer_Container_Network_IntrusionProtection_Statistics data type, which we loop through it to generate the output for our report header:

 
streamWriter.WriteLine("\nMain Statics Report for the Top {0} Attack(s)", numberOfAttacks);
streamWriter.WriteLine("");
streamWriter.WriteLine("Total Attack(s),Time Frame,Target Type,Target");
 
foreach (SoftLayer_Network_TippingPointReporting.SoftLayer_Container_Network_IntrusionProtection_Statistics stats in service.getMainStatistics(numberOfAttacks))
{
    streamWriter.WriteLine("{0},{1},{2},{3}", stats.totalAttacks, stats.timeFrame, stats.targetType, stats.target);
}
 

This code snippet produces CSV output similar to:

Main Statics Report for the Top 5 Attack(s)

Total Attack(s),Time Frame,Target Type,Target
7175,Last Hour,datacenter,dal01
82209,Last 24 Hours,datacenter,dal01
1684,Last Hour,datacenter,sea01
601169,Last 24 Hours,datacenter,sea01
13,Last Hour,Account - Top Attacks,username
137,Last 24 Hours,Account - Top Attacks,username

Reporting Attack Details

Now that we have our report's summary header let's drill down and get a more detailed report of the attacks against our account's subnets. Use the getSubnetReportForEntireAccount method in the SoftLayer_Network_TippingPointReporting service to get a list of these attacks. This returns a SoftLayer_Container_Network_IntrusionProtection_SubnetReport object, which we can use with the drillDownAttack method to get the SoftLayer_Container_Network_IntrusionProtection_Event objects that we loop through to generate specific CSV output, like so:

 
streamWriter.WriteLine("\n\nSubnet Reports for the Last {0} min(s)", timeFrame); // Section Title
streamWriter.WriteLine("\nCidr,Direction,Subnet Ip Address, Event(s)"); // Header row for the subnet report
 
// Call SoftLayer_Network_TippingPointReporting::getSubnetReportForEntireAccount. 
// This returns a SoftLayer_Container_Network_IntrusionProtection_SubnetReport 
// object which contains subnet information and an array of 
// SoftLayer_Container_Network_IntrusionProtection_Event objects for each 
// event reported. 
foreach (SoftLayer_Network_TippingPointReporting.SoftLayer_Container_Network_IntrusionProtection_SubnetReport statistics in service.getSubnetReportForEntireAccount(timeFrame,null,null,false))
{
    cidr = 0;
    if(statistics.cidrSpecified)
        cidr = Convert.ToInt32(statistics.cidr);
 
    // Write the CIDR, subnet address, and direction to the CSV event header.
    streamWriter.WriteLine("{0},{1},{2},Attack Count, Attack Name,Classification,Protocol,Platform,Bug Track Id,CVE Id,Severity,Action Taken,Signature Id,Beginning Time,End Time,Destination Ip Address, Destination Port, Source Ip Address, Source Port, Description",
        statistics.cidr,
        statistics.direction,
        statistics.subnetIpAddress);
 
    // Loop through the events for the subnet and call 
    // Call SoftLayer_Network_TippingPointReporting::drillDownAttack 
    // to retrieve more details about each attack.
    foreach(SoftLayer_Network_TippingPointReporting.SoftLayer_Container_Network_IntrusionProtection_Event events in statistics.events)
    {
        attackCount = 0;
        destinationPort = 0;
        sourcePort = 0;
        classification = null;
        bugtraqId = null;
        CVEId = null;
        attackLongDescription = null;
 
        // Call SoftLayer_Network_TippingPointReporting::getDrilldown and output the event's details to the CSV file.
        SoftLayer_Network_TippingPointReporting.SoftLayer_Container_Network_IntrusionProtection_SubnetReport drillDown = service.drillDownAttack(events.signatureId, "All Subnets", 32, timeFrame, statistics.direction.ToUpper());
        foreach (SoftLayer_Network_TippingPointReporting.SoftLayer_Container_Network_IntrusionProtection_Event drillDownEvents in drillDown.events)
        {
            // Scrub the API response before outputting it to the CSV file
            if (drillDownEvents.attackCountSpecified)
                attackCount = Convert.ToInt32(drillDownEvents.attackCount);
            if (drillDownEvents.destinationPortSpecified)
                destinationPort = Convert.ToInt32(drillDownEvents.destinationPort);
            if (drillDownEvents.sourcePortSpecified)
                sourcePort = Convert.ToInt32(drillDownEvents.sourcePort);
            if (drillDownEvents.classification != null)
                classification = drillDownEvents.classification.Replace(",", " ");
            if (drillDownEvents.bugtraqId != null)
                bugtraqId = drillDownEvents.bugtraqId.Replace(",", ";");
            if (drillDownEvents.CVEId != null)
                CVEId = drillDownEvents.CVEId.Replace(",", ";");
            if (drillDownEvents.attackLongDescription != null)
                attackLongDescription = drillDownEvents.attackLongDescription.Replace(",", ";");
 
            streamWriter.WriteLine(",,,{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16}",
                attackCount,
                drillDownEvents.attackName,
                classification,
                drillDownEvents.protocol,
                drillDownEvents.platform,
                bugtraqId,
                CVEId,
                drillDownEvents.severity,
                events.actionTaken,
                events.signatureId,
                drillDownEvents.beginTime,
                drillDownEvents.endTime,
                drillDownEvents.sourceIpAddress,
                sourcePort,
                drillDownEvents.destinationIpAddress,
                destinationPort,
                drillDownEvents.attackLongDescription.Replace(",", " "));
        }
    }
}
 

The bugtraqId and CVEId variables in this snippet refer to an attack's entries in the SecurityFocus Vulnerability and Common Vulnerabilities and Exposures databases. This snippet produces output similar to:

Subnet Reports for the Last 60 min(s)
Cidr,Direction,Subnet Ip Address, Event(s)
,Inbound,All Subnets,Attack Count, Attack Name,Classification,Protocol,Platform,Bug Track Id,CVE Id,Severity,Action Taken,Signature Id,Beginning Time,End Time,Destination Ip Address,  Destination Port, Source Ip Address, Source Port, Description
,,,2, HTTP: Zen Cart PHP File Include Vulnerability,Vulnerability: Invalid Input (Command injection  Cross-site Scripting  SQL injection  etc),http,Multi-Platform Server Application or Service,,,Critical,Block,00000001-0001-0001-0001-000000004657,2008-03-20T18:49:35-05:00,2008-03-20T18:51:00-05:00,165.10.0.0.4,41925,10.0.0.5,80, This filter detects an attempt to post the contents of an external  script to the zen cart PHP application.  This application is vulnerable to a file include vulnerability  attack when "register_globals" is enabled. This attack could allow  an attacker to insert custom code into a variable that would be  executed by all users of the vulnerable application.  Reference:  Secunia   http://archives.neohapsis.com/archives/secunia/2006-q3/0606.html

...
...

Remember that your output will vary depending on how much suspicious network traffic your subnets send and receive. Once the program is done looping through the data it saves the CSV file and exits. Sounds easy enough, right?

The Complete Source

Here's the full source to the main program. These are provided as part of our example's solution files. If you want to see the example in action then check out our included project files. Otherwise you'll need to create your own Web References if you're creating this project from scratch.

 
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
 
// Generate a CSV report containing the network-based attacks directed toward 
// an account's subnets. The top of the report states the total number of 
// attacks against the account and the total number of attacks per datacenter. 
//
// The main body of the report contains a more detailed list of attacks against 
// a subnet including the type of attack, severity, source IP and port, and 
// destination IP and port.
//
// SoftLayer API authentication, the maximum number of attacks to retrieve, a 
// time frame of the number of attacks to retrieve for, and a path to save the 
// CSV report to are each provided by arguments to this program. Only API 
// username and key are requires arguments. Number of attacks defaults to 5, 
// time frame defaults to 60 minutes, and path defaults to the current 
// directory + "\SoftLayer". Each report is saved with the file name 
// "TippingPoint-yyyy-MM-dd-hh-mm-ss.csv", where "yyyy-MM-dd-hh-mm-ss" 
// corresponds to the time at which the program is called.
//
// This project was built in Visual Studio 2008 Express Edition on Windows XP 
// SP2 and Windows Vista Business SP1.
//
// The latest version of this code can be found at 
// http://sldn.softlayer.com/wiki/index.php/Retrieving_TippingPoint_Reports_in_.NET .
//
// This project is created by SoftLayer Technologies, Inc. and is available for 
// use under the Creative Commons Attribution 3.0 United States license. 
// <http://creativecommons.org/licenses/by/3.0/us/>.
 
namespace SLTippingPointClientApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("SoftLayer Technologies, Inc. - Statistics Report Application");
            string userName = null;
            string apiKey = null;
            string pathDirectory = null;
            string newDirectory  = null;
            string timeStamp = null;
            int timeFrame = 0;
            int numberOfAttacks = 0;
 
            // Process program arguments. 
            //  - API username and key are required. Generate your API key at https://manage.softlayer.com/UserManagement/apiKeychain
            //  - numberOfAttacks defaults to 5
            //  - timeFrame defaults to 60
            //  - path is only set when numberOfAttacks, timeframe, and path are specified.
            switch (args.Length)
            {
                case 2:
                    userName = args[0];
                    apiKey = args[1];
                    numberOfAttacks = 5;
                    timeFrame = 60;
                    break;
                case 3:
                    userName = args[0];
                    apiKey = args[1];
                    numberOfAttacks = Convert.ToInt32(args[3]);
                    timeFrame = 60;
                    break;
                case 4:
                    userName = args[0];
                    apiKey = args[1];
                    numberOfAttacks = Convert.ToInt32(args[2]);
                    timeFrame = Convert.ToInt32(args[3])*60;
                    break;
                case 5:
                    userName = args[0];
                    apiKey = args[1];
                    numberOfAttacks = Convert.ToInt32(args[2]);
                    timeFrame = Convert.ToInt32(args[3])*60;
                    pathDirectory = args[4];
                    break;
 
                default:
                    // Write a small usage statement if no or more than 5 arguments were entered.
                    Console.WriteLine("");
                    Console.WriteLine("Usage: SLTippingPointClientApplication.exe <username> <apiKey> [numberOfAttacks] [timeFrame] [path]");
                    Console.WriteLine("");
                    Console.WriteLine("  username:        Your SoftLayer portal username");
                    Console.WriteLine("");
                    Console.WriteLine("  apiKey:          Your SoftLayer user's API key");
                    Console.WriteLine("");
                    Console.WriteLine("  numberOfAttacks: (optional) The maximum number of attacks to report.");
                    Console.WriteLine("                   Default: 5");
                    Console.WriteLine("");
                    Console.WriteLine("  timeFrame:       (optional) The number of minutes from the current time to");
                    Console.WriteLine("                   retrieve attacks for. Default: 60");
                    Console.WriteLine("");
                    Console.WriteLine("  path:            (optional) The path to save your report to. Default:");
                    Console.WriteLine("                   " + Directory.GetCurrentDirectory() + @"\SoftLayer");
                    Console.WriteLine("");
                    return;
 
            }
 
            // Determine the path to write the CSV report to. 
            timeStamp = DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss");
 
            if (pathDirectory == null)
            {
                newDirectory = Directory.GetCurrentDirectory() + @"\SoftLayer";
                Directory.CreateDirectory(newDirectory);
                pathDirectory = newDirectory + @"\TippingPoint-" + timeStamp + ".csv";
            }
            else
            {
                Directory.CreateDirectory(pathDirectory);
                pathDirectory = pathDirectory + @"\TippingPoint-" + timeStamp + ".csv";
            }
 
            // Create the filestream and write out the CSV header.
            Console.WriteLine("\nWriting file to directory: {0}\nPlease wait while we process the report...",pathDirectory);
 
            FileStream file = new FileStream(pathDirectory, FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter streamWriter = new StreamWriter(file);
 
            streamWriter.WriteLine("Report for {0}", timeStamp);
            streamWriter.WriteLine("User Name: {0}", userName);
 
            try
            {
                // Create the connection to the SoftLayer_Network_TippingPoint service.
                SoftLayer_Network_TippingPointReporting.SoftLayer_Network_TippingPointReportingService service = new SLTippingPointClientApplication.SoftLayer_Network_TippingPointReporting.SoftLayer_Network_TippingPointReportingService();
 
                // Set up authentication to the SL API.
                SoftLayer_Network_TippingPointReporting.authenticate serviceAuthentication = new SLTippingPointClientApplication.SoftLayer_Network_TippingPointReporting.authenticate();
                serviceAuthentication.username = userName;
                serviceAuthentication.apiKey = apiKey;
                service.authenticateValue = serviceAuthentication;
 
                // Continue writing the CSV header and set up for writing our general attack information.
                streamWriter.WriteLine("\nMain Statics Report for the Top {0} Attack(s)", numberOfAttacks);
                streamWriter.WriteLine("");
                streamWriter.WriteLine("Total Attack(s),Time Frame,Target Type,Target");
 
                // Call SoftLayer_Network_TippingPoint::getMainStatistics and write out it's response to the CSV file.
                foreach (SoftLayer_Network_TippingPointReporting.SoftLayer_Container_Network_IntrusionProtection_Statistics stats in service.getMainStatistics(numberOfAttacks))
                {
                    streamWriter.WriteLine("{0},{1},{2},{3}", stats.totalAttacks, stats.timeFrame, stats.targetType, stats.target);
                }
 
                // Prepare to loop through a subnet report and write it's header to the CSV.
                int cidr;
                int attackCount;
                int destinationPort;
                int sourcePort;
                string classification;
                string bugtraqId;
                string CVEId;
                string attackLongDescription;
 
                streamWriter.WriteLine("\n\nSubnet Reports for the Last {0} min(s)", timeFrame); // Section Title
                streamWriter.WriteLine("\nCidr,Direction,Subnet Ip Address, Event(s)"); // Header row for the subnet report
 
                // Call SoftLayer_Network_TippingPoint::getSubnetReportForEntireAccount(). 
                // This returns a SoftLayer_Container_Network_IntrusionProtection_SubnetReport 
                // object which contains subnet information and an array of 
                // SoftLayer_Container_Network_IntrusionProtection_Event objects for each 
                // event reported. 
                foreach (SoftLayer_Network_TippingPointReporting.SoftLayer_Container_Network_IntrusionProtection_SubnetReport statistics in service.getSubnetReportForEntireAccount(timeFrame,null,null,false))
                {
                    cidr = 0;
                    if(statistics.cidrSpecified)
                        cidr = Convert.ToInt32(statistics.cidr);
 
                    // Write the CIDR, subnet address, and direction to the CSV event header.
                    streamWriter.WriteLine("{0},{1},{2},Attack Count, Attack Name,Classification,Protocol,Platform,Bug Track Id,CVE Id,Severity,Action Taken,Signature Id,Beginning Time,End Time,Destination Ip Address, Destination Port, Source Ip Address, Source Port, Description",
                        statistics.cidr,
                        statistics.direction,
                        statistics.subnetIpAddress);
 
                    // Loop through the events for the subnet and call 
                    // SoftLayer_Network_TippingPoint::drillDownAttack 
                    // to retrieve more details about each attack.
                    foreach(SoftLayer_Network_TippingPointReporting.SoftLayer_Container_Network_IntrusionProtection_Event events in statistics.events)
                    {
                        attackCount = 0;
                        destinationPort = 0;
                        sourcePort = 0;
                        classification = null;
                        bugtraqId = null;
                        CVEId = null;
                        attackLongDescription = null;
 
                        // Call SoftLayer_Network_TippingPoint::getDrilldown and output the event's details to the CSV file.
                        SoftLayer_Network_TippingPointReporting.SoftLayer_Container_Network_IntrusionProtection_SubnetReport drillDown = service.drillDownAttack(events.signatureId, "All Subnets", 32, timeFrame, statistics.direction.ToUpper());
                        foreach (SoftLayer_Network_TippingPointReporting.SoftLayer_Container_Network_IntrusionProtection_Event drillDownEvents in drillDown.events)
                        {
                            if (drillDownEvents.attackCountSpecified)
                                attackCount = Convert.ToInt32(drillDownEvents.attackCount);
                            if (drillDownEvents.destinationPortSpecified)
                                destinationPort = Convert.ToInt32(drillDownEvents.destinationPort);
                            if (drillDownEvents.sourcePortSpecified)
                                sourcePort = Convert.ToInt32(drillDownEvents.sourcePort);
                            if (drillDownEvents.classification != null)
                                classification = drillDownEvents.classification.Replace(",", " ");
                            if (drillDownEvents.bugtraqId != null)
                                bugtraqId = drillDownEvents.bugtraqId.Replace(",", ";");
                            if (drillDownEvents.CVEId != null)
                                CVEId = drillDownEvents.CVEId.Replace(",", ";");
                            if (drillDownEvents.attackLongDescription != null)
                                attackLongDescription = drillDownEvents.attackLongDescription.Replace(",", ";");
 
                            streamWriter.WriteLine(",,,{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16}",
                                attackCount,
                                drillDownEvents.attackName,
                                classification,
                                drillDownEvents.protocol,
                                drillDownEvents.platform,
                                bugtraqId,
                                CVEId,
                                drillDownEvents.severity,
                                events.actionTaken,
                                events.signatureId,
                                drillDownEvents.beginTime,
                                drillDownEvents.endTime,
                                drillDownEvents.sourceIpAddress,
                                sourcePort,
                                drillDownEvents.destinationIpAddress,
                                destinationPort,
                                drillDownEvents.attackLongDescription.Replace(",", " "));
                        }
                    }
                }
            }
 
            // If we encountered any exceptions during this process then 
            // close the file stream and exit.
            catch (Exception e)
            {
                Console.WriteLine("\n{0} Exception caught.", e);
                streamWriter.Close();
                file.Close();
                Console.WriteLine("\nReport is incomplete.");
                return;
            }
 
            // If we got here then there were no errors. Close the file stream
            // and exit.
            streamWriter.Close();
            file.Close();
            Console.WriteLine("\nReport is done.");
        }
    }
}
 

See Also

Associated Methods

External Links

Personal tools