Thursday, February 24, 2005

Glossary:

Cracker

someone who gains unauthorised access to a system. Not to be confused with a hacker. A hacker is really someone who like to play with computers and write good software. The media often tends to confuse the two. Hackers create, Crackers break.

IDS

Intrusion detection system. A system that tries to detect if your system has been compromised, and warns you of it.

Tripwire

A kind of IDS that checks whether critical system binaries and configuration files have been modified or not.

Firewall

a system that filters traffic moving from outside the network to inside, and vice-versa.

Port scanner

a program that checks a host to see which ports are open for external connections. It generally does a blind connect on all ports of a host. Some port scanners can do stealth scanning.

Security scanner

a program that checks a host for known vulnerabilities. Security scanners generally try to exploit a vulnerability without causing any harmful effects that would happen in a genuine break in. Some exploits are desined to crash a system, and in these cases, the security scanner may well have to crash a system if it is vulnerable. It is better though to be crashed while scanning your own system, than when someone is actually trying to crash you.

Introduction

Some of the most common questions asked by people trying to secure their linux systems are: What is security? How can I protect myself from a break-in? How secure should my linux box be? Which is the most secure linux distribution?

Security, in a nutshell, is ensuring the Confidentiality, Integrity, and Availability of your systems and network.

In short, to protect yourself, you should install the most recent security patches for your distro, turn off unused/unrequired services, run the others through tcpwrappers, and instead of telnet/ftp for remote access, use a secure alternative. The rest of this document will attempt to cover in more detail how to go about securing your linux system.

Most important is to decide how secure you need to be. You need to assess the risk to you, and base your security on that.

risk=(threat*vulnerability*impact)

Threat: the probability of being attackedVulnerability: how easy is it to break inImpact: what is the cost of recovering from an attack

You cannot be 100% secure because there will always be security holes that you either do not know about, or are infeasible to patch.

When picking a distribution with security in mind, you should really pick one that has secure default values that you can tweak later. There's no point in installing a system that someone breaks into before you even have a chance to secure it.

Most distros do not have secure defaults because this tends to make the system hard for end users to use. Securing a system is really a trade-off between convenience to your users, and protecting their data.

Alternately, OpenBSD, was designed from the ground up as a secure unix, and is probably your best choice for a pure unix implementation. OpenBSD servers and firewalls are extremely secure.

A good idea would be to set up a rather open internal network, with tight security between the inside and the outside. That way, local users still have all the convenience, while the system is secure from an external threat. There are still two problems with this approach.

If you have legitimate users who need to connect to your system remotely, they would be inconvenienced by your external security. This shouldn't be an issue, as opening up your system to one person, can really open it up to the world.

On the inside too, if your users cannot be trusted, then lax internal security could hurt you. Your users could compromise your system by simply not setting good passwords, or leaving their terminals logged in while they are away. There have been cases when crackers have walked into offices, and found system passwords pasted on the office bulletin board for everyone's convenience. Although hitherto unheard of in India, companies abroad have been known to place spies in competitor's companies to steal corporate secrets. There's no use in having the ultimate in network security if your employee is simply going to copy all your secrets onto a floppy and walk out with it.

Apart from securing each computer system, and the network as a whole, one also needs to physically secure the entire installation.

Firewalls

To protect your network, you'd use a firewall between your internal network and the rest of the world.

A firewall set up is basically a set of rules that tell the firewall whether a given packet is to be allowed through or not. It can also log information on packets passing through, as well as modify or redirect these packets.

In general, you will require to configure IP Chains, IP Filter or IP Tables depending on whether you have a 2.2, 2.4 or 2.6 kernel.

A firewall is indispensible to the security of a network. Whether it is a dedicated machine or running as a service on another makes a difference.

Since a firewall is meant to filter traffic to and from your network, you ideally want it to sit between your network and the rest of the world. Your firewall would have two network interfaces, one of which connects to your network, and the other to the world.

Firewall rules decide which packets get from one side to another.

A firewall is generally implemented at the kernel level, and can be fast provided it works completely in memory and does not have too many rules. Ideally, you only want your firewall to filter IPs, and let a higher level service handle service based filtering, for example, have tcpd check if anyone is trying to connect to restricted ports on your system, or use a proxy based system to restrict websites that your users may visit. Better logging can be done at these levels, and they are less demanding on the kernel.

