Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Thursday, June 11, 2009

Dealing With "Permissions on the password database may be too restrictive" Errors On SUSE Linux 10.x

Hey there,

Here's something I ran into for the first time in my life today (and I don't mean the longest frickin' subject line I've ever written ;)

I was working with a colleague, booting up a recently panicked (I'm assuming, since I wasn't involved when "the incident" happened) SUSE Linux 10 system, when we saw the following error:

Login Failed: Permissions on the password database may be too restrictive.

Or something to that effect. Unfortunately, I don't have the screen to cut-and-paste from (not complaining). We ended up getting this error for regular users and administrative users, including root. It seemed like there wasn't an account available that could log in to the box. Eventually the problem was solved, but it was an interesting situation and, perhaps, some of the following troubleshooting information might be of help to you in the future (So you don't have to boot "rescue" off of CD more than once ;)

Here's how it went down (try to contain your excitement. This is edge-of-your-seat stuff, so, please, go to the bathroom before you continue reading ;)

1. The first thing we did was to try logging in with all the accounts we could think of. None of them worked, although we were relatively sure that they were enabled and had worked previously.

2. Then we did the sanity-check that (interestingly) you don't see too many people do any more: We quit trying to login to the default run level (5 - X-Windows) and tried the same logins we did in step 1 on the machine's local console. At this point, we considered that we may have hit some limit on failed login attempts, but quickly discounted that theory, since our logins had been failing from the start. It's also worth mentioning that this was a newer machine and (as it turned out) had not been attacked in any way that might disable passwords from being accepted.

3. Next, we booted off of CD and ran SUSE Linux in "rescue" mode. This gave us a very easy login. Username: root. No password required. Using "lvscan" we were able to to identify the root partition and ran fsck on all available partitions to ensure that no file system corruption existed.

4. Once all the fsck's came back "OK," we mounted /dev/system/root onto a temporary directory (/tmp/root for instance):

host # mkdir /tmp/root
host # mount /dev/system/root /tmp/root


5. Then we changed directories into what would normally be our /etc directory to look for any obvious signs of damage. None could be found. In fact, it seemed as though the error we were getting was completely erroneous:

host # cd /tmp/root/etc
host # ls -l passwd shadow
-rw-r--r-- 1 root root 25729 Jun 10 05:52 passwd
-r-------- 1 root root 14268 Jun 10 05:51 shadow


Those permissions may seem restrictive, but they're actually required so that users' passwords can remain secure. /etc/passwd should be readable by anyone, but the "passwd" program actually runs "setuid root" so that it can verify the user's password by reading the /etc/shadow file:

-rwsr-xr-x 1 root root 27768 Jul 17 2006 /usr/bin/passwd

6. We added our own user id's to the "wheel" group (root was already a member) and rebooted, to see if that would help, but it didn't. That was lame, I know, but much better than finding out later that it was actually the solution and we never tried it ;)

7. Booting up in rescue mode and mounting the root partition again, we took a look at the /tmp/root/etc/sysconfig/permissions file (We couldn't use Yast's X-Window interface, as explained below). It turns out that the line:

PERMISSION_SECURITY=

was set to paranoid for local security!!!! This was easily fixable by changing it back to the least restrictive of settings (you have easy, secure and paranoid to pick from, I believe):

PERMISSION_SECURITY="easy local"

saved that file and rebooted. All was well :)

The Aftermath:

One interesting thing I noted, when taking a look at the problem afterward, was that "paranoid" local settings were actually set on purpose by another admin (the default for our install image was what we reverted back to - "easy local").

This setting seems like a good idea, because, from the documentation I could find, it purports to make it so that the administrator gets to choose which users can run X sessions and "setuid" programs, although (obviously) it should never be set up and not completely finished and tested before leaving it go ;)

One of the major issues is that, if no one is specifically allowed to run X sessions and/or use setuid programs after this setting is enforced and the machine is rebooted, root is included in the accounts that are denied access to these programs.

The X denial is okay. I can live with that. But not allowing root (and every other account) to use setuid programs makes it impossible for anyone to login. The reason for this is actually pretty simple. When login asks for your password, in simplistic terms, it employs "passwd" (a "setuid" program, as shown above) to read your user entry from /etc/shadow and confirm that your password is actually correct. Since no one is allowed to use "setuid" programs, no one (including root) can login (Via X, remotely or even directly on the local console).

Crazy, but fun for a while ;) Hopefully this helps someone out there :)

Cheers,

, Mike


Banner for College Student-Oriented Sites (728 version 1)



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Thursday, January 8, 2009

More Perl Security Through Obfuscation For Linux and Unix

Hey there,

Today's post is going to be a bit on the short side (like, under 5000 words ;) as I'm up to my neck in the work I do to feed my family :) This is also all in fun. I make no claims that anything I write in these types of posts should stand as a replacement for real security measures :)

As you may recall, we've done a number of posts, previous to this one, dealing with security through obfuscation. The basic premise of all of them being that, if you can make the risk of destroying your code, simply by changing it, just one more step closer to probable, no one will ever mess with your code... probably ;)

Today, we're going to be looking at a simple script that we'll feed through another simple script to generate our "stored code," and then one final script to process that code and execute it. Simple enough :)

First things first: The original script (This is the script we don't want people to mess with. It may seem to not do much and be rather harmless, but... it actually doesn't do much and is pretty harmless ;)

host # cat simple.pl
#!/usr/bin/perl

print "Goodbye Cruel World\n";
$counter = 1;
while ( $counter < 4 ) {
print "Goodbye ";
$counter++;
}
print "\n";
exit(0);


Now, since you've seen the code and the gravity of keeping it secure has just slammed on top of you like a Wile E. Coyote Acme Anvil, we'll convert our ".pl" (Perl) script into a ".bs" (bastioned source... better than what I had in mind originally ;) script ;). We'll do this by running it through another simple script that unpacks the code into Hex and then unpacks the Hex into Binary:

host # ./bs-in.pl simple.pl
host # cat simple.bs
0100110011001100010011001000110001001100011001101110110010101100111011001100110011101100010011000100110001100110011011000100110001101100100111000110110010100110010011000110011011101100000011000110110010101100111011000100110001101100110001100000110010000110000011001000011011101100000011001110110001001100011011001001110001101100101001101110110000101100010011000000110001001100010011000010110011101100011011000110011001101100011001100110110000101100011011000100110011101100100111000110110010101100010011000000110000101100110011001110110001001100111011001010110001101100101011000110110011000110010011000000110010101100111011000110110001100110111011000100110001101100110001100110110000101100101011001100011001101100101001100100110001001100110011000100011000001100100001100100110000101100011011001100110001101100011001101110110010101100011011001010011011101100001011000110110010101100111011000100110001001100000011001100110000100110010011000000110011001100100011001100110001000110000011001000011011101100111011000110110000011100011011001001110001101100110001100110110010101100010011000000110001001100000111000100110000001100010011000010110001101100110011000110110001100110111011001010110001101100101001101110110000101100011011001010110011101100010011000100110000001100110011001100011001001100000011001100110000101100010011000000110001001100100111000000110010011100111011000100011000001100100001100000110010011100111011000000110011101100010011000110110010011100011011001010011011101100001011000100110000001100010011000100110000101100111011000110110001100110011011000110011001101100001011000110110001001100111011001001110001101100101011000100110000001100010011000100110011001100010001100000110010000110000011001001110001001100001011000110110011001100011011000110011011101100101011000110110010100110111011000010110001101100101011001110110001001100010011000100011001001100010001101100110001000110000011001000011011101100001001100000110010000110111011000000110011101100010011000110110010011100011011001010011011101100001011000100110000001100010011000100110010101100110001100110110010100110010011000100110011001100010001100000110010000110011011001010110011101100000111000110110010011100111011000010110001001100000111001100110000001100010011001001110011001100010001100000110010000110


And you check that new ".bs" script into CVS separately from your "bs-in.pl" script (which you keep secured by packs of wild dogs ;), and destroy the original "simple.pl" script :)

Now, if you ever need to run your new-fangled script, you'll just process it through another script you've got set aside to parse your ".bs" scripts (permission and ownership protected, so folks can't see how easily you're making things difficult for them, of course) and you get the output you would have gotten if you just ran the regular "simple.pl" script:

host # ./bs-out.pl <simple.bs
Goodbye Cruel World
Goodbye Goodbye Goodbye


If you want, you can modify bs-out.pl to take command line arguments instead of STDIN, or both. You can also modify the execution line in "bs-out.pl" so it will run any executable script fairly simply. For today, this is as good as it gets ;)

Hope you enjoy hash-binary/binary-hash unpacking/packing your "Hello World" scripts (This one came out slightly different since Pink Floyd is playing in the background ;) Both scripts are tagged onto the end of this post.

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# bs-in.pl - Usage: bs-in.pl "regular script or program in any language"
#
# 2009 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

local $/;
open(FILE, "<$ARGV[0]");
$simple = <FILE>;
close(FILE);
$simple1 = unpack "H*", $simple;
$simple2 = unpack "b*", $simple1;
$outputfilename = `echo $ARGV[0]|sed 's/\.pl\$/.bs/'`;
open(FILE2, ">>$outputfilename");
print FILE2 "$simple2";
close(FILE2);




Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# bs-out.pl - Usage: bs-out.pl <YourBSFile.bs
#
# 2009 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

local $/;
$simple = <STDIN>;
$simple1 = pack "b*", $simple;
$simple2 = pack "H*", $simple1;
system("/usr/bin/perl -e '$simple2';");


, Mike




Discover the ClickBank affiliate program that pays 100% commission!



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Monday, December 15, 2008

Updating Unix And Linux Passwords Via The Web Browser

Hey there,

QUICK NOTICE FOR REGULAR READERS: We didn't want to lead off the week with this, but tomorrow's post will be an op-ed bit having to do with this blog, its contents and some of the shortcomings of, shall we say, "where we are" (literally). We'll also be putting up a poll to confirm that our opinion is the same as yours (we hope ;) To cut it short, if you find downloading scripts form this site a HUGE PITA, please glance at tomorrow's post and anonymously answer the poll if possible. Thanks :)

This Monday's script is actually a web-page frontend (CGI, to be exact) to make use of another script. That script can be any you want, but, if you like, we published an Expect script some time ago to do network wide updates from a single source that can be modified to restrict it to password changing only.

Now, we'll go on record right away (admittedly, this is the second paragraph, so we're lagging behind already ;) by stating that we do not specifically endorse this method of password changing. It's very convenient (for users both trustworthy and malicious) and does the job, but, use of this script in a secure environment (or any environment that requires protection) is not recommended. Not only does this script open up many potential security holes by allowing access to system commands (albeit via another script that gets called, so it's not "unbelievably" easy to misuse), it will almost guarantee that you won't get your Sarbanes Oxley compliance certificate :) That being said, if you have a small internal net (quarantined from production and other environments) this can be a handy way to do your updates. In the worst case, you can just forego the "web experience" and do your mass password updates using Expect (or any other tool) from the CLI.

Since glitz seems to be the order of the day, the web frontend is presented here and now. We've left out the frontend form where you would enter your name, current password and new password, as creating one of these would probably be specific to your organization and simple enough to knock out. If this is a pain for any of you, just write in (via the "Send Me A Comment" link at upper right corner of every page) and we'll be happy to write one up and post it here.

Hope you enjoy it but, as always, exercise prudence, caution, and all those other qualities that will keep you from getting into a situation that involves immediate termination of employment :)

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# change_password.cgi
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

&read_parse;

$login = $FORM{'mylogin'};
$password = $FORM{'mypwd'};
$password =~ s/([;?!])/\\$1/;
$new1 = $FORM{'mynewpwd1'};
$new2 = $FORM{'mynewpwd2'};
if ( $new1 ne $new2 ) {
¬_match;
}
$new1 =~ s/([;?!])/\\$1/;
$new2 =~ s/([;?!])/\\$1/;
$nickname = &get_gecos;
$litmus = 0;
$date=`date +%m%d%y`;
open(PASS, "</etc/passwd");
@etcpass = <PASS>;
close(PASS);

foreach $line (@etcpass) {
if ( $line =~ /^$login/ ) {
$litmus = 1;
}
}

if ($litmus == 0) {
print "Content-type: text/html\n\n";
print "<html>\n";
print "<head>\n";
print "<title>Error</title>\n";
print "</head>\n";
print "<body BGCOLOR=\"#000000\" TEXT=\"#00FF00\" LINK=\"#FFFF00\" VLINK=\"#0000FF\" ALINK=\"#BECD8C\">\n";
print "<p>\n";
print "<br><hr><br>\n";
print "<p>\n";
print "<center><FONT COLOR=\"#FF0000\"><H3>Bad User Name</h3></FONT></center>\n";
print "<p>\n";
print "<br>\n";
print "<p>\n";
print "<center>The Name $login doesn't have a login yet!</center>\n";
print "</body>\n";
print "</html>\n";
exit;
}

system("/path/to/your/mass/password/changing/program $login $password $new1");

print "Content-type: text/html\n\n";
print "<html>\n";
print "<head>\n";
print "<title>All Done</title>\n";
print "</head>\n";
print "<h3>\@hummer</h3>\n";
print "<body BGCOLOR=\"#000000\" TEXT=\"#00FF00\" LINK=\"#FFFF00\" VLINK=\"#0000FF\" ALINK=\"#BECD8C\">\n";
print "<p>\n";
print "<br><hr><br>\n";
print "<p>\n";
print "<center><FONT COLOR=\"#FF0000\"><H3>Fine Job, $nickname!</h3></FONT></center>\n";
print "<p>\n";
print "<br>\n";
print "<center><FONT COLOR=\"#FF0000\"><H3>Assuming that your intial password was valid, your Password has been changed!</h3></FONT></center>\n";
print "<center><FONT COLOR=\"#FF0000\"><H3>Remember, also, that all passwords must contain at least one numeric or non-alpha character in order to be accepted.</h3></FONT></center>\n";
print "<p> \n";
print "</body>\n";
print "</html>\n";
exit;

sub not_match {
print "Content-type: text/html\n\n";
print "<html>\n";
print "<head>\n";
print "<title>Error</title>\n";
print "</head>\n";
print "<body BGCOLOR=\"#000000\" TEXT=\"#00FF00\" LINK=\"#FFFF00\" VLINK=\"#0000FF\" ALINK=\"#BECD8C\">\n";
print "<p>\n";
print "<br><hr><br>\n";
print "<p>\n";
print "<center><FONT COLOR=\"#FF0000\"><H3Passwords Don't Match!</h3></FONT></center>\n";
print "<p>\n";
print "<br>\n";
print "<p>\n";
print "<center>The Password $new1 doesn't match $new2</center>\n";
print "</body>\n";
print "</html>\n";
exit;
}

sub read_parse {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
}

sub get_gecos {
$boner = `grep $login /etc/passwd`;
@stuff = split(/:/, $boner);
return $stuff[4];
}


, Mike




Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Thursday, December 4, 2008

Linux And Unix Internet User And Site Security - How Much Is Too Much?

Hey there,

Today's post is going to be about security on Linux and Unix, since we're building up to doing some work with CAPTCHA in the near future and need to keep ourselves awake and interested ;) To be more specific, today's post is going to deal with site, and user, security on the Internet (although you could apply these examples to various arenas). As we all know, maintaining a decent level of personal and professional site security on the Internet is possible to a degree. Unfortunately, as long as there's profit in breaching that security, building industries devoted to thwarting those breaches or some interdependent mish-mosh of the two, there's no way to achieve absolute security on the Internet unless you opt not to use it (The Internet, that is ;)

To get us started, I wanted to gloss over some points taken directly from RFC 4732 which, although it is (admittedly) more geared toward Denial Of Service attack prevention, still provides many useful and simple guidelines with regards to Internet security in general (identity protection, etc). The RFC is from 2006, but it seems to be the most concise and easily digestible security RFC out there. Of course, I don't read them all ;) I mainly chose this one because of it's easy blending of useful information and readability.

We'll blaze through some of the points made in RFC 4732 at a quick pace. Check out the link for more information. The following is a quick bullet list of just some of the (now standard) recommendations for DOS protection (and general Internet User and Site Security) - I'll follow each selected point (taken from the RFC almost verbatim) with a quick (hopefully, one line) summation so we get the flavour but don't have to eat the whole bird ;) Some of the suggestions for enhanced general security include:

1. Don't Hold State for Unverified Hosts: This is always good practice. If an unverified host doesn't complete a TCP handshake, let 'em go.

2. Make It Hard to Simulate a Legitimate User: Solutions like CAPTCHA, Reverse Turing Tests, Puzzles and Reachability Testing are all good ways to try and determine if you're interacting with an intelligent entity (for now, we'll assume that only means "a human being" ;)

3. Isolate Router-to-Router Traffic: Containment is always a good idea. It's much harder for someone to jump 15 hurdles than it is to jump 1.

4. Check Protocol Syntax and Semantics: Check that your (for instance) TCP traffic is legitimate and conforms to its protocol's format.

5. Properly Handle Resource Exhaustion: This is common sense. Don't allow your resources to become exhausted by design. This won't protect you from attack or inconvenience, but it will, most probably, protect you from being "downed."

6. Avoid Livelock: This has to do with how you deal with network data transactions. By utilizing polling mechanisms, rather than interrupt-driven ones, you can protect your OS kernel from spending all its time dealing with lower-level interrupts and little to no time dealing with ensuring traffic security at the application level.

7. Use Unpredictable Values for Session IDs: Being unpredictable is always a good idea. Unless you're trying to keep your job ;)

8. Establish a Monitoring Framework: If you have a relatively decent idea of what your normal system metrics look like, it will be incredibly easy to pick up on possibly bad situations that are coming 'round the bend.

The above listed points were a very limited selection from the final section of RFC 4732, and they bring us to our own little list that deals with today's topic of Internet user and site security. Oddly enough, none of my suggestions require you to have any technical knowledge to implement. In other words, they all have to do with "Social Engineering" (The world's second-oldest profession... although arguments could be made ;)

Note: These examples have been written to be personal in nature. Since social engineering is a term that covers all forms of deception, I thought it read better as a "how to not get screwed" list than a complicated network security list

1. Don't trust anyone you don't know: Yes, not even me. Don't take anything at face value (at least, initially) and don't be afraid to question authority. Odds are you don't know me and, although it may seem that my motives for writing this blog are purely altruistic, I could be [INSERT NAME OF BIG-TIME-SCAM INTERNET MARKETER HERE] using a clever pseudonym and recycling my post material from lesser known works by honest hard-working professionals who never received the recognition they deserved just so I can, eventually, steal a few pennies from each of you (an, admittedly, cost-ineffective strategy) Seriously, if you ever question anyone's credentials, authority or advice, take the time to do a little independent investigation. 5 minutes on Google can save you a major headache or two. I'm one of the good guys, I swear. Of course, no one who's looking to screw you will admit to anything less... Just be careful that you don't pass the tipping point and end up living in full-fledged paranoia.

2. Under the proper circumstances, always politely insist that people "prove" themselves to you (above and beyond whatever "proof" they may freely offer up to put that part of your mind to sleep and make you more suggestible). The "proper circumstances" will almost always mean any situation where you are initially approached. If you're reaching out for help to a specific person, you've - hopefully - already established trust and enjoy a secure relationship with them. If someone you don't know approaches you and attempts to elicit any sort of personal or confidential information, be sure that you understand why by simply asking them. Be prepared to deal with mock outrage, a misdirected reply, questioning of your question or your reason for asking it, among many other things. These are clear indicators that you just stopped someone from attempting to do something to you that they know is wrong. Not many honest people get offended if a stranger doesn't immediately trust them.

3. Check this blog out (do a search for "password," "guesser," "cracker" or any combination thereof) for a couple reasons why you should come up with a decent password, if you do anything that requires one, and never share it with anyone or leave yourself physical reminders (like a sticky-note with it written on there ;)

4. If you're approached via a non-direct medium, like the phone or via email, and you don't know who you're dealing with and/or they want information from you that you're not comfortable handing out, ask them for their return phone number or email address so that you can call them back or write them. Make up a reason (if they're full of it, you can always rationalize it as a form of sincere reciprocation), just don't email them the information if you're approached in that manner. Use the callback and the email response, etc, as a way of establishing that you can get to that person if you need to. If at all possible, insist on getting a phone number or having the requester contact a third party, whom you trust, to get their request for information approved. Do whatever you can to make a phisher's job difficult (they'll almost always blow you off if you create this sort of situation, because, in that "numbers game" you're not going to be worth the time they waste) and, if you still feel uncomfortable, refuse to communicate with them unless through your manager (if at work), an intermediary or "at all" if on your own.

5. Respond to veiled threats with indifference. If you deflect an initial attempt to gain information from you, and the requester isn't legitimate, they may attempt to intimidate you or appeal to your sense of sympathy (or some other emotion we have that separates us from the animals ;). If they intimate that your not giving them the information right away might cause you damage away from which you will never be able to walk, you're most likely safer than you've ever been when you choose to ignore them. If a guy from the "IT" department calls up and says he needs your password so he can update your computer or you won't be able to get any work done the next day (and, as a consequence, you'll be in hot water with your boss and/or he'll have some explaining to do and he made an honest mistake when he overlooked you), suck it up and let him know that you're sorry (You're not, but it never hurts to be polite ;), but you can't give out that information without proper authorization and refer back to point 4.

Well, that's enough for today. Perhaps we'll come back to social engineering again. There's a whole lot more to it than what we've laid out here today, but it merits more than what I can put on this page without breaking my RSS feed again ;)

And, even though these examples are meant as weak allegories relating to Linux/Unix/Windows/Mac computer and network security, they're also meant as a few simple tips to help safeguard "you" and your personal information.

But, wait! Before you go, be sure to fill out the form below to get your free 97 page report on how to bake a cake that will make you millions on auto-pilot. Just be sure to include your name, social security number, mother's maiden name and a valid credit card to pay the 99 cents for shipping and handling ;)

Cheers,





...There's no form. Just kidding, of course :)

, Mike




Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Thursday, July 31, 2008

Insanely Securing Your Unix or Linux Systems

Hey again,

Since this week has been all over the map, I thought we'd spend today going back and dipping into the over-the-top-security well ;) You may recall a post from last year that we did on making generic user accounts su-only and, maybe even more so, a post we just recently did on using mkfifo and script to keep tabs on user account usage. Both of these were aimed at providing relatively decent security for the Unix or Linux admin, while allowing the user the freedom to do his or her job without too much of a hassle. Both of these posts assumed a box that had consistent user activity, but needed to be secured from those "ooops" moments that end up burning up your night-time hours and, possibly, creating a financial problem as well (most places I've worked have at least one box that is fairly lax, security-wise, but hemorrhages cash the instant it gets taken offline. The logic of maintaining the status quo in that situation baffles me. But I'm not rich and I don't own the company. I may be missing something ;)

With that in mind, and a grin in our heart, let's look at some other ways you have to secure yourself (and your machines) against misuse and/or abuse by users (and, of course, the innocent mistake made by someone with too much access). We'll assume that you've cranked up the user-account security to the relatively-user-friendly levels we set out in those previous security posts. Everything from here on out is above and beyond. Don't take too much of this literally (of course) unless you have to. Especially if you're walking into a situation where you'll be taking away freedoms users' have become accustomed to. You'll make bitter enemies and they will probably steal your sack lunch ;) This, I repeat, is all in good jest :)

Here are a few more suggestions to ratchet up the security level. We'll start out with the stuff that will be the least offensive to the end user.

1. Remove the additional line that allowed for additional profile sourcing that you added to each user's .profile/.bashrc, etc and don't allow them to set any environment variables through their root-owned and root-writable login profile. Now your users will have a .profile/.bashrc that they can only execute and read, but cannot write to. The final line that allowed them to create a separate file to set their own environment variables has been removed. You're control is slightly more defined now, but the user can still set all that stuff manually or just create a script and run it separately every time they log in. It won't take anyone long to develop a habit, or create an alias to make it even easier. If you want to avoid this nasty side effect, be sure to make the variables you set in the users' .profile/.bashrc "read only", so instead of:

PATH=/usr/bin

use

readonly PATH=/usr/bin

Results and methods will vary from shell to shell.

2. Take the idea of making generic accounts su-only one step further and start restricting access to the su binary as much as possible. If you can get away with it, ensure that your /usr/bin/su file is chowned to root:special and chmod'ed to 4750. Now only root and users who belong to the "special" group can even use su to do anything. Everyone else will get an error just for trying to run it. This has the potential to get some folks angry. And they may have a good point; especially if you've already made it so that they have to log in as themselves in order to su to a generic account that they need to work under.

At this point, I can see why the user base is fuming. You've made their lives impossible! You can get around this easily, though (on those machines where you have generic su-only accounts) by making use of file access control lists (or facl's as they're often cleverly referred to ;). We've only really touched on this once before on this blog, in our post on securing programs using FACL's, which may be a good reason to do a post on them in the near future. For now you should be able to get along by working with the facl on /usr/bin/su and allowing for another group to have write and execute permissions. The actual syntax varies between Linux flavours and Unix flavours, and the man page is always your best friend on this one, but you should be able to add an additional group (with read and execute privilege) to /usr/bin/su by executing the following command (or a variation thereof):

host # setfacl -m g:aGroupName:r-x /usr/bin/su

Be sure to check the permissions of /usr/bin/su after you've verified the new privileges using "getfacl." Sometimes, modifying a setuid root binary will unset the setuid bit and you'll need to just re-chmod it with:

host # chmod 4750 /usr/bin/su

3. Well, by this point you've managed to alienate almost everybody in your organization, but at least you have workable solutions that people will get used to over time. Now it's time to amp it up a few notches and become a walking target ;)

a. Implement s/key-opie type of one time password systems. If your setup isn't sophisticated enough to do that, set your default password length to the max it can be and require everyone to have to pick a new password every other day. Make sure you keep a password history for each user that goes back about 10 or 20 "unique" iterations.

b. Use chroot, or otherwise jail, everyone who logs in. If they need to login as a generic account, provide a separate su binary in their system root with access open only to them and root (using facl's).

c. Disallow all forms of network communication to and from the box except on port 22, if possible.

d. Read the post mentioned above and use extended facl's to lock down /dev/tcp and /dev/udp. Do it in chrooted environments individually, if possible.

e. Intermittently shut down the system (having setup syslog.conf to dump everything to /dev/null) and keep a backup stash of syslog, messages, etc, files that prove that the machine has been up since the beginning of time.

And, oh yeah, be sure to treat the guy who authorizes your paychecks very very kindly :)

Cheers,

, Mike

Saturday, June 28, 2008

Fight Phishing From The Unix Or Linux Command Line

Hey There,

This weekend, we're going to look at a little something (actually a HUGE something) that we all seem to have to deal with now (through email, IM, etc). It's called phishing and, for lack of a better explanation, it's a fraudulent way for a malicious individual, or group, to get username and password information from you using deceptive practices (was that redundant? ;) It's most commonly used to get information regarding a person's online bank accounts, credit card/mortgage management information, etc. In other words, stuff that could really screw up their lives if someone else had it.

First off, I'd like to be clear that I am "not against SPAM." As annoying as it may be, I don't begrudge anyone their right to send me a sales pitch, even if that product is a complete scam and I didn't ask to be pitched. I've been throwing stuff out that I get in my regular postal mail since I've been able to throw stuff out and I'm not sure if I've ever double-opted-in (the ethical way) or just had my address sold to some random company when it comes to internet SPAM.

Phishing, on the other hand, upsets me to no end. I do begrudge everyone their right to try and, literally, steal from others, using the internet. I feel the same way about the folks who used to steal carbons from credit cards (when that trick used to work... sadly, to a degree, it still does) and that other, more honest, faction of individuals who walk right up to the counter, point a gun in a bank teller's face and demand everyone else's hard earned cash. I'm not that this sort of activity should be encouraged, or glorified, in any way. I'm just saying it, at least, shows some character. If you're going to steal, and that's your business, why not come right out and say it? Only cowards pretend they're not pointing that figurative gun in your face and giving you a good mugging.

I can, literally, feel my email box filling with requests for password-resets at my bank of choice. Funny thing is, a lot of times, these clowns don't even bother to verify your personal information before they try and scam you. IMPORTANT NOTICE TO PHISHER'S WORLDWIDE: I do not have an account at the Federated Bank Of Hindustan. And, even if I did, it's been so long since I've attempted to speak Urdu that I can't possibly remember my clever username ;)

If you have the time and inclination to hurt these phishers, check out sites like The Anti-Phishing Working Group and PhishTank, and read up on how this whole operation works at sites like Security Focus. PhishTank actually even has a plug in for FireFox named Site Checker. Here's another site that provides a great list of possible phishing programs that may be running on your machine. The advantages that these organizations bring is that they don't merely do "anti-spam" work (which is, by all means, necessary and laudable). They actually collect data on phishing schemes, get to these people backward through their own chains of deceit and, if possible, have them put in cell block A (or wherever it is that they can legally squirrel away thieves and murderers - preferably together).

Unfortunately, though the calls-for-action are many, you should not expect any automated anti-phishing toolbars, etc, for your web browser. There's a very good reason why they're slow in coming out. Phishing is a lot like "social engineering," whereby a stranger attempts to extract personal information from you under a false pretense. Using this as an example, a stranger may also innocently request information you're not comfortable with giving under a legitimate pretense (?) or it all may be a big misunderstanding. This is why most phishing, SPAM and "social engineering" confidence violations are handled by manual submission or, at least, with some degree of user interaction. If you set Internet Explorer on auto-pilot to trash every site it thought was a phishing site, I'd bet about 50% of legitimately required bank (or other e-commerce) authorization, or confirmation, emails would end up getting skunked and ruin your web experience (and a few reputations in the process) very very quickly.

To wrap this all up (although it's certainly not the only solution), I prefer to use PhishTank since they have a very easy email submission process (You must register with them to send phishing complaints, and I encourage you to investigate their legitimacy on your own; but I like 'em a lot) which works whether or not you're sending them phishing information from your PC email client or from your Linux or Unix box (or any box that you may not have actually "received" the message on -- more below).

This is where the Linux and Unix command line comes into play. While you can easily forward an email from your mail client of choice to phish@phishtank.com (Not a mailto link on purpose), you will almost always lose some vital information in the forwarding. Instead I prefer to do the following:

1. From my email software of choice, view the entire email, including headers <-- Aside from the phishing URL, this is the most important part!

2. Log on to my Linux box (like I'm not already ;) and use any editor, like vi to paste the "entire contents" of the above output into a file.

3. Then, I send email to PhishTank using the customized email address that they've provided me. Their customized email address, for a user to send reports in from anywhere, is of the following format: phish-YOURACCOUNTNAME.YOUR_RANDOMLY_GENERATED_PHISHTANK_KEY@phishtank.com. Note that your randomly generated key will remain the same unless you want to change it. You can use any email client you like to send them the email, then. Assuming you put in it a text file called WTF, you might use mailx to send it, like so (Note that no Subject line is actually necessary):

host # mailx -s "Phishing Abuse Report" phish-YOURACCOUNTNAME.YOUR_RANDOMLY_GENERATED_PHISHTANK_KEY@phishtank.com < WTF

And, just like that, you've launched an investigation and, hopefully, put some purse-snatcher out of business.

And, lest it be said that I never said it, always double check any emails you receive from PhishTank, any bank, any service, even from me :) It never hurts to take a second and make sure you're not being scammed. The alternative can be devastating!

Best wishes,

, Mike

Tuesday, June 24, 2008

Linux And Unix System Security Wrap-Up - Part 4b

Hey again,,

Well, to run down the list once last time, this series of posts has gone through basic Linux and Unix installation security, even more security measures, user, group and account-based security, ensuring existing software's security and looking at additional security software. And now (finally? ;) we're ready to wrap it up by going over additional security software that you may (or may not) want to add to your list of always-installed security-enhancing programs, as well as a few extra thoughts on random things that didn't seem to fit anywhere else.

Be sure to check yesterday's system security post if you want to learn more about encap.

I'd love to be able to say that this is the end, but (like most things in life) hopefully this is just the beginning for many of you. There's always room for improvement ...I'm sounding like my Dad more and more every day ;)

Cheers,

9. Install John The Ripper:

Update /usr/dict/words (or your system's dictionary file) with a better wordfile.
Add “/usr/local/encap/jtr-VERSION/john.sh” (which you can grab from this post on password cracking software) to root's cron.

10. Install tripwire (This might be a bone of contention, since I still have a binary from when they used to give it out free on Solaris. As of my last test on Solaris 10, the last free release for Solaris still works adequately. If you want a copy of that last release, email us and we'll be happy to send it to you. If enough people are interested, we'll put it up here on the site along with instructions on how to get it up and running quickly and securely. It's always been free for Linux):

Copy installation binaries from the install cd, or the packaged version of the public domain software (hereafter referred to as PDSTW in parenthetical instructions).
Edit install.sh in the appropriate directory to set the base directory to /var/TSS (PDSTW - /var/tripwire).
If you’re unaware of the site and local key conventions used, please consult a member of your administration group before creating these (PDSTW - Unnecessary. Security is handled by permissions and ownership).
Create a policy file and configuration file from the examples provided with the distribution. Use other policy and config files for speed of application (PDSTW - Edit tw.config)
Edit your policy file (PDSTW – Edit tw.config) to remove any listed programs that no longer exist on your system.
Install policy and configuration files (PDSTW - Unnecessary).
Initialize the tripwire database (generally with "tripwire --init" You may need to specify -c with the location of the config file, as well).
Run tripwire.
Read the damage report.
Update the tripwire database, if necessary, and rerun until you’ve rectified all problems (PDSTW - Edit tw.config).
Add email functionality to your tripwire policy.
Reinstall the tripwire policy (PDSTW - Edit tw.config).
Add “/var/TSS/bin/tripwire --check --email-report >/dev/null 2>&1” to root's cron (PDSTW - add “/var/tripwire/tw-mailer”, or whatever you decide to call your script, to root cron).

11. Install Your Custom Log Management Scripts (These will, of course, vary, since you'll be putting all your log-rotating/removing scripts here. You wrote them, so, I can't name them specifically ;):

mkdir /var/logs

Copy over the logging encap package to /usr/local/encap.
Add all your log scripts to root's cron.
Add “/usr/bin/find /var/logs/ -type f –mtime +30 –exec rm {} \;” to root's cron, if you want to remove log files after they get a month (give-or-take-a-day) old.

12. Install EGD:

The entire program consists of one file: /usr/local/encap/perl-VERSION/bin/egd.pl
Create a startup script for egd and place it in /etc/init.d. Make appropriate links to it in /etc/rc2.d and /etc/rc0.d. (NOTE: This service must be initialized before SSH in the startup sequence. It should also be killed after SSH in the shutdown sequence. If you are using the OpenSSH/SSH that came with your system, this part doesn't matter)

13. Install OpenSSH (Version 5.0p1 or later):

The package you've put together should include OpenSSH, OpenSSL and zlib. Ensure all are available, or OpenSSH’s programs will not run properly
Review the documentation on creating host-keys.
Create host keys.

EX:
/usr/local/encap/openssh-5.0p1/bin/ssh-keygen -b 1024 -f /usr/local/encap/openssh-5.0p1/ssh/ssh_host_key -N ''; /usr/local/encap/openssh-5.0p1/bin/ssh-keygen -b 1024 -f /usr/local/encap/openssh-5.0p1/ssh/ssh_host_rsa_key -N '';/usr/local/encap/openssh-5.0p1/bin/ssh-keygen -d -f /usr/local/encap/openssh-5.0p1/ssh/ssh_host_dsa_key -N ''


Edit /usr/local/encap/openssh-5.0p1/etc/sshd_config. Set PermitRootLogin no, X11-Forwarding no and PrintMotd yes.
Be sure that all unnecessary r-services that can be replaced with s-services are not still functional on the machine.

14. Minimally setup ntpd or xntpd:

Create a startup script in /etc/init.d and link it to the appropriate place in /etc/rc2.d.
Add “/usr/sbin/ntpdate TIMESERVER >/dev/null 2>&1” to root's cron, unless xntpd has already been set up.

15. Install the tcp-wrappers encap package.

16. Install the wu-ftpd (proftpd, vsftpd, etc) encap package – if necessary.

Change the appropriate line in /etc/inetd.conf to use /usr/local/sbin/in.ftpd –da.
Edit /usr/local/lib/ftpd/ftpaccess to the particular machines specifications.

17. Install The Coroner’s ToolKit encap package.

18. Install the chkrootkit Root Kit and/or worm/trojan checking package of your choice (install two, they're free ;).

19. Install the Top encap package.

20. Install the environment-specific Perl package.

21. Install the lsof encap package.

22. Install the sudo encap package.

Set it up initially to allow no privileges whatsoever. Modify, per the sudo online manual pages, to suit your site requirements.

21. Build and install the Uptime (Big Brother, Nagios, cfenginge or other monitoring software) client for your server. This will most likely be provided to you in pkg format.

22. Install the NetBackup client, or whatever backup software is necessary for the environment your machine exists in and be sure to coordinate your efforts with the administrator of the backup host you will be using.

23. Build and install any additional packages required by your particular environment. Be sure to build them to encapped specifications so that you can manage all software centrally and with greater ease.

24. Remove any unnecessary packages on the machine. This may be a double or triple check for you ;)

25. Edit /etc/vfstab on Solaris (/etc/fstab on RedHat) to mount /usr read only (Only if the machine is not heavily developed upon and /usr is a separate mount point and is not being used to house any files of a volatile nature, such as if /usr/local/ does not have its own mount point).

26. Lock passwords (e.g. passwd –l accountName) for bin, sys, adm, daemon, nobody, nobody4, noaccess and any other system accounts that do not have password locking on by default. This is a double check, again, but during the course of customization things may have been added that weren't on your system initially. Best bet, since the default system accounts differ based on OS version, is to cat /etc/passwd and lock passwords for all accounts with a UID under 100, except for root, of course. On RedHat and Open Solaris, be sure to check above uid 100, too)

27. chmod 4550 /usr/bin/su – generally only on administration-team-owned or production machines – otherwise make sure permissions are 4755.

28. chown root:yourAdminGroup /usr/bin/su – generally only on administration-team-owned or production machines – otherwise make sure ownership is set root:other on Solaris or root:root on RedHat.

29. If running a web server, be sure to include the following lines (Apache specific – use equivalent for Netscape, Tomcat, JBoss, etc) to the main directory directives:

<Limit GET POST OPTIONS PROPFIND>
Order allow,deny
Allow from all
</Limit>
<Limit PUT DELETE PATCH PROPPATCH MKCOL COPY MOVE LOCK UNLOCK>
Order deny,allow
Deny from all
</Limit>
Order allow,deny
Allow from all


30. Create additional init scripts for any products that need to start up at boot time (i.e. Interbase, Uptime, Oracle, NetBackup, etc. This may be obviated by your Jumpstart or Kickstart image but may be necessary (on a per-software-package basis) if doing a manual installation).

31. Reboot the Machine over and over again, while keeping tabs on your console output, until you're satisfied that you've done your best :)

Excellent Job! :)

, Mike

Monday, June 23, 2008

Securing Your Linux Or Unix System - Part 4a

Hey again,,

Well, so far in this series we've hit upon basic Linux and Unix installation security, even more security measures, user, group and account-based security and ensuring existing software's security. Today, we're going to continue by going over some additional security software that you may (or may not) want to add to your list of always-installed security-enhancing programs. This post, like the basic Linux and Unix installation security post, is going to end up being a two-(long)-parter. If only I planned my writing before I sat down and wrote these little novels... ;)

Cheers,

OS Installation Guidelines, Part 4: Additional Software Installation

Note: Our assumption here is that you've built your additional custom software to live in /usr/local/encap/PRODUCT-VERSION and packaged your it using a program called encap, originally developed at UIUC by a former manager of mine, who's name I will not mention because I haven't seen him in a long time and I don't publish anything personal about anyone else but me on this blog (unless they want me to ;) If you're reading this, you know who you are and my hat's still off to you, sir. Thanks for politely kicking me in the arse until I got my act together ;) I'm actually super-old-school on this, install all my custom software in /usr/local/encap, prefer version 1.2 (encap.pl) and haven't ever had the need to complicate my life with any of the newer versions. They should all be available for download from the above link, including instructions on proper usage.

Apologies for getting misty up there ;) Aside from our assumption, which will explain some of the instructions, any (or all) of this can be handled by Solaris pkg's or RedHat RPM's (rolling your own is my preference if I go down that road, but, these days, the products that come out are usually good enough if you're okay with "default build options"). The relative pro's and con's of using encap or epkg vs. regular packages are listed at the encap FAQ.

Note, also, that any packages for which there are no additional instructions do not require any additional setup, necessarily.

1. Clean up the /usr/local area as well as possible:

Remove all compilers (preferably, build the software on a different machine, or just clean up when you're done) if the machine is on our network’s perimeter. Be sure to check if they were installed, using pkginfo on Solaris or rpm -qa on RedHat, so you can remove them that way.

Remove any unnecessary programs, or rebuild them in encapped form before deleting them. If you do build new packages in encapped form, follow the same process as building any encapped software and place it in the /usr/local/encap directory.

2. Install encap to place software –

mkdir –p /usr/local/encap

3. assuming that you've built everything on another server, unpack your compiled software bundle into /usr/local/encap. A good collection of packages might look something like this, and then some (Note that a lot of these programs are included with Solaris 10, Open Solaris and RedHat, but have been included for folks still using older OS versions):

encap-1.2.
cops.
tcp-wrappers – tcpd.
chrootuid.
skey.
lsof.
gzip-gunzip.
John The Ripper.
Log management scripts.
Perl – Statically stripped in production environments.
egd – Entropy Gathering Daemon.
Open-SSH (Compiled to use EGD).
wu-ftpd or similar ftp server (if necessary).
The Coroner’s ToolKit (TCT).
top.
ntpd/xntpd
sudo
chkrootkit-latest-version (Or latest revision)


4. Create a file called /usr/local/encap/encap.exclude, which should include the lines:

cops
jtr
tct
tcp-wrappers
chkrootkit-latest-version


5. Run:

/usr/local/encap/encap-1.2/bin/encap.pl /usr/local/encap /usr/local

NOTE: You really don't need to run this command until you have successfully installed all of the packages per the instructions following for each. If you do, you will need to re-run it once you’ve completed your installations to ensure that all the links get made (or removed) as necessary.

6. Install cops:

mkdir /usr/local/encap/cops-VERSION

Copy your entire cops distribution to this directory.
Edit /usr/local/encap/cops-VERSION/cops and ensure that the secure directory is set to /usr/local/encap/cops-VERSION, the MMAIL variable is set to YES, the ONLY_DIFF variable is set to NO, the RUN_SUID variable is set to YES and the secure user is set to yourAdminGroup@yourhost.com.
Edit the cops executable script. Look for this section and add the noted line if it does not exist already:

if $TEST ! -s $RESULT".FILT" ; then
$RM -f $RESULT
$RM -f $RESULT".FILT"
<--- Add this line so your directory doesn't fill up with useless files.
exit 0
fi


Run cops.
Fix reported problems
Run cops again.
Repeat until you’re left with a report you can live with.
Run /usr/local/encap/cops/cfm (a script you can grab from this previous post on how to create a cops filter file).
Add “/usr/local/encap/cops-VERSION/cops –f /usr/local/encap/cops-VERSION/cops_filter” to root's cron.

7. Install the gzip-gunzip encap package.

8. Install S/key (configure only if not a heavy-user machine or if the machine acts as a login gateway) – (Check out the s/key entry in Wikipedia for lots of links to downloads and explanations of this one-time-password system. OPIE, SecuRemote, and others are all equally worthwhile but s/key is about the cheapest you can get (Free!!! :)

Run “keyinit username” for all user accounts except root and system accounts.
Change all user account login shells to /usr/local/bin/keysh.

to be continued...

, Mike

Sunday, June 22, 2008

Linux and Unix Software Security Basics - Part 3

Howdy,

Continuing along, following our first 3 posts on basic Linux and Unix installation security, even more security measures and user, group and account-based security, we're ready to move on to the next section. Today, we'll be focusing more specifically on locking down and/or removing existing software on your newly-installed system.

Again, I hope this series of posts is able to help out, if just a little bit, and I welcome any suggestions for improvement or expansion to include other OS's :)

See you tomorrow for the wrap-up!

Cheers,

OS Installation Guidelines, Part 3: Existing Software Modifications

1. chmod o-w /var/adm/utmp, /var/adm/wtmp, /var/adm/wtmpx, /var/adm/utmpx - any and/or all on Solaris. On RedHat, these files should be in /var/log. If only one of the four files exists, you're okay.

2. touch /var/adm/loginlog.

3. Add “/usr/lib/acct/accton /var/adm/pacct” to /etc/init.d/syslog, if possible considering the caveats in our previous posts. Again, this is only necessary on Solaris. The psacct RPM for RedHat should take care of this for you.

4. chmod 0 /usr/bin/at or /usr/sbin/at.

5. chmod 0 /usr/bin/finger or /usr/sbin/finger.

6. rm /etc/acct/holidays (If this generates errors, just create a file with one line, indicating what year it is).

7. chmod o-rwx /etc/security. On RedHat, or Solaris with PAM enabled, limit access to /etc/pam.d, as well, if possible.

IMPORTANT NOTE: For points 8 through 15, the file locations are general and your particular release of either Solaris of RedHat may place the binaries elsewhere, but you can generally find them in one of the directories we go through in these steps. It should also be noted that, removing the pkg's or RPM's associated with these files should have, theoretically, removed them already, but I don't believe in things working the way they should (a hazard of my profession ;) Obviously, if you're using lp or CUPS, you won't want to delete any of the print commands. For all of these steps, my recommendation is to always ask if you're unsure. If I started a new job and removed all the NIS commands on a box and then found out that's what they used for their directory service... ouch!

8. In /usr/bin, rm if necessary and possible (ask first, if unsure):

cu
disable
enable
tip
uucp
uuencode
uudecode
uuglist
uulog
uuname
uupick
uustat
uuto
uux
cancel
lp
lpget
lpset
lpstat
rsh
<--- The remote shell as opposed to restricted sh!
rdate
rdist
rcp
remsh
rlogin
rup
ruptime
rusers
rwho
yppasswd
nispasswd


9. In /etc, rm if possible (ask first, if unsure):

–r lp
–r uucp


10. In /usr/lib, rm if possible (ask first, if unsure):

accept
–r lp
print
reject
lpadmin
lpfilter
lpforms
lpsched
lpshut
lpmove
lpsystem
lpusers
–r uucp
–r nfs
–r netsvc
rsh


11. In /usr/sbin, rm if possible (ask first, if unsure):

lpmove
lpadmin
lpfilter
lpforms
lpshut
lpsystem
lpusers
accept
reject
sadmind


12. For /usr/sbin/in.*, remove all except the following files, if possible (ask first, if unsure):

in.ftpd
in.telnetd
in.rarpd


13. In /usr/sbin/static (on Solaris only), rm if possible (ask first, if unsure):

rcp

14. In /usr/ucb (also only on Solaris), rm if possible (ask first, if unsure):

lpc
lpq
lpr
lprm
lptest
rcp
rdate
rdist
rlogin
rsh
ruptime
rusage
rwho


15. In /var, rm if possible (ask first, if unsure):

–r lp
–r uucp
–r spool/lp
–r spool/uucp
-r spool/print


16. Comment out all of /etc/rpc except the rpcbind line. NOTE: If using Solstice Disk Suite (Volume Manager) software, do not comment out the following lines (on Solaris 9 leave all lines uncommented near the bottom of the file, beginning with the line for metad and ending with the last line of the file). As always, be sure not to comment out any services you really need:

rpc.metad
metad
rpc.metamhd
metamhd


17. chmod –R 0 , if possible, /usr/openwin/bin/* on Solaris and /usr/X11R6 on RedHat.

18. chmod –R 0 , if possible, /usr/dt/bin/* on Solaris. Additional locations of X-Windows binary files might be in many different locations on RedHat. Check out the man pages for your system and Gnome, KDE, etc, to be sure that you're disabling all access to the GUI.

19. All device files have should have good permissions at first. Do not change them unless it's really necessary or you're looking to do enhanced network security of the order we went over in an older post on securing all network programs at once using extended ACL's. That goes a bit beyond the scope of this series ;)

to be continued...

, Mike

Saturday, June 21, 2008

Security Basics For Linux and Unix Installations - Part 2

Hey there,

Following up on our first two posts on basic Linux and Unix installation security and even more installation security measures, we're going to move on to the next section. Today, we'll be focusing more specifically on user, and group, accounts, and modifications that we want to make in that arena.

Again, this series of posts is based mostly on Solaris Unix and RedHat Linux, so it can't possibly apply to everything. I welcome any comments regarding it, especially as they pertain to additional security and other Operating Systems. Just to be clear, also, we won't be touching on more advanced stuff like setting up firewalls, etc. The summary of this 5-part post should end up being a bullet list that you can run through and take care of without having to go too crazy ;)

And, of course, my suggestion, to everyone who has the rights and means, is to script out as much of this method as possible. However you end up securifying your system, once you have your routine down, having Jumpstart or Kickstart do it for you from then on out is much less of a hassle (usually :)

See you tomorrow for section 3!

Cheers,

OS Installation Guidelines, Part 2: Users and Accounts

1. Add accounts for all necessary users. Require valid reasons for all accounts created.

2. You can ignore this step if you're using Solaris or RedHat's OpenSSH pkg or rpm, since it will be complete already: Be sure to add a user account for sshd. This will be required for our OpenSSH to run correctly. Should be as simple as

host # useradd –m –d /users/sshd sshd
host # passwd –l sshd
<--- (The passwd –l just locks the password so no one can login to the account. This is okay, since the sshd account is only necessary for privilege separation.

IMPORTANT NOTE FOR POINTS 3 THROUGH 6 REGARDING USER REMOVAL: Please note that for point three, we specify "userdel -r," because these users have home directories that are NOT "/" - If there is any doubt in your mind that an account you want to remove has the root filesystem as its home directory, use "userdel" without the -r, as use of that flag may effectively destroy your system. An easy way to find out what a user's home directory is involves simply grepping the username out of /etc/passwd and checking out the second to last field.

3. userdel –r lp, uucp, nuucp, some, all or more if possible (the nobody account should be removed, too, unless it’s used by a web server or some other application). Note that your list will be larger on RedHat since they generally have a user for every service and you should remove every user for every service you're not using if it wasn't removed by rpm -e. Also, on Redhat, be sure to check for matching entries for the user in /etc/group

4. userdel nobody (This should not be removed if it’s used by a web server or some other application)

5. userdel smtp (Non-existent in Solaris9).

6. userdel mail (Non-existent in Solaris9).

7. chmod 700 all user directories.

8. Comment out gsscred and nfsfind from root cron on Solaris. Delete sys, lp, adm, root.au, uucp and all unnecessary crontabs, if possible.

9. Add “0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/lib/sa/sa1” and “59 23 * * * /usr/lib/sa/sa2 -b -g -r –u” to root's cron. On RedHat you'll need to have the sysstat RPM installed in order to use sar. If it "is" installed on Redhat, check out /etc/cron.d to make sure that it is being run in cron and modify the setup per above, to increase or decrease the number of times it runs, if you need to.

10. Create the directory /var/adm/sa (/var/log/sa on RedHat) if it doesn't exist, and chown it to root:yourAdministratorsGroup. Then chmod the directory to 660.

11. Add “/usr/lib/acct/ckpacct” to root's cron on Solaris, if the machine does not have high user activity and has adequate disk space for logging. Remove any other /usr/lib/acct lines in the Solaris root crontab. For RedHat users, make sure that you have the psacct RPM installed. The default settings should be okay and you can use chkconfig or ntsysv to ensure that process accounting is set to run at boot time.

12. Remove user directories for users who no longer have accounts on the machine.

13. Remove crontab entries in /usr/spool/cron/crontabs (Solaris) or /var/spool/cron (RedHat) for users that no longer have accounts on the machine.

14. Add empty .rhosts, .netrc and .exrc files in all user home directories.

15. chmod 0 and chown root all user .rhosts, .netrc and .exrc files.

16. userdel (–r, if their home directory isn’t "/" ) all users, aside from root, with uid 0.

17. Change the group for any user (other than root) that has a gid of 0, if possible.

18. Be sure to include a umask of 022 in any user’s .profile if their account will require their home directory to be somewhat publicly available. Examples of such an accounts include development or group-based accounts. These kind of accounts are used to ease the ability of a group to work together. Of course, the standard 027 umask would make this impossible. Please use discretion and do this only for accounts where the need is real.

19. For all generic accounts, make them su-only. You can find detailed instructions on how to do this, including some pitfalls and stumbling blocks you may encounter, in our post on making generic accounts su only. As luck would have it, it's still aptly named ;)

to be continued...

, Mike

Friday, June 20, 2008

Installation Security Baselines For Linux and Unix - 1b

Hey there,

Following up on yesterday's beginning of our five part post series on basic Linux and Unix installation security, we're going to complete the initial installation guidelines today. I'll dispense with the fancy rhetoric, and if necessary, apologize for the length of yesterday's post (and today's ;). Although this list is, without a doubt in my mind, incomplete in many ways, I hope that some of you out there find it helpful. If even one suggestion gives you a boost, all this typing is worth it :)

I'll see you on the other side, or when part 2 on user account security comes out tomorrow. Hopefully, given the general connotation of the phrase I just used, it will be the latter ;)

Cheers,

For the initial "default value steps," there are many different default script locations (as well as /etc/xinetd.d), where you can set many of these - through step 25 - on Redhat. I think the most important thing to note is that we're hammering down the umask setting and default paths wherever possible.

20. Set the following values in /etc/default/login (leave all else):

PATH=/bin:/usr/bin
SUPATH=/bin:/usr/bin:/sbin:/usr/sbin
TIMEOUT=300
UMASK=027


21. Set the following value in /etc/default/passwd (check your password policy for setting expiration, etc):

PASSLENGTH=8

22. Set the following values in /etc/default/su (leave all else):

CONSOLE=/dev/console
PATH=/usr/bin:/bin
SUPATH=/usr/bin:/bin:/usr/sbin:/sbin


23. Set the following value in /etc/default/sys-suspend (leave all else):

PERMS=-

24. Create /etc/default/telnetd with the following contents, if this is a box that you own:

BANNER=”\nThis computer is the property of YOURCOMPANYNAME HERE.\nUnauthorized use is expressly forbidden. Violators\nwill be prosecuted to the full extent of the law.\n\n”
UMASK=027


25. Create /etc/default/ftpd with the following contents:

BANNER=”Unauthorized access prohibited”. This will basically be obviated by wu-ftpd (and other, more secure ftp servers), but should be kept in case of any situation which requires you to revert back to the original in.ftpd.
UMASK=027


26. Create /etc/issue (along with /etc/release, /etc/redhat.release, /etc/issue.net and any other issue/release files you may have) with the following contents, if this is a box that you own. The return before the closing double quote is necessary on most systems for the output to format correctly and not bleed into whatever comes next:

“This computer is the property of YOURCOMPANYNAME.
Unauthorized access is expressly forbidden. Violators
will be prosecuted to the full extent of the law.
“


27. cp /etc/issue /etc/motd.

28. Run /etc/security/bsmconv on Solaris. To achieve the same effect on RedHat, add the line "audit=1" to your grub.conf or supply it to grub on the command line. Also, for Redhat, this makes step 29 unnecessary)

29. Add all user accounts on Solaris to /etc/security/audit_user with attributes username:lo:no (NOTE – Please be sure to add and remove users from this file henceforth whenever adding or deleting an account on the system!!!)

30. If possible, within system’s application, add empty .rhosts and hosts.equiv in / and /etc respectively, and chmod 0 and chown root the .rhosts and hosts.equiv files.

31. If possible, within system’s application, add empty .netrc and .exrc files in /. chmod 0 and chown root both.

32. If possible, within system’s application, add empty netrc and exrc files in /etc. chmod 0 and chown root both.

33. Edit /etc/init.d/inetsvc to bring up inetd with –st flags (Use -sd for xinetd). Also, add the following code snippet to the end of inetd's, or xinetd's, init script and disable the specific system auditing user's crontab if possible (On RedHat this may end up in the /etc/cron.* directories). Note that for RedHat, we should use /var/log rather than /var/adm:

if [ ! -d "/var/adm/sa" ]
then
mkdir /var/adm/sa
fi
chown root:itopsgroup /var/adm/sa
chmod 644 /var/adm/sa/*


34. Uncomment “enable-cache hosts no” line in /etc/nscd.conf. Add “enable-cache passwd no” and “enable-cache group no”, also.

35. If not running Solaris 7 or higher, uncomment savecore in /etc/init.d/sysetup. For RedHat, ensure that you have the diskdumputils RPM installed.

36. Create /etc/ftpusers. Include all accounts except administrators, if possible. Definitely include all generic accounts. Otherwise, it should include root and all system accounts. This will basically be obviated by wu-ftpd (and other more advanced ftp software), but should be kept in case of any situation which requires us to revert back to the original in.ftpd.

37. Create /etc/hosts.allow and /etc/hosts.deny files. If possible, limit the hosts that are allowed to connect by subnet or domain (By IP would be great, but probably impractical). Otherwise, create placeholder files to generate tcpd logging (e.g. ALL:ALL). NOTE: Remove X-11 Forwarding if it is present and you can afford to.

38. Set the following parameters in /etc/profile or /etc/bashrc (add or mix around to suit your needs). Many directories listed are specific to Solaris. Your best judgment on what should be in the default PATH, MANPATH and LD_LIBRARY_PATH variables should be enough to guide you on this part. Everyone's setup is probably different:

PATH=$PATH:/bin:/usr/bin:/usr/local/bin:/etc/vx/bin
umask 027
MANPATH=$MANPATH:/usr/man:/usr/local/man:/usr/share/man:/usr/openwin/man:/usr/dt/man:/opt/VRTSvxvm/man
LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/share/lib:/usr/openwin/lib:/usr/dt/lib
EDITOR=vi
export PATH MANPATH LD_LIBRARY_PATH EDITOR


39. Add administrators group (groupadd –g 666 itopsgroup).

40. Add administrators to the administrators' group.

41. Add additional interface files, if needed, in /etc (e.g. /etc/hostname.hme1 on Solaris or /etc/sysconfig/network-scripts/ifcfg-NICNAME on RedHat).

42. Add two lines containing “set noexec_user_stack=1” and “set noexec_user_stack_log=1” to /etc/system on systems up to and including Solaris version 9. You can still add this in 10, but in later versions of 9, and in 10, this isn't necessary any more. For RedHat, consider using something like execShield or your alternate preferred method to prevent buffer overflow attacks system-wide.

43. Set hostname to the simple, unqualified hostname, rather than the FQDN, if possible.

to be continued...

, Mike

Thursday, June 19, 2008

Basic Installation Security Guidelines For Linux and Unix - Part 1a

Hey there,

Today we're back at the concept-well, and starting out a five part post on setting up a Unix or Linux system securely. This should be an interesting series of posts since I (like most folks, probably) haven't worked with every flavour of Linux or Unix out there, so this set of guidelines is more of a "rough draft" based on experience with Solaris and RedHat servers than an attempt to encompass all areas of system installation, setup and security on every possible OS. Doing so would either be incredibly vague or unbelievably presumptuous. Probably, both ;)

With that in mind, we'll get going with part 1a. Setting up the basic system and keeping it clean from the start. If you're a big fan of numbered lists, you're gonna love this post ;) Hopefully, this post (and the following to come) will generate feedback from users of other systems - or these same systems running different versions - and become a nice broad-but-useful guide to system setup and security!

Best wishes,

OS Installation Guidelines, Part 1a: Basic Setup and System Security Steps (1 of 2... as in too many to fit on one reasonably sized page ;)

1. Create a list of functions the machine will be expected to perform and the services required to fulfill those needs. Also create a map of partitions you expect to use on the disks you have available.

2. Install the basic Operating System. NOTE: If you will be using disk management software (e.g. Solstice Disk Suite, Volume Manger, LVM, Veritas Volume Manager, etc), be sure to read the documentation for these packages before doing your OS install. Most of these types of packages require free partitions to store their disk management data.

3. Download the latest Recommended Patch bundle from sunsolve.sun.com for Solaris machines. Also download the Security Patch bundle if this exists separately. Install both and reboot the machine. For Redhat, do a complete up2date run-and-reboot cycle as many times as necessary.

4. Comment out the following files in /etc/init.d (Some filenames may vary or not exist, depending on what OS you're installing. For an easy way to comment out base init.d files, assuming they're linked to run level directories, check out our old post on editing startup scripts with the vi editor. Don't let the Solaris brand name in the post put you off. It works for any OS on which you can run vi) - Note, also, that this list is pulled from a Solaris box and your security standards may require removing even more. As a general rule, if you don't need it, disable it! RedHat users can do this with chkconfig or ntsysv more easily. Solaris 10 user can make use of the svcs and svcadm commands):

a. acct ( since we prefer to control the process accounting ourselves).
b. asppp ( if we won’t be hooking up a modem to do ppp dialups to the machine).
c. autofs (if automounting not necessary)
d. autoinstall (if machine is not a bootp client)
e. cachefs.daemon (if you will not be using nfs’s cachefs subsystem)
f. cachefs.root (if you will not be using nfs’s cachefs subsystem)
g. cacheos (if you will not be using nfs’s cachefs subsystem)
h. cacheos.finish (if you will not be using nfs’s cachefs subsystem)
i. dhcp (if machine is not a dhcp server or client)
j. dtlogin (if software in use does not require X-windows default login - Removing this will not remove X-windows functionality)
k. init.dmi (if machine will not be availing itself of snmp management)
l. init.snmpdx (if machine will not be availing itself of snmp management)
m. initpcmcia ( if the machine has no pcmcia devices).
n. lp (if print services are not required)
o. mkdtab ( this script runs after installation and is never used again).
p. nfs.client (if the nfs client subsystem will not be required)
q. nfs.server (if the nfs server subsystem will not be required)
r. pcmcia (if machine has no pcmcia devices)
s. power (if machine doesn’t use individual ups power management)
t. rpc (if machine will not be using rpc services) (If the machine will be using rpc services, comment out all of the start section of the script, except for the rpcbind initialization. All other parts of this section initiate nis services, which aren't necessary if you don't use nis :)
u. sendmail (if machine will not need to be a mail receiving agent.)
v. sshd (if you'll be installing you own ssh to maintain flexibility to be more up to date with any security releases).
w. spc ( if print services are not required).
x. uucp ( if you won’t be making use of the uucp subsystem).
y. xntpd (if machine will not serve as a time server or be doing persistent ntp scanning)
z. PRESERVE (this invokes /usr/lib/expreserve, which has a known buffer-overflow bug).
aa. README (read it first, if you like).

5. rm /etc/init.d/*.old

6. Check in /etc/rc0.d, /etc/rc1.d, /etc/rc2.d and /etc/rc3.d (or your system specific run level directories) for any old links to nonexistent files. Delete these.

7. Check in the rc directories, also, for files beginning with X or lowercase s or k. Delete these files as well.

8. If sshd is running, stop it. If you don't plan on using Sun's or RedHat's packaged ssh, we'll be replacing this later. You can leave it if you like.

9. Run /etc/init.d/openssh (or /etc/init.d/sshd) start to start OpenSSH.

10. Connect to the machine via ssh to continue executing the steps in this document. This way you won’t have to worry about poor console terminal emulation creating any accidental errors in the files you will be editing.

11. After installation, ensure that all unnecessary processes have been disabled, using a simple scan of ps output, and disable any that are running and not necessary (sendmail, for instance, is a program that is notorious, on Solaris, for being reactivated as a mail sending agent after patching and/or updating!)

12. Next, be sure to check the network interface. Many of the Sun machines come with all the network ndd settings enabled, which can cause problems with some routers, which are pinned to certain speeds and don’t auto-negotiate. RedHat user's should have been asked about what network settings they wanted to enforce during installation. If not, ethtool can be used to force the required speed/duplex setting Do the following to test:

i. ftp, or scp a file from somewhere, or to somewhere over the network

ii. Run netstat –ian and check the Collisions column. This should still be at 0 for the network interface. If it isn’t, you’ll need to augment the /etc/init.d/nddconfig script, use nddconfig or (for RedHat) use ethtool (and double check the /etc/sysconfig/network and /etc/sysconfig/network-scripts/ifcfg-NICNAME files) to suit the machine and/or environment.

iii. Should you need to fix the interface, so that you get zero collisions (which collisions should, theoretically be impossible on a packet-switched network) and ensure maximum speed without any dropped packets, refer to your system's, or department's documentation. There are really no generalities that can be put to paper here. In my experience, Solaris Gig NIC's usually require auto-negotiation at the switch (for Cisco's) and adv_autoneg_cap set to 1, with all other configurable parameters set to 0, in order for them to work, while old hme interfaces require that the switch be pinned to 100mb and only the adv_100fdx_cap be set to 1 in order for them to function properly. Cut and paste the contents into /etc/init.d/nddconfig after the case/esac clause and before the exit command to ensure the configuration happens at boot time. For RedHat, update the /etc/sysconfig/network and /etc/sysconfig/network-scripts/ifcfg-NICNAME files if necessary). If hme0 gives you a really big headache on Solaris, check our older post on disabling network devices at the PROM level.

13. Comment out every unnecessary line in /etc/inetd.conf (or delete or set to "off" all unnecessary files in /etc/xinetd.d), particularly the unnecessary r-services, and ensure that all services, where applicable, are managed through tcpd – ensure that telnetd is enabled as a backup during install (but, only if you plan on using a custom SSH later, and then just in case)

Ex: ftp with: /usr/local/encap/tcp-wrappers/bin/tcpd and /usr/sbin/in.ftpd –d as the file and args.

14. Add loghost to /etc/syslog.conf: (NOTE: It is imperative that a tab, and not a space, separate the list of facilities-severities and the hostname of the remote logging host or target file!) Also Note that, at this point, if you do NOT have a syslogging server dedicated and set up, you do NOT have to complete this step (not at all, if you don't plan on using one):

*.err;*.emerg;*.crit;*.alert;mail.debug;kern.notice;auth.notice;auth.info @loghost.xyz.com
*.err;kern.debug;daemon.notice;mail.crit;auth.notice;auth.info /var/adm/messages


Also be sure to change any references to /var/console to /var/adm/console on Solaris or /dev/console on RedHat.

15. Configure sendmail to use its relay properly, if you are going to use it to send mail out. If the machine is an email server; that’s another story. NOTE: If running sendmail v8.8.8 or earlier, be sure to reverse the ruleset for S94 to ensure proper masquerading of envelope addresses from the host, if you have that feature enabled!

16. Set up networking and name services minimally:

a. Create /etc/hosts with loopback, host, logging host , default router, nameserver, and mail host information if applicable. (Note: When entering host information, ensure that the first entry in the host field is the fully qualified domain name. This is a pet peeve of mine. You can do the simple hostname first and then the FQDN. Preferably, list them both for each IP.)

b. Create and populate /etc/defaultrouter or set the DEFAULT_GATEWAY value in either of the /etc/sysconfig/network and /etc/sysconfig/network-scripts/ifcfg-NICNAME files on RedHat.

c. Edit /etc/nsswitch.conf to use "dns [ NOTFOUND="continue"]" for hosts. If you don't set NOTFOUND, the default value is "return" and this can cause issues with telnet and ftp hostname lookups, etc.

d. Create and populate /etc/resolv.conf.

17. If host is multi-homed, disable IP-forwarding by creating /etc/notrouter on Solaris. Do "echo 0 > /proc/sys/net/ipv4/ip_forward" on RedHat to disable packet routing/forwarding.

18. If possible, trim /etc/mail/aliases to include at least (and, maybe, at most) the following (be sure to execute newaliases if any changes are made):

Postmaster: root
MAILER-DAEMON: root
nobody: /dev/null
root: itopsgroup@xyz.com
itopsgroup: itopsgroup@xyz.com


19. Create /etc/shells with these contents (remove any shells you don't want to be run on your system and add any, that I forgot to include, that you do!):

/sbin/sh
/bin/ash
/bin/sh
/bin/csh
/bin/ksh
/usr/bin/ksh
/bin/false
/bin/bash
/bin/zsh
/usr/local/bin/keysh (Only include if using keysh on system)


To be continued...

, Mike