Bryan Geraghty

Security

SHA-3 Finalists: PHP Speed Comparison

by Bryan on Mar.04, 2011, under Programming, Security

Background

As everyone interested in cryptology knows, NIST has been running a cryptographic hash algorithm competition to determine the successor of SHA-2. The chosen algorithm will be aptly named, SHA-3.

NIST selected five SHA-3 finalists – BLAKE, Grøstl, JH, Keccak, and Skein to advance to the third (and final) round of the competition on December 9, 2010, which ended the second round of the competition.

As I’ve said in other places, the SHA-3 competition is extremely important because it draws in the entire cryptology industry together to beat on the submitted algorithms for three years. You can be pretty confident in any algorithm that advances to the final round. But what the competition ultimately determines is which function is the “Jack of all trades”. For those of us who do large-scale database operations where hashes are part of the works, a high security margin and speed are more important than the number of CPU cycles and bits of memory saved, and how well it can be implemented in embedded systems. So I set out to test the five finalist hashes in a typical web application environment.

Why I created the test

My foray into this test began when I wrote a quick CLI PHP script to download photos from my cell phone. As part of the copy process, I naturally built in a checksum routine to verify that each file was copied correctly. I have been an avid follower of the SHA-3 competition from the beginning, and I had read good things about the Skein function, so I had decided to implement it in the script just for fun.

Right around the same time, NIST published its rationale for selecting the five finalists in the competition. After reading through the rationale, I became really curious to see how each function would stack up against one-another in a PHP environment. So after creating PHP extensions for each of the finalists that didn’t already have one, I modified my download script to do some hash benchmarking, and ran the test.

The Test

After using the script to download the photos off of my cell phone, I decided that the amount of data (about 40 MB) just wasn’t large enough to give me a good benchmark. So I decided to run the script against a whole month of exported JPG photos from my DSLR which ended up being nearly 1 GB of data (154 files @ 4-6 MB each). Since each file is hashed twice, we’re approaching 2GB of data hashed each time the operation runs. Since we are only benchmarking the performance of the hash functions, all of the files were copied once and verified a couple of times before the official timing began.

Here is basic overview of how the script works:

  • List the source directory contents recursively, looking for .jpg files
  • Iterate through the list
  • Get the file creation date
  • Build a destination path based on the file creation date and file name
  • If the destination file does not exist, or hashes of the files do not match, copy the file
  • If hashes of the files still don’t match, report a failure

Click here for the source code.

Since the files have already been copied and verified, as mentioned above, the file copy and the last verify never happen in the speed comparison test. It essentially loops through all of the files, builds hashes of the source and destination files, and verifies that they all match.

For the purposes of this test, I needed to be able to keep track of the exact number of bytes hashed (for verification between runs) and the exact amount of time spent actually hashing data so we wouldn’t have to worry about other operations clouding the results. To that end, I built a class with an internal counter for each. The class also contains an isolated hash wrapper function which only accepts the raw data to be hashed, increments the counters, and passes the data on to hash function configured at the object level.

A new object is created and destroyed for each hash function being tested, per round. The wrapper function increments the counters for the lifetime of the object. The number of bytes hashed is an explicit count of the bytes fed to the wrapper function. The time spent hashing is calculated by getting the microsecond time stamp immediately before the hash function is executed, and once again immediately after. The former is subtracted from the latter, and the internal counter is incremented by the result.

The Results

To establish a baseline, I ran iterations of MD5 and SHA-512. MD5 has been the hash of choice for the past few years where speed was a major concern. Unfortunately, MD5 is now considered to be cryptographically broken but it served its purpose here in determining a reasonable floor for speed. I chose SHA as the second baseline because it is the current standard, and I chose to implement its 512 bit mode because that is what the new algorithms will be using.

I ran the entire script, which performs the the verification of the entire dataset for all seven hash functions (MD5, SHA-512, BLAKE, Grøstl, JH, Keccak, Skein), five times.

This test was performed on a 64-bit Ubuntu 10.10 installation running PHP 5.3.3-1ubuntu9.3 in CLI mode. The CPU is an Intel Core2 Duo T9300 @ 2.50GHz and the machine has 4 GB of memory installed. During the entire duration of the test, the load average of the machine peaked at 1.2, CPU usage peaked at 85%, and memory usage peaked at 25%.

