ANALYSIS OF AN INTRUSION DETECTION SYSTEM BASED ON IMMUNILOGY MOHAMMED HUSSEIN SAEED AL-AMOUDI A project report submitted in partial fulfillment of the Requirements for the award of the degree of Master in Information Security Faculty of Computer Science and Information System Center of advance software engineering (CASE) University Technology Malaysia November 2008 iii DEDICATION To my parents, Thanks for your support, encouragement, and for everything you have taught me. iv ABSTRACT It is believed that many of the mechanism covered in the biological immune system are adapted to the field of computer intrusion detection within “LISYS”. In this report, I went briefly on the mechanisms of the biological immune system, their parallels in LISYS are presented, and how they may operate to intrusion detection in a computer environment is discussed. LISYS is an artificial immune system, which need to be implemented and examine through experiments with variety of challenges in detecting intrusive behaviour in real network with simulated network environment. Components of LISYS need to be challenge also to see wither those mechanisms are really necessary v ABSTRAK Adalah dipercayai bahawa kebanyakan mekanisma yang terkandung dalam sistem immunisasi (pertahanan) biologikal telah diadaptasikan ke bidang pengesanan ganguan komputer menerusi ‘LISYS”. Dalam laporan ini, saya akan menjelaskan secara ringkas berhubung mekanisma-mekanisma sistem immunisasi (pertahanan) biologikal, membentangkan persamaannya dalam LISYS dan membincangkan bagaimana ia akan beroperasi terhadap pengesanan gangguan di dalam persekitaran komputer. LISYS adalah satu sistem immunisasi (pertahanan) tiruan, yang perlu dilaksana dan dikaji melalui kajian-kajian yang mempunyai kepelbagaian dalam mengesan aktiviti ganguan di dalam jaringan sebenar dengan menggunakan persekitaran jaringan yang telah disimulasi. Komponen-komponen yang terkandung dalam LISYS perlu diuji bagi melihat akan keperluan mekanisma-mekanisma tersebut. vi TABLE OF CONTENTS CHAPTER 1 1.1 1.2 1.3 2 2.1 2.2 2.3 2.4 2.5 2.5.1 2.6 2.6.1 2.6.2 TITLE PAGE Declaration Dedication Abstract Abstrak Table of contents List of tables List of figures List of symbols List of appendices ii iii iv v vi-vii viii ix x xi INTRODUCTION 1 Motivation Contribution Overview 1 2 2 BACKGROUND 4 Intrusion detection system Anti-viruses system Firewalls Limitation on effectiveness Immune System Immunity Lymphocytes & Antigen B-Lymphocytes 4 5 6 7 7 8 9 10 T-Lymphocytes 10 vii 2.7 2.8 2.9 3 4 4.1 4.2 4.3 4.4 4.5 4.5.1 4.5.2 4.6 4.6.1 4.6.2 5 Recognition of Antigens Negative Selection Co-stimulation 11 11 12 METHODOLOGY 13 ARTIFICIAL IMMUNE SYSTEM Related work LISYS The Detection Life-cycle Detector Set Activation Thresholds & Sensitivity Level Activation Threshold Sensitivity Level Co-stimulation and Memory Detectors Co-stimulation Memory Detector 15 16 17 19 21 22 23 23 24 24 24 IMPELEMENTATION Running LISYS Data Data set Normal Data Attack data Experiment Results 26 26 28 28 29 29 29 20 6.1 6.2 finding Observation 31 34 7.1 7.2 Future work Conclusion 37 38 References LISYS CODE 39 41 5.1 5.2 5.2.1 5.2.2 5.2.3 5.3 5.4 6 7 Appendix A viii LIST OF TABLES TABLE NO. TITLE PAGE Table 1.1 Number of incident reported to the CERT/CC 7 Table 5.1 LISYS Parameters Values 30 ix LIST OF FIGURES FIGURE No. TITLE PAGE Figure 1 Methodology Processes 14 Figure 2 The LISYS 49-bits SYN Packet Compression scheme 18 Figure 3 R-contiguous bits matching rule 18 Figure 4 The LISYS detector life cycle 20 Figure 5 negative selections Method 20 Figure 6 method of secondary representation 22 Figure 7 LISYS detection snap-shot 27 Figure 8 LISYS broadcasting snap-shot 27 Figure 9 Generated detection activity view 28 x LIST OF APPENDICES APPENDIX TITLE PAGE A LISYS Code 41 CHAPTER 1 INTRODUCTION Natural immune system is a source of inspiration for the computer security in the age of the internet, where it is believed that the Immune System solves similar problems that are facing today’s most usable security software (IDS). Human immune system is very complex and robust, so does its mechanism can be apply to the technology of computation as a model of intelligence, and show some reliability. Since 1988, the CERT coordination center (CERT/CC) has been observing computer instructions activities and reports that the number of incidents reported to them has been approximately doubling every year since they started, also Malaysian cert has been reported that in the second quarter of 2006 saw an increased in intrusion incidents with a total of 227 incident (the reported one), which is more than two folds from the previous quarter. 1.1 MOTIVATION The problem of network intrusion has been there for some time, but with much of services from the ISPs as high speed broadband involve, that provides us the capabilities for video conferencing, VOIP, Video on demand, and on-line gaming etc, in-return, the internet has become ubiquitous in all societies. On the other hand, the internet intrusion of all types have become one of the most important and challenging 2 problems faced by computer experts. In today world, Worms and Viruses are capturing most of the attention and are responsible for much of the damage. And if we look to the view years back, Viruses and Worms delayed airline flight, infected wireless printer, disrupted cash-dispensing machines, and hijack modems to make long distance phone calls, and it’s going to get worse (Secrets and Lies, 2000, p. 45). Given the sophisticated and speed of propagation of today’s attacks, the defenses system in place that are tailored to particular attack signatures is unlikely to keep pace as so called Zero-day attacks become prevalent. A successful defense system must achieve one goal, must be able to respond to wide range of attacks, including those not seen before. 1.2 CONTRIBUTION Presented in this report is the LISYS approach an example of many other AISs have been developed to replace or solve the problem facing the current computer network intrusion detection. Further, the implementation of an AIS known as LISYS (Lightweight intrusion detection system), with more realistic environment and data to produce a fine result from the experiments and deeply analyze LISYS to see wither it achieves the principle of AIS. 1.3 OVERVIEW The rest of this written paper structured as follows. The following Chapter “2” I focus in some related background. Follow up with Research Methodology in Chapter “3”. In Chapter “4”, I went through related work, and describe LISYS in detail. In 3 Chapter “5”, I report experimental results and experience in running LISYS. In Chapter “6”, I discuss a direction of future work in this area. 4 CHAPTER 2 BACKGROUND There are several areas of research that are relevant to this thesis. In this chapter, I review related work done in the general area of intrusion detection system, Antivirus, and firewall to have a close look regards their effectiveness. Follow up by mapping the way that LISYS inherit its features from the Human Immune System in the second part of this chapter. 2.1 INTRUSION DETECTION SYSTEM Bruce Schneier defines IDS in his book (Secrets and Lies, 2000, p. 194) as “IDSs are network monitors. They watch your network, looking for suspicious behavior: think of them as autonomous police detectives wandering around town; they know what suspicious behavior looks like-Probing a system for access, poking around for bugs to exploit, or whatever-and they keep an eye out for it.” We can generalize the types of approaches that available used by an IDSs as two main approaches, an IDS used to detect malicious activity on that host is called a hostbased IDS, in the other hand an IDS which tries to detect events of interest by analyzing and monitoring network traffic data is called a network-based IDS. There are two techniques are used in building an IDS, the basic one is the misuse 5 detection, whereby an IDS knows what an attack look like and search for it. And such a technique can be achieved by scanning every packet, looking for bit strings indicating a certain attack. This type is easy to implement, fast and have low false-positive, but it needs a constantly updated database of attack signatures. The other type is anomaly detection. This type of IDS works based on the assumption that unusual or abnormal behavior is intrusive. But only after it model its network and figures out what is normal. This type can be achieved either with rules or statistics. The draw-back here if an individual been hacked as she/he train the system; Then hacked is considered normal. Basically, network-based IDS products are built as sensors sit on the network and examine packets as they pass by it, this type has an advantage of stealth, and operate without affecting the rest of the network. Host-based IDS look at system, audit, and event logs from individual systems. But in today’s marketplace available products are combination of both called “hybrid”. 2.2 ANTI-VIRUSES SYSTEM The most common method used for protecting computers from Viruses, Trojans, and Worms is antivirus software’s [Symantec, trend micro]. These software’s are in general signature-based scanners installed on a user’s machine, and they perform two tasks: prevent infection by known viruses or worms and at the same time, treat computers that are already infected by clean them from infection. This is a useful type of software, but it has one problem that it shares with other knowledge-based system. Antivirus software can only stop threats and protect computer from known attacks, whereas new Malware can go through undetected. Current antivirus programs 6 are signature-based and in order to create a signature, a sample of an attack needs to be provided. In which can be possible if only there is a connection been established between the antivirus companies and a Malware writers, so if not, then a signature can be created only after an infection is spreading in the wild. Another constraint is the time required to create a reliable signature takes days, in which is much slower than the time it takes for a virus to spread all around the internet. And if we assumed, the signature can be created very quickly, it still need to be distributed to all vulnerable hosts faster than the spread of the Malicious software. 2.3 FIREWALLS Another face of an example to a security system in place is called firewall, which has been built with an automatic response. It function by blocking network access on specified ports to or from a computer or group of computer, or to block access to all ports except a list of specifically allowed ports. Firewalls moves from being only in enterprise level network, to become common in home network. Any home broadband routers used to share an internet connection between multiple machines have built-in firewalls. And by default, these firewalls are configured to prevent all incoming connections except those specifically open by the user, which allowing all outgoing connection initiated by computers inside the firewall. The increase of laptops users makes these firewalls less affective. Laptops moves between home networks and network hotspots wirelessly. Therefore, viruses and worms can be transmitted to vulnerable laptop inside one of these firewalls from another infected computer inside the same firewall, and then the infected laptop can be physically transported behind another firewall where it can further spread the infection. All that took place without the need for an infection to cross the firewall boundary over the network. 7 2.4 LIMITATION OF EFFECTIVNESS With all that techniques put in place, security still a hard thing to achieve. Majority of organization today uses a multiple defense systems but an intrusions doubles from year to other as we can see clearly by the numerical table (1.1) that presented in (CERT coordination center 2002). TABLE 1.1: Number of incident reported to the CERT/CC 2.5 IMMUNE SYSTEM In this part, I’m introducing some of the mechanisms present in the biological IS (Immune System) from which the field of AIS (artificial Immune System) draws its inspiration. IS still under heavy and focus research of how it works? So there is a possibility that the information presented will be proven incorrect over the course of time. 8 2.5.1 IMMUNITY Biologically, immunity is the competence of a human body or generally of an organism to resist attacks from invasion by other organisms (Parham, 2000, p 1). Such an organism a foreign substance called a pathogen and is recognized by the IS as an antigen (Ag). The Ag can be nearly any type of large foreign molecule inside the body, including those contained in infective agents, food, scorpion venom, and other cells and tissue from different species, including human. The Immune System (IS) is a multi-layered architecture, with defenses on several layers. After protection of God”Allah”, the skin considered as the first barrier to infection, followed by another barrier is physiological, in which both creates the Innate Immunity. Immunity of two types; namely, the mentioned earlier innate immune response (non-specific) and including the (specific) acquired or adaptive immune response. These immune mechanisms kill a wide variety of microbes, regardless of whether those have challenged the body before. Innate immunity non-specific in that its mechanisms can act against different types of microbes that have no similarity to each other. After a course of infection by an individual and recovery took place, it at most cases does not get that illness again. And here where the acquired immunity plays apart. It is specific in that its responses are outfitted to act against a specific microbe or its products. Most of the inspiration of LISYS has been drawn from the adaptive Immune system, and it called so, because it “adapt” or “learn” to recognize a particular kind of pathogen and create a “memory” of them which can be retains once needed to speed up future responses (similar to signature) . So the coming part will be focusing on the adaptive immunity. 9 There are two main aspects that the IS are faces: the identification or detection of pathogens (Ags), and the efficient elimination of those pathogens. At first to do so, the IS must distinguish between “SELF” materials of the body and “NON-SELF” materials of the foreign substance. But that considered as a very wide definition, in which an immune system could cause harm to the body if it auto-reacted to the self and in the other hand some of the pathogens (Ags) are not harmful. In those cases it could be more right to say that the problem faced by IS that of distinguishing between harmful non-self and every thing else (Matzinger, 1998). This ability is appeared in majority of living entities and it’s a feature of the white blood cells called Lymphocytes. 2.6 LYMPHOCYTES AND ANTIGENS The cells responsible for both innate and adaptive immune responses are white blood cells, which contain the Lymphocytes. Lymphocytes have the ability to differentiate and react to an almost unaccountable number of different Ags. But in the scope of the project will briefly focus on the small Lymphocytes, which are the cells responsible for adaptive responses and carry the recognition molecules of adaptive immunity by a receptor on their surfaces. The small lymphocytes are originate in the bone marrow and there two kinds of it, B- & T- Lymphocytes (also known as B- & Tcells). The antigenic determinant that is recognized by a receptor is called an Epitope. Furthermore, an Epitope is a location on the surface of a pathogen (Ag) or a protein fragment, which is called a peptide. A variety of Epitopes can be seen on a different area of an Ag’s surface, which in-return might invoke response from a variety of specific Lymphocytes. 10 2.6.1 B-LYMPHOCYTES The B-Lymphocytes (B-Cells) are originating in the bone marrow and complete their maturation in it before entering the circulation. B-Celss divide & differentiate into plasma cells of a single specificity, which make antibodies, and place it on its outer surface to act as a receptor. On activation by infection (Ag), it is faced by with a vast array of Lymphocytes, all bearing different Abs each with its individual recognition site, then an antigen will attach to those receptors with which make it make a good fit. Those bound receptors of a Lymphocyte to an Ag will trigger a signal and transform into Ab-forming plasma cells. 2.6.2 T-LYMPHOCYTES T-Cells have more diverse function, in which they interact with other cells of the IS such as the B-cells, whereby many intracellular pathogens such as viruses are able to infect cells as B-Lymphocytes and take advantage of the fact that if they live inside cells of their host, as present anti-body (Ab) on the surface of B-cells, is unable to reach them. But at this stage the T-cells take responsibility as a specialized to operate against such microorganisms exists on the surface of B-cells Ab. Unlike the B-lymphocytes, the TLymphocytes also originated on the bone marrow but then T-cells leave the bone marrow at an immature stage to the thymus, where they complete their maturation. The T-lymphocytes are only able to recognize Ag when it is presented on the surface of a body cell (B-cells). Therefore, the T-cells receptors (TCRs) recognize Ag plus a surface marker indicating that it is presented on the surface of another cell. And those markers are cells belong to group called the Major histo-compatibility complex (MHC) (Weir and Stewart, 1997, p 95). 11 Particular individual in a group of cells is genetically capable of making a small set of these MHC marker, but one set of MHC types differ from one individual to another. Hence, individuals in a population are capable of recognizing different shape of peptides. This mechanism provides a major form of population-level diversity (Hofmeyr & Forrest, 2000). 2.7 RECOGNITION OF ANTIGENS The Lymphocytes after become functional, only then will have a genetic arrangement in how it bind to Antigens. The arrangement shape of binding as of an Ab to an Ag-peptide or in the other side could be a TCR to MHC-peptide are very complex. But to make it simple, if two of the above mentioned structure have complementary shapes that can closely approach each other then binding will happen (Percus et al, 1993). The types of matching are not exact (but Approximate), which gives an ability to one particular Lymphocyte to bind to many different types of structurally related pathogens, but the binding is depend on the affinity between the two (e.g. an Ag to a single Ab), the higher the affinity, the stronger the binding. 2.8 NEGATIVE SELECTION All blood cells are generated within bone marrow, but then T-lymphocytes leaves and migrate to the Thymus to become mature there, but in the way they are with no ability to stimulate by Aq. T-lymphocyte enters the Thymus as immature Lymphocytes, and the only one that manage to leave called mature Lymphocytes. This process of maturation is known as “Tolerization”, T-lymphocytes multiply in number 12 while passing through a complex work within the thymus cells. As they multiply, they develop receptors and differentiate into different T-lymphocyte sub-classes. During tolerization most of the T-lymphocytes that entered the Thymus die there, around 2% only survive tolerization (Forrst et al., 1997). That is the consequence of Ag receptors are randomly created, as a result, many of them will tend to recognize self Ags. So they are auto-reactive, and if they allowed to be mature then surely will attack the body own tissues. Consequently, most of them are deleted by the programmed death cell called apoptosis in the Thymus. This mechanism called negative selection, whereby prevent the body of developing an autoimmune Lymphocytes. 2.9 COSTIMULATION Consequently, some of the self “peptides” are never expressed in the thymus during the tolerization process, so mature Lymphocytes that passed the process in thymus might tend to bind to those proteins and cause an auto-immune reaction [Hofmeyr and Forrest, 2000]. In real performance this dose not takes place because in the addition of binding to an Ag, a T-lymphocyte acquired to receive a co-stimulation signal in order to be activated. This signal takes a form of chemical alert. 13 CHAPTER 3 METHODOLOGY Starting a literature review by studying and reviewing some of the current strategies been used for the prevention of the computer network. The three most popular commercial security measures are Intrusion detection systems, antivirus software and Firewall. In general these systems can be effective at stopping known virus and attacks, but they are not adaptive and they required human action and monitoring or in other side updates. We are looking for a system which gives us beyond that limitation. At next stage, briefly we need to put some focus in the Human Immune system by explaining the mechanism and the job function of some part of it that can be applied to the computer network security. In parallel, we will be mapping LISYS components to its corresponding entities in the Human Immune System to clarify the inspiration source. We will study LISYS “Light Weight Intrusion System” deeply and explore its every single component to ease the understanding behind the function and the add-on made by those components to the system as a whole. Next, we will implement and Test the system by using multiple testing environments to ensure the system efficiency. At last, we will record and draw the experiment and list its result. Also, we will report on the effectiveness of LISYS against the Principle of (Somayaji et al., 1997) that put a measurement for any immune inspired system. And those principles of Somayaji include: Distributed Protection, Robustness, Diversity, Adaptability, flexibility, Memory “signature-based detection”, Anomaly detection, and Scalability. 14 Start Study and Review several problems occur in previous systems used by the industry such as, Intrusion Detection Systems, Virus Detection, And Firewall. Study and Review roughly in an biological immune system mechanisms that inspired LISYS Study and draw LISYS system in details as a whole and its sub-system. Implementing and Testing LISYS in a Variety of environment by using multiple testing mechanisms to ensure its efficiency Draw and Record Experiments Report on the effectiveness of LYSIS against the Principle ( Somayaji et al., 1997). End Figure1: Methodology Process 15 CHAPTER FOUR ARTIFICIAL IMMUNE SYSTEM Most AIS can be thought of as learning to discriminate between “self” and “nonself”. Almost any set of patterns that can be expressed as strings of symbols can be placed into this framework, example; the set of normal occurring TCP connections in a local area network (LAN) and the set of TCP connections observed during a network attack. My focus implementation will be in testifying and verifying LISYS (lightweight intrusion detection system) (Hofmeyr ,1999; Hofmeyr and Forrst 2000) by showing how LISYS can comply with the principle mentioned earlier in section 2.1, and I will achieve that by stripping LISYS from its components and start test the basic module of LISYS to that of full LISYS. Then describe a series of experiments which than add-on components to the basic module and test the performance compared to the full LISYS. LISYS is a complex architecture, similar in complexity to learning classifier system (Holland et al., 1986) and the mission of understanding and predicting its behavior is challenging. So, deepen understanding of the contributions made by LISYS’ many components to its overall performance, it’s the goal I would like to achieve. The reminder of this chapter will be focusing in LISYS sub-system and mechanisms used. Section 3.1 Related Work, Section 3.2 LISYS in overall, section 3.3 the Detectors life-cycle, section 3.4 Detector set, section 3.5 Activation Threshold and Sensitivity Level, and at last 3.6 Co-stimulation and Memory detectors. 16 4.1 RELATED WORK AISs have been widely implemented in the area of computer security. Such ideas has been started and explored generally by many researcher such as namely, Hofmeyr (1999), Hofmeyr and Forrest (2000), Somayaji et al (1998), Dasgupta (1999). Those works has focused both on computer security architectures as a whole and on specific area in computer security. And if we look at the specific area in computer security where involved AISs implementation, even-though some still experimental phase only, range from virus detection (host based anomaly detection) (Forrest, 1994) and OS process monitoring ( Forrest, 1996), to network intrusion detection by (Hofmeyr and Forrest, 2000) as in the form of distributed network-based anomaly detection. Also, (Kim and Bentley, 1999) describe an architecture for an AIS-based network IDS, and if we look at the reported results of experiments on some of the system key components. As in LISYS, anomalies are detected through a performer of negative detectors distributed among multiple hosts. Unlike LISYS, generation of detectors done at a single node “centralized” (similar to the natural immune system), and communication between nodes is “ON” to decide upon anomaly. Also similar to LISYS in monitoring TCP connection, but as extra feature Kim and Bentley system monitors all packets in a connection. CDIS (Computer Defense immune system) is the second example of an immuneinspired network IDS, which been reported by William (William, 2001). Processing of the data-stream take place at the packet level, just like LISYS dose, but it extended LISYS in three different protocols (TCP, UDP, and ICMP) in monitoring packets. Whereby the number of fields represented is large than used by LISYS (28 features for TCP, and 16 features for UDP and ICMP). Detectors in CDIS are exact map for packet in which is clear and precise. But in LISYS randomly generated immature detectors undergo a filtering process using negative selection. Another difference come through co-stimulation, at LISYS human operator is involved, where CDIS between detectors. 17 (Desputa, 1999) introduced an immune-inspired architecture for general intrusion detection, whereby multiple mobile agents is used to monitor system status and in-return respond to intrusion, and add to that, a specialized agents just to help other agents to communicate. The system goal is to produce information from multiple domains area, for example, system level, the user level, and network level. Also the system has variety of responses once an intrusion is detected, may attend of blocking a particular IP address, changing users or administrator privileged. 4.2 LISYS LISYS operate at the Local Area Network, whereabouts it monitors traffic. LISYS consist of a set of detectors (continually compared against network traffic), which is similar to Lymphocytes in the immune system. If we receive any match between detectors and event, we trade such match as an anomaly. The current implementation of LISYS monitors TCP connections, that specific to the initial SYN packets followed by a SYN/ACK response in a TCP connection. Self is the set of normal pair-wise TCP/IP connections between computers, and non-self is the set of the connections, which are not normally observed on the LAN. Connections can take-place between any two computers in the LAN and also between a computer in the LAN and an external computer such as one in the WAN. A connection is defined in terms of its “data-path-triple”, source IP address, destination IP address, and port by which computers communicate. The data-path-triple is compressed to form a single 49-bit string (Hofmeyr, 1999) as shown in figure 2. To achieve that, it is assumed that one of the IP addresses is always internal, so only the final byte of this address needs to be stored. Also port number is compressed from 16bits to 8 bits by remapping the ports into a number of different classes. 67 commonly assigned privileged ports are each allocated their own, unique ID number (from 0 to 66), while all other ports are each assigned to one of three classes: 18 non-privileged ports (ports 6000-6063, ID 69), and at last, all other non-privileged port (ID 68). Figure 2: The LISYS 49-bit SYN packet compression scheme (Glickman, Balthrop, and Forrest, 2005). In the other hand, also the detectors 49-bits strings, along with a small amount of local state. If we assumed, a perfect match took place between a detector and a bit string representing a TCP connection, which means at each location in the 49-bit string, 100% similarity. But that is not the case with LISYS, whereby a perfect match is not need; LISYS perform partial match detection so that it can generalize from its sample of observed normal traffic. LISYS uses a matching rule known as r-contiguous bits matching in which two string match if they are identical in at least r contiguous location, shown in figure 3 (Using the r-contiguous bits matching rule with r = 4, the two strings on the left constitute a match. The two on the right, with a maximum of 3 matching contiguous bits, do not match, Glickman et al., 2005). Figure 3: r-contiguous bits matching 19 4.3 THE DETECTOR LIFE-CYCLE LISYS detectors experience a multi-stage lifecycle, as illustrated in (figure 4). The stages are; immature (analogous to immature T-cells undergoing negative selection in thymus), mature (analogous to naïve B-cells that have never been activated), activated (and awaiting co-stimulation), memory, and death. Randomly LISYS’ Detectors are created and directly enter the immature phase (T-cells in the thymus and B-cells in the bone marrow) where they remain for the tolerization period depends on the system parameter been set, either a fixed number of observed packets or a specific length of time. At this particular phase every detectors matches a TCP connection will be discarded and replaced by randomly newly generated detectors (Figure5, Candidate negative detectors (represented by dark circle) are generated randomly, and if they match any string in the self set (i.e. if any of the point covered by the detector are in the self set), they are eliminated and regenerated. This process is repeated until we have a set of valid negative detectors that do not match any self string, Forrest, 1994). Those detectors, that fails to match any connections during its tolerization period will take new stage and become mature. From the previous process detectors will learn to tolerate normal traffic. At later stage, all detectors that manage to survive negative selection [Forrest et al., 1994] and gone to maturity level are facing a fixed probability Pdeath of dying randomly once it has matured, on each time step. So every detector dies sooner or later, when it dies, it is replaced by a new randomly-generated, immature detector. So that such lifetime of detector, with detectors generation and tolerization, similarly to the Bcells turnover in the body, this has given rolling covering to the self set. 20 Figure 4: The LISYS Detector Lifecycle (Glickman et al., 2005). Figure 5: The negative algorithm. 21 Activation only keeps a mature detector alive and if it fails to do so, then consequentially dies. Activated means, detector manage to achieve a sufficient number of matches connection during its mature phase. If a detector is activated, then has to wait to get co-stimulated for a fixed period of time (Glickman et al., 2005). At the highest stage; those detectors which receive co-stimulation will be promoted as a memory detector, but the one who doesn’t receive co-stimulation dies, and that just like the second signaling systems in the IS. 4.4 DETECTOR SETS Detectors in LISYS are distributed among separate computers; each computer has a group of detector, which creates a set of those detectors with freedom of action. This architecture or design has a several advantages. At first, there is no central point of failure, resulting from independency operating per node (computer). Secondly, individual nodes do not need to communicate with other nodes or with a higher level controller in order to make a decision about an individual packet that gives a potential improvement per node efficiency. At last, every node uses its own unique representations, which give diversity on detection abilities throughout the system. Further more, detector set uses a secondary representation drown from its base representation. Diversity is achieved by having such slight different representation, (called secondary representation), closely similar to MHC diversity in the natural immune system. Secondary representation plus the r-contiguous bits matching, allow each node to generalize differently from observed network traffic. Having such multiple secondary representations is to increase LISYS’ discrimination abilities with decreasing the total generalization of the system as whole. 22 Hofmeyr’s (Hofmeyr, 1999) method of secondary representation is used here ,showing how each host will assign a unique randomly generated substring hash to the base representation in figure 2, where by, this secondary representation is a remapping applied to string encoded in the base representation, seen clearly in (Figure 6, A substring-hash has two components: A random hash function, h, which maps each value from [0...255] to another, unique value in [0..255], and a random permutation of 6 elements. The 49-bit string is divided into 6 bytes, with one remaining bit. Each of the 6 bytes is remapped using h. The 6 bytes are then permuted, and the 49th bit is passed through unchanged). Figure 6: method of secondary representation 4.5 ACTIVATION THRESHOLDS AND SENSITIVITY LEVELS The two mechanism been introduced from the facts that, the training set dose not include all self strings, similarly in the immune system not all the self agents are introduced in the thymus. Such a circumstance will result in false positive, so activation thresholds and sensitivity level main implementation to reduce false positive. 23 4.5.1 ACTIVATION THERSHOLDS It is based on the concept of affinity thresholds in the immune system, whereby, multiple receptors on a Lymphocyte must bind to epitope before that Lymphocyte is activated (Weir and Stewart, 1997, p 114). Similarly, this mechanism is operate, each detector records the number of packets its matches. With the match counter in place, activation of detector happens once the number of matches exceeds the activation threshold. There is another factor controller in this mechanism, time range: over time, in the absence of further matches, probability of match count dropping by one. 4.5.2 SENSITIVITY LEVEL In the case of an attack been lunched from different source, activation thresholds are not sufficient, because they require that a single detector match repeatedly, therefore a single detector may not match such distributed attack. Sensitivity level mechanism is used to overcome this problem. And it’s approximates the local sensitization signal used by the immune system, when suspicious activity is detected by some cells of the IS, cytokines are released which alert the rest of the immune system (Tizard, 1992, p113). Each detector set at a node has one sensitivity level, and its work as, whenever the match count of a detector goes from zero to one, that detector sets sensitivity level is incremented. Sensitivity level also prevented from rising to high value so it controlled and decay probabilistically toward zero. 24 4.6 CO-STIMULATION AND MEMORY DETECTORS 4.6.1 COSTIMULATION In the immune system, co-stimulation provide away of eliminating auto-reactive Lymphocytes, but that will be decided if and only if, Lymphocytes received signal Í in the absence of signal ÍÍ, ( signal Í is provided by binding to pathogen epitopes, And signal ÍÍ is provided by other cells of the immune system), (Weir and Stewart. 1997, p110). Co-stimulation signal in LISYS is external feedback supplied by an operator. The operator will receive a message once a detector becomes activated; in return, operator has an option of providing confirmation that the detector has correctly identified an anomalous event of interest. If no confirmation from the operator (mean “no co-simulation), the activated detector is considered as auto-reactive and is deleted (Glickman et al., 2005). Detector receives a co-stimulation will be promoted to a higher stage “the memory state”. In summary, co-stimulation helps in many areas, eliminate auto-reactive detector as mentioned earlier, in result, further reducing of false positive and serve as trigger in generating memory detectors. 4.6.2 MEMORY DETECOR Memory detectors are LISYS’ analog of memory cells in the immune system (Weir and Stewart, 1997, p116], to improve average detection rates, so an memory detectors are used, in which, after discovering new or novel non-self a memory is retained and that is analogous to signature detection. As mentioned earlier, a previous detected non-self is stored in the form of 25 memory detectors, and it’s used in the subsequent detections. Memory detector have no different from an ordinary one except; they are long-lived (no probability of dying, whereby P-death= 0), and also they are very sensitive to anomaly then mature one, in which; it need a single successful match to be activated (threshold “T” = 1). The selection of memory detectors is work as follow, once a mature (nonmemory) detector is activated by a string S (49-bits, which result from triple-data-path), this specific detector inters into a competition to become a “memory”. If a number of detectors were activated by S, the one with best match (d-beast) is chosen to become a memory detector (Hofmeyr, 1999). For LISYS uses the contiguous bits rule, “d-best” is the one match S in the most contiguous bits. And that detector “d-best” which been chosen, does not become a memory detector directly after activated, but it prompted to a provisional memory detector until it receives co-stimulation to conform that the match is non-self ( under the condition, if and only if, match = non-self confirmed it become memory). LISYS has an advantage of using an external expert advice (“co-stimulation” such as a human operator or an available independent intrusion detection system) (Glickman et al., 2005). 26 CHAPTER 5 IMPLEMENTATION 5.1 RUNNING LISYS There are two goals behind the experiment in this chapter. The first is to understand how LISYS works, in other words, what LISYS does to achieve the performance that we believe it’s capable of doing. The second target collecting a new set of data from a segment of real network, and uses it to train LISYS’s detectors to simulate the normal “self” network, and then set different parameters in a single Machine to face labs made series of attacks and rate the performance of LISYS detection capabilities. LISYS installation run through different stages, starting with requirements before the attempting to install or run the software as follow, TCPDump to be installed in every single machine, a JDK of 1.2 or greater and all machines must be on the same subnet. Adjusting the setting for LISYS parameters to ensure giving better result comes as second stage, further down you can “make” the file folder and file followed by “make install” to get the software installed. As last you need to run the LISYS Detectors and Broadcasters by typing lisys-detection or lisys-broadcasting followed by the enter key on the command line (noted: to stop lisys broadcasting or detection you need to key in –k after lisys-detection or lisys broadcast). Lisys should be starting actively after setting all it needs and here I’m providing three screen shots as a part of running LISYS (Figure 7, 8, 9). 27 Figure 7: running LISYS detector. Figure 8: running LISYS broadcaster 28 Figure9: some generated detection activities. 5.2 DATA The data collected here from a small restricted university lab while still collecting data in a realistic context. 5.2.1 DATA SET We used an internal network within University Technology Malaysia Kuala Lumpur branch; the collection of data took place at the training lab at the university’s library. Data were collected for a period about 30 days from one single segment 192.168. 2.200/254 from 10 Machines which is running different versions of UNIX based operating system “Redhat and Suze” and One Apache Web Server been used to 29 Monitor LISYS. With given it all permission to run CGI Perl scripting to Inquire into status of each single Node. There were an actively more than 7 users uses that lab from time to time to generate the most possible good quality of collected data. The internal university network uses a VLAN for management and put much of restriction on each segment network, that’s let us be relatively certain there were no attacks during the training periods. 5.2.2 NORMAL DATA Data were collected using TCPDUMP software from the subnet for a period of 30 days. The data set contains a total of 254,507 TCP SYN Packets. Those include the web Traffic (30%), in average of 5939 packets per day as Normal Data. 5.2.3 ATTACK DATA We have used a different collection of attacks, some of those attacks considered old but still actively used today, in which had been drawn from (Balthrop, 2002b). I have chosen five out of total eight attacks described by Balthrop, and those attacks as follow: Address probing, large scale port scanning, limited scanning (Some ports), single port Scan, and DDOS attack. Shark network scanner been used to generate most of Thos attacks, whereby the attacks packets been inserted to the network stack of the offline testing machine by using a packet injection program called Nemesis. 5.3 EXPERIMENT In consideration to the restriction on the university lab of running such attacking 30 activities, resulted data-set to be collected from on-line production network, the experiment took place in an off-line simulated machine that was running a simulated program from LISYS package, which can be found on its LisysSim Directory. we followed one set of parameter as is showed in table (5.1 Hence all the 10 machines, in the network have 100 detectors in which each machine Act as single detection node), in particular setting, we ran a 30 simulation test, and averaged the result over these. Everytime we attempted for a new simulation the detectors will be set to immature, and the system will be for 30 simulated days as a training period under the normal set of data. After that, LISYS was challenged with the attacks data. Parameter Value String length 49 bits Match length 11 bits Activation threshold 1 matches Match decay period 0 days Sensitivity decay level 0.1 days Tolerization period 10000 packets Costimulation delay 20000 packets Number detectors per node “Machine” 100 Table (5.1): The parameter for the simulation. 5.4 RESULTS LISYS was capable of detecting all the 5 intrusive activity that been introduced through over the simulation period, and in top of that, the number of false positive rate averaged to less than 15 per day. For such an experiment, running a simulation that mapped the 30 day of data, the average false positive rate achieved considered encouraging. 31 CHAPTER 6 This Chapter explores some implications and consequences of the results presented in previous chapters. And some of the idea could be view as a future work. The first section (6.1) discusses some important findings that listed to give us a point of measurements to challenge LISYS effectiveness and performance. In section (6.2) we went trough some observed points from the results generated out from the experiment. 6.1 FINDINGS LISYS was originally tested on data collection from a subnet in the computer science department at the University of New Mexico, (Hofmeyr, 1999; Hofmeyr and Forrest, 2000). In this experiment, there are 50 computers were active on the subnet and the data were collected for a duration of 50 days. And also, network connection to web and ftp servers were removed from the data, as well as all traffic involving hosts with local, dynamically assigned IP addresses. The second experiment with LISYS were also took place with new data set by Balthrop (Balthrop et al., 2002b). The data been collected in a shorter period of time compared to the previous experiment, collection of data took two weeks from an internal broadcast network of six computers in a research lab. Connectivity to the internet passed through a firewall using network address translation. 32 We can see clearly, that the second data set and experiment conducted is more realistic than the first one, but the duration of time were short. Hence, the need for new data set and experiment took place with Glickman (Glickman et al., 2003). In the third attempt, the data were collected in long period (62 days), a larger network (12 static hosts plus five distinct dynamic IP addresses), with a number of more active users (about ten). The idea of which better to use for such system, a negative detection or a positive detection, is under high debate. Steven Forrest (Forrest, et al, 1997) developed a system based on negative detection; for the reason that will incorporate many of the immunological principles, such as, Detectors can be distributed by placing different detectors on different computers confers diversity, because different computers will be able to detect different intrusions. And also, system is robust because the loss of some detectors on a single computer will not result in a complete absence of protection. But in the other side, Thomas Stibor (Stibor et al.2005) argued to the use of negative detection in Forrest proposed algorithm , and his argument summarized in two point, first, since a vast numbers of randomly generated detectors need to be discarded before the required number of suitable once obtain. Secondly, the algorithm is defined over a shape-space associated with an affinity function which induces additional problems. He has discussed these problems in his published article “Is negative selection appropriate for anomaly detection”. Somayaji (Somayaji et al., 1997) had drawn a guide in designing an artificial immune system, in which consist of principles. So an AIS approach that achieve a majority of this principles listed down could give us an efficient system: “Distributed protection” The IS consists of millions of agents or components, distributed throughout the body. These components interact locally to provide protection 33 in a completely distributed fashion: there is little or no centralized control or coordination, and hence no single point of failure in the system. “Diversity” There is several forms of diversity in the immune system. For example, each individual in a population has a unique IS, which improves the robustness of a population, because all individuals will not be vulnerable to the same extent to the same diseases. Within an individual, the components of the IS are different, providing diverse pattern recognition so that the IS can detect a variety of pathogens. “Robustness” Individual components of the IS are multitudinous and redundant, and the architecture of the IS such that the loss of only a few of these components will have little effect on the functioning of the IS. These disposable components combined with the lack of centralized or hierarchical control in the IS make it robust and tolerant of faults in the form of failures in a few components. “Adaptability” The IS can adapt to pathogenic structures, “learning” to recognize pathogens with increasing accuracy so that it can mount an increasingly effective response. Adaptation speeds up a current response and enables future responses to be more rapid than past responses. “Memory (signature-based detection)” Adaptations remain in force for periods of time up to the lifetime of an organism. This immunological “memory” allows the IS to more rapidly the second time around to pathogens similar to ones it has encountered in the past. Immune memory implements signature-based detection, by allowing the IS to monitor for characteristics of known pathogens. “Implicit policy specification” The definition of self used by the IS is empirically defined. Self is implicitly determined by the “monitoring” of proteins that 34 are currently in the body. The advantage of this approach is that self is equivalent to the actual normal behavior, and not a specification of what normal behavior ought to be. In other words, the IS does not suffer from the problems inherent in trying to correctly specify a security policy. “Flexibility” The IS is flexible in the allocation of resources for the protection of the body. “Scalability” Viewed from the perspective of distributed processing, the IS is scalable: communication and interaction between all IS components is localized, so there is little overhead when increasing the number of components. “Anomaly detection” Through a variety of mechanisms, the immune system has the ability to detect novel pathogens. In most cases this anomaly detection is not as effective as signature-based detection, but anomaly detection is essential to the survival of the organism, because any organism will always encounter novel pathogens in its lifetime. 6.2 OBSERVATION As a total result of these experiments and having a closer look at properties that LISYS exhibits. On the other hand, those properties are not available by current existing NID systems. Robustness of LISYS is qualified by showing amazing result which is achieved by the distribution of its detection nodes and no communication are required between them to do the job, and even though you loss some of these detection nodes will cause a very gradual degradation on performance. 35 Scalability of lisys is also tested from the view that each node act independently and if we adds more nodes that does not required us to increase the computational requirement of any others running detection nodes. So that make LISYS scalable to a larger network and no matter how fast is the network is grows, you just can add nodes depends in the need. Having a negative detectors that results out of the negative selection algorithm made LISYS perform an anomaly detection to attacks never been introduced to the system before. Where by other NIDs are not capable of achieving. Adding to anomaly that LISYS does performs signature detection just as the NID to give it fast reaction to previous attack but with the different that LISYS extracted its signature automatically with no need for update or human interference. Those signatures generated from the non-self data, and kept part of the overall of the detectors as memory live long detectors. And to prevent the hall system of turning all its detectors to become memory detectors and we ended with complete signature based system, a mechanism within LISYS set just a percentage of detectors to turn to memory which automatically be replaced by the newer qualified memory detector. That made LISYS capable of balancing its behavior as anomaly and signature based system and put in mind those attribute or controlling mechanisms can be adjustable to give the best result possible. In LISYS there are two more mechanism, tolerization and the finite number of detectors made the system adaptable with out intervention from human and also changes made to it with no need for input from human. Flexibility is achieved by allowing changes to be made to the properties that control LISYS and outcome its behaviors, specially the number of detectors per 36 detection node in the network. Obviously we can say that LISYS is capable and achievement been made by including most characteristics set to ensure the quality of any Artificial immune system. 37 CHAPTER 7 7.1 FUTURE WORK There are many areas in lisys can bring the extension to the system, obviously LISYS mainly act on the TCP SYN packet domain whereby other protocol can bring an attack such as UDP, so to add more protocols to the features of lisys will be great with adding more complexity. Rather than kept the system standing on the triple data path from the SYN packet, source, destination and port service. Possible to extend to include traffic frequencies and packet content with putting in mind keeping the system Lightweight and cheap, that the system achieved from its original representation 100 binary strings of length 49bits per machine. Automatic mobilization of the detectors between the detection nodes, that’s can make the detection nodes share each other knowledge but the draw back that have to take care of is the over load that might be generated and the security of the mobile agent. Working closer on testing and knowing exactly how sensitivity level and costimulation thresholds works and participate on the effectiveness of the over-whole of the system. It’s more advisable to go in more experiment to know the best out of these two properties, in which still ambiguous. 38 7.2 CONCLUSION current security arms works as the body’s skin and innate protection to infection, so we still in much need for defenses lines such as good passwords policy, appropriate access control, cryptography and all have to be carefully designed to achieve the best of prevention in top of that all we need to add such AIS in place as a compliment to enhance the over all and no harm in having one more weapon in the war against Viruses, worms and other ways of attacks. Reports showed that security is decaying, resulting from the existing security systems, and surely these systems will not be able to response to security threat from the new networks that the future will bring. This because current systems are not built with these threats in mind “can’t adapt new attacks”. IDS job is just to alert an administrator. Current IDS is called Knowledge-based systems, in which are effective at stopping known attack, based on predefined signature or policies, with no learning mechanism made them useless to attacks never been seen before. Behavior-based systems are the solution, in which inspired by biological immune system. These are a promising ideas for detecting novel attack but small number of such system been built. LYSIS is one of those systems in place; therefore LISYS is worthy to be implemented to extend the empirical evaluation of its performance to new and more challenging data set, to deepen the understanding of the contributions made by each component of it to its overall performance. 39 REFERENCES Balthrop, J., Forrest, S., and Glickman, M. (2002b). Revisiting LISYS: Parameters & normal behavior. CEC-2002. Proceeding of the congress on evolutionary computing. Bruce Scneier. Secret and Lies. Indianapolis, Indiana: Wiley publishing, 2000. CERT Coordination centre 2002, April. “CERT/cc statistics 1988-2002.” Technical report, Carnegie Mellon University. Dasgupta, Dipankar. (1999). Immunity-based intrusion Detection System: A General (NISSC). Virginia/United state: National Institute of standards and technology and national computer security center, Forrest, S., Perelson, A. S., Allen, L., and Kuri, R. C. (1994). Self –Non self discrimination in a computer. In proceedings of the 1994 IEE Symposium on research in security and privacy, Los Alemitos, CA.IEEE computer society press. Forrest, S., Hofmeyr, S. A., Somayaji, A., and Longstaff, T. A. (1996). A sense of self for Unix processes. California. United state: IEEE Computer Society press. Forrest, S., Hofmeyr, S. A., and Somayaji, A. (1997). Computer Immunology. Communication of the ACM. Glickman, M. Balthrop, J. Forrest, S. (2003). A Machine Learning Evaluation of an Artificial Immune system. Massachusetts Institute of Technology. Hofmeyr, S. (1999). An immunological model of distributed detection and its application to computer security. University of New Mexico: PhD thesis. Hofmeyr, S., and Forrest, S. (2000). Architecture for an artificial immune system. Evolutionary computation Journal. Kim, J. and Bentley, P. (1999). The artificial immune model for network intrusion detection. Aachen, Germany: in 7th European Conference on Intelligent Techniques and Soft computing. Parham Peter. (2000). The immune System. New York: Garland Publishing. Percus, J. K., Ora E. P., and Perelson A. S. (1993). Predicting the size of the T-cell Receptor and antibody combing region from consideration of efficient self-non self discrimination. Proceeding of the national academy of sciences of the United State of 40 America. Stibor, T., Mohr, P., Timmis, J. (2005). Is negative selection appropriate for anomaly detection?. USA: ACM. Somayaji, A. Hofmeyr, S. and Forrest, S. (1997). Principles of a Computer Immune System. ACM. Symantec Norton Antivirus 2005. http://www.symantec.com/nav/nav-9xnt/,2005. Trend Micro-Trend Micro outbreak http://www.trendmicro.com/en/products/global/enterprise.html,2005. management. Tizard, I. R., (1992). Immunology. Third edition. Texas: A&M University. Weir, D. M. and Stewart, J. (1997). Immunology. Eight Edition. New York: CHURCHILL LIVINGSTONE. Williams, P. Anchor, K. Bebo, J. Gunsch, G. and Lamont, G, (2001). Towards a computer immune system for detecting network intrusion. Berlin, Springer-Verlag. Nemesis packet injection. http://packetfactory.net/projects/nemesis/ , 2005. 41 APPENDIX A # -*- tab-width: 10; -*include templates/global.properties JAVAC=javac BIN_DIR=/usr/bin build: clean mkdir classes cd src && \ $ (JAVACl -d .. /classes/ 'find -name *.java' install: mkdir mkdir mkdir mkdir mkdir cp -r cp cp cp cp build -p /etc/lisys -p $ (logpathl -p $ (statepathl -p $ (pidpathl -p $ (classpathl classes/* $(classpathl/ templates/global.properties /etc/lisys/global.properties templates/detection.properties /etc/lisys/detection.properties templates/broadcast.properties /etc/lisys/broadcast.properties templates/filter. rules /etc/lisys/filter.rules cp templates/lisys-detection $ (BIN_DIRl/lisys-detection cp templates/lisys-broadcast $(BIN_DIR)/lisys-broadcast cp templates/lisys-sim $(BIN_DIRl/lisys-sim cp templates/lisys-http $(BIN_DIRl/lisys-http chmod +x $(BIN_DIRl/lisys-detection chmod +x $ (BIN_DIRl/lisys-broadcast chmod +x $(BIN_DIRl/lisys-sim chmod +x $(BIN_DIRl/lisys-http clean: rm -rf classes dist: clean cd .. ; tar -cvzf lisys-0.1.tgz lisys-D.1 =================~/ 6nqa a * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL) , version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*1 package edu.unm.cs.lisys.debug; import import import import edu.unm.cs.lisys.util.*; java.io.*; java.util.*; java.text.*; 1**========== * Debug. java * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> * * Our debug class sends to System. err * * There are three levels of debug: * off, standard, and verbose *==========*1 public class Debug { II By default, we'll use the standard debugging level. private static int debugFlag = 1; private static final int VERBOSE = 0; private static final int STANDARD = 1; private static final int OFF = 2; 1**========== * setLevel: * Sets the level of debugging. * * @param s the level of debugging (verbose, off, or standard) *==========*1 public static void setLevel(String s) { if (s.equalsIgnoreCase("verbose")) , debugFlag = VERBOSE; Debug. standard ("Debug: debug level set to verbose"); } else if (s.equalsIgnoreCase("off")) { II Output the change before we turn debugging off. Debug.standard("Debug: debug level set to off"); debugFlag = OFF; } else if (s.equalsIgnoreCase("standard")) debugFlag = STANDARD; Debug.standard("Debug: debug level set to standard"); } else { debugFlag = STANDARD; Debug. verbose ("Debug: debug level" + s + " unrecognized, defaulting to standard"); 1**========== * verbose: * Prints a message if the level is verbose. * * @param s the message *==========*1 public static void verbose (String s) { if (debugFlag == VERBOSE) { send (System. err, "dbg-vrb", s); 1**========== * standard: * Prints a message if debugging isn't off. * * @param s the message *==========*1 public static void standard(String s) { if ((debugFlag == VERBOSE) I I (debugFlag send(System.err, "dbg-std", s); STANDARD)) { 1*========== * exception: * Prints an exception message if debugging isn't off. Prints a * stack trace if the debugging level is verbose. * * @param 0 the object * @param e the exception *==========*1 public static void exception(Object 0, Exception e) { if ((debugFlag == STANDARD)) { send(System.err, "dbg-exc" , o.toString() + ": " + e); , } else if ((debugFlag == VERBOSE) I I (debugFlag == STANDARD)) send(System.err, "dbg-exc" , o.toString() + ": " + e); e.printStackTrace() ; /**========== * exception: * Prints an exception message if debugging isn't off. Prints a * stack trace if the debugging level is verbose. * * @param s the string * @param e the exception *==========*/ public static void exception(String s, Exception e) { if ((debugFlag == STANDARD)) { send (System. err, "dbg-exc", s + ": " + e) i } else if ((debugFlag == VERBOSE) I I (debugFlag == STANDARD)) send (System. err, "dbg-exc" , s + ": " + e) i e.printStackTrace() i /**========== * send: * Prints a message to a print stream with a timestamp. * * @param out the print stream * @param tag the tag for the message * @param message the message *==========*/ private static void send(PrintStream out, String tag, String message) { String timestamp = (new Date(System.currentTimeMillis())) .toString() i synchronized (out) { System.err.println("[" + tag + "@" + timestamp + "] message) i } " + { =================~/ * Copyright (C) 2001 Dennis Chao * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL) , version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*1 package edu.unm.cs.lisys.detection; import import import import import edu.unm.cs.lisys.debug.*; edu.unm.cs.lisys.detection.bip.*; edu.unm.cs.lisys.detection.bif.*; edu.unm.cs.lisys.detection.matchrule.*; edu.unm.cs.lisys.util.*; import java.lang.System; import java.util.*; import java.io.*; 1**========== * DetectionNode.java * Base class that implements basic Lisys detection node features. * Each node contains a vector of Detectors. This is a butchered * version of NewDetectionNode.java. * * The main public methods are: * boolean isAnomalous(BinarylnputPattern bip) * void costimulate(BinarylnputPattern bip) * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Hajime Inoue <hinoue@cs.unm.edu> * @author Dennis Chao <dlchao@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*1 public class DetectionNode implements Serializable { II input from constructor nNumDetectors; private int detectors private MatchRule mMatchRule; private String _szBipType; private String _szBifTypei private int _nBipLengthi II total number of II II II II match rule BIP type BIF type length of BIPs private private private detectors private tolerize long boolean int _nRandomSeedj _bUseMemorYj _nMaxMemoryDetectorsj II II II used to seed random use memory? maximum memory int _nTolerizationPeriodj II time it takes to II Detector arguments private int _nActivationThreshhold private int _nCostimulationDelayj private double _dDeathProbabilitYj private double _dMatchDecayj private int _nMinMatchLengthj II state private int _nNumMemoryDetectorsj detectors private double _dSensitivityLevelj private double _dSensitivityDecayj private double _dSensitivityIncrementj public Vector _vDetectorsj private KnuthRandom _randomj private BinaryInputFilter _bifj II Statistics private long _nNumBipsReceivedj private long _nNumAnomaliesj seen private long _nNumDetectorsKilledj = 10j II number of memory II sensitivity level II II II list of detectors random number generator binary input filter II II number of BIPs seen number of anomalous BIPs II number of detectors killed II Accessor functions public long getNumBipsReceived() return _nNumBipsReceivedj public long public double return _nNumAnomaliesj } return _dSensitivityLevelj getNumAnomalies() getSensitivityLevel() public int getNumDetectors() public int getNumMemoryDetectors() nNumMemoryDetectorsj } public long getNumDetectorsKilled() _nNumDetectorsKilledj } public int getTolerizationPeriod() _nTolerizationPeriodj } return _nNumDetectorsj return return return public void setTolerizationPeriod(int n) { _nTolerizationPeriod = n j for (Enumeration detectors = vDetectors.elements()j detectors.hasMoreElement~()j ) { Detector detector = (Detector) detectors.nextElement()j detector.setTolerizationPeriod((int)_nTolerizationPeri od)j public int getNumMatureDetectors() { int nummature = OJ for (Enumeration detectors = vDetectors.elements()j detectors.hasMoreElement~()j ) { Detector detector = (Detector) detectors.nextElement(); if (!detector.islmmature()) nummature++; } return nummature; public int getNumActivatedDetectors() int numactivated = 0; for (Enumeration detectors = vDetectors.elements(); detectors.hasMoreElements(); ) { Detector detector = (Detector) detectors.nextElement(); if (detector.isActivated()) numactivated++; } return numactivated; public void printMatureDetectors() { for (Enumeration detectors = vDetectors.elements(); detectors.hasMoreElements(); ) { Detector detector = (Detector) detectors.nextElement(); if (!detector.islmmature()) { System.err.println(detector.toString()); 1**========== * DetectionNode: * Constructor that reads in the parameters from the supplied * filename, initializes them, and sets things like the * biptype. *==========*1 public DetectionNode(int nNumberOfDetectors, MatchRule mMatchRule, String szBipType, String szBifType, int nBipLength, int nTolerizationPeriod, boolean bUseMemory, int nMaxMemoryDetectors, double dSensitivitylncrement, double dSensitivityDecay, long nRandomSeed, int activationThreshhold, int costimulationDelay, double deathProbability, int minMatchLength, double matchDecay) II Grab our state from the constructor arguments. _nNumDetectors = nNumberOfDetectors; _nNumDetectorsKilled = 0; _mMatchRule = mMatchRule; _szBipType = szBipType; _szBifType = szBifType; _nBipLength = nBipLength; _bUseMemory = bUseMemory; _nMaxMemoryDetectors = nMaxMemoryDetectorsi _nRandomSeed = nRandomSeedi _dSensitivitylncrement = dSensitivitylncrementi _dSensitivityDecay = dSensitivityDecaYi II Detector variables _nActivationThreshhold = activationThreshholdi _nCostimulationDelay = costimulationDelaYi _dDeathProbability = deathProbabilitYi _nMinMatchLength = minMatchLengthi _dMatchDecay = matchDecaYi nTolerizationPeriod = nTolerizationPeriodi II initialize _nNumMemoryDetectors = Oi _dSensitivityLevel = Oi _nNumBipsReceived = Oi _nNumAnomalies = Oi random = new KnuthRandom( nRandomSeed) i ~y ( bif = ((BinarylnputFilter) Class.forName(_szBifType) .newlnstance()) .constructFilter ( random, _nBipLength)i } catch (Exception e) ( Debug. exception (this, eli vDetectors = new Vector() i II Generate individual detectors. for (int i=o i i < _nNumDetectors i i++) ( Detector detector = new Detector(_bif, _mMatchRule, _random, _nActivationThreshhold, _nCostimulationDelay, _nTolerizationPeriod, _dDeathProbability, _nMinMatchLength, _dMatchDecay, _szBipType) i _vDetectors.addElement(detector) i Debug.verbose("Tolerization period " + nTolerizationPeriod) i 1**========== * isAnomalous: * Determines whether the binary input pattern is anomalous or not. * Memory competition occurs only when detectors are costimulated. * * @see #costimulate * @param bip the binary input pattern to classify * @return true if the bip is classified as anomalous *==========*1 public boolean isAnomalous(BinaryInputPattern bip) { boolean alarm = false; boolean sensitivityEffect false; _nNumBipsReceived++; for (Enumeration detectors = vDetectors.elements(); detectors.hasMoreElement;(); ) { Detector detector = (Detector) detectors.nextElement(); switch (detector.respondToBip(bip, _dSensitivityLevel)) case Detector.ACTIVATED: alarm = true; break; case Detector.ADJUST SENSITIVITY: sensitivityEffect = true; break; case Detector.DIE: Debug.verbose(this.toString() + ": DETECTOR DIES"); _nNumDetectorsKilled++; detector.recreate(_bif, _mMatchRule, _nActivationThreshhold, _nCostimulationDelay, _nTolerizationPeriod, _dDeathProbability, _nMinMatchLength, _dMatchDecay, _szBipType) ; break; default: break; II Adjust the sensitivity level if appropriate. if (sensitivityEffect I I alarm) _dSensitivityLevel += _dSensitivityIncrement; II Decay the sensitivity level. The decay factor is generally II less than 1.0 and the sensitivity level can't go below II zero. _dSensitivityLevel -= _dSensitivityDecay; if (_dSensitivityLevel < 0) _dSensitivityLevel = 0; if (alarm) { _nNumAnomalies++; return true; else { return false; 1**========== * costimulate: * Checks to see what detectors were activated by bip and * costimulates them. Any detector that has its activated flag * set and that matches the bip will be costimulated and enter * the memory competition. * * @param bip the binary input pattern to be costimulated *==========*1 public void costimulate(BinarylnputPattern bip) { II II Randomly select some memory to be replaced, if we have reached the limit. int demoteMemoryRank = 1; int demoteMemorylndex = 0; if (_bUseMemory) { demoteMemoryRank _random.intRange(_nMaxMemoryDetectors) ; int countMemoryDetectors = 0; we've seen. int maxMatchLength = 0; int competitionWinner = -1; Enumeration detectors II The number of memory detectors _vDetectors.elements() ; int dlndex = 0; while (detectors.hasMoreElements()) { Detector detector = (Detector) detectors.nextElement(); if (detector.costimulate(bip)) { II This detector matches the bip. if (detector.getMatchLength() > maxMatchLength) II This detector is the best match so far. competitionWinner = dlndex; maxMatchLength = detector.getMatchLength(); if (detector.isMemory()) { countMemoryDetectors++; if (countMemoryDetectors == demoteMemoryRank) { II This is the memory detector that will be II demoted if necessary. demoteMemorylndex = dlndex; } dlndex++; if (_bUseMemory && (competitionWinner > -1)) Detector winningDetector = (Detector) _vDetectors.elementAt(competitionWinner); II Now we make the winning detector into a memory II detector, if it isn't already memory. if (lwinningDetector.isMemory()) { winningDetector.setMemory(true) ; if (countMemoryDetectors < _nMaxMemoryDetectors) { II We have increased the total number of memory II detectors since the memory isn't already full. _nNumMemoryDetectors++; } else { II II II We already have full set of memory detectors, so we demote the previously randomly selected detector. ( (Detector) _vDetectors.elementAt(demoteMemoryIndex)) . setMemory (false) ; } }; 1*================= * Copyright (C) 2001 Steven Hofmeyr * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL) , version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * * http://www.cs.unm.edu/-judd/lisys/ * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTYl *=================*1 package edu.unm.cs.lisys.detection; import import import import import import edu.unm.cs.lisys.debug.*; edu.unm.cs.lisys.util.*; edu.unm.cs.lisys.detection.bip.*; edu.unm.cs.lisys.detection.bif.*; edu.unm.cs.lisys.detection.matchrule.*; . . *; Java.lO. 1**========== * Detector. java * * Many people have worked on this code. Here they are in the order they * have worked on it: * @author Steven Hofmeyr <sah@santafe.edu> * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Hajime Inoue <hinoue@cs.unm.edu> * @author Dennis Chao <dlchao@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> * * * * * * * * The actual "detector" that behaves like a single T cell. A detector consists of a BIF (binary input filter) and a BIP (binary input pattern) Incoming BIPs are filtered and then compared to the BIP. The main public methods are: int respondToBip(BinarylnputPattern incomingBip, double sensitivityLevel) * boolean costimulate(BinarylnputPattern verifyBip) *==========*1 public class Detector implements Serializable { private private private private private private private private private private private private KnuthRandom random; boolean memory = false; boolean awaitingCostimulation = false; boolean immature = true; long age = 0; int numberMatches = 0; long ageAtLastMatch = 0; BinarylnputFilter localBif; BinarylnputPattern localBip; MatchRule localMatchRule; boolean activated = false; int currentMatchLength = 0; II length of last match private private private private private private private String _szBipType; int nActivationThreshhold int _nCostimulationDelay; int _nTolerizationPeriod; double _dDeathProbability; double _dMatchDecay; int _nMinMatchLength = 0; II These are the values public static final int public static final int public static final int public static final int II the name of the BIP class = 10; II minimum length of a match that are returned by activated method. NONE = 0; DIE = 1; ADJUST_SENSITIVITY = 2; ACTIVATED = 3; public Detector (BinarylnputFilter bif, MatchRule matchRule, KnuthRandom r, int activationThreshhold, int costimulationDelay, int tolerizationPeriod, double deathProbability, int minMatchLength, double matchDecay, String bipType) II Use the parameters to set the class variables. localBif = bif; localMatchRule = matchRule; random = r; _nActivationThreshhold = activationThreshhold; _nCostimulationDelay = costimulationDelay; _nTolerizationPeriod = tolerizationPeriod; _dDeathProbability = deathProbability; _nMinMatchLength = minMatchLength; _dMatchDecay = matchDecay; II Now we'll try to look up the BlP class using it's name. szBipType = bipType; try { localBip (BinarylnputPattern)Class.forName(_szBipType) .newlnstance(); localBip.constructBinaryString(random) ; } catch (Exception e) { Debug.exception("Sorry, the BlP doesn't exist: ", e); 1**========== * recreate: * This is the same as the constructor except we don't get a new * random number generator. *==========*1 public void recreate (BinarylnputFilter bif, MatchRule matchRule, int activationThreshhold, int costimulationDelay, int tolerizationPeriod, double deathProbability, int minMatchLength, double matchDecay, String bipType) II Use the parameters to set the class variables. localBif = bif; localMatchRule = matchRule; _nActivationThreshhold = activationThreshhold; _nCostimulationDelay = costimulationDelay; _nTolerizationPeriod = tolerizationPeriod; _dDeathProbability = deathProbability; _nMinMatchLength = minMatchLength; _dMatchDecay = matchDecay; II Try to look up the BlP class by name. szBipType = bipType; try { localBip (BinarylnputPattern) Class.forName (_szBipType) .newlnstance(); localBip. constructBinaryString (random) ; PERPUSTAKAAN SULTANAH ZANARIAH U'Uversiti TeknoJogi Malaysia 2 2 JUL 2009 } catch (Exception e) { Debug. exception {"Sorry, the BIP doesn't exist: ", e); II We also need to reset the detector back to it's initial II immature state. memory = false; awaitingCostimulation = false; immature = true; age = 0; numberMatches = 0; ageAtLastMatch = 0; activated = false; public int getTolerizationPeriod{) return _nTolerizationPeriod; public int setTolerizationPeriod{int i) { if (i > 0) _nTolerizationPeriod = i; return _nTolerizationPeriod; 1**========== * respondToBip: * Using the incoming BIP, this function determines what happens * next. The detector always gets older. In additon to that, we * can either die, become activated, adjust our sensitivity or * do nothing. * * @param incomingBip - the BIP used to determine our action * @param sensitivityLevel - how sensitive will we be * @return a constant indicating the response to the BIP *==========*1 public int respondToBip{BinaryInputPattern incomingBip, double sensitivityLevel) { age++; !I If the detector has exceeded the costimulation period then it must die. if {awaitingCostimulation && ({age - ageAtLastMatch) > _nCostimulationDelay)) { Debug. verbose (this.toString{) + ": died from lack of costim") ; return DIE; II Check to see if the detector matures. if {immature && (age >= _nTolerizationPeriod)) immature = false; II Check for death from old age. if {!immature && !memory && (_dDeathProbability > 0)) if (random.fraction{) < _dDeathProbability) Debug.verbose(this.toString() + ": died of old age"); return DIE; II Permute the binary string. BinaryInputPattern filteredBip = 10caIBif.filter(incomingBip); II Adjust the threshold according to sensitivity and memory. double adjustedThreshold = nActivationThreshholdsensitivityLevel; if (adjustedThreshold < 1) adjustedThreshold = 1; if (memory) adjustedThreshold = 1; currentMatchLength filteredBip) ; activated = false; boolean firstMatch = 10caIMatchRule.match(locaIBip, = false; if (currentMatchLength >= nMinMatchLength) if (immature) { Debug.verbose(this.toString() + ": died on immmature match") ; return DIE; II Even 1 match is death for an immature detector! } numberMatches++; II Check if the detector has been activated. if (numberMatches >= _nActivationThreshhold) activated = true; numberMatches = 0; II the age II If we are awaiting costimulation then don't reset at the last match, otherwise set it to the current age. if (1 awaitingCostimulation) { ageAtLastMatch = age; awaitingCostimulation = true; if (numberMatches 1) firstMatch true; II Randomly decay the number of matches. if (numberMatches > 0) { if (random.fraction() < _dMatchDecay) numberMatches--; if (activated) return ACTIVATED; if (firstMatch) return ADJUST_SENSITIVITY; return NONE; public boolean isActivated() { return activated; } public boolean isImmature() public int getMatchLength() return immature; } return currentMatchLength; 1**========== * costimulate: * Checks to see if the given BIP stimulates the detector. * Costimulation cannot occur if the BIP is a memory detector or * an immature detector. * * @param verifyBip - the BIP used to determine stimulation * @return whether this detector was costimulated *==========*1 public boolean costimulate(BinaryInputPattern verifyBip) { if (immature II memory II lawaitingCostimulation) return false; II Permute the binary string. BinaryInputPattern filteredBip int currentMatchLength filteredBip) ; = = localBif.filter(verifyBip); localMatchRule.match(localBip, if (currentMatchLength >= _nMinMatchLength) II Costimulation received! awaitingCostimulation = false; return true; return false; public boolean isMemory() { return memory; } public void setMemory(boolean bool) { memory = bool; } public String toString() { return localBip.toString(); 1*================= * * * * * * * * * * * * * * * * Copyright (C) 2001 Hajime Inoue Lisys is a program that monitors TCP SYN packets to detect network traffic anomalies. Licensed under the GNU General Public License (GPL), version 2 or higher. Please see the COPYING and PATENT files included with the Lisys distribution, which can be found at: http://www.cs.unm.edu/-judd/lisys/ Also, the current text of the GPL can be found at: http://www.gnu.org/copyleft/gpl.html Note that Lisys has NO WARRANTYl *=================*1 package edu.unm.cs.lisys.detection; import import import import import edu.unm.cs.lisys.debug.*; edu.unm.cs.lisys.detection.bip.*; edu.unm.cs.lisys.detection.bif.*; edu.unm.cs.lisys.detection.matchrule.*; edu.unm.cs.lisys.net.SimpleServer; import import import import import java.lang.System; java.net.URLEncoder; java.net.lnetAddress; java.util.*; java.io.*; /**========== * NodeServer.java * * Many people have worked on this code. Here they are, in the order * they've worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Hajime Inoue <hinoue@cs.unm.edu> * @author Dennis Chao <dlchao@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> * * A server that manages a single DetectionNode. One NodeServer should * probably run on each machine in the network. * * * * * * * * * * * * * * * * * * * * * * * * * * * The protocol is as follows: <ul> <li>The first line is one of the following commands: BROADCAST, COSTlMULATE, STATS, SAVE, MAIL, or ANOMALIES. Case doesn't matter. <li>If the command is BROADCAST, the next line contains how many bips there are. Each subsequent line is then a bip. The number of subsequent lines (and hence bips) should equal the integer given on the first line. <li>If the command is COSTIMULATE, the next line is the anomalous bip. <li>If the command is STATS, statistics about the server are returned in a yet undefined manner. <li>If the command is MAIL, mail will be sent to the usual list of recipients. <li>If the command is SAVE, the detector will be serialized to hostname.dnd. <li>If the command is ANOMALIES, the detector will output its list of anomalies. </ul> *==========*/ public class NodeServer extends SimpleServer implements Serializable II Command string values private static final String private static final String private static final String private static final String private static final String private static final String broadcast costimulate stats save mail anomalies "BROADCAST" ; "COSTlMULATE"; "STATS"; "SAVE" ; "MAIL"; "ANOMALIES" ; II Parameters are stored here private Parameters parameters; private DetectionNode private Vector private Vector mailed private String private String _node; anomalyLinks; mailLinks; 10calIPMask; anomalyFilename; private transient PrintWriter private static final String "anomalies.log.file"; II Statistics private int bipsSinceLastMail private int bipsSinceLastSave II II II II the detection node stores current anomalies stores anomalies to be anomaly log filename anomalyFile; II anomaly log file anomalyLogFileKey = 0; 0; 1**========== * NodeServer: * Constructor that reads in the parameters from the supplied * filename, initializes them, and sets things like the biptype. *==========*1 public NodeServer(String filename) { II Read in parameters parameters = new Parameters (filename) ; II Start initialization port = parameters.getPort(); mailLinks = new Vector(); anomalyLinks = new Vector(); anomalyFilename = parameters.getAnomaliesLog(); try { 10calIPMask = InetAddress.getLocalHost() .getHostAddress(); 10calIPMask = 10calIPMask.substring(O, 10calIPMask.lastlndexOf(' .• )); } catch(Exception e) { System.err.println(e) ; e.printStackTrace() ; node new DetectionNode(parameters.getNumberOfDetectors(), parameters.getMatchRule(), parameters.getBIPType() , parameters.getBIFType(), parameters.getBIPLength(), parameters.getTolerizationPeriod(), parameters.useMemory(), parameters.getMaximumNumberOfMemoryDetectors() , parameters.getSensitivityIncrement(), parameters.getSensitivityDecay() , parameters.getRandomSeed() , parameters.getActivationThreshold(), parameters.getCostimulationDelay(), parameters.getDeathProbability(), parameters.getMatchLength() , parameters.getMatchDecay()); Date d = new Date(); System.err.println("Constructed on "+ d.toString()); 1**========== * readObject: * Deserializes this object from a stream. Calls the default * method then reconstitutes the anomaly log stream. *==========*1 private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException Date d = new Date(); System.err.println("Deserializing on stream.defaultReadObject( ); openLog(); II + d.toString()); 1**========== * serveConnection: * Figures out whether this is statistics request, costimulation * order, or input from the broadcast node. *==========*1 public void serveConnection(InputStream ins, OutputStream outs) throws Exception Debug.verbose("Getting a connectionl"); II Attach the streams to more convenient ones BufferedReader in = new BufferedReader(new InputStreamReader(ins)) ; PrintWriter out = new PrintWriter(outs); II Do a little bit of parsing String line = in.readLine() .trim(); String command = line; String args = 1111; i f ( line. indexOf (I I) 1= - 1) { command = line.substring(O, line.indexOf(1 I)) .trim(); args = line.substring(line.indexOf(' .) + 1) .trim(); Debug. standard (command + ": II + args); if (command.toUpperCase() .equals(broadcast)) readBips(args, in, out); else if (command.toUpperCase() .equals(costimulate)) readCostimulate(in, out); else if (command.toupperCase() .equals(stats)) readStats(in, out); else if (command. toupperCase () .equals(mail)) readMail(in, out); else if (command.toUpperCase() .equals(save)) save() ; else if (command.toUpperCase() .equals(anomalies)) printAnomalies(in, out); else readError(command, in, out); out.flush() ; public void init(String filename) { try { FileReader fir= new FileReader(filename); BufferedReader in = new BufferedReader(fir); PrintWriter out = new PrintWriter(System.err); String biptype = parameters.getBIPType(); String bipline; while((bipline = in.readLine()) 1= 1111) { bipline = localIPMask + II II + bipline; Debug. verbose (bipline) ; BinarylnputPattern bip = (BinarylnputPattern) Class. forName (biptype) .newlnstance(); bip. constructBinaryString (bipline) ; boolean anomaly = _node. isAnomalous (bip) ; bipsSinceLastMail++; bipsSinceLastSave++; if ( bipsSinceLastMail > parameters.getCostimulationMailDelay() && mailLinks. size () l = 0 ) mailHumanOperator() ; if ( bipsSinceLastSave > parameters.getSaveDelay() save() ; } catch(Exception e) { Debug. exception (this, e); public void save() { . ) { try { FileOutputStream fos = new FileOutputStream(parameters.getSaveFile()); ObjectOutputStream out = new ObjectOutputStream(fos) ; bipsSinceLastSave = 0; out.writeObject(this) ; out.flush(); out.close(); } catch(Exception e) { Debug. exception (this, e); /**========== * readBips: * Reads a series of BlPS and checks if they are anomalous. At * the end, it checks to see if the BlP count is greater than * the specified amount and sends an email to the operator if * need be. *==========*/ private void readBips(String biptype, BufferedReader in, PrintWriter out) { String bipline = ""; boolean alarm = false; int bips try { bips 0; Integer.parselnt(in.readLine()) ; } catch(Exception e) { Debug. exception (this, e); return; biptype = parameters.getBlPType(); for(int i=O; i < bips; i++) { try { bipline = in.readLine(); if ( bipline != "" ) { BinarylnputPattern bip (BinarylnputPattern)Class.forName(biptype) .newlnstance(); Debug. verbose (bipline) ; bip.constructBinaryString(bipline); if (_node.isAnomalous(bip)) alarm=true; addCostimulationLink(bipline) ; } else break; } catch(Exception e) network: Debug.exception("packet source and destination outside + bipline, e); break; II if ( ++bipsSinceLastMail > parameters.getCostimulationMailDelay() && mailLinks.size() != 0 ) mailHumanOperator() ; if ( ++bipsSinceLastSave > parameters.getSaveDelay() bipsSinceLastSave = 0; save () ; ) { /**========== * readCostimulate: * Handle the costimulate command. *==========*/ private void readCostimulate(BufferedReader in, PrintWriter out) { String bipline String biptype try { bipline = , 1111 • parameters.getBIPType() ; in.readLine(); } catch(IOException e) { Debug. exception (this, e); if ( ! bipline. trim () . equals (II II) try { BinaryInputPattern bip ) { = (BinaryInputPattern) Class. forName (biptype) .newInstance(); bip.constructBinaryString(bipline); _node.costimulate(bip); String part1 = bipline.substring(O, bipline.indexOf('<')); String part2 = bipline.substring(bipline.indexOf('<') +1) ; out.println(part1 + II &It II + part2 + II was costimulated.\n") ; } catch(Exception e) { Debug. exception (this, e); out.println("Unable to construct the BIP.\n ll ) ; } else { out.println("The BIP was formatted improperly.\n"); } out.flush() ; /**========== * readStats * Should print out stats but doesn't do much now. *==========*/ private void readStats(BufferedReader in, PrintWriter out) { out.println(_node.getNumBipsReceived() + " bips received."); out.println(bipsSinceLastMail + " since last mail."); out.println(bipsSinceLastSave + " since last save."); out.println (_node.getNumAnomalies () + " anomalies."); out.println (_node.getNumDetectors () + " detectors."); out.println (_node.getNumMemoryDetectors () + " memory detectors.") ; out.println(_node.getSensitivityLevel() + " sensitivity level."); out.println (_node.getNumMatureDetectors () + " mature detectors."); out.println (_node.getNumActivatedDetectors () + " activated detectors.") ; out.flush() ; private void readMail(BufferedReader in, PrintWriter out) { int bips = bipsSinceLastMail; mailHumanOperator() ; out.println("Mailed Human operator" + bips + " messages."); out. flush () ; private void printAnomalies(BufferedReader in, PrintWriter out) { out.println(anomalyLinks.size() + " anomalies\n"); for (Enumeration e = anomalyLinks.elements(); e.hasMoreElements(); ) { String singleLink = (String) e.nextElement(); out.println(singleLink) ; /**========== * readError: * Handle illegal commands. *==========*/ private void readError(String command, BufferedReader in, PrintWriter out) { out.println(command + " is not a legal command."); } /**========== * mailHumanOperator: * Sends in a bip list to the human operator. *==========*/ private void mailHumanOperator() { Debug.standard("\n\n MAILED HUMAN OPERATORS \n\n"); Vector recipientList = parameters.getCostimulationMailList(); String recipients = new String() ; for (int i=O; i < recipientList.size(); i++) { recipients += (String) recipientList.elementAt (i) + " "; } Debug.standard("Mail send to: " + recipients + "\n"); try { Process mailproc = Runtime.getRuntime() .exec("mail "+ recipients) ; PrintStream out = new PrintStream(mailproc.getOutputStream()) ; out.println("Subject: costimulation alarm @ " + (new Date()) .toString()); out.println("Please click on all links below that correspond to a Binary Input Pattern (BIP) deemed anomalous: \n"); for (Enumeration e = mailLinks.elements(); e.hasMoreElements(); ) { out.println((String) e.nextElement()); } out.close(); } catch (Exception e) { Debug. exception (this, e); } mailLinks.removeAllElements() ; bipsSinceLastMail = 0; 1**========== * addCostimulationLink: * Adds a link to the email being sent out indicating the bip is * anomalous so the user has the option of costimulation. Also * adds a link to the anomalies list. * * @param sb the tcpdump line prepended by the local ip mask *==========*1 private void addCostimulationLink(String sb) { II Construct the query args for this bip HTML link representation. Debug.verbose(sb) ; String queryArgs = URLEncoder.encode(sb); String httphost = parameters.getCostimulationServer(); int httpport = parameters.getCostimulationServerPort(); String link = new String("<p><a href=\"http://" + httphost + ":" + httpport + "I" + parameters.getDetectionNodeHost() + ":" + parameters.getPort() + "?" + queryArgs + "\">" + "#" + (mailLinks.size() + 1) + ": " + sb + "</a>"); mailLinks.addElement(link) ; String alink new String(parameters.getDetectionNodeHost() + I I . II + parameters.getPort() "?" + queryArgs); + anomalyLinks.addElement(alink) ; II Make sure anomaly list doesn't get too large. if (anomalyLinks.size(»parameters.getCostimulationDelay()) anomalyLinks.removeElementAt(O) ; public static NodeServer read(String filename) throws Exception FilelnputStream fis = new FilelnputStream(filename) ; ObjectlnputStream in = new ObjectlnputStream(fis) ; NodeServer node = (NodeServer)in.readObject(); return node; public void openLog() try { II Try to append to anomaly log. anomalyFile = new PrintWriter(new FileOutputStream(anomalyFilename, true)); } catch (IOException ioe) { Debug. exception (this, ioe); 1**========== * main: * Starts a new node as a thread. *==========*1 public static void main(String[] args) { if (args.length % 2 != 0 I I args.length == 0) { System.err.println("Usage: java NodeServer <arguments>\n"); System.err.println("\tPossible flags are:\n"); System.err.println("\t\t-i <filename>\tinitialize with this tcpdump file (optional)"); System.err.println("\t\t-p <filename>\tproperties file"); System.err.println("\t\t-l <filename>\tload save file\n"); System.err.println("\t\tEither properties or save flag is required. \n") ; } boolean props saves inits false, false, false; String properties = null, save = null, II Properties file II Save file name init = null; II TCPDump initialization file for(int i=O; i < args.length; i+=2 if (args[i] . equals ("-i") ) inits = true; init = args[i+1]; } else if (args [i] . equals (II _pll) ) props = true; properties = args[i+1]; } else if (args[i].equals("-l")) saves = true; save = args[i+1]; } else { System.err.println("Unknown flag found. System.exit(O) ; Exiting ... "); if (props && saves) { Debug.standard("Cannot use both property file and savefile. Exiting ... "); System.exit(O) ; if (props) { NodeServer node = new NodeServer(properties) ; node.openLog() ; if (inits) node.init(init); node.start() ; } else if (saves) try { NodeServer node = NodeServer.read(save) ; node.openLog() ; if (inits) node.init(init); node.start() ; } catch(Exception e) { Debug.exception("Exception in NodeServer.main:", e); 1*================= * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL) , version 2 or * higher. Please see the COPYING and PATENT files included with the Lisys * distribution, which can be found at: * * * http://www.cs.unm.edu/-judd/lisys/ * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*/ package edu.unm.cs.lisys.detection; import import import import import import import edu.unm.cs.lisys.debug.*; edu.unm.cs.lisys.detection.bip.*; edu.unm.cs.lisys.detection.bif.*; edu.unm.cs.lisys.detection.matchrule.*; java.util.*; java.io.*; java.lang.reflect.*; /*========== * Parameters. java * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Hajime Inoue <hinoue@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*/ public class Parameters implements Serializable { private String debugLevel = "standard"; private String host = ""; private int port = 9090; private String saveFile = ""; private int saveDelay = 10000; private String anomaliesLog = ""; private String bipType = "bip.TCPDump49BitBIP"; private String bifType = "bif.PurePermutationBIF"; private String matchRuleType = "matchrule.ContiguousMatchesMatchRule"; private int matchLength = 12; private int activationThreshold = 10; private double sensitivityIncrement = 1.5; private double sensitivityDecay = 0.1; private int maxMemoryDetectors = 0; private boolean useMemory = false; private int numberDetectors = 100; private int maxPossibleDetectors = 10000; private double deathProbability = 0.0; private int tolerizationPeriod = 50000; private long randomSeed = 10000; private private private private private private private int costimulationDelay = 25000; boolean costimulationStatus = false; Vector costimulationMailList = new Vector(); int costimulationMailDelay = 200; String costimulationServer = ""; int costimulationServerPort = 0; double matchDecay = 0; public Parameters (String propsFilename) { Properties props = new Properties(System.getProperties()); try { props. load (new BufferedlnputStream(new FilelnputStream(propsFilename))) ; System.setProperties(props) ; catch (IOException ioe) { Debug. exception (this, ioe); II set the global debug level debugLevel = getStringProperty(props, Debug.setLevel(debugLevel) ; "debug. level", debugLevel); host = getStringProperty(props, "detection.node.host", host); port = getlntProperty(props, "detection.node.port", port); saveFile = getStringProperty(props, "save.file", saveFile); anomaliesLog = getStringProperty(props, "anomalies.log.file", anomaliesLog) ; saveDelay = getlntProperty(props, "save.delay", saveDelay); bipType = getStringProperty(props, "bip.type", bipType); bifType = getStringProperty (props, "bit. type", bifType); matchRuleType = getStringProperty(props, "matchrule.type", matchRuleType) ; matchLength = getlntProperty(props, "matchrule.matchlength", matchLength) ; activationThreshold = getlntProperty (props, "activation.threshold", activationThreshold); sensitivitylncrement = getDoubleProperty (props, "sensitivity. increment", sensitivitylncrement); sensitivityDecay = getDoubleProperty (props, "sensitivity.decay", sensitivityDecay); maxMemoryDetectors = getlntProperty (props, "detectors.max.memory", maxMemoryDetectors); useMemory = getBooleanProperty(props, "memory.use", useMemory); numberDetectors = getlntProperty(props, "detectors.number", numberDetectors) ; maxPossibleDetectors = getlntProperty (props, "detectors.max.possible", maxPossibleDetectors); deathProbability = getDoubleProperty (props, "death.probability", deathProbability); tolerizationPeriod = getlntProperty (props, "tolerization.period", tolerizationPeriod); randomSeed = getLongProperty(props, "random. seed", randomSeed); costimulationDelay = getlntProperty (props, "costimulation.delay", costimulationDelay); costimulationStatus = getBooleanProperty (props, "costimulation.status", costimulationStatus); costimulationMailList = getStringVectorProperty (props, "costimulation.mail.list", costimulationMailList); costimulationMailDelay = getIntProperty (props, "costimulation.mail.delay", costimulationMailDelay); costimulationServer = getStringProperty (props, "costimulation.server", costimulationServer); costimulationServerPort = getIntProperty (props, "costimulation.server.port", costimulationServerPort) ; matchDecay = getDoubleProperty(props, "match.decay", matchDecay); private String getStringProperty(Properties props, String key, String value) { String s = props.getProperty(key); if (s == null) return value; else return s; private Vector getStringVectorProperty(Properties props, String key, Vector value) { Vector v = new Vector() ; String s = props.getProperty(key); i f (s == null) { return value; } else { StringTokenizer st = new StringTokenizer(s, ":"); while (st.hasMoreTokens()) v.addElement(st.nextToken()) ; return v; private boolean getBooleanProperty(Properties props, String key, boolean value) { String s = props.getProperty(key); if (s == null) return value; else return (Boolean.valueOf(s)) .booleanValue(); private long getLongProperty(Properties props, String key, long value) { String s long 1; if props.getProperty(key); (s -- null) return value; } else { try 1 Long.parseLong(s); } catch (NumberFormatException e) Debug. exception (this, e); return value; { } return 1; private double getDoubleProperty(properties props, String key, double value) { String s = props.getProperty(key); double d; if (s == null) return value; } else { try { Double bigD = Double.valueOf(s); d = bigD.doubleValue(); } catch (NumberFormatException e) Debug. exception (this, e); return value; { } return d; private int getlntProperty(Properties props, String key, int value) { String s int i; = props.getProperty(key); if (s == null) { return value; } else { try i Integer.parselnt(s) ; } catch (NumberFormatException e) Debug.exception(this, e); return value; return i; { public BinarylnputPattern getBIP() { try { BinarylnputPattern bip (BinarylnputPattern) Class.forNarne(bipType) .newlnstance(); return bip; } catch (Exception e) { Debug. exception (this, e); } return null; public String getBIPType() { return bipType; public void setBIPType(String s) { bipType = s; public int getBIPLength() { try { BinarylnputPattern bip = getBIP(); return bip.getLength(); } catch (Exception e) { Debug. exception (this, e); } return 0; public BinarylnputFilter getBIF() { try { BinarylnputFilter bif = (BinarylnputFilter) Class.forNarne(bifType) .newlnstance(); return bif; } catch (Exception e) { Debug. exception (this, e); } return null; public String getBIFType() { return bifType; public void setBIFType(String s) { bifType public MatchRule getMatchRule() { try { MatchRule rnr = (MatchRule) Class.forNarne(rnatchRuleType) .newlnstance(); return rnr; } catch (Exception e) { = s; Debug. exception (this, e); } return null; public String getMatchRuleType() { return matchRuleType; public void setMatchRuleType(String s) public String getDetectionNodeHost() public int getPort() { matchRuleType s; { return host; } { return port; } public String getSaveFile() public int getSaveDelay() return saveFile; { return saveDelay; } public String getAnomaliesLog() public int getMatchLength() { return anomaliesLog; { return matchLength; public void setMatchLength(int i) = { matchLength public int getActivationThreshold() i; { return activationThreshold; public void setActivationThreshold(int i) i; = { activationThreshold = } public double getSensitivityIncrement() sensitivityIncrement; } { return public void setSensitivityIncrement(double d) sensitivityIncrement = d; } public double getSensitivityDecay() { { return sensitivityDecay; public void setSensitivityDecay(double d) { sensitivityDecay = d; public int getMaximumNumberOfMemoryDetectors() maxMemoryDetectors; } { return public void setMaximumNumberOfMemoryDetectors(int i) maxMemoryDetectors = i; } public boolean useMemory() { { return useMemory; } public int getNumberOfDetectors() { return numberDetectors; public void setNumberOfDetectors(int i) public int getMaximumPossibleDetectors() maxPossibleDetectors; } { numberDetectors i; { return public void setMaximumPossibleDetectors(int i) maxPossibleDetectors = i; } public double getDeathProbability() = { { return deathProbaqility; } public void setDeathProbability(double d) public int getTolerizationPeriod() { return tolerizationPeriod; public void setTolerizationPeriod(int i) public long getRandomSeed() { deathProbability = d; { tolerizationPeriod = i; { return randomSeed; public int getCostimulationDelay() { return costimulationDelay; public boolean getCostimulationStatus() costimulationStatus; } { return public Vector getCostimulationMailList() costimulationMailList; } public int getCostimulationMailDelay() costimulationMailDelay; } public String getCostimulationServer() costimulationServer; } public int getCostimulationServerPort() costimulationServerPort; } { return { return public void setCostimulationDelay(int i) public double getMatchDecay() } { costimulationDelay { return { return { return matchDecay; public void setMatchDecay(double d) { matchDecay = d; public String toString() { StringBuffer sb = new StringBuffer(); sb.append("\n\n=== " + this.getClass() .getName() + " values ===\n"); Field[] fields = this.getClass() .getDeclaredFields(); for (int i = 0; i < fields.length; i++) { try { sb.append(fields[i] .getName() + " [" + fields [i] .getType() + "] = " + fields [i] . get (this) + "\n"); String s = fields[i] .getType() .toString(); } catch (Exception e) { Debug.exception(this, e); } sb.append("=== " + this.getClass() .getName() + " values ===\n\n") ; return sb.toString(); i; /*================= * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * * http://www.gnu.org/copyleft/gpl.html * Note that Lisys has NO WARRANTYl *=================*/ package edu.unm.cs.lisys.detection.bif; import edu.unm.cs.lisys.util.*; import edu.unm.cs.lisys.detection.bip.*; import java.util.*; /**========== * BinaryInputFilter.java * An interface for specifying a permutation class for binary input * patterns. * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*/ public interface BinaryInputFilter { /**========== * constructFilter: * Given a random number and a length, construct a class to do * some sort of permutation on a BIP. * * * @param random a radnom number generator * @param length the length of the BIPs to be filtered *==========*/ public BinaryInputFilter constructFilter(KnuthRandom random, length) ; /**========== * filter: * Does the filtering. int * * @param bip the bip to be filtered *==========*/ public BinaryInputPattern filter(BinaryInputPattern bip) ; /**========== * toString: * The string representation *==========*/ public String toString(); /*================= * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*/ package edu.unm.cs.lisys.detection.bif; import import import import import import edu.unm.cs.lisys.debug.*; edu.unm.cs.lisys.util.*; edu.unm.cs.lisys.detection.*; edu.unm.cs.lisys.detection.bip.*; java.util.*; java.io.*; /**========== * PurePermutationBIF.java * A class that creates filters based on a pure permutation scheme * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*/ public class PurePermutationBIF implements BinaryInputFilter, Serializable { private int[] filter; /**========== * main: * A test program. *==========*/ public static void main(String[] args) { KnuthRandom random = new KnuthRandom(lOO) ; for (int i = 0; i < 5; i++) { BinarylnputFilter bif = (BinarylnputFilter) new PurePermutationBIF() ; bif.constructFilter(random, 49); BinarylnputPattern bip = (BinarylnputPattern) new TCPDump49BitBIP() ; bip.constructBinaryString(random) ; Debug.standard(bip.toString()) ; Debug.standard(bif.toString()) ; Debug.standard(bif.filter(bip) .toString()); /**========== * constructFilter: * Constructs a permutation for a number of bits. *==========*/ public BinarylnputFilter constructFilter(KnuthRandom random, int numBits) { int[] filter = new int[numBits]; boolean[] used = new boolean [numBits] ; for (int i = 0; i < numBits; i++) { int randlnt; do { randlnt = random.intRange(numBits); } while (used[randlnt]); filter[i] = randlnt; used [randlnt] = true; } this. filter = filter; return this; /**========== * filter: * Uses the permutation calculated before to permute the pattern * and return it. *==========*/ public BinarylnputPattern filter(BinarylnputPattern bip) { BitSet bits = bip.getBinaryString(); int size = bip.getLength(); BitSet filteredBits = new BitSet(size); for (int i = 0; i < size; i++) int index = filter[i]; if (bits.get(i) == true) filteredBits.set(index) ; . II Create a new BIP of this type, set the bits, and return it. BinarylnputPattern newBip = (BinarylnputPattern) bip.clone(); newBip.setBinaryString(filteredBits) ; return newBip; 1**========== * toString: * Returns the string representation of the filter *==========*1 public String toString() { StringBuffer sb = new StringBuffer(); sb.append(" [") i for (int i = 0; i < filter.length; i++) sb.append(filter[i] + II II); sb.append(II] II); return sb.toString(); 1*================= * Copyright (C) 2001 * Todd Kaplan * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also. the current text of the GPL can be found at: * http://www.gnu.org/copyleft/gpl.html * * * Note that Lisys has NO WARRANTY! *=================*1 package edu.unm.cs.lisys.detection.bipi import edu.unm.cs.lisys.util.*; import java.util.*; import java.io.*; 1**========== * BinarylnputPattern.java * A string a bits that represents both TCP connections * and * detectors. * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*/ public abstract class BinarylnputPattern implements Cloneable, Serializable { static final long serialVersionUID protected BitSet binaryString; public BinarylnputPattern() 179432837854725317L; { } public BinarylnputPattern(BitSet bits) { constructBinaryString(bits) ; } /**========== * constructBinaryString: * Randomly creates a BIP. *==========*/ public abstract BinarylnputPattern constructBinaryString(KnuthRandom random) ; /**========== * constructBinaryString: * Creates BIP by extracting appropriate info from supplied string. *==========*/ public abstract BinarylnputPattern constructBinaryString(String s); /**========== * constructBinaryString: * Creates BIP using the supplied BitSet. *==========*/ public BinarylnputPattern constructBinaryString(BitSet bs) { this.binaryString return this; = bs; public abstract String toString() ; public abstract String getConstructorString(); public BitSet getBinaryString() { return binaryString; } public void setBinaryString(BitSet bits) { this.binaryString = bits; } abstract public int getLength(); .. /**========== * clone: * @return an exact copy of the current BIP *==========*/ public Object clone() { BinarylnputPattern bip; try { Class c = Class.forName(this.getClass() .getName()); bip = (BinarylnputPattern) c.newlnstance(); bip.setBinaryString(this.binaryString) ; return bip; } catch (Exception e) { System.err.println(this.toString() + ": " + e); return new String("clone failed"); /*================= * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*/ package edu.unm.cs.lisys.detection.bip; /**========== * InvalidTCPConnectionException.java * The TCP connection provided is not valid. Could occur if a TCP * packet is received where neither machine falls within the local IP Mask. This Class calls super on all methods. * * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> @author Justin Balthrop <judd@cs.unm.edu> * *==========*/ public class InvalidTCPConnectionException extends Exception { public InvalidTCPConnectionException() { super(); } public InvalidTCPConnectionException(String s) { super(s); 1*================= * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*1 package edu.unm.cs.lisys.detection.bip; import import import import import edu.unm.cs.lisys.debug.*; edu.unm.cs.lisys.util.*; java.io.*; java.util.*; java.net.*; 1**========== * My49BitBIP.java * The basic BIP implementation consists of boiling * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*1 public class My49BitBIP extends BinarylnputPattern implements Serializable { private static final int NUMBER OF BITS = 49; private byte[] localIPMask; private boolean serverFlag; private String tcpOumpString; II Properties read from the constructorString. private String constructorString = new String() ; private String timestamp; public My49BitBIP() { } public My49BitBIP(BitSet bits) { super(bits); } /**========== * constructBinaryString: * Creates a random binary string. *==========*/ public BinarylnputPattern constructBinaryString(KnuthRandom random) { BitSet bits = new BitSet(NUMBER_OF_BITS); for (int i = 0; i < NUMBER_OF_BITS; i++) int value = random. intRange (2) ; i f (value == 1) bits.set(i) ; binaryString return this; bits; /**========== * constructBinaryString: * Constructs binary string from a string of O's and l's. *==========*/ public BinarylnputPattern constructBinaryString(String s) { constructorString = s; packBinaryString(s) ; return this; public int getLength() { return NUMBER_OF_BITS; private void packBinaryString(String s) { binaryString.xor(binaryString) ; for (int i=o; i<s.length(); i++) i f (s. charAt (i) == ' 1 ') { binaryString.set(i) ; public String toString() { StringBuffer sb = new StringBuffer(); if (tcpDumpString != null) sb.append(tcpDumpString + II II); sb. append (II [II); for (int i = 0; i < NUMBER_OF_BITS; i++) .. if (binaryString.get(i)) sb.append("l") ; else sb.append(II0ll) ; i f (( (i+ 1) % 8) == 0) sb.append(".") ; sb.append(II]II) ; return sb.toString(); public String getConstructorString() { return constructorString; } /*================= * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTYl *=================*/ package edu.unm.cs.lisys.detection.bip; import import import import import edu.unm.cs.lisys.debug.*; edu.unm.cs.lisys.util.*; java.io.*; java.util.*; java.net.*; /**========== * TCPDump49BitBIP.java * The basic BIP implementation consists of boiling * a connection down to 49 bits: * - local 8 bits * - remote 32 bits * - incoming/outgoing 1 bit * - port 8 bits * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*1 public class TCPDump49BitBIP extends BinaryInputPattern implements Serializable { private static final int NUMBER_OF_BITS = 49; private static final int NUM PACKED BYTES = 6; private private private private byte[] localIPMask; byte[] packedBytes = new byte [NUM_PACKED_BYTES] ; boolean serverFlag; String tcpDumpString; II Properties read from the constructorString. private String constructorString = new String(); private String timestamp; public TCPDump49BitBIP() { } public TCPDump49BitBIP(BitSet bits) { super (bits) ; } 1**========== * constructBinaryString: * Creates a random binary string. *==========*1 public BinaryInputPattern constructBinaryString(KnuthRandom random) { BitSet bits = new BitSet(NUMBER_OF_BITS); for (int i = 0; i < NUMBER_OF_BITS; i++) int value = random.intRange(2); i f (value == 1) bits. set (i) ; binaryString return this; bits; 1**========== * constructBinaryString: * Constructs binary string from data. * * A typical string looks like: * 192.12.12: 19:38:19.868920 192.12.12.60.35108 > 204.202.129.230.80: * S 2366857996:2366857996(0) win 8760 <mss 1460> (DF) *==========*1 public BinaryInputPattern constructBinaryString(String s) { constructorString = s; II strip off the local ip mask StringTokenizer st = new StringTokenizer(s, " "); localIPMask = getLocalIPMask(st.nextToken()); II second token is timestamp and tcpDumpString -- separate them timestamp = st.nextToken(); String source = st.nextToken(); st.nextToken(); II throwaway">" String destination = st.nextToken(); Iistrip off the trailing I : ' destination = destination. substring (0, destination.length() tcpDumpString = new String(source + " > II + destination); try { packBytes(IPtoBytes(source) , IPtoBytes(destination)); } catch (InvalidTCPConnectionException e) Debug. exception (this, e); binaryString { packBinaryString() ; return this; public int getLength() { return NUMBER_OF_BITS; 1**========== * packBinaryString: * Packs the bytes into a BitSet *==========*1 private BitSet packBinaryString () { BitSet bs = new BitSet(NUMBER_OF_BITS); bs = BitSetUtils.mergeBytes(packedBytes); if (serverFlag) bs.set(NUMBER_OF_BITS - 1); return bs; 1**========== * packBytes: * Packs the bytes by determining whether the connection is * internal or external. *==========*1 private void packBytes(byte[] source, byte[] destination) throws InvalidTCPConnectionException if (isLocalIP(destination)) { packedBytes[O] = destination [3] ; packedBytes[l] = source [0] ; packedBytes[2] = source [1] ; packedBytes[3] = source [2] ; packedBytes[4] = source [3] ; packedBytes[5] = destination [4] ; serverFlag = true; - 1); } else if (isLocalIP(source)) { packedBytes[O] = source [3] ; packedBytes[l] = destination[O]; packedBytes[2] = destination[l]; packedBytes[3] = destination [2] ; packedBytes[4] = destination [3] ; packedBytes[5] = destination [4] ; serverFlag = false; } else throw new InvalidTCPConnectionException("Neither IP is internal. II) ; } /**========== * isLocalIP: * Determines whether the IP is in the local network *==========*/ private boolean isLocalIP(byte[] ip) { ip[O]) && ip[l]) && ip[2]) ) if ((localIPMask[O] (localIPMask [1] (localIPMask [2] return true; return false; /**========== * IPtoBytes: * Maps an ip address to a byte array (of 4, naturally). *==========*/ private byte[] IPtoBytes(String ipAddress) { StringTokenizer st = new StringTokenizer(ipAddress, ".: byte[] array = new byte [5] ; for (int i = 0; i < 5; i++) { int it = Integer.parselnt(st.nextToken()); byte b = (byte) it; i f (i == 4) b = TCPDump49BitServiceMap.get(it); array[i] = b; return array; /**========== * getLocalIPMask: * Returns the first 3 bytes of the local IP network. *==========*/ private byte[] getLocalIPMask(String s) { StringTokenizer st = new StringTokenizer(s, "."); II); byte[] bytes = new byte [3] ; for (int i = 0; i < 3 i i++) { String tok = st.nextToken(); int tokInt = Integer.parseInt(tok); if (tokInt < 128) bytes [i] (byte) else bytes [i] (byte) tokInt; (tokInt - 256); } return bytes; public String toString() { StringBuffer sb = new StringBuffer() ; if (tcpDumpString != null) sb.append(tcpDumpString + II II); sb.append(II ["); for (int i = 0; i < NUMBER_OF_BITS; i++) if (binaryString.get(i)) sb.append("l") ; else sb.append("O") ; if { % 8) == 0) sb.append(".") ; (( (i+ 1) sb.append(II]") ; return sb.toString() ; public String getConstructorString() { return constructorString; } /*================= * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL) , version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * http://www.gnu.org/copyleft/gpl.html * * * Note that Lisys has NO WARRANTY! *=================*1 package edu.unm.cs.lisys.detection.bip; import edu.unm.cs.lisys.debug.*; import java.util.*; 1**========== * TCPDump49BitServiceMap.java * Used by TCPDump49BitBIP. * * * * * * The service type is mapped from its category to a number from 0 to 255. All non-assigned privileged ports are represented by a single number, and all non-assigned non-privileged ports are represented by a different single number. See page 46 of Hofmeyer dissertation for a complete breakdown of the mapping. * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*1 public class TCPDump49BitServiceMap private static Hashtable mapHash; public static void main(String[] args) { System.out.println("mapping for port #178: "+ get(6060)); } public static byte get(int i) { Integer fx = (Integer) mapHash.get(new Integer(i)); if (fx == null) { if (i <= 1023) II privileged ports fx = new Integer(67); else i f ((i >= 6000) && (i <= 6063)) fx = new Integer(69); else if (i >= 1024) fx = new Integer(68); } return (byte) fx.intValue(); static { mapHash = new Hashtable(); mapHash.put(new Integer(l), new Integer(O)); mapHash.put(new Integer (7) , new Integer(l)); mapHash.put(new Integer (9) , new Integer(2)); mapHash.put(new Integer(ll), new Integer(3)); mapHash.put(new Integer(13), new Integer(4)); mapHash.put(new Integer(19) , new Integer(S)); mapHash.put(new Integer(20), new Integer(6)); mapHash.put(new Integer (21) , new Integer(7)); .~ mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new mapHash.put(new Integer(22), new Integer(8)); Integer(23), new Integer(9)); Integer(25), new Integer(10)); Integer(37), new Integer(ll)); Integer(38), new Integer(12)); Integer(42), new Integer(13)); Integer(43), new Integer(14)); Integer(53), new Integer(15)); Integer(68), new Integer(16)); Integer(70), new Integer(17)); Integer(79), new Integer(18)); Integer(80), new Integer(19)); Integer(87), new Integer(20)); Integer(94), new Integer(21)); Integer(95), new Integer(22)); Integer(109), new Integer(23)); Integer(110), new Integer(24)); Integer(lll), new Integer(25)); Integer(113), new Integer(26)); Integer(119), new Integer(27)); Integer(123), new Integer(28)); Integer(130), new Integer(29)); Integer(131), new Integer(30)); Integer(132), new Integer(31)); Integer(137), new Integer(32)); Integer(138), new Integer(33)); Integer(139), new Integer(34)); Integer(143), new Integer(35)); Integer(156), new Integer(36)); Integer(161), new Integer(37)); Integer (162) , new Integer(38)); Integer(177), new Integer(39)); Integer(178), new Integer(40)); Integer(194), new Integer(41)); Integer(199), new Integer(42)); Integer(200), new Integer(43)); Integer(201), new Integer(44)); Integer(202), new Integer(45)); Integer(203), new Integer(46)); Integer(204), new Integer(47)); Integer(205), new Integer(48)); Integer(206), new Integer(49)); Integer(207), new Integer(50)); Integer(208), new Integer(51)); Integer(210), new Integer(52)); Integer(213), new Integer(53)); Integer(220), new Integer(54)); Integer(372), new Integer(55)); Integer(387), new Integer(56)); Integer(396), new Integer(57)); Integer(411), new Integer(58)); Integer(443), new Integer(59)); Integer(512), new Integer(60)); Integer(513), new Integer(61)); Integer (514) , new Integer(62)); Integer(515), new Integer(63)); Integer(523), new Integer(64)); I 1 ~ j ~ ~~ ~ ~ I,': mapHash.put(new Integer(540), new Integer(65)) mapHash.put(new Integer(566), new Integer(66)) /*================= * Copyright (C) 2001 i i Hajime Inoue * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*/ package edu.unm.cs.lisys.detection.broadcasti import edu.unm.cs.lisys.debug.*i import edu.unm.cs.lisys.net.*i import java.util.*i import java.io.*i import java.net.*i /*========== * TCPBroadcast.java * Broadcasts SYN packet info to nodes listed in detection.nodes. * It will send after it receives maxbips packets and at least 3000 * ms have elapsed since the last send. * * Usage: * Pipe output of tcpdump to TCPBroadcast * Use the following tcpdump flags: -nl -p -tt * Suggested tcpdump filter rules: * (tcp[13] & 2 != 0) and not (src port 80) and not (dst port 80) * and not ((src net 64.106.21) and (src port 9090)) and not * ((dst net 64.106.21) and (dst port 9090)) * * * One TCPBroadcast should be run on each machine in the network. * Here are the people who have worked on this code in the order they * have worked on it: * @author Hajime Inoue <hinoue@cs.unm.edu> * @author Dennis Chao <dlchao@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*/ public class TCPBroadcast { private PrintWriter tcpout; II tcpdump log file private Properties properties; private static final String detectionNodesKey = "detection.nodes"; private static final String tcpdumpLogFileKey = "tcpdump.log.file"; private static final String maxClientsKey = "clients.max"; private static final String clientSleepDurationKey = "clients.sleep.duration"; private String 10calIP; private String 10calIPMask; address private int maxbips = 40; bips Random r = new Random() ; II ip address of this machine II first part of the machine's ip II broadcast if list has this many public static void main(String[] args) { TCPBroadcast broadcast broadcast.run() ; = new TCPBroadcast(args[O]); public TCPBroadcast(String propertiesFilename) { this.properties = readProperties(propertiesFilename); this.maxbips = 40; String tcpdumpFilename = properties.getProperty(tcpdumpLogFileKey) ; try { 10calIP = InetAddress.getLocalHost() .getHostAddress(); 10calIPMask = 10calIP.substring(0, 10calIP.lastlndexOf(l. I)); Vector v = getDetectionNodeList(); System.out.println("IP address: " + 10calIP); System.out.println("local IP mask: " + 10calIPMask); System.out.print("Broadcast list: "); for(Enumeration e = v.elements(); e.hasMoreElements(); ) { System.out.print(((NodeAddress)e.nextElement()) .getHost() + " II); } System.out.println() ; System.out.flush() ; } catch(Exception e) { Debug. exception (this, e); } try { tcpout = new PrintWriter(new FileOutputStream(tcpdumpFilename, true)); } catch (IOException ioe) { Debug. exception (this, ioe); public String readLine() throws IOException { String s = new String(} ; int c; while ((c=System.in.read(}) !='\n' && c!=-l} { s += (char}c; } if (c==-l) { II throw exception on EOF IOException e = new IOException("End of file"}; throw e; } return s; 1**========== * isValidPacket: * Returns true if the tcpdump line contains the address of this * machine as a source or destination. This is to compensate for * promiscuous cards or stray packets. *==========*1 private boolean isValidPacket(String s} { StringTokenizer st = new StringTokenizer(s, II get rid of timestamp String temp = st.nextToken(}; II II); String source = st.nextToken(}; source = source.substring(O, source.lastlndexOf("."»; II get rid of ">" temp = st.nextToken(}; String dest = st.nextToken(}; dest = dest.substring(O, dest.lastlndexOf(".")}; if (source.equals(localIP) II dest.equals(localIP)} return true; else { System.err.println("packet not for this machine: return false; II + s}; public void run() { String s; Vector v = new Vector(); Date d = new Date(} ; Debug.standard("Started TCPBroadcast on II + d.toString()}; long time = 0; while (true) { try { if ( (s = readLine()} != null && isValidPacket(s}} { tcpout.println(s) ; tcpout. flush () ; v.addElement(s} ; long diff = System.currentTimeMillis() - time; if ( v.size() > maxbips && diff > 3000 ) { System.out.println("Sending "+ v.size() + " packets!") ; broadcast (v) ; v.removeAllElements(); time = diff + time; } catch(Exception e) { Debug.exception(this, e); private void broadcast (Vector tcpData) { Vector v = getDetectionNodeList(); System.out.println("BROADCAST BEGINS"); for(Enumeration e = v.elements(); e.hasMoreElements(); try { sendTo((NodeAddress)e.nextElement(), localIPMask, tcpData); } catch(Exception ex) { Debug. exception (this, ex); } Debug. standard ("BROADCAST ENDS") ; private Vector getDetectionNodeList() { Vector vec = new Vector(); String list = properties.getProperty(detectionNodesKey) ; StringTokenizer st = new StringTokenizer(list, ","); while (st.hasMoreTokens()) { String item = st.nextToken() .trim(); StringTokenizer st2 = new StringTokenizer(item, II strip out the host and port -- separated by String host = st2.nextToken(); int port = Integer.parseInt(st2.nextToken()); NodeAddress na = new NodeAddress(host, port); vec.addElement(na) ; " : II ) i II .. II return vec; private void sendTo(NodeAddress na, String localIPMask, Vector tcpData) throws DataSendException try { Thread.sleep((int)r.nextDouble()*3000); Socket s = new Socket(na.getHost(), na.getPort()); s. setSoTimeout (500) ; PrintWriter outsock = new PrintWriter(s.getOutputStream()); outsock.println("BROADCAST") ; outsock. flush () ; outsock.println(tcpData.size()) ; outsock. flush () ; for(Enumeration e = tcpData.elements(); e.hasMoreElements(); { ) String data = (String)e.nextElement(); String bip = localIPMask + " " + data; outsock.println(bip) ; } outsock.println() ; outsock.println() ; outsock. flush () ; Thread.sleep(1000 + (int)r.nextDouble() *1000) ; s.close() ; } catch(Exception e) { Debug. exception (this, e); private Properties readProperties(String filename) { Properties props = new Properties(System.getProperties()); try { props.load(new BufferedlnputStream(new FilelnputStream(filename))) ; System.setProperties(props) ; } catch (Exception e) { Debug. exception (this, e); Debug.standard(this.toString() + ": failed to load properties list."); Debug. standard(this. toString () + ": shutting down.") ; System.exit(l); } return props; package edu.unm.cs.lisys.detection.broadcast; public class DataSendException extends Exception { } /*================= * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTYl *=================*/ package edu.unm.cs.lisys.detection.matchrule; import import import import import edu.unm.cs.lisys.debug.*; edu.unm.cs.lisys.util.*; edu.unm.cs.lisys.detection.bip.*; java.util.*; java.io.*; /**========== * ContiguousMatchesMatchRule.java * * Here are the people who have worked on this code, starting with * the most recent: * @author Justin Balthrop <judd@cs.unm.edu> * @author Todd Kaplan <kaplan@cs.unm.edu> * * Contiguous bits rule (number of bits in a row) . * The result will depend on the permutation mask. *==========*/ public class ContiguousMatchesMatchRule implements MatchRule, Serializable { public static void main(String[] args) { KnuthRandom random = new KnuthRandom(lOO) ; for (int i = 0; i < 5; i++) { BinaryInputPattern bipl = new TCPDump49BitBIP(); bipl.constructBinaryString(random) ; Debug.verbose(bipl.toString()); BinaryInputPattern bip2 = new TCPDump49BitBIP() ; bip2.constructBinaryString(random) ; Debug.verbose(bip2.toString()) ; MatchRule mr = new ContiguousMatchesMatchRule(); int length = mr.match(bipl, bip2); Debug. verbose (Illength of match = II + length); /**========== * match: * Looks for the r most contiguous bits to match between two * BIPs *==========*/ public int match(BinarylnputPattern first, BinarylnputPattern second) { BitSet bits1 = (BitSet) first.getBinaryString() .clone(); BitSet bits2 = (BitSet) second. getBinaryString () .clone() ; bits1.xor(bits2) ; /* now, search for the longest streak of xored bits set to 1 */ int longestMatch = 0; int currentMatches = 0; for (int i = 0; i < first.getLength(); i++) { boolean bit = bits1.get(i); i f (bit ! = true) { currentMatches++; if (currentMatches > longestMatch) { longestMatch = currentMatches; } } else currentMatches } } return longestMatch; /*================= * Copyright (C) 2001 Dennis Chao = 0; * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*/ package edu.unm.cs.lisys.detection.matchrule; import import import import import edu.unm.cs.lisys.debug.*; edu.unm.cs.lisys.util.*; edu.unm.cs.lisys.detection.bip.*; java.util.*; java.io.*; /**========== * HammingDistanceMatchRule.java * (based on ContiguousMatchesMatchRule.java) * * Here are the people who have worked on this code, starting with * the most recent: * @author Justin Balthrop <judd@cs.unm.edu> * @author Dennis Chao <dlchao@cs.unm.edu> * * Hamming distance rule (number of same bits) * Permutation masks don't change the result. *==========*/ public class HammingDistanceMatchRule implements MatchRule, Serializable { public static void main(String[] args) { KnuthRandom random = new KnuthRandom(lOO) ; for (int i = 0; i < 5; i++) { BinaryInputPattern bipl = new TCPDump49BitBIP()i bipl.constructBinaryString(random) ; BinaryInputPattern bip2 = new TCPDump49BitBIP(); bip2.constructBinaryString(random) ; system.err.println(bipl.toString()) ; System.err.println(bip2.toString()) ; MatchRule mr = new HammingDistanceMatchRule()i int length = mr.match(bipl, bip2) i System.err.println("length of match = II + length); 1**========== * match: * @param first binary input pattern to match * @param second binary input pattern to match * @return the number of bits the patterns have in common *==========*1 public int match(BinaryInputPattern first, second) BinaryInputPattern { BitSet bits1 = (BitSet) first.getBinaryString() .clone(); BitSet bits2 = (BitSet) second.getBinaryString() .clone(); bits1.xor(bits2) ; II Now, search for the number of xored bits set to 1. int currentMatches = 0; for (int i = 0; i < first.getLength(); i++) boolean bit = bits1.get(i); if (bit ! = true) { currentMatches++; } return currentMatches; 1*================= * Copyright (C) 2001 Todd Kaplan { * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*/ package edu.unm.cs.lisys.detection.matchrule; import edu.unm.cs.lisys.detection.bip.*; import java.util.*; /**========== * MatchRule.java * Interface specifying the methods needed by * child classes specifying matches. * * Here are the people who have worked on this code, starting with * the most recent: * @author Justin Balthrop <judd@cs.unm.edu> * @author Todd Kaplan <kaplan@cs.unm.edu> *==========*/ public interface MatchRule { public int match(BinaryInputPattern first, BinaryInputPattern second) ; } anOUI aW1~BH 100~ (J) 4q61~AdoJ ~ =================~/ * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL) , version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTYl *=================*/ package edu.unm.cs.lisys.net; import edu.unm.cs.lisys.detection.bip.*; import java.io.*; import java.net.Socket; /**========== * HttpServer * A very simple single-threaded http server used with lisys that * will NOT serve files, only accept posts. This server has just * * enough to make it work. * * * Format for POST messages is as follows: * * <machine>?<packet> * * machine is in the traditional form. * packet is in the ugly URL encoded form. * * For example: * * umwert.cs.unm.edu?destination%3d198%2e59%2e151%2e21%2e25%3a+S+ * 1178336325%3al178336325%280%29+win+32120+%3cmss+1460 * %2csackOK%2ctimestamp+69622901%5b%7ctcp%5d%26source * %3d198%2e59%2e151+14%3a24%3a03%2e900180+198%2e59%2e151 * %2e54%2e3588 * * The above would work if it were allan one line. * * Here are the people who have worked on this code in the order they * have worked on it: * @author Hajime Inoue <hinoue@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*/ public class LisysHttpServer extends SimpleServer { public LisysHttpServer() this (8080); } public LisysHttpServer(int port) { this.port port; } pUblic void serveConnection (InputStream ins, OutputStream outs) throws Exception BufferedReader in = new BufferedReader(new InputStreamReader(ins)) ; PrintWriter out = new PrintWriter(outs); String request = in.readLine(); // Break into pieces: This should consist of a GET/POST followed by a very long // // string of file information, followed by (possibly) HTTP/l.x. // Strip off GET/POST, since they are equivalent here request = request.substring(request.indexOf(' ')+1); // See if HTTP is there int index = request.indexOf(' '); if ( index != -1 ) request = request.substring(O, index); out.println("<HTML><H4>Result of costimulation request:<P>") ; out.println(doCostimulation(request)) ; out.println("</HTML>") ; out. flush () ; public String doCostimulation(String request) throws Exception // Get host information String host = request.substring(l, request.indexOf('?')) .trim(); String hostname = host.substring(O, host.indexOf(': ')) .trim(); String port = host.substring(host.indexOf(': ')+1) .trim(); int portnum = Integer.parselnt(port); // Get bip information String bip = URLDecoder.decode(request.substring(request.indexOf('?')+1)); return costimulateDetectionNode(hostname, portnum, bip); public String costimulateDetectionNode(String host, int port, String bipstring) { try { Socket s = new Socket (host, port); s.setSoTimeout(1000); BufferedReader in = new BufferedReader (new InputStreamReader(s.getlnputStream())); PrintWriter out = new PrintWriter(s.getOutputStream()); out .println ("COSTIMULATE") ; out.println(bipstring) ; out.flush() ; String response = in.readLine(); System.out.println(response) ; return response; } catch(Exception e) { System.err.println("ERROR IN COSTIMULATION:"); System.err.println(e) ; return new String("An error occured in contacting the detection node\n" + host + " for the costimulation of " + bipstring + "\n"); } public static void main(String[] args) { LisysHttpServer server = new LisysHttpServer(); server.start() ; /*================= * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL) , version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * http://www.cs.unm.edu/-judd/lisys/ * * * Also, the current text of the GPL can be found at: * http://www.gnu.org/copyleft/gpl.html * * * Note that Lisys has NO WARRANTY! *=================*/ package edu.unm.cs.lisys.net; /**========== * NodeAddress.java * NodeAddress class consisting of the host and port. * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*/ public class NodeAddress { private String host; private int port; /**========== * NodeAddress: * * @param host the domain name as a string * @param port the port *==========*/ pUblic NodeAddress(String host, int port) { this.host this.port host; port; public String getHost() public int getport() { return port; } public String toString() /*================= * Copyright (C) 2001 { return host; { return host + n:n + port; } Hajime Inoue * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL), version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*/ package edu.unm.cs.lisys.net; import import import import import import java.io.InputStream; java.io.OutputStream; java.io.*; java.net.ServerSocket; java.net.Socket; edu.unm.cs.lisys.debug.*; /**========== * SimpleServer.java * A very simple single-threaded abstract class that allows for easy * implementation of servers using a single function. * * * * This is written to accomodate the new design of DetectionNode, though it is general enough to handle HTTP service duties as well, if they are very low bandwidth. * * Here are the people who have worked on this code in the order they * have worked on it: * @author Hajime Inoue <hinoue@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*/ public abstract class SimpleServer extends Thread implements Serializable { protected int port; /**========== * run: * The run function accepts connections and hands them off * to the serveConnection function to deal with. * * * NOTE - this is not multithreaded. No intensive computations should occur in serveConnection. *==========*/ public void runt) { Debug.verbose("In run()"); ServerSocket server; try { server = new ServerSocket(port, 16); } catch(Exception e) { Debug.exception(this,e) ; return; while (true) try { Socket s = server.accept(); Debug. verbose (1I0pened Connection") ; try { System.err.println("Serving Connection") ; s.setSoTimeout(10000) ; serveConnection(s.getInputStream() , s.getOutputStream()) ; s.close(); } catch(Exception e) s.close() ; Debug.exception(this,el; } Debug.verbose("Closed Connection"); } catch (Exception e) { Debug. exception (this,e) ; } System.gc() ; /**========== * serveConnection: * Subclasses implement this function. * * @param in * @param out The input stream of the socket The outputstream of the socket *==========*/ public abstract void serveConnection (InputStream in, OutputStream out) throws Exception; /*================= * Copyright (e) Reserved. * 2001 The University of New Mexico. All Rights * Lisys is a program that monitors TCP SYN packets to detect network * * * * * * * * * * * * * traffic anomalies. Licensed under the GNU General Public License (GPL), version 2 or higher. Please see the COPYING and PATENT files included with the Lisys distribution, which can be found at: http://www.cs.unm.edu/-judd/lisys/ Also, the current text of the GPL can be found at: http://www.gnu.org/copyleft/gpl.html Note that Lisys has NO WARRANTY! *=================*1 package edu.unm.cs.lisys.net; 1**========== * URLDecoder.java * Since java 1.1 doesn't have the URLDecoder (this appears in java * 1.2), we have written an equivalent. * * The class contains one static function, used to decode URLs encoded * by java.net.URLEncoder. * @see java.net.URLEncoder * * Here are the people who have worked on this code in the order they * have worked on it: * @author Hajime Inoue <hinoue@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*1 public class URLDecoder { 1**========== * decode: * When given an encoded URL as a string, it decodes it. * * @param url the URL to be decoded * @return the decoded URL *==========*1 public static String decode (String url) { StringBuffer sb = new StringBuffer(); for(int i=O; i < url.length(); i++) { int val = (int)url.charAt(i); if ( (val >= 'a' && val <= 'z') II (val >= 'A' && val <= 'Z') I I (val >= '0' && val <= '9') I I (val == '&') I I (val == '.') I I (val == 'I') II (val == '_') II (val == '?') ) { sb.append((char)val) ; } else if ( val == '+') sb . append (' '); } else if ( val == '%') { char first = url.charAt(i+1); char second = url.charAt(i+2); val = hex (first, second); sb.append((char)val) ; i = i+2; } return sb.toString(); HEX, 1**========== * hex: Utility function used to calculate hex values from two * characters. For instance, if you have the value 20 in * it will return the value 32 in DECIMAL. * * * @param first the first char in hex representation * @param second the second char in hex representation * @return the decimal value of the two chars as an integer *==========*1 protected static int hex (char first, char second) { int x, y; x y = = (int)first; (int) second; II To upper case ( x > 71 ) x = x - 32; if ( y > 7 1 ) Y = Y - 32; if i f ( x > 57 ) x = 16 * ( x-55); else x = 16 * ( x - 48); if ( y > 57 ) Y = Y - 55; else y = y - 48; return x + y; Utility /*================= * Copyright (C) 2001 Todd Kaplan * * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL) , version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * http://www.cs.unm.edu/-judd/lisys/ * * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*1 package edu.unm.cs.lisys.util; import edu.unm.cs.lisys.debug.*; import java.util.*; 1**========== * BitSetUtils.java * This class adds a couple methods for making BitSets. * * Here are the people who have worked on this code in the order they * have worked on it: * @author Todd Kaplan <kaplan@cs.unm.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*1 pUblic class BitSetUtils { 1**========== * byteToBitSet: * Makes a BitSet from a byte. * * @param b the byte to be converted * @return a BitSet *==========*1 public static BitSet byteToBitSet(byte b) { BitSet bs = new BitSet(8); int num = (int) b; if (num < 0) num += 256; int divisor = 128; int msb = 7; for (int i = 0; i <= 7; i++) if «num 1 divisor) > 0) bs. set (i) i num -= divisor; } divisor } return bs; 1= 2; /**========== * mergeBytes: * Make a BitSet by merging an array of bytes. * * @param bytes an array of bytes * @return a BitSet *==========*/ public static BitSet mergeBytes(byte[] bytes} { int numBytes = bytes. length; BitSet bs = new BitSet(numBytes}; int bits = 8; BitSet tempBS; int index = 0; for (int i = 0; i < numBytes; i++) { tempBS = byteToBitSet(bytes[i]}; for (int j = 0; j < bits; j++, index++) if (tempBS.get(j) == true} bs. set (index) ; return bs; /*================= * Copyright (C) 2001 * Steven Hofmeyr * Lisys is a program that monitors TCP SYN packets to detect network * traffic anomalies. * * Licensed under the GNU General Public License (GPL) , version 2 or * higher. Please see the COPYING and PATENT files included with the * Lisys distribution, which can be found at: * * * http://www.cs.unm.edu/-judd/lisys/ * Also, the current text of the GPL can be found at: * * http://www.gnu.org/copyleft/gpl.html * * Note that Lisys has NO WARRANTY! *=================*/ package edu.unm.cs.lisys.utili import edu.unm.cs.lisys.debug.*; import java.io.*i import java.lang.Mathi /**========== * KnuthRandom.java * This algorithm is based on the code on page 283 of "Numerical * Recipes in C" * * Here are the people who have worked on this code in the order they * have worked on it: * @author Steven Hofmeyr <sah@santafe.edu> * @author Justin Balthrop <judd@cs.unm.edu> *==========*/ public class KnuthRandom implements Serializable { private static final long MBIG = 1000000000; private static final long MSEED = 161803398i private static final double FAC = (1.0 / MBIG)i private int inext; private int inextpi private long[] rna = new long[56]; public KnuthRandom(long rseed) { initializeRandom(rseed); /**========== * initializeRandom: * This initializes the random seed. If we feed in a negative * number, then time is used to initialize the seed. * * @param seed the seed * @return the seed that was used *==========*/ private long initializeRandom(long seed) { long mj, mki if (seed < 0) seed = System.currentTimeMillis() % MBIG; if (seed >= MBIG) Debug. exception (this, new KnuthRandomException ("Seed value too large (> " + MBIG + ")"+ seed)); System.exit(-l); mj = Math.abs(MSEED-Math.abs(seed)); mj = mj % MBIG; ma[55] = mj; mk = 1; for (int i = 1; i <= 54; i++) int j = (21 * i) % 55; ma[j] = mk; mk = mj - mk; if (mk < 0) mk += MBIG; mj = ma[j]; for (in t k = 0; k < for (int i = 1; mali] -= ma[l if (ma[i] < 0) 4; k ++ ) { i <= 55; i++) { + (i + 30) % 55]; mali] += MBIG; inext = 0; inextp = 31; return seed; /**========== * fraction: * * @return a random double between 0 and 1 *==========*/ public double fraction() { long mj; if (++inext == 56) inext = 1; if (++inextp == 56) inextp = 1; mj = ma[inext] - ma[inextp]; if (mj < 0) mj += MBIG; ma[inext] = mj; return mj * FAC; /**========== * intRange: * * @param range one more than the largest random number possible * @return an integer between 0 and range - 1 inclusive *==========*/ public int intRange(int range) { int retval = (int) (fraction() * range); if (retval < 0 II retval >= range) { II This should never happen. Debug. exception (this, new KnuthRandomException("Out of bounds."» ; System.exit(l) ; } return retval; 1**========== * * * * * inBetween: @param start the smallest random number possible @param finish the largest random number possible @return an integer between start and finish *==========*1 public int intBetween(int start, int finish) int spread = (finish + 1) - start; return intRange(spread) + start; { package edu.unm.cs.lisys.util; public class KnuthRandomException extends Exception { II There's not much here. public KnuthRandomException() { super(); } Templates # "," plus whitespace separated list: of Detect:ionNode # host:port locations which should be broadcasted BIP information # (e. g. "kaps. santafe. edu: 9090, \ 127.0.0.1:9090") # detection.nodes=arcturus.cs.unm.edu:9090, \ java.cs.unm.edu:9090, \ binky.cs.unm.edu:9090, \ pink-parasol.cs.unm.edu:9090, \ faceplant.cs.unm.edu:9090, \ badshot.cs.unm.edu:9090, \ gondolin.cs.unm.edu:9090, \ sleet.cs.unm.edu:9090 tcpdump. log. file=$logpath/$HOSTNAME.tcpdump. log costimulation.mail.list=person@changethis.edu costimulation.server=server.changethis.edu debug.level=verbose detection.node.host=$HOSTNAME detection.node.port=9090 save.file=$statepath/$HOSTNAME.detector save.delay=1000 anomalies.log.file=$logpath/$HOSTNAME.anomalies.log bip.type=edu.unm.cs.lisys.detection.bip.TCPDump49BitBIP bif.type=edu.unm.cs.lisys.detection.bif.PurePermutationBIF matchrule.type=edu.unm.cs.lisys.detection.matchrule.ContiguousMatchesMa tchRule matchrule.matchlength=ll match.decay=O costimulation.status=true costimulation.mail.delay=2000 costimulation.delay=20000 costimulation.server.port=8080 activation.threshold=l sensitivity.increment=1.5 sensitivity.decay=O.l detectors.max.memory=O detectors.number=100 detectors.max.possible=10000 memory.use=false death.probability=O.Ol tolerization.period=10000 random.seed=-l (tcp[13] == 2) and not (src port 80) and not (dst port 80) and not ((src net $network) and (src port 9090)) and not ((dst net $network) and (dst port 9090)) network=64.106.21 java=java tcpdump=/usr/sbin/tcpdump #===== # You should probably remake and reinstall Lisys after # changing any of the variables below, or at the very least, # you should make sure the directories exist and make sure # the Java class files are in the classpath. #===== classpath=/usr/share/java/repository logpath=/var/log/lisys pidpath=/var/run/lisys statepath=/var/state/lisys #!/usr/bin/perl #================= # Copyright (C) 2001 Justin Balthrop # # Lisys is a program that monitors TCP SYN packets to detect network # traffic anomalies . # # # # # # # # Licensed under the GNU General Public License (GPL), version 2 or higher. Please see the COPYING and PATENT files included with the Lisys distribution, which can be found at: http://www.cs.unm.edu/-judd/lisys/ Also, the current text of the GPL can be found at: # # http://www.gnu.org/copyleft/gpl.html # # Note that Lisys has NO WARRANTY! #================= #================= # lisys-broadcast # Justin Balthrop (Summer 2001) # # Starts and stops lisys broadcasting. # Pipes tcpdump output to TCPBroadcast, which broadcasts the information # to its list of Lisys detection nodes. #================= use strict; use Getopt: :Std; sub read_in; sub write_out; select(STDERR); # Location of the properties files. my $globalyroperties = "/etc/lisys/global.properties"; my $broadcastyroperties = "/etc/lisys/broadcast.properties"; my $filter_rules = "/etc/lisys/filter.rules"; # If any of these files don't exist, we can't continue. print "Global properties file not found: $globalyroperties\n" and exit(l) unless -f $globalyroperties; print "Broadcast properties file not found: $broadcastyroperties\n" and exit(l) unless -f $broadcastyroperties; print "Filter file not found: $filter_rules\n" and exit(l) unless -f $f il ter_rules; my $heapsize = "40M"; # Read in the variables that we need from the properties files. my $propfile = prop_eval ("/tmp/broadcast.properties", $globalyroperties, $broadcastyroperties); my my my my my my $hostname = $ENV{HOSTNAME}; $javayidfile = $ENV{pidpath}."/broadcast.pid"; $tcpdumpyidfile = $ENV{pidpath}."/tcpdump.pid"; $logfile = $ENV{logpath}."/$hostname.broadcast.log"; $classpath = $ENV{classpath}; $java = $ENV{java}; my $tcpdump = $ENV{tcpdump}i # Now do the variable substitution into the filter.rules file. my $filterfile = prop_eval ("/tmp/filter.rules", $filter_rules) i my %opt ions i getopts ("k", \%options); # Try to stop broadcast. i f ($options{k}) { if (-f $java-pidfile I I -f $tcpdump-pidfile) print "Stopping lisys broadcast.\n"; my $java-pid = read_in $java-pidfile; my $tcpdump-pid = read_in $tcpdump-pidfilei # Kill tcpdump and the java interpreter. kill 1, $java-pidi kill 1, $tcpdump-pidi unlink $java-pidfile; unlink $tcpdump-pidfile; } else { print "Lisys broadcast doesn't seem to be running.\n"; } # Try to start broadcast. else { # Check to see if broadcast is already running. if (-f $java-pidfile && -f $tcpdump-pidfile) { my $java-pid = read_in $java-pidfile; my $tcpdumP-Fid = read_in $tcpdumP-Fidfile; my $java_cmdline; my $tcpdump_cmdline; $java_cmdline = read_in "/proc/$java-Fid/cmdline" if (-e "/proc/$java-pid") ; $tcpdump_cmdline = read_in "!proc!$tcpdumP-Fid!cmdline" if (-e "!proc!$tcpdump-p id ") ; if ($java_cmdline =- !java! && $tcpdump_cmdline print "Lisys broadcast already running. \n"; exit 0; } elsif ($java_cmdline =- !java!) { # Java is running, but tcpdump is not. kill 1, $java-Fid; } elsif ($java_cmdline =- !java!) { # Tcpdump is running, but java is not. kill 1, $tcpdump-pid; print "Starting lisys broadcast.\n"; # Fork and run broadcast. my $pid; =- !tcpdump!) { if (!defined ($pid = fork)) { die "Unable to fork: $l\n"; # The child process elsif (! $pid) { # Put our PID in a file so we can be killed. write_out $$, $java-Fidfile; # Run tcpdump and pipe our input from it. Also, store the PID # of tcpdump in a file so we can kill it. open STDIN, "$tcpdump -nl -p -F $filterfile 2> my $tcpdumP-Fid /dev/null I"; # Check to make sure that tcpdump really started. if ($tcpdumP-Fid) { write_out $tcpdumP-Fid, $tcpdumP-Fidfile; } else { print "Tcpdump doesn't seem to be installed. Cannot start lisys broadcast.\n"; exit 0; # Redirect standard output and standard error to the logfile. open STDOUT, ">$logfile" or die "Couldn't open $logfile: $!\n"; open STDERR, ">&STDOUT" or die "Couldn't open $logfile: $!\n"; # Run broadcast. exec ($java, "-Xmx$heapsize", "-classpath", "$classpath", "edu.unm.cs.lisys.detection.broadcast.TCPBroadcast", "$propfile") ; } #========== # prop_eval: # A utility function that does variable substitution in files based # on the ENV hash. It reads new variable declarations into ENV as it # goes. # # NOTE: If a variable is defined twice, the second declaration will # just overwrite the first. #========== sub prop_eval my $PROPS my $FILE; shift; open (PROPS, "> $PROPS"); while ($FILE = shift) { open (FILE, $FILE); while «FILE» { next if r#/; s/\$([A-Za-z l\w*)/$ENV{$l}/ge; if (/ ( [A - Za - ;-_1 \ w*) \ s * =( . *) /) { $ENV{$1}=$2; } chomp; print PROPS; print PROPS "\n"; } close(FILE) ; } close (PROPS) ; return $PROPS; #========== # read_in: # A utility function that reads the contents of a file and returns # them. #========== sub read_in { my $filename = shift; open (FILE, "$filename"); my $result = <FILE>; close(FILE); return $result; #========== # write out: # A utility function that writes a string out to a file. #========== sub write out my $value = shift; my $filename = shift; open (FILE, "> $filename"); print FILE $value; close(FILE) ; #!/usr/bin/perl #================= # Copyright (C) 2001 Justin Balthrop # # Lisys is a program that monitors TCP SYN packets to detect network # traffic anomalies. # my $tcpdump = $ENV{tcpdump}; # Now do the variable substitution into the filter. rules file. my $filterfile = prop_eval ("!tmp!filter.rules", $filter_rules); my %options; getopts ("k", \%options); # Try to stop broadcast. i f ($options{k}) { if (-f $java-pidfile I I -f $tcpdump-pidfile) print "Stopping lisys broadcast. \n"; my $java-pid = read_in $java-pidfile; my $tcpdump-pid = read_in $tcpdump-pidfile; # Kill tcpdump and the java interpreter. kill 1, $java-pid; kill 1, $tcpdump-pid; unlink $java-pidfile; unlink $tcpdump-pidfile; } else { print "Lisys broadcast doesn't seem to be running.\n"; } # Try to start broadcast. else { # Check to see if broadcast is already running. if (-f $java-pidfile && -f $tcpdump-pidfile) { my $java-pid = read_in $java-pidfile; my $tcpdump-pid = read_in $tcpdump-pidfile; my $java_cmdline; my $tcpdump_cmdlinei $java_cmdline = read_in "!proc!$java-pid!cmdline" if (-e "!proc!$java-pid") ; $tcpdump_cmdline = read_in "!proc!$tcpdump-pid!cmdline" if (-e "!proc!$tcpdump-p id ") ; if ($java cmdline =- !java! && $tcpdump cmdline print-"Lisys broadcast already runn"ing.\n"; exit 0; } elsif ($java_cmdline =- !java!) { # Java is running, but tcpdump is not. kill 1, $java-pid; } elsif ($java_cmdline =- !java!l { # Tcpdump is running, but java is not. kill 1, $ tcpdump-pid; print "Starting lisys broadcast.\n"i # Fork and run broadcast. my $pid; !tcpdump!) { if (!defined ($pid = fork)) { die "Unable to fork: $!\n"; # The child process elsif (! $pid) { # Put our PIO in a file so we can be killed. write_out $$, $javayidfile; # Run tcpdump and pipe our input from it. Also, store the PIO # of tcpdump in a file so we can kill it. my $tcpdumpyid open STOIN, "$tcpdump -nl -p -F $filterfile 2> Idevlnull I"; # Check to make sure that tcpdump really started. if ($tcpdumpyid) { write out $tcpdumpyid, $tcpdumpyidfile; } else { print "Tcpdump doesn't seem to be installed. Cannot start lisys broadcast.\n"; exit 0; # Redirect standard output and standard error to the logfile. open STOOUT, ">$logfile" or die "Couldn't open $logfile: $!\n"; open STOERR, ">&STOOUT" or die "Couldn't open $logfile: $!\n"; # Run broadcast. exec ($java, "-Xmx$heapsize", "-classpath", "$classpath", "edu.unm.cs.lisys.detection.broadcast.TCPBroadcast", "$propfile") ; } #========== # prop_eval: # A utility function that does variable substitution in files based # on the ENV hash. It reads new variable declarations into ENV as it # goes. # # NOTE: If a variable is defined twice, the second declaration will # just overwrite the first. #========== sub prop_eval my $PROPS my $FILE; shift; open (PROPS, "> $PROPS"); while ($FILE = shift) open(FILE, $FILE); while «FILE» { next if 1"#1; s/\$( [A-Za-z ]\w*)/$ENV{$l}/ge; if (I ([A-Za-;- ] \w*) \s*= (. *) I) { $ENV{$1}=$27 } chomp; print PROPS; print PROPS n\nn; } close (FILE) ; } close(PROPS); return $PROPS; #========== # read in: # A utility function that reads the contents of a file and returns # them. #========== sub read in { my $filename = shift; open(FILE, n$filename n ); my $result = <FILE>; close (FILE) ; return $result; #========== # write out: # A utility function that writes a string out to a file. #========== sub write out my $value = shift; my $filename = shift; open(FILE, n> $filename n ); print FILE $value; close(FILE) ; #!/usr/bin/perl #================= # Copyright (C) 2001 Justin Balthrop # # Lisys is a program that monitors TCP SYN packets to detect network # traffic anomalies. # # # # # # # # # # # # Licensed under the GNU General Public License (GPL) , version 2 or higher. Please see the COPYING and PATENT files included with the Lisys distribution, which can be found at: http://www.cs.unm.edu/-judd/lisys/ Also, the current text of the GPL can be found at: http://www.gnu.org/copyleft/gpl.html Note that Lisys has NO WARRANTY! #~~~~~~~===~=~==== #===~~~==~~~~=~=~= # # # # # # # # # # # # lisys-detection Justin Balthrop (Summer 2001) Starts and stops NodeServer, the Lisys detection node. It will receive information from one or more TCPBroadcast programs. NodeServer will mail the designated user when it encounters anomalous connections. NodeServer can be queried by telneting to port 9090, but this is not recommended. The web or mail interfaces to NodeServer are easier to use. If there is a save file, then this script uses the savefile to start the program and appends to the old log files. #~~=~=~~=~====~=~= use strict; use Getopt::Std; sub read_in; sub write_out; select (STDERR) ; # Location of the properties files. my $globalyroperties = "/etc/lisys/global.properties"; my $detectionyroperties = "/etc/lisys/detection.properties"; # If either of these files don't exist, we can't continue. print "Global properties file not found: $globalyroperties\n" and exit(l) unless -f $globalyroperties; print "Detection properties file not found: $detectionyroperties\n" and exit(l) unless -f $detectionyroperties; my $heapsize = "40M"; # Read in the variables that we need from the properties files. my $propfile = prop_eval ("/tmp/detection.properties", $globalyroperties, $detectionyroperties); my my my my my $hostname ~ $ENV{HOSTNAME}; $pidfile = $ENV{pidpath}." /detection.pid"; $statefile ~ $ENv{statepath}."/$hostname.detector"; $logfile = $ENV{logpath}."/$hostname.detector.log"; $classpath = $ENV{classpath}; my $java = $ENV{java}j my !lroptionsi getopts ("k", \!lroptions) i # Try to stop detection. if ($options{k}) { if (-f $pidfile) { print "Stopping lisys detection.\n"j my $pid = read_in $pidfilei # Kill the java interpreter. kill 1, $pidi unlink $pidfile; } else { print "Lisys detection doesn't seem to be running.\n"; } # Try to start detection. else { # Check to see if detection is already running. if (-f "$pidfile") { my $pid = read in $pidfilei if (-e "/proc/$pid") { my $cmdline = read_in" /proc/$pid/cmdline"; if ($cmdline =- /java/) { print "Lisys detector already running.\n"; exit 0; print "Starting lisys detection. \n"; # Fork and run detection. my $pid; if (!defined ($pid = fork)) { die "Unable to fork: $! \n" ; } # The child process elsif (! $pidJ { # Put our PID in a file so we can be killed. write_out $$, $pidfile; if (-f "$statefile") { # Redirect standard output and standard error to append to the logf ile. open STDOUT, "»$logfile" or die "Couldn't open $logfile: $!\n"; open STDERR, ">&STDOUT" or die "Couldn't open $logfile: $l\n"i # Run detection. exec ($java, "-Xmx$heapsize", "-classpath", "$classpath", "edu.unm.cs.lisys.detection.NodeServer". "-1", "$statefile") i } else { # Redirect standard output and standard error to the logfile. open STDOUT, ">$logfile" or die "Couldn't open $logfile: $l\n"; open STDERR, ">&STDOUT" or die "Couldn't open $logfile: $l\n"; # Run detection. exec ($java, "-Xmx$heapsize", "-classpath", "$classpath", "edu.unm.cs.lisys.detection.NodeServer", "_p", "$propfile"); } #========== # prop_eval: # A utility function that does variable substitution in files based # on the ENV hash. It reads new variable declarations into ENV as it # goes. # # NOTE: If a variable is defined twice, the second declaration will # just overwrite the first. #========== sub prop_eval my $PROPS = shift; my $FILE; open (PROPS, "> $PROPS"); while ($FILE = shift) { unless (open(FILE, $FILE)) { die "Can't open $FILE: $l\n"; next; } while «FILE» { next if r#/; s/\$([A-Za-z ]\w*)/$ENV{$l}/ge; if (/([A-Za-~ ]\w*)\s*=(.*)j) { $ENV{$1}=$2-;- } chomp; print PROPS; print PROPS "\n"; } close (FILE) ; } close (PROPS) ; return $PROPS; #========== # read in: # A utility function that reads the contents of a file and returns # them. #========== sub read_in { my $filename = shift; open(FILE, "$filename") or die "Can't open $filename: $l\n"; my $result = <FILE>; close(FILE) ; return $result; #========== # write_out: # A utility function that writes a string out to a file. #~=~=~~~~~~ sub write out my $value = shift; my $filename ~ shift; open (FILE, "> $filename") or die "Can't open $filename: $!\n"; print FILE $value; close(FILE) ; #!/usr/bin/perl #================= # # # # # # Copyright (C) 2001 Justin Balthrop Lisys is a program that monitors TCP SYN packets to detect network traffic anomalies. Licensed under the GNU General Public License (GPL) , version 2 or # # # # # # # # # # higher. Please see the COPYING and PATENT files included with the Lisys distribution, which can be found at: http://www.cs.unm.edu/-judd/lisys/ Also, the current text of the GPL can be found at: http://www.gnu.org/copyleft/gpl.html Note that Lisys has NO WARRANTY! #================= #================= # # # # # # # # # lisys-http Justin Balthrop (Summer 2001) Starts and stops the lisys http server, which accepts requests in http format to costimulate Lisys detection nodes. This should be done by following the links e-mailed by the detection nodes. Running this server is only necessary if you want to costimulate nodes using the mailed links. The cgi scripts provide an alternative web interface. #================= use strict; use Getopt::Std; sub read_in; sub write_out; select (STDERR) ; # Location of the properties files. my $globalyroperties = "/etc/lisys/global.properties"; # If this file doesn't exist, we can't continue. print "Global properties file not found: $globalyroperties\n" and exit(l} unless -f $globalyroperties; my $heapsize = "40M"; # Read in the variables that we need from the properties files. prop_eval ("/dev/null", $globalyroperties); my $pidfile = $ENv{pidpath}."/http.pid"; my $classpath = $ENV{classpath}; my $java = $ENV{java}; my %options; getopts ("k", \%options); # Try to stop http server. i f ($options{k}) { i f (-f $pidfile) { print "Stopping I isys http server. \n" ; my $pid = read_in $pidfile; # Kill the java interpreter. kill 1, $pid; unlink $pidfile; } else { print "Lisys http server doesn't seem to be running.\n"i } # Try to start http server. else { # Check to see if http server is already running. if (-f "$pidfile") { my $pid = read_in $pidfile; if (-e "/proc/$pid") { my $cmdline = read in "/proc/$pid/cmdline"i if ($cmdline =- /java/) { print "Lisys http server already running.\n"; exit 0; print "Starting lisys http server.\n"i # Fork and run http server. my $pid; if (!defined ($pid = fork)) { die "Unable to fork: $!\n"i } # The child process elsif (! $pid) { # Put our PID in a file so we can be killed. write_out $$, $pidfile; # Run http server. exec ($java, "-Xmx$heapsize", "-classpath", "$classpath", "edu.unm.cs.lisys.net.LisysHttpServer") i #========== # prop_eval: # A utility function that does variable substitution in files based # on the ENV hash. It reads new variable declarations into ENV as it # goes. # # NOTE: If a variable is defined twice, the second declaration will # just overwrite the first. #========== sub prop_eval my $PROPS = shifti my $FILEi open (PROPS, "> $PROPS"); while ($FILE = shift) { unless (open(FILE, $FILE)) { die "Can't open $FILE: $!\n"i next; } while «FILE» { next i f 1"#/; s/\$([A-Za-z_]\w*)/$ENV{$l}/ge; if (/ ([A-Za-z ] \w*) \s*= (. *) /) { $ENV{$1}=$2-;- } chomp; print PROPS; print PROPS "\n"; } close (FILE) ; } close (PROPS) ; return $PROPS; #========== # read in: # A utility function that reads the contents of a file and returns # them. #========== sub read_in { my $filename = shift; open(FILE, "$filename") or die "Can't open $filename: $!\n"; my $result = <FILE>; close (FILE) ; return $result; #========== # write out: # A utility function that writes a string out to a file. #========== sub write out my $value = shift; my $filename = shift; open (FILE, "> $filename") or die "Can't open $filename: $!\n"; print FILE $value; close (FILE) ;