Services

Run only the services that you require and no more. On a desktop system, which you will not access remotely, there should not be any services. Run different levels of services on different machines.

You can find out which services are running by using the ps and netstat commands:

ps auxfw will show you a tree structure of processes running, while netstat -ap and netstat -altpu will show you which processes are listening on network ports.

You may also want to do a port scan of your machine using a tool like nmap (remember, Trinity used it in the Matrix Reloaded), or a security scanner like nessus.

Some really unsafe services include rsh, rcp, rexec. Many versions of sendmail and bind have well known security holes. Also disable echo, discard, finger, daytime, chargen and gopher if you don't use them.

Wherever possible, use an encrypted protocol rather than a plain text protocol. for example, use ssh instead of telnet/rsh, use scp instead of ftp, use IMAP w/SSL instead of POP3.

On a single user system, you should also disable identd, but on a multiuser system, this is a good way of tracking down problem users on your system.

You also want to use tcpwrappers to start your services. tcpwrappers are basically an intermediate between inetd and the service that actually serves a connection, like say telnet. Tcpd will check to see if the connecting host is allowed to connect to this service. Different kinds of access control and logging can be done through tcp wrappers.

TCPWrappers

TCPWrappers, and their associated configuration files /etc/hosts.deny and /etc/hosts.allow help a system administrator set up good access control for his system.

First, some background. Most unix systems use what is called a super server to run other servers. The purpose of a superserver is basically to listen on all ports that you want people to connect to, and when a connection is made to that port, it spawns the relevant server. The advantage of such a set up is threefold.

Primarily, all these other servers do not need to implement socket io routines. They simply communicate through stdio, and the superserver connects the socket's io streams to stdio before spawning a server.

Secondly, we keep our process table small by not running all servers all the time. Only one server runs all the time, and servers that are never required are never started. A server that is required is run only for the duration that it needs to serve a connection.

Finally, and really as a consequence of such a set up, we can implement security centrally, and have all servers benefit from it, even if they have no idea that it exists. In fact, these servers know nothing about security at all.

Now, in older systems, the superserver was inetd, or the Internet Daemon. In newer systems, it has been replaced with xinetd, which is simply an extended inetd. xinetd can implement security internally, while inetd spawns an external security handler, most commonly tcpd.