Seconds spent hashing 154 files (1937164902 bytes)
Function Round 1 Round 2 Round 3 Round 4 Round 5
MD5 5.731552 5.729477 5.817808 5.813912 5.740509
SHA-512 14.610088 14.269413 14.222281 14.468436 14.378429
Skein-512 6.952610 6.767148 6.858372 6.877997 6.812982
Keccak-512 8.023958 7.778949 7.952572 7.887774 7.886457
JH-512 8.195324 7.830080 7.916424 8.040076 7.995283
Grøstl-512 8.192576 8.121383 8.205048 8.063461 8.326136
BLAKE-512 9.894579 9.715329 9.627831 9.588126 9.610026

Click here for the raw results.

Well, that’s it. I’ll leave the analysis of what the results mean to the reader.

Oh, and if you’re interested in the PHP extensions I wrote, they’re available at: https://github.com/archwisp

Leave a Comment :, , , , , , , , more...

Go, Sanford!

by Bryan on Nov.19, 2010, under Security

It’s good to finally see an airport questioning the insanity. I hope this becomes a trend. Unfortunately, they will still have to follow the TSA guidelines, but those change all the time and hopefully the private company will have higher standards of training and accountability for its employees.

The backlash continues over those new TSA screening measures, and now one Central Florida airport has decided to go with a private security screening firm.

The TSA points out that even if an airport decides to use a private firm for security, the screeners still must follow TSA guidelines. That would include using enhanced pat-downs and the full-body scanners if they are installed at the airport.

via: http://wdbo.com/localnews/2010/11/sanford-airport-to-opt-out-of.html

1 Comment :, , , , more...

Adobe Reader X – Upgrade Now

by Bryan on Nov.19, 2010, under Security

For those of you who aren’t aware of what’s been going on, Adobe has been working on a “sand-boxed” version of Reader to help protect the underlying operating system from whatever flaws it may have. Now, it was just released, so who knows how effective their sand-boxing attempt will prove to be; However, it will most definitely be better than what we have now: Reader vulnerabilities being reported every couple of weeks.

I urge everyone to download and install this update as soon as possible.

Here is the download link:
http://get.adobe.com/reader/

Here is the press-release from Adobe:
http://blogs.adobe.com/adobereader/2010/11/adobe-reader-x-now-available.html

1 Comment :, , , , more...

CVE-2010-3765 (firefox)

by Bryan on Oct.28, 2010, under Programming, Security

This is not good.

Unspecified vulnerability in Mozilla Firefox 3.5.x through 3.5.14 and 3.6.x through 3.6.11, when JavaScript is enabled, allows remote attackers to execute arbitrary code via unknown vectors, as exploited in the wild in October 2010 by the Belmoo malware.

National Vulnerability Database

via CVE-2010-3765.

The recent prevalence of this sort of browser bug is really disconcerting. I didn’t realize the severity of the problem until I recently investigated how one of these exploits work; and let me tell you, it’s not pretty. If the browser is hi-jacked, the web developer has essentially no control over what is happening after the page is loaded. For instance, you could visit your bank’s website and receive the actual web page served over SSL/TLS with a valid certificate. Then, the exploit steps in and over-loads (or creates) the JavaScript form handling function. From that point on, anything you enter in the form is known to the operator of the exploit.

With AJAX functionality becoming the norm, it’s also becoming more difficult to disable JavaScript in the browser and still enjoy your web browsing experience. On top of that, who knows whether JavaScript is actually disabled if the browser has been compromised?

Unfortunately, Mozilla is not the only one to blame here. Microsoft’s Internet Explorer, Google’s Chrome, and Apple’s Safari browsers have all had this type of vulnerability reported within the last few months. The other vulnerabilities may not have been exploitable by a “remote attacker”, but the exploit I mentioned was very successful as a local exploit. How many of you are certain you will be protected by a 0-Day exploit which then hi-jacks your browser? Remember, this is a user-space vulnerability; no root required here.

So this is a revelation for me. I’ve been a web-developer for 10 years and I always considered web applications relatively safe and secure when written and implemented properly. Unfortunately, the old axiom, “Nothing is secure”, remains true. The fact that a web site may be completely free of bugs and vulnerabilities (however unlikely that may seem) is completely negated by the fact that a web browser is required to interact with the application. And due to the nature of the Internet, the browser in use is mostly controlled by the user. I say mostly because web developers have some remedial tricks for detecting browsers but they can all be circumvented if the user has the technical prowess. Also, because they may be using a computer controlled by their employer where they may or may not have permission to use their browser of choice.

So ultimately, the security of the data passing between the user and the web application rests in the hands of the browser developer. We can do everything possible to “secure” the client machine and the web site, but if the browser is flawed, all is for naught.

Happy days.

Leave a Comment :, , , , , more...

A Lesson From Cyber-Raid 0: Protect Your Nagios Server

by Bryan on Oct.14, 2010, under Security

