Libpcap to read pcap file

Following is a simple C program that allows you to read a pcap file using the libpcap library. The pcap is generated using Wireshark.

I tried this code in Visual studio. Don’t forget to add WPCAP in Property->Preprocessor->Preprocessor Definitions  and also wpcap.lib in Properties->Linker->Input-> Additional dependencies.


#include <stdio.h>
#include <pcap.h>

#define LINE_LEN 16

/* 4 bytes IP address */
typedef struct ip_address {
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
}ip_address;

/* IPv4 header */
typedef struct ip_header {
u_char    ver_ihl;        // Version (4 bits) + Internet header length (4 bits)
u_char    tos;            // Type of service
u_short tlen;            // Total length
u_short identification; // Identification
u_short flags_fo;        // Flags (3 bits) + Fragment offset (13 bits)
u_char    ttl;            // Time to live
u_char    proto;            // Protocol
u_short crc;            // Header checksum
ip_address    saddr;        // Source address
ip_address    daddr;        // Destination address
u_int    op_pad;            // Option + Padding
}ip_header;

/* UDP header*/
typedef struct udp_header {
u_short sport;            // Source port
u_short dport;            // Destination port
u_short len;            // Datagram length
u_short crc;            // Checksum
}udp_header;

void packet_handler(u_char *, const struct pcap_pkthdr *, const u_char *);

int main(int argc, char **argv)
{
pcap_t *fp;
char errbuf[PCAP_ERRBUF_SIZE];
char source[PCAP_BUF_SIZE];

if(argc != 2) {

printf("usage: %s filename", argv[0]);
return -1;

}

/* Create the source string according to the new WinPcap syntax */
if ( pcap_createsrcstr(    source,            // variable that will keep the source string
PCAP_SRC_FILE,    // we want to open a file
NULL,            // remote host
NULL,            // port on the remote host
argv[1],        // name of the file we want to open
errbuf            // error buffer
) != 0) {

fprintf(stderr,"\nError creating a source string\n");
return -1;
}

/* Open the capture file */
if ( (fp= pcap_open(source,            // name of the device
65536,            // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
PCAP_OPENFLAG_PROMISCUOUS,     // promiscuous mode
1000,                // read timeout
NULL,                // authentication on the remote machine
errbuf            // error buffer
) ) == NULL) {
fprintf(stderr,"\nUnable to open the file %s.\n", source);
return -1;
}

// read and dispatch packets until EOF is reached
pcap_loop(fp, 0, packet_handler, NULL);

return 0;
}

void packet_handler(u_char *temp1,
const struct pcap_pkthdr *header, const u_char *pkt_data) {
struct tm ltime;
char timestr[16];
ip_header *ih;
udp_header *uh;
u_int ip_len;
u_short sport, dport;
time_t local_tv_sec;

(VOID)temp1;

/* convert the timestamp to readable format */
local_tv_sec = header->ts.tv_sec;
localtime_s(&ltime, &local_tv_sec);
strftime(timestr, sizeof timestr, "%H:%M:%S", &ltime);

/* print timestamp and length of the packet */
printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);

/* retireve the position of the ip header */
ih = (ip_header *)(pkt_data +
14); //length of ethernet header

/* retireve the position of the udp header */
ip_len = (ih->ver_ihl & 0xf) * 4;
uh = (udp_header *)((u_char*)ih + ip_len);

sport = uh->sport;
dport = uh->dport;

/* print ip addresses and udp ports */
printf("%d.%d.%d.%d:%d -> %d.%d.%d.%d:%d\n",
ih->saddr.byte1,
ih->saddr.byte2,
ih->saddr.byte3,
ih->saddr.byte4,
sport,
ih->daddr.byte1,
ih->daddr.byte2,
ih->daddr.byte3,
ih->daddr.byte4,
dport);
}

 

 

Suricata, Snort, Bro

Are you looking for a tool to use as an intrusion detection system for your network? Did you come accross the tools Suricata, Snort and Bro ? Are you wondering which tool you might want to use?

All the three tools are proven effective with their own exclusive features. Understanding the specific features of each of them and their differences will help you in deciding which tool would suite your need the best.

The article ‘Open Source IDS High Performance Shootout’ by SANS helped me giving a detailed picture about a comparitive study between the three. I would like to summarise the key points for you.