The configuration files for these servers are usually /etc/inetd.conf and /etc/xinetd.conf, /etc/xinetd.d/*. We aren't concerned too much about the contents of these files, except what services are started by it. Most commonly, the superserver will start services like telnetd, ftpd, rlogind, rshelld, rstatd, fingerd, talkd, ntalkd, etc. Many of these may not be required, and can be stopped. In inetd, this would involve commenting out the relevant line in inetd.conf, while in xinetd, this would involve setting disabled=yes in /etc/xinetd.d/service_name.

Disabling these services altogether will cause an inconvenience for your users. For example, you may want to allow nfs connects from certain hosts within your network, but disable it for everyone else. Furthermore, several services have well known exploits, and detecting when someone is trying these is a good early warning system for a possible attack.

This is where tcpwrappers, or tcpd (the tcp daemon) as it is known, comes in. TCPWrappers are basically wrappers around your services. It is implemented in two ways, either through the tcp daemon, which starts the requested service after doing access control checks, or through libwrap,
which may be linked into the server itself. Either way, the wrappers rely on the files /etc/hosts.{deny,allow}.

The full intent and use of tcp wrappers is well documented, and is shipped with all linux distributions. It can be found in /usr/doc/tcp_wrappers/* or /usr/share/doc/tcp_wrappers/*. Here I will outline the most important usage.

How exactly does tcpd come in to play?

Instead of directly starting the server, inetd can start tcpd, and tell tcpd to start the correct server after performing any checks, etc. that it wants. If one opens /etc/inetd.conf, one will find against the telnet and ftp lines that the daemon to be spawned is tcpd with
in.telned/in.ftpd as arguments.

telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd

The other values on the line aren't important for that discussion, and you'll figure them out soon enough.

Now, in execve parlance, the first argument passed in the argument vector corresponds to argv[0], i.e., the name that the program should call itself. tcpd takes this hint, and calls itself in.telnetd (which is what will show up if you list running processes). It performs its checks, and then execs in.telnetd, passing all file descriptors on.

Thus, we have tcpd, which has a single access control file, doing checks for most daemons. Further more, since tcpd comes into the picture only while a connection is being estabilished, and leaves the scene thereafter, there is no overhead involved (except for that during checking, which is what we want).

Now, not all servers are started through inetd. Many, like sendmail, apache, and sshd, run as standalone servers. These servers can have tcpd compiled into them using libwrap.a and tcpd.h. They will then automatically check with hosts.allow and hosts.deny.

Now all these options must be selected while compiling tcpd and libwrap, but the defaults are decently secure anyway.

To check the configuration of your tcpd wrappers, use /sbin/tcpdchk. Give it the -v flag for more information.

The hosts.{deny,allow} files

Wietse Venema, the creator of tcpd, also developed a 'language' for specifying the access control rules that govern who can use which service.
These rules are specified in hosts.allow and hosts.deny. The normal strategy is to deny all connections, and explicitly allow only services that you want people connecting to. For eg: your hosts.deny would read like:

ALL: ALL

This means deny all services to requests from all addresses.

Remember that hosts.allow is checked first, then hosts.deny. The first rule that matches is applied, so basically, if a match is not found in hosts.allow, it will be denied. If hosts.deny is empty or missing, then the default is to grant access. The extended acl language also allows deny rules to be specified in hosts.allow, so you really only have to manipulate a single file.

Rather than go into the details of all possible configurations, I'll just paste my own hosts.allow file here, and explain it line by line.

The above file starts off by allowing anyone to connect to my sendmail daemon. The sendmail daemon is in a better position to do access control, as this needs to be done based on sender and recipient address rather than IP address. If you suspect that certain hosts are unnecessarily hitting you on 25, then you can block them explicitly.

The next line allows ssh connections from certain specific hosts in the 202.141.152. domain, and all hosts in the 202.141.151. domain. I may need to connect to my machine from different places on my network. These connections would be over a broadcast network, so I prefer ssh for connecting.

I allow finger and talk from within my domain, but not from 202.141.151.1.

Finally, I set a booby trap for anyone connecting to services that they are not authorised to access. A reverse finger is done on the attacking host, and a mail is sent to the administrator of my machine with this information.

Intrusion Detection

Intrusion Detection is the ability to detect people trying to compromise your system. Intrusion detection is divided into two main categories, host based, and network based. Basically, if you use a single host to monitor itself, you are using a host based IDS, and if you use a single host to monitor your entire network, you are using a network based IDS. Most home users would use a host based IDS, while universities and offices would have a network based IDS.

There are many Intrusion Detection Systems (IDS) for linux, the most popular, for host based and network based is snort. Others are portsentry and lids - the Linux Intrusion detection system. Going into the details of each of these is beyond the scope of this document, but all tools have very good
documentation.

In addition to an IDS, you would also want to use an Integrity checker, which basically makes sure that none of your binaries and critical configuration files have been modified.

When a cracker compromises a system, the first thing he's likely to do, is create a backdoor for himself. There have been many instances where critical binaries like the ssh daemon have been replaced with trojaned versions that capture passwords and mail them back to the cracker. This
then gives the attacker free access to the system, even if the original hole is plugged.

Tools like tripwire, AIDE, and FreeVeracity check the integrity of your binaries. Of the above, FreeVeracity is reputed to be very easy to set up and use.

Typically, one would create an integrity database when the system is installed, and update it whenever new binaries are installed. The database should always be backed up onto read-only media like a CD. The checker should be run everyday through a cron tab entry, to check all critical files. If the tool finds any discrepancies, it sends a mail to a pre-defined email address.

The Integrity Checker should be configured well to prevent false alarms which makes it a hindrance more than an aide.

So, how do you know whether you've been compromised or not?

Check what your integrity checker has to say about your system binaries

Check for packet sniffers which may or may not be running

If you didn't install it, it shouldn't be there

Check your crontabs and at queues.

Check for services that shouldn't be running on your system

Check /etc/passwd for new accounts/inactive accounts that have suddenly become active

Full details, including how to do the above are listed in the abovementioned document.

So what do you do once you know that you've been compromised?

Well, the first thing is not to panic. It is very important not to disturb any trails that the cracker has left behind, as these can all be used to detect who the attacker was, and even exactly what he did. Very importantly, don't touch anything on the system.

Step one is to disconnect the machine from the network. This will not only prevent further attacks, it will also prevent the attacker from covering up his trails if he finds out that he's been caught.

To prevent any data from being changed, you should also mount your file systems read-only.

Copy all your log files out to another system, or a floppy disk, where you can examine them safely.

Analyse the saved data to determine what the attacker did to break in and what he did after that.

Testing Security

There are many commercial organisations that will test the security of your system for you. These are costly though. A cheaper alternative may be to use one of the many web based security scanners to test your system.

You shouldn't trust what they tell you, but it will be interesting to monitor your logs and network while an attack is in progress.

You can also test yourself by using your own port scanner and security scanners.

Nmap is the most popular and widely used port scanner around, both by black hats and white hats. It can also determine which OS you use, which is what a cracker would need to know to find OS specific vulnerabilities.

If nmap can't figure out which OS you're using, that could slow down your attacker for a while.

SATAN (Security Analysis Tool for Auditing Networks) that was developed by Dan Farmer of Sun Microsystems, and Wietse Venema (of tcpd and postfix fame) from Eindhoven University of Technology, Netherlands, and currently at IBM, was developed with the specific intent of doing everything that an attacker would do to gain unauthorised access. This tool has been replaced with a next generation version called SAINT

Nessus has a plugin based architecture. Vulnerabilities checks are written as plugins, which means that you can check for new holes as they become publicly known, without upgrading your entire binary.

Viruses and Trojans

The real question in this section is, is linux vulnerable to viruses and trojans.

Practically, no. Technically though, it is possible.

Due to the design of Linux, it is difficult for viruses to spread far within a system, as they are confined to infecting the user space of the user who executes them. Of course, this is a problem if infected files are launched by root, but as a security conscious individual, you wouldn't be running untrusted files as root, would you?

It is theoretically possible for a virus launched by a regular user to escalate its privileges using system exploits; however, a virus with this capability would be quite sizable, and difficult to write. As of this date, few viruses have actually been discovered for Linux, and the ones that have been discovered aren't worth losing sleep over. This will undoubtedly change with time.

Worms like l10n and Top Ramen only worked because the systems were insecure to begin with. An insecure ftpd/rstatd was used to automatically gain access to machines, and use them as further launching grounds.

Viruses do exist for Linux, but are probably the least significant threat you face. On the other hand, Linux is definitely vulnerable to trojans.

A trojan is a malicious program that masquerades as a legitimate application. Unlike viruses, they do not self replicate, but instead, their primary purpose is (usually) to allow an attacker remote access to your computer or its resources. Sometimes, users can be tricked into downloading and installing trojans onto their own computers, but more commonly, trojans are installed by an intruder to allow him future access to your box.

Trojans often come packaged as "root kits". A "root kit" is a set of trojaned system applications to help mask a compromise. A root kit will usually include trojaned versions of ps, getty, passwd.

At this point in time, virus Scanners for Linux are aimed at detecting and disinfecting data served to Windows hosts by a Linux file/mailserver. This can be useful to help stop the spread of viruses among local, non-Unix machines. Due to the lack of viruses for Linux, there are presently no scanners to detect viruses within the Linux OS, or its applications. Trojans present a greater threat to the Linux OS itself than do viruses, and can be detected by regularly verifying the integrity of your binaries, or by using a rootkitdetector.

Trojan Detectors:

Chkrootkit: Checks Linux system for evidence of having been rootkitted.

Finally, a system administrator must understand that security is a process. You need to keep yourself up to date with all the latest security news. Subscribe to the securityfocus, cert, and other security related mailing lists. Stick to the comp.os.linux.security newsgroup. That's also a good place to post your queries - if they haven't already been answered (hey, most of this doc was from the faq in there).