A few weeks ago, I participated as a Red Team member in Cyber-Raid 0; a mock hack/defend event held in Kansas City. It was a fun event even if there were a few issues with how the rules were defined and enforced.

Teams

There were 4 teams of defenders (Blue Teams) which represented companies, and one big team of attackers (Red Team) continually attacking the Blue Teams.

Setup

Six networks were accessible by the Red Team, all connected by one Cisco ASA: one for the Red Team, one for each of the four Blue Teams, and one for the scoring server. The Red Team was responsible for providing all of their own equipment. Blue team members were responsible for providing a windows laptop with which they would manage their VSX servers. The infrastructure was provided by White Wolf Security and the entire game network was completely isolated from the internet… sort of ;)

Scoring

Blue Team scoring was handled by the score-bot connecting to services and verifying that they were running. If a service could not be contacted, points were added to the Blue Team responsible for that server. The objective of the Blue Teams was to keep their respective scores as low as possible. Red Team members scored points by executing the provided Phone-Home program on one of the Blue Team servers. The more points the Red Team scored, the better.

Rules

There were essentially no rules but to keep the game fun, a few simple rules were laid out: 1) No “layer-two shenanigans”. 2) Traffic cannot be blocked from the “WAN” based on source IP. 3) No communication between Red and Blue team members.

Replay

We were notified that some people who took part in this event did not want that information shared, so I will not include any identifying information in my recounting of events.

First thing in the morning was breakfast followed by a “Briefing” where the rules and concept of the game were laid out, followed by by questions. After that, the teams split into their respective rooms isolated from one another. The Blue Teams were given an hour to become familiar with their systems and we were given the addresses of our network, the Blue Teams’ class C networks, and the scoring server. We were given no other information about the target systems.

The first hiccup in the game came here: the Red Team could not connect to the scoring server because of a routing problem. Once the router was working as it was supposed to, each us registered our “Hacker Handle” and received an account on the scoring server from which we could download the Phone Home program.

Before we get to the action, I’ll start off by saying that the Red Team room was not very organized. A few teams showed up together and tended to work together but there were quite a few of us who arrived alone and sort of teamed-up based on who we were sitting near. This disorganization ultimately proved to be a extremely counterproductive in the long-run because we ended up working against each other.

Once everything was connected, I think everyone on the Red Team fired off a network scan. Me and the guys I was working with separated the networks up and started doing SYN scans with decoys which ended up working pretty well. We Identified a mix of about a dozen Windows and Debian servers on each of the networks. After we collected all of the host info, I started poking around with telnet on Blue Team 1′s network and… “WTF, I can’t connect to any of those services”. We tried talking with the organizers and explaining that the servers were inaccessible, but one of the helpers replied with some BS about clever techniques. Well, we would later find out that they added a blanket deny firewall policy to all traffic coming from the Red Team’s network. (Did you see rules #2?) If the Red Team had been more organized, we would have collaborated and realized that nobody could connect to the services and raised more of a fuss. So that was the state of the game for about half of the day. We sat around trying to hack the ASA server between us and them; ultimately getting nowhere.

Apparently, one of the groups on the Red Team had taken the more aggressive approach of just telling Metasploit to attack whatever it could find and got a phone-home script running in the moments before the Great Wall came down. Unfortunately, the scoring server was not working at the time, so no points were credited to them.

After the lunch break, things were looking brighter; Apparently, the game organizers had caught on to the shenanigans and told them to open up specific services; as would be the case in a real-world network. Well, it turns out that even though the incoming policies were opened up, outgoing traffic was still denied, so even when someone found a vulnerability, they couldn’t connect back and get a shell. In my opinion, that approach is perfectly reasonable. I highly recommend egress filtering of all but the necessary ports specifically for this reason. It is especially effective when you do filtering on either a VLAN or a host-by-host basis.

Finally, Some Progress

The first thing we managed to leverage was an “Open Source Application For Disaster Management”. When we first stumbled upon it, all of the security was disabled and we could plainly see the application’s configuration; including the database login credentials. Unfortunately, the Database server was not accessible from the “WAN”, so that didn’t go anywhere right away.

I continued exploring the application and found a few input sanitation vulnerabilities which occupied me until the end of day one. Ultimately, I was able to get a compressed malicious file uploaded to the server but couldn’t find the means to decompress it. I also wasted more time after I found a list of “flags” on the scoring server which you could use to earn points by acquiring key bits of sensitive information. What the organizers didn’t announce officially was that these flags were not working. So after trying a few with no success, I asked, and they confirmed that they were in fact, not working.

In the mean-time, some of the other Red Team groups discovered PHPMyAdmin running on a few of the servers. So that, combined with the login credentials from the “Open Source Application For Disaster Management”, the they had access to the MySQL database; including the ability to browse the local file system of the database server.

Lesson 1) Don’t run PHPMyAdmin on a server accessible via HTTP from a lower security zone than the DB server. (in case you didn’t already know)

