Saturday, November 21, 2009

Ubuntu & The Nobody User

There are certain programs that run on linux which require a nobody user in order to work.  It's also a good idea to have a nobody account if you want to assign files to someone that no long needs access on the system and you don't want to delete their files just yet.  With Ubuntu their default for the nobody user is to assign them a shell.  This is a bad idea as it leaves a user account open to brute force attack.  This may also be the case on other distros as well however I have only been using Ubuntu as of late.  A quick for this is to just change the login shell of the nobody user.  We can do this by editing /etc/shells and adding the following line to the end:

/dev/null

Save the file and run the following command to change the shell of the nobody user.

sudo chsh -s /dev/null nobody

While this doesn't bring a huge overhaul to system security it does help prevent attacks against the nobody account.

Wednesday, November 18, 2009

MySQL Security

Yesterday I talked about SSH security in relation to a security audit that I was conducting of our internal network.  I also know that we have database systems on our network (MySQL) and I needed a way to also check for either default credentials that were left when the system was setup or a way to bruteforce weak passwords.  Well a little time with python and I managed to write a script that will do everything I needed.  The script requires the MySQLdb package in python (which throws a warning that it is deprecate, but it still works fine).  You might also want to put together some word lists for username/password combination's if you plan to use the brute forcing feature.

import MySQLdb
import sys

user_list = []
pass_list = []

def mysql_connect(u, p, ip):
        try:
                print "[+] Attempting Connection..."
                db = MySQLdb.connect(user = u, passwd = p, host = ip, connect_timeout = 5)
                print "[+] Connection Successful!\n"
                print "[+] ----------------------------------------"
                print "[+] Username: ", u, "  Password: ", p
                print "[+] IP: ", ip
                print "[+] Server Info: ", db.get_server_info()
                print "[+] ----------------------------------------"
                db.close()
                print "[-] Connection Closed\n"
                exit(0)
        except Exception:
                print "Access denied\n"
                print u, " | ", p
                print ip
                pass

# Begin main program
print ""
print "+--------------------+"
print "| MySQL Scanner v1.0 |"
print "| Written by Damian  |"
print "+--------------------+"

if(len(sys.argv) == 2):
        print "[+] Setting up default credentials list\n"
        user_list = ["admin", "administrator", "root"]
        pass_list = ["password", "admin", "", "locked"]
elif(len(sys.argv) == 4):
        print "[+] Building word list\n"
        f = open(sys.argv[2], 'r')
        for line in f.readlines():                     
                user_list.append(line)
        f.close
        print "[+] Building password list\n"
        f = open(sys.argv[3], 'r')
        for line in f.readlines():
                pass_list.append(line)
        f.close()

else:
        print "\nUsage:"
        print "\tsql_scanner.py [host]"
        print "\tsql_scanner.py [host] [word_list] [password_list]\n"
        exit(0)

ip_address = str(sys.argv[1])

for x in user_list:
        for y in pass_list:
                mysql_connect(x, y, ip_address)

print "Scan Complete\n" 
  

Tuesday, November 17, 2009

SSH Security

While working on an internal security audit I was looking for everything that I can relating to SSH.  SSH is used on all our non-windows servers for remote management and therefore we needed to make sure that everything is secure and updated frequently.  The best way I find to go about auditing things is to always have a plan in place first.  First thing on the list was to perform a visual inspection of the config files to make sure that things were configured correctly.  I was looking for the following during visual inspection:

  • A copy of the original config file accessible by only the root user
  • The listen address was configured correctly
  • The protocol was set to 2 (version 1 has many vulnerabilities)
  • The port which the SSH server is listening on (for extra security make it non-standard)
  • For security reasons, also ensure that X11 forwarding is off unless absolutly necessary

After these things have been confirmed and documented, I moved on to password cracking to ensure that all users are using strong passwords.  For this I used brutessh which you can grab [http://www.edge-security.com/edge-soft.php].  This program is written in python and is very quick and efficient.  For input you will need a username and a password list for the program to use.  I ran this against all our severs with SSH providing the list of our users:

python brutessh.py -h 192.168.1.10 -u [username] -d [wordlist.txt]

After a few runs it returned only one user that was using a dictionary password.  If it does find a password for a user it will return green text along with the password that worked.  I was also careful to take note of the log messages that it was producing given that it was attempting to brute force user accounts.  For here again I documented my finds and also promptly emailed the user to change his password (or I would "kindly" do it for him).  There are other programs out there that will brute force different network services.  I found brutessh to be lite and efficent however, as well as Hyrda. 

There are also programs out there (fail2ban) that will monitor your logs and watch for password brute forcing, banning any address that exceed the threshold.  Hopefully this will give you a process for auditing the security of SSH servers.  In another post we will look at other services and programs like fail2ban.  If you are also looking for additional security you can download and run ssh-vulnkey to check for blacklisted keys on the SSH server itself.

Monday, November 16, 2009

Better Package Searching

Many people in the tech industry today have tried Linux at one point or another.  Recently Ubuntu has been on the rise and is gaining popularity for its ease of use.  They also make frequent updates, is pretty secure right out of the box, and is fairly straight forward to use.  Personally it is the distribution that I use for my servers.  One of the things that I find myself doing frequently is installing software or packages.  For those of you that are familiar with the command line of Linux may be able to do this with no trouble.  If you have never used the command line for this before, Ubuntu uses the APT package manager to find and install software/packages.  The commands might look something like this:

apt-get install -y [package name]

The -y forces a "yes" answer to any confirmation that is normally prompted to the user.  Also note that you probably need to run this command as a super user (using sudo).  You can also find packages that you are looking for in a similar manner:

apt-cache search [package name]

For those of you that are used to working with the command line you may be saying "ok I know this...whats the point here".  While it may be easy to find packages that are looking for and install them, not everyone knows how to query already installed packages on the system.  With Ubuntu this is done using the alternative package manager dpkg.  Using some command line fu we can search to see if something is already installed on the system (instead of wasting time re-installing it).

dpkg --get-selections

Now before you run off and plug this into the command line you may want to understand that this will return ALL packages installed on your system.  You should probably filter your results further using the "grep" command.  For example I was recently working with python and SSH and needed to know if the python-crypto package was installed.  The command for that might look like this:

dpkg --get-selections | grep python-crypto

If the package was installed it will return something like:

python-crypto                              install

Suppose that I just wanted to see all packages that are installed relating to python however.  You might run something like

dpkg --get-selections | grep python

This will return all packages that are related to python and installed on your system.  As a last little tid bit of help with package management we will look at one other option.  Going back to the python-crypto package that I was working with, suppose that I wanted to know what files are in this package.  You can run the following to find the location of all files within a package:

dpkg -L python-crypto

There are many other things that you can do with the apt package manager that are not included here, such as upgrade or updating the system, removing packages, or even purging them from the system.  For a quick "cheat sheet" google for fosswire Ubuntu cheat sheet.  It provides a quick list of the most common commands used on Ubuntu and the apt package manager is a big part of that.

Saturday, November 7, 2009

Personal Password Security

In the last post I talked about password security and how some companies and even users don't bother to take password security very seriously.  One that that is simple enough to do is develop a strategy which will allow you to use your own personal alogrithm to generate secure passwords.  Not only will this help with password security for your personal use, but if you are an IT admin and are constantly resetting passwords it will help keep your users safe.  By developing a personal algorithm for passwords it also allows you to re-create the password for a site (or user) if need be without remembering the user or site's password.  This may sounds a little confusing at first but lets take a closer look to get a better understanding.

A password algorithm would require the following in order to work:
  1. A secret code (this would be a simple easy to remember word)
  2. A secret digit (a random number chosen by you, larger isn't always better)
  3. Either a website name or domain name (for IT admins)
An algorithm like this will then only require you to remember the secret word & code because if you ever forget your generated password you can regenerate it!!  In order to see this in action I've developed a simple python script which implements this algorithm.  Remember this is just one implementation of something that can be done hundreds of different ways.

import string
import re

# Get the site & secret code that the user wants to use
print " "
print "Password Gen v1.0"
print " "
url = raw_input("Enter url or domain name: ")
digits = int(raw_input("Enter a secret digit(s): "))
code = raw_input("Enter a secret password: ")

# Strip out the generics from the site so the password isn't guessable
x = re.compile("^[^:]*://")
url = x.sub("", url)

y = string.find(url, 'www.')

if (y == 0):
    url = url[4:]

# Store url as individual chars and calculate length
url_stack = []

for c in url:
    url_stack.append(c)

if (url.endswith('.com') or url.endswith('.net') or url.endswith('.org')):
    url_len = len(url_stack) - 5
else:
    url_len = len(url_stack) - 1

# Store code as individual characters
code_stack = []

for c in code:
    code_stack.append(c)

code_len = len(code_stack) - 1

# Start building the password
p_word  = code_stack[0]
p_word += str(ord(url_stack[0]) + digits)
p_word += '!'
p_word += code_stack[code_len - 1]
p_word += str(ord(url_stack[url_len].upper()) + digits)
p_word += code_stack[code_len].upper()

print "Your password is: " + p_word
print ""


Now that we have the script lets run a quick test and see how it works.  I'm going to use the following credentials:

Secret Code: yellow
Secret Digit: 4
Website: www.citibank.com

Running these options through the script yields a password of: y103!o79W
Supposing that you don't want to take my word for the secure aspects of this generated password (for those of your paranoid trust no one types), you can visit the following site which checks the strength of passwords:

http://www.passwordmeter.com/

As you can verify on this site this password is rated as "Very Strong" with a score of 100!  While not all passwords will score exactly 100, all should retain a rating of "Very Strong".  This script when also run will strip out "http://", "www", ".com", ".net", and ".org" from any site entered as these are common on all sites and therefore make the password generation less secure.  Hope you enjoy the script and even if you modify it or don't use it all remember that password security is a serious matter and should not be taken lightly inside or outside the work place.

Wednesday, November 4, 2009

Bad Password Policies

Today I wanted to look at a company that had no regard for security.  They started as a small business and rapidly grew over the last few years, however they still run their systems off of a old infrastructure that wasn't designed to scale, with no security in mind, and now runs in complete disarray.  One thing that I wanted to point out off the bat is their use of default passwords.  This company had a policy in place to use a single default password, except that they used this password for everything from client desktops, to servers, to hosted services.  This just shows that password policies are important and time should be spent on developing a policy that will efficiently handle passwords, account lockout, and password complexity.  Although having a default password policy is good for new users, or temp accounts, these accounts should be monitored and audited to ensure that the passwords are changed and that temp account are set to expire.

You can also find a good article on SANS site about things that you can do to improve security as a whole in a company, and what not to do to "suck at information security".