Usage:

To give an overall picture, Snort and Suricata come under the category of a Signature based IDS while Bro could be called a behaviour based one. In Snort and Suricata, you need to specify rules based on already known knowledge about malwares. A sample rule set would like this:


alert tcp $EXTERNAL_NET any -> $HOME_NET 139
flow:to_server,established
content:"|eb2f 5feb 4a5e 89fb 893e 89f2|"
msg:"EXPLOIT x86 linux samba overflow"
reference:bugtraq,1816
reference:cve,CVE-1999-0811
classtype:attempted-admin

Suricata also mention about a very similar rule set.

Fig reference here.

Bro has a very different approach compared to the idea of rules. Bro works with scripts. A sample Bro script looke like:

@load protocols/ssl/expiring-certs

const watched_servers: set[addr] = {
	87.98.220.10,
} &redef;

# Site::local_nets usually isn't something you need to modify if
# BroControl automatically sets it up from networks.cfg.  It's
# shown here for completeness.
redef Site::local_nets += {
	87.98.0.0/16,
};

hook Notice::policy(n: Notice::Info)
	{
	if ( n$note != SSL::Certificate_Expired )
		return;

	if ( n$id$resp_h !in watched_servers )
		return;

	add n$actions[Notice::ACTION_EMAIL];
	}

For someone with a typical linux scripting mindset, the bro scripts looks very appealing. Bro provides a totally new scripting language that makes it a highly flexible platform compared to Snort and Suricata. But from the perspective of a beginner, it might be as well hard to master the Bro scripting compared to understanding the Snort and Suricata rulesets.

Performance:

Snort is highly efficient in the scenario of moderate traffic with a single core processor. Based on architecture, snort uses 10% of CPU for parsing, 10-20% for normalisation and 70-80% of CPU for payload inspection and detection. In a test perfromed by SANS, Snort gave a perfomance of 500Mbps with 1 CPU core for 1000 signatures. For 4000 signatures, it required 2.4 CPU at a rate of 400 Mbps. It was found that a single instance of Snort is more efficient than Suricata with 50% less memory utilisation. Recent versions of Snort support PF-RING and PCAP acceleration providing support for higher traffic.

Suricata is more focused on large scale networks. In a way, it could be considered as an extension of Snort for large networks. In a scenario with a 45 CPU hosting 12 cores per CPU and 125 GB of RAM, the network throughput was 20 Gbps. Suricata had a very less packet drop of 7% while it was 53% in Snort. Suricata provides support for PF-Ring, AF packet, PCAP acceleration and NFLOG. It also works better with multi-threading. In snort the normalisation is performed for every instance while for Suricata and Bro, the normalisation is performed only once before multithreading. Suricata also support GPU cuda acceleration for pattern matching. There are also about 4000 file types build for file extraction and logging also providing MD5 matching.

Bro, as mentioned above is script driven IDS. Bro has support for clustering for high throughput environments. Bro provides a ‘worker’ based architecture to utilise multiple processors. Bro’s developers recommend allocating one core for every 80 Mbps of traffic that is being analysed. It also have features allowing to interact with other systems in the enterprise, send email messages, page on-call staff, or automatically terminate existing connections. Bro also works based on file hash extraction and matching with the use of publicaly available hash registers. It is important to notice that the processing per core is significantly low compared to Snort or Suricata. But Bro has built in capacity to spread the load across multiple machines via Bro cluster thereby proving greater scalability. But there have some research showing that the overhead of distributed processing slows down the performance. Thus the performance acceleration is applicable onlz till a certain saturation point.

 Snort is the perfect solution for a moderate traffic scenario, about 400 Mbps. There are also acceleration support like PFRing in the newer versions aimed at solving the high throughput scenarios. But for high thoughput systems with 10Gbps or more, Suricata is better due to its extensive support for large scalability. ISPs using 20Gbps could use Suricata effectively. Bro could be considered as a high throughput research environment due to its great flexibility. Its powerful scripting features is definitly a greater advantage compared to the rule sets in Snort or Suricata.

Reference :

[1] http://www.sans.org/reading-room/whitepapers/intrusion/open-source-ids-high-performance-shootout-35772

[2] https://www.snort.org/documents

[3] https://www.bro.org/documentation/index.html

[4] Sample snort signatures: http://www.icir.org/vern/cs294-28.Spr09/notes/NIDS.pdf