What most of the Red Team didn’t know was that one of the smaller groups had managed to leverage the PHPMyAdmin avenue to get access to most of the servers on all of the networks and started racking up points. The first thing they did once they gained access to the MySQL server was to grab the /etc/passwd file, as most of the other groups did. Where they went one step further was, instead of discarding the file because shadow passwords were enabled, they scanned the list of user names looking for services. One of these user names stood out: nagios. Well, they found the Nagios server and tried the default password: nagios; Success! This proved to be the only successful avenue of scoring for the remainder of the game.

Lesson 2) Nagios needs an account for every service which needs to be checked and those user names/passwords are stored in plain-text. If someone gets into it, they get into everything. (in case you didn’t already know)

Day 2

Well, day two was a bit of a disappointment because a lot of the Blue Team members didn’t show up and two of the networks were completely down. This meant that there were only two instances of any given service running; including the one I was investigating. Remember the “Open Source Application For Disaster Management”? Well, I had download the source code and was looking for vulnerabilities. Unfortunately, one of Blue Teams realized that the MySQL service had been compromised and they changed the password which left the application crippled in a “Can’t connect to the database” state. I still don’t know if they had point scored against them for this because the score-bot would just be checking whether it could connect to the service or not. So this left one more instance of the “Open Source Application For Disaster Management” running. And just as I was about to test a vulnerability that I found, the database for that service disappeared; someone had inadvertently deleted it; another case of disorganization. From then on, with about 3 hours left in the game, we were just kinda poking and prodding but nothing came to fruition.

Conclusion

Overall, it was a fun experience; It gave me a chance to sit in the attacker’s seat and focus all of my attention on gaining access. I also got to meet and work with a lot of talented people; it sure is a small world. At the end of the day, all of the Red Team agreed that we should have started sharing information at the beginning of the game and organized ourselves. Ultimately, the only significant scores posted were leveraged via the Nagios server. If we had been sharing information, maybe we would have made good use of the lost time and found another avenue of attack. I guess we’ll never know.

I look forward to participating again next year.

Leave a Comment :, , , more...

Linux ACL Management Functions

by Bryan on Jan.07, 2010, under Programming, Security

Traditional file system permissions management in Linux leaves most users wanting. Fortunately, there’s a feature that most linux users don’t even know about called ACLs and it’s most likely already available on your system. All you have to do to enable it is add the `acl` option to your volume in `/etc/fstab` and re-mount the volume.

Once that is done, here are some functions that I wrote to help manage these ACLs.

Here is an example of a command that grants apache permission to read a directory with these functions:

$ source aclfunctions.bash; grantUserRead 'apache' /var/www '*';

aclfunctions.bash:

# Author :: Bryan Geraghty
# Date :: 2009-10-28
# Notes :: ACL management functions
 
##
# Resets permissions on all files and directories in the specified path and removes
# and ACL entries
#
# @param string $2 Base path Path in which all operations will take place
#
function resetAll
{
   echo "Resetting permissions on all files in directory $1";
 
   echo "Removing ACLs...";
   setfacl -Rb $1;
 
   echo "Resetting directories...";
   find $1 -type d -exec chmod 770 {} \;
 
   echo "Resetting files...";
   find $1 -type f -exec chmod 660 {} \;
}
 
## 
# Grants read permissions to all files/folders with names matching $3, which reside
# inside of directory $2, to user $1.
#
# @param string $1 Username The user to whom read permissions will be granted
# @param string $2 Base path Path in which all operations will take place
# @param string $3 Target Name of the file/directory on which to set the permissions
#
function grantUserRead
{
   echo "Granting read permission to user $1 on files/folders named $3 in directory $2";
 
   ## Set the default permissions for new files on the specified directory
   echo "Setting defaults...";
   find $2 -name "$3" -type d -exec setfacl -d -m u:$1:rx {} \;
 
   ## Recusively set the permissions on all existing directories and files within the
   ## specified directory
   echo "Setting directory permissions...";
   find $2 -name "$3" -type d -exec setfacl -R -m u:$1:rx {} \;
 
   ## Grant permissions to any files with the specified name
   echo "Setting file permissions...";
   find $2 -name "$3" -type f -exec setfacl -m u:$1:r {} \;
}
 
