|
||||||||
|
||||||||
|
|
Công Cụ | Xếp Bài |
28-10-2009, 10:07 PM | #1 |
Guest
Trả Lời: n/a
|
Building an IPS using Snort
Building an IPS using Snort The two most popular ways of protecting computer networks from cyberintruders are firewalls and intrusion detection systems (IDS’s). Firewalls work by monitoring the packets sent between network segments, while intrusion detection systems examine the information sent in the packets and sound the alarm if anomalies or behaviour patterns typical of known attacks are detected. However, the security attained using these methods is not entirely satisfactory. Any firewall always has to let some traffic through - otherwise there would be little point in connecting the protected network to the outside world - and therefore leaves the network open to attacks that exploit permitted services. You can of course have an IDS detect attacks that get through the firewall, but IDS’s only provide notification of attacks and cannot prevent them. In theory, you could also link up an IDS and firewall and configure them so as to block all detected penetration attempts or break off any suspicious connections. Unfortunately, there are a number of problems with this approach. First off, many attacks require only one or a handful of packets to get through. DoS attacks on an application or system that crashes upon receiving suitably crafted data or buffer overflow attacks with return connections to the attacker’s computer will all succeed, even if the IDS instructs the firewall to block incoming connections from a specific IP. Worse still, an attacker can use knowledge of such mechanisms to cause specific addresses to be blocked by spoofing attacks from these addresses. Intrusion prevention systems (IPS’s) provide an effective solution to all these problems by combining the functionality of a firewall and IDS. IPS’s occupy the same place as firewalls in network infrastructure, i.e. should be located so that all network traffic passes though them. An IPS analyses traffic for behaviour characteristic of known attacks and either allows packets through or blocks them, depending on the result. The security software market is full of various IPS solutions, with prices ranging from several thousand to tens of thousands of dollars. In this article, we will go through building a custom IPS using freely available software. Toolkit Our intrusion prevention system will run on a Linux box with the 2.6.12.6 kernel. I mention the kernel version because 2.6 series kernels have integrated support for network bridges, while 2.4 series kernels require patches to add this functionality. The actual Linux distribution is irrelevant, but the system should be installed in a pretty basic console configuration - no X-Window, multimedia applications and such like. The IPS will be based on the open source Snort IDS version 2.4.0. Snort is a very advanced IDS, used in several commercial IDS/IPS solutions. We will be using version 2.4.0, as it is integrated with the snort_inline project to allow network packets to be captured not via the libpcap library (as is the case with the standard configuration), but via netfilter and iptables. We will also need some additional libraries and utilities, most notably the libnet 1.0.x and LIBIPQ libraries and the bridge-utils utility. LIBIPQ is included with the iptables package and can either be found in development packages or installed from source by installing iptables using the make install-devel command. We will also use the Oinkmaster application to provide automatic signature updates. The box we will run the IPS on has three network adapters, of which only one will have an IP assigned and will be used to control the system. The other two adapters will only be configured up to OSI layer 2 and all network traffic being analysed will be sent between them. The IPS will therefore act as a network bridge, transparent to other network devices and hosts. Figure 1 presents a diagram of a sample network after such an IPS is connected. Note that in this article we will not go into building the entire network, but rather we will focus on the IPS system itself. Figure 1. IPS installation in a sample network configuration Netfilter The netfilter mechanism is a Linux kernel subsystem supporting packet filtering and manipulation and network address translation, available since kernel version 2.4 and still being developed in current 2.6 series kernels. Filtering or translation rules are defined using a user-space program called iptables, although this is not the only way of controlling kernel-level network traffic filtering. Building a bridge A network bridge is a device that operates on the data link OSI layer and is used to connect two separate network segments. There are two main advantages to using a bridge-based IPS or firewall:
Once the recompiled kernel has been restarted, we need to add a new virtual network interface and assign it the physical interfaces eth0 and eth1 using the following commands: # ifconfig eth0 0.0.0.0 up # ifconfig eth1 0.0.0.0 up # brctl addbr br0 # brctl addif br0 eth0 # brctl addif br0 eth1 # ifconfig br0 0.0.0.0 up We also need to configure the eth2 interface which we will use to control the IPS: # ifconfig eth2 10.0.0.1 \ netmask 255.255.255.0 up From now on, all packets received by eth0 will be sent via eth1 to the network segment on the other side of the IPS and vice versa. The eth2 adapter has an IP, allowing us to remotely log onto the IPS host. Listing 1. System kernel configuration Device Drivers Networking support Networking options <*> 802.1d Ethernet Bridging Network packet filtering (replaces ipchains) <*> Bridged IP/ARP packets filtering IP: Netfilter Configuration <*> Userspace queueing via NETLINK <*> IP tables support (required for filtering/masq/NAT) Bridge: Netfilter Configuration <*> Ethernet Bridge tables (ebtables) support Installing Snort Snort installation proceeds in typical Linux fashion, with one exception: the configuration script should be executed with the --enable-inline switch to allow the application to operate in inline mode (i.e. with network traffic passing through it). The following commands configure, compile and install Snort: $ ./configure --enable-inline $ make # make install Next, we need to create the /etc/snort directory and copy all the required configuration files to it: # cp classification.config \ gen-msg.map \ generators \ reference.config \ sid sid-msg.map \ snort.conf \ threshold.conf \ unicode.map \ /etc/snort Finally, we need to modify the main configuration file snort.conf. We don’t have any attack signatures just yet, so we need to comment out (by inserting # at the beginning of a line) all the lines that include signature files - they can be found at the end of the file and are of the format include $RULE_PATH/*.rules. We’ll also need to change the variable that defines the signature directory from var RULE_PATH ../rules to var RULE_PATH /etc/snort/rules. IPS types The system described in this article is a network intrusion prevention system (NIPS) - currently the most popular type of IPS. Other IPS types include:
Signature checking Attack rules available for download from the Snort website come in three groups: subscription rules, registration rules and unregistered rules. Unregistered rules are only updated when a new Snort release appears and subscription rules require regular subscription fees to be paid, so a sensible choice is to use rules that only require registration. However, before we download and install official attack rules, let’s test the configuration we’ve got so far. We will create a few test signatures to probe the capabilities of the IPS. We will use three new inline mode rule types to define Snort behaviour upon encountering a match:
The first test rule is: drop tcp any any -> any 22 (classtype:attempted-user; msg:"Port 22 Connection Initiated". It’s a very simple rule that recognises, blocks and logs all packets incoming to TCP port 22, effectively allowing the IPS to block all attempts to connect to SSH servers. Listing 2 presents a typical event log entry created by Snort whenever a matching packet is encountered - in this case, this would be a SYN packet to initiate a TCP connection. Our second rule is alert icmp any any <> any any (classtype:attempted-user; msg:"ICMP Echo Request"; icode:0;itype:8 to recognise and log all ICMP Echo Request packets. When a match is encountered, the Snort event log will updated with an entry similar to that in Listing 3. The final test rule is also the most interesting: alert udp any any <> any 53 (classtype:attempted-user; msg:"DNS Request"; content:"yahoo"; replace:"lycos". It will detect and log all UDP packets sent to port 53 (the DNS server) that contain the string yahoo. Matching packets will be allowed through, but with the string yahoo replaced with lycos. The replace field specifies the string that is to be inserted instead of the string specified in the content field. As a result, whenever a DNS query for www.yahoo.com is received, the DNS server will respond by sending the IP of www.lycos.com and the entry shown in Listing 4 will be appended to the event log. The replace feature of inline Snort operation is very useful when protecting a honeypot system that the intruder should be able to compromise, but unable to use for attacking other systems. If we load the IPS with a rule to recognise a specific shellcode, as shown in Listing 5, all attacks matching that pattern will fail. The rules listed above should be written to the test.rules file in the /etc/snort/rules directory, with the entry include $RULE_PATH/test.rules being appended to /etc/snort/snort.conf. Next, we need to configure iptables to send all packets through Snort, and then run Snort itself: # iptables -P FORWARD DROP # iptables -A FORWARD -j QUEUE # snort -Q \ -c /etc/snort/snort.conf \ -l /var/log/snort -v The last command runs Snort in inline mode (the -Q switch). Program configuration is specified in the /etc/snort/snort.conf file (the -c switch) and logs are written to /var/log/snort (the -l switch). For test purposes, we are also using the -v switch to enable verbose IPS operation and provide us with detailed information about any configuration errors. For production deployment, we will replace -v with -D to make Snort run in the background as a daemon. Listing 2. Snort’s reaction to a packet matching the first rule [**] [1:0:0] Port 22 Connection Initiated [**] [Classification: Attempted User Privilege Gain] [Priority: 1] 09/19-20:19:07.436667 192.168.0.2:1049 -> 193.219.28.2:22 TCP TTL:128 TOS:0x0 ID:702 IpLen:20 DgmLen:48 DF ******S* Seq: 0x29821EB9 Ack: 0x0 Win: 0xFAF0 TcpLen: 28 TCP Options (4) => MSS: 1460 NOP NOP SackOK Listing 3. Snort’s reaction to a packet matching the second rule [**] [1:0:0] ICMP Echo Request [**] [Classification: Attempted User Privilege Gain] [Priority: 1] 09/19-20:12:57.194560 192.168.0.2 -> 212.76.32.1 ICMP TTL:128 TOS:0x0 ID:420 IpLen:20 DgmLen:60 Type:8 Code:0 ID:512 Seq:256 ECHO Listing 4. Snort’s reaction to a packet matching the third rule [**] [1:0:0] DNS Request [**] [Classification: Attempted User Privilege Gain] [Priority: 1] 09/19-20:21:12.989775 192.168.0.2:1041 -> 212.76.39.45:53 UDP TTL:128 TOS:0x0 ID:818 IpLen:20 DgmLen:59 Len: 31 Listing 5. A simple rule change will alter the shell code and prevent an effective attack Before the change: alert ip $EXTERNAL_NET $SHELLCODE_PORTS -> $HOME_NET any § (msg:"SHELLCODE Linux shellcode"; content:"|90 90 90 E8 C0 FF FF FF|/bin/sh"; § reference:arachnids,343; classtype:shellcode-detect; sid:652; rev:9 After the change: alert ip $EXTERNAL_NET $SHELLCODE_PORTS -> $HOME_NET any § (msg:"SHELLCODE Linux shellcode"; content:"|90 90 90 E8 C0 FF FF FF|/bin/sh"; § replace:"|90 90 90 E8 C0 FF FF FF|/ben/sh"; § reference:arachnids,343; classtype:shellcode-detect; sid:652; rev:9 Iptables configuration In this example, we’re using the iptables -A FORWARD -j QUEUE command to redirect all network traffic to a user-space application, making the IPS analyse all incoming packets. However, we could also limit analysis to selected connection types. For example, to make Snort scan only packets sent to Web servers, we would use iptables -A FORWARD -p tcp --dport 80 -j QUEUE. It is time to equip our IPS with official, production-quality attack signatures. We will use rules available to registered users only, so you will first need to create a user account on the Snort website. Once you’ve downloaded the latest signatures, unpack them to the /etc/snort directory. The default Snort action for all rules is to log attack information (the alert directive). We want to block attacks, not just log them, so we need to replace the alert action with drop for all rules, for example using the following shell command: $ for f in `ls *.rules` ;\ do sed s/^alert/drop/g \ $f > ${f}.new ; \ mv ${f}.new $f ; \ done We will also need to uncomment the lines in snort.conf that load the particular signature files (the ones we commented out for testing). Now we can run Snort: # snort -Q -D \ -c /etc/snort/snort.conf \ -l /var/log/snort Note, however, that deploying a new IPS to a production network and immediately enabling packet dropping for all rules is generally a very bad idea. All IDS/IPS solutions should first be tuned to match the requirements of a specific network environment in order to eliminate the numerous false alarms that always appear in initial stages of operation. If we instruct the system to drop anything remotely suspicious without accounting for specific network behaviour, some network services could be blocked or disrupted, as the IPS will block some or all of their packets. Before deploying to a production environment, it is therefore a good idea to start by inspecting the reactions of particular rules to typical network traffic and disabling any rules that generate false alarms in a given environment. Once that’s done, you can enable packet dropping to provide actual attack prevention functionality. Automatic updates Any IDS/IPS solution quickly becomes outdated, even if the latest signatures were used during installation. New threats appear all the time, requiring attack signatures to be updated daily for protection to be effective. Manual updating is a tedious task, so we will automate it using Oinkmaster 1.2. Apart from the application itself, we will also need an OinkCode to allow access to rules available to registered Snort users. You can generate the code after logging into your Snort user account. Oinkmaster is a Perl script, so installing it is very simple: $ tar zxvf oinkmaster-1.2.tar.gz $ cd oinkmaster-1.2 # cp oinkmaster.pl /usr/local/bin/ # cp oinkmaster.conf /etc/ Configuration is fairly straightforward, requiring only a handful of changes to the oinkmaster.conf file. Most importantly, we need to specify the signature file to be downloaded. We want the most recent rules, so we need to modify the line # url = http://www.snort.org/pub-bin/oinkmaster.cgi//snortrules-snapshot-CURRENT.tar.gz by deleting the initial # and replacing with the OinkCode generated on the Snort website. If we left the remaining configuration as it is by default, all new signatures would use the default alert action for all attacks. We want attacks to be blocked, so we need to append an entry to oinkmaster.conf that will cause the default alert action to be changed to drop for all active rules: modifysid * "^alert" | "drop". We can also indicate rules that should be disabled by default using disablesid , which is very useful when you have a properly tuned IPS and don’t want an update to mess up the configuration (for example by enabling rules that had previously been disabled). The application is run using the following command: # oinkmaster.pl -o /etc/snort/rules/ where the -o parameter specifies the target directory for new rules. It is also a good idea to use the -b parameter to indicate the directory where previous signature files should be moved. For updates to be applied, Snort should be reloaded after each change to the signature files, so the last touch is to write a simple script to control the update and reload process and add it to /etc/crontab or a similar file for another job scheduler. |
|
|