How to upgrade to Python 2.7 in Solaris 11

Following are simple steps to upgrade from default version (python 2.6.8) to python 2.7 in Solaris 11. Many of the python frameworks are build on top of python 2.7. Hence this might be a good fix to  solve many problems.

Download and install python 2.7 to your system using the following commands.

$ pkgadd -d http://get.opencsw.org/now
$ /opt/csw/bin/pkgutil -U
$ /opt/csw/bin/pkgutil -y -i python27 
$ /usr/sbin/pkgchk -L CSWpython27 # list files

The new version of python gets installed in the directory  /opt/csw/bin. Inorder to make the default version to the latest one, create a symbolic link as root to the new binary file:

$ ln -sf /usr/bin/python2.6 /usr/local/bin/python

Linear feedback shift register

Modern ciphers are classified mainly as stream ciphers and block ciphers. LFSR is a simple method to generate a stream cipher. 

Stream ciphers are generated by adding each bit of plaintext with long generated bits called the keystream. Keystream is made out of a small secret called the seed, which is developed into a very long sequence of bits. 

Stream ciphers are generally based on states, an update function that navigates from one state to another and an output. 

You can read more about LFSR here

Following is the implementation of LFSR in magma with the given specification:

INPUT: 	(P,L,t)  	
         - P is the connection polynomial for the LFSR
			- L is a list for the initial state 
(note that Degree(P) eq #L) 
			- t the length of the keystream that we get 
from the initial state


OUTPUT (Ks,S)		
         - Ks is a List of length t which contains the keystream
			- S is a list of length t+1 which contains 
the states of the LFSR
			  (so S is a list of lists)

function RightLFSR(P, L, t)
	C:= Coefficients(P);
	C:=Reverse(C);

	V:=[];
	L;

	for i in [1..t] do
		V[i]:=L[#L]; // The output value is
                             //the last bit of each stream excluding
                             //the last register value.
		k:=GF(2)!0;
		L1:=L;
		//Shift the register to the right
		for j in [1..#L1]do
			if j+1 in [1..#L] then
				L[j+1] := L1[j];
			end if;
		end for;
		//XOR the values based on the polynomial
		S:=[];
		for j in [1..#L] do
			S[j]:=L1[j]*C[j+1]; // The previous state of
                         // the register before
                          //shifting is taken to find the first bit.
			k:=k+S[j];
		end for;
		L[1]:=k;
		L;
	end for;
return V;
end function;

R<x>:=PolynomialRing(GF(2));
RightLFSR(x^5 + x + 1,[GF(2)!1,0,0,1,0],8);
//Calling the function above

The divine manifestation

Mind works so strange.
For the past one year, I had told this
To myself, for plenty of times!
Haven’t you also felt the same?
At least once in your life?

I build palaces of dreams with imaginations..
I live in that world..
It makes me feel so real.
I find it hard to believe that the images that
I see in front of me are images..
They are not real.
The rails, the grass, the buildings,
the people, the cars, the dogs,
the birds, the mountains, the clouds,
They are all images, of my imagination.

I got an idea to feel myself in others.
Not very sure how that works.
But I just got a glimpse of it!
I found myself manifesting in different forms.
I found my body trembling out of pain.
All beings manifested from me.
May be that is also a part of my minds imagination.

That was just for a fraction of a second.
And then back to my dream of believing
That I am a tiny creature with an ugly body
with a huge mind full of garbage,
with a beautiful brain, so polished and new
the one which is the least used..

Aaah.. no.. don’t fool me again..
I am not this! I am that..
Seems like Maharshi’s dialogue when he left home..
But please don’t misunderstand..
That was just a desire..
Not the truth!
One day, I would reach that heights..
So high.. that the differences diminishes..
Like the view from an aeroplane..
I would see them all merging into one.
I would see them merging into me!

Until then, I need to play around
with the part of myself
that is cheating me showing a fake world.
I need to remember to wake up
Not to fall deep and deep into
the fallacies of imagination..
But to awake, I need a call
from the Divine mother..
Who needs to take me in her hands,
and fly to those heights,
that would diminish the differences..

Multi tier web architecture

It is easy to build an application these days. You can find kids developing mobile apps, websites, etc, and playing around with them. Running an application, with a business logic, and a nice, cool look, would make the application interesting. But there is the element of engineering is missing in it. And it is inevitable in case of large applications, especially distributed ones. 

When you are building an application, a large system, say for managing a company’s employees’ details or a search engine like Google, or even a student management system in a University, etc, the development is no more just the logic and the looks. There are so many more details to be considered. How many people can use the system at the same time? What is the maximum server load? How do you perform software updates while the site is already running? How to connect  the server,  the database, the user? How to handle multiple servers, shutdown one without affecting the other? What to do in case of a catastrophic failure of a system ?etc … It is found that software developers prefer component based frameworks, where a component is a separate element, which could be used for executing an abstract functionality. There are some techniques used by the web tier to handle the distributed application by dividing the whole application to multiple components, and interacting with each other using interfaces, and remote method invocations. 

Multi-tier deployment

Multi-tier deployment

Enterprise JavaBeans, or EJBs are used for deploying server side distributed components meant to perform server side operations.  It performs tasks different from the client side operations like rendering GUI’s, performing client side validations, deal directly with end user or end application. EJB’s on the other hand, perform activities like executing complex algorithms, access the database (eg: JDBC API), integrate with other systems etc. A distributed component, also called as a remote object is callable from a remote system. It means that it is not only accessable to an in-process client but also to an out-of process client that is located somewhere in the network. Some of the clients that access distributed objects are : 

  • Application clients that execute on users desktop and connect to EJB though network.
  • Web servers, that manage dynamically generated web pages. These web servers need to connect to the EJB server to get the actual business logic to generate the web page. 
  • Web services – There are no human users, but instead there is a system trying to access the distributed components via a web application. Here, the EJB’s can act as a web service client. 

My next post explains more about remote method invocations, and distributed components. 

Naming Services and JNDI

A naming service provides the facility to find an object based on a name. Whenever we need to associate name to things, we can use a naming service. It is similar to the idea of telephone directory that we use. JNDI and registries are other examples to a naming service.

During development, if is useful to have the powerful containers like Glassfish. It contains the web server, like tomcat, the application server, embedded in it. The user is not aware of the embedded features in a big container like JBOSS or glassfish.

But, during actual deployment, you want to have, DMZ – Demilitarized Zone.  We need to separate everything, like the web tier and persistence tier, and logic tier and put firewall in between so that web tier and persistence layers are separated. It gives more security and granularity. When you learn the technology, you use just one machine! But in real world scenarios, we need to split up the whole application to different modules that essentially runs on different machine.

JNDI becomes more relevant in such scenarios. It acts as the binding between different tiers by providing API’s that can connect and look up for things or data in each other.

Naming services are made with a hierarchical organisation similar to the structure of a tree. The leaves are the actual data in the structure. JNDI is also having a tree structure.

JNDI consists of a set of set of APIs that allows us to interact with directory services like LDAP, NIS etc. Some of the advantages of using JNDI are as follows:

  1. You can use multiple frameworks. All we need to change is the binding.
  2. You just have to learn one API, and hides you from protocol and implementation details.
  3. You can save java objects using JNDI
  4. You can also link different directory services using JNDI.

Directory services like JNDI and relational databases are used for storing data. But there are significant differences between the two.

  1. Directory services are hierarchical in structure and not relational.
  2. Before relational db, we had hierarchical db, which had an internal model similar to that of directory service.
  3. Most of the operation in directory services is read and we rarely perform write.
  4. As a result, dir services are more optimised for read and writing works slower in a directory service.

Now we take a look at the API part of JNDI. It has a set of APIs.

The term binding in JNDI is the association of a name with an object. To use JNDI, we need to acquire a context. A context is a set of bindings. In the hierarchical structure that I mentioned above, each leaf is a collection of pairs – <name, object>. A context can contain many leaves of the type above. JNDI names look like urls. There is a special prefix as java:. Java is a special token that represents a scheme and in this scheme there are some predefined locations. In order to acquire a context, you need to provide IP address of server, port number, the starting location within JNDI trees. It might be protected by password as well.

Some of the operations in JNDI are as follows:

  • list() – list the directory structure as in a file system
  • createSubcontext() – creates a sub context, similar to creating a folder in a directory.
  • bind() – creates an association, write a pair,name value in the current context
  • rebind() — forces binding something that is already in the tree.