## 
# Grants write permissions to all files/folders with names matching $3, which reside
# inside of directory $2, to user $1.
#
# @param string $1 Username The user to whom read permissions will be granted
# @param string $2 Base path Path in which all operations will take place
# @param string $3 Target Name of the file/directory on which to set the permissions
#
function grantUserWrite
{
   echo "Granting write permission to user $1 on files/folders named $3 in directory $2";
 
   ## Set the default permissions for new files on the specified directory
   echo "Setting defaults...";
   find $2 -name "$3" -type d -exec setfacl -d -m u:$1:rwx {} \;
 
   ## Recusively set the permissions on all existing directories and files within the
   ## specified directory
   echo "Setting directory permissions...";
   find $2 -name "$3" -type d -exec setfacl -R -m u:$1:rwx {} \;
 
   ## Grant permissions to any files with the specified name
   echo "Setting file permissions...";
   find $2 -name "$3" -type f -exec setfacl -m u:$1:rw {} \;
}
 
## 
# Grants read permissions to all files/folders with names matching $3, which reside
# inside of directory $2, to group $1.
#
# @param string $1 Group The user to whom read permissions will be granted
# @param string $2 Base path Path in which all operations will take place
# @param string $3 Target Name of the file/directory on which to set the permissions
#
function grantGroupRead
{
   echo "Granting read permission to group $1 on files/folders named $3 in directory $2";
 
   ## Set the default permissions for new files on the specified directory
   echo "Setting defaults...";
   find $2 -name "$3" -type d -exec setfacl -d -m g:$1:rx {} \;
 
   ## Recusively set the permissions on all existing directories and files within the
   ## specified directory
   echo "Setting directory permissions...";
   find $2 -name "$3" -type d -exec setfacl -R -m g:$1:rx {} \;
 
   ## Grant permissions to any files with the specified name
   echo "Setting file permissions...";
   find $2  -name "$3" -type f -exec setfacl -m g:$1:r {} \;
}
 
## 
# Grants write permissions to all files/folders with names matching $3, which reside
# inside of directory $2, to group $1.
#
# @param string $1 Group The user to whom read permissions will be granted
# @param string $2 Base path Path in which all operations will take place
# @param string $3 Target Name of the file/directory on which to set the permissions
#
function grantGroupWrite 
{
   echo "Granting write permission to group $1 on files/folders named $3 in directory $2";
 
   ## Set the default permissions for new files on the specified directory
   echo "Setting defaults...";
   find $2 -name "$3" -type d -exec setfacl -d -m g:$1:rwx {} \;
 
   ## Recusively set the permissions on all existing directories and files within the
   ## specified directory
   echo "Setting directory permissions...";
   find $2 -name "$3" -type d -exec setfacl -R -m g:$1:rwx {} \;
 
   ## Grant permissions to any files with the specified name
   echo "Setting file permissions...";
   find $2 -name "$3" -type f -exec setfacl -m g:$1:rw {} \; 
}
 
## 
# Grants execute permissions to all files/folders with names matching $3, which reside
# inside of directory $2, to user $1.
#
# @param string $1 Username The user to whom read permissions will be granted
# @param string $2 Base path Path in which all operations will take place
# @param string $3 Target Name of the file/directory on which to set the permissions
#
function grantUserExec
{
   echo "Granting execute permission to user $1 on files/folders named $3 in directory $2";
 
   ## Set the default permissions for new files on the specified directory
   echo "Setting defaults...";
   find $2 -name "$3" -type d -exec setfacl -d -m u:$1:rwx {} \;
 
   ## Recusively set the permissions on all existing directories and files within the
   ## specified directory. One command will siffice for files and directories when
   ## setting execute permissions 
   echo "Setting directory and file permissions...";
   find $2 -name "$3" -exec setfacl -R -m u:$1:rwx {} \;
}
 
## 
# Grants execute permissions to all files/folders with names matching $3, which reside
# inside of directory $2, to group $1.
#
# @param string $1 Group The user to whom read permissions will be granted
# @param string $2 Base path Path in which all operations will take place
# @param string $3 Target Name of the file/directory on which to set the permissions
#
function grantGroupExec
{
   echo "Granting execute permission to group $1 on files/folders named $3 in directory $2";
 
   ## Set the default permissions for new files on the specified directory
   echo "Setting defaults...";
   find $2 -name "$3" -type d -exec setfacl -d -m g:$1:rwx {} \;
 
   ## Recusively set the permissions on all existing directories and files within the
   ## specified directory. One command will siffice for files and directories when
   ## setting execute permissions 
   echo "Setting directory and file permissions...";
   find $2 -name "$3" -exec setfacl -R -m g:$1:rwx {} \;
}
1 Comment :, , , , more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Links

A few highly recommended links...