Brandon Checketts

Web Programming, Linux System Administation, and Entrepreneurship in Athens Georgia

Page 23 of 30

Terminating Cat5 cables . . . at 70 feet in the air!

I work for a company that is a Wireless ISP, so I deal a fair amount with wireless networking equipment. Usually, though, I work on them from behind a keyboard and occasionally on the ground in a lab-type environment. We’ve been working recently on adding some 802.11a equipment to one of our towers. I worked on getting everything ready on the ground, including terminating the Cat5 cables that plugged into the radios.

Unfortunately, I forgot to run the cables through the weatherproofing connector before sending the wire up the tower. We had a professional lineman mount all of the radios and antennas for us, but he wasn’t able to re-terminate the Cat5 ends before he had to finish up.

So, up I went to re-do the termination. It actually wasn’t too bad. With the right equipment, climbing up and working was pretty easy and I felt pretty secure the whole time. In fact, the thing that worried me the most was that I felt pretty comfortable with it and was afraid that I’d forget that I was 70 feet in the air and do something dumb.
TowerTower

PHP 4’s call_user_func passes everything by value

I spent quite a while today debugging a problem where call_user_func was not passing a parameter by reference. I was trying to pass an object into a function whose name is not known until run time.

Passing it by reference means that changes made to $var inside foo() are made to the actual variable instead of to a copy of the value (when passed by value).  However, for some reason, when calling a function with call_user_func(), it passes everything by value, regardless of how the function is defined.

function foo(&$var)
{
  $var++;
}

$bar = 1;
foo($bar);
echo $bar;    // outputs '2'

$function = 'foo';

call_user_func($function, $bar);
echo $bar;  // you'd expect this to output 3 now, but it still outputs 2

$function($bar);
echo $bar;  // outputs 3 now

As the sample code shows, the solution is to avoid the use of the call_user_func() function by using a variable function name. Thanks to Steve Hannah’s blog post at https://www.sjhannah.com/blog/?p=86 for helping me to solve this one.

mod_auth_mysql makes managing Apache authentication simple

I administer about 20 different web applications, each of which uses Apache authentication to control access. In the past, I’ve just used simple htpasswd authentication because it works and is readily available. However when adding or removing employee’s access, it required pretty manual editing of all of the htpasswd files every time that we added or removed and employee

I just starting using mod_auth_mysql which provides a way to centralize the authentication. It is available as a package on any distro that I’ve used, and is pretty simple to configure. Just create a database with the following tables:

CREATE TABLE users (
  user_name CHAR(30) NOT NULL,
  user_passwd CHAR(20) NOT NULL,
  PRIMARY KEY (user_name)
);
CREATE TABLE groups (
  user_name CHAR(30) NOT NULL,
  user_group CHAR(20) NOT NULL,
  PRIMARY KEY (user_name, user_group)
);

Populate the users table with username/passwords taken straight from the .htpasswd file. Optionally, you can make users a member of a group via the groups table. Create a database user with permission to SELECT from those two tables.

Then configure the following in the Apache config or .htaccess file for each your web applications:

AuthName "Some Webapp"
AuthType Basic
AuthMySQLEnable on
AuthMySQLHost myauthserver.someplace.com
AuthMySQLUser YourDatabaseName
AuthMySQLPassword YourDatabaseUserPassword
AuthMySQLDB YourDatabaseName
AuthMySQLUserTable users
AuthMySQLNameField user_name
AuthMySQLPasswordField user_passwd
AuthMySQLGroupTable groups
AuthMySQLGroupField user_group

require valid-user
#require group ThisApp

Now you can centrally manage your Apache authentication. Uncomment the ‘require group’ line and add an appropriate entry in the groups table for any users you want to allow specifically to this app.

Credit Card Validation using the mod10 algorithm in PHP

I’m working on a site that will use the Paypal API for submitting merchant account transactions to them. I’d like to validate as much credit card information as possible before passing any information to a 3rd party, since are different kind of credit cards companies and options, so I’ve been reading to find out more about it. I came across the mod10 check that credit cards use and wrote a little PHP function to validate a card number

function sumdigits($number)
{
  $sum = 0;
  for($i = 0; $i <= strlen($number) - 1; $i++) {
    $sum += substr($number, $i, 1);
  }
  return $sum;
}

function mod10check($number)
{
  $sum_number = '';
  for($i = strlen($number) - 1; $i >= 0; $i--) {
    $thisdigit = substr($number, $i, 1);
    $sum_number .= ( $loop %2 == 0) ? $thisdigit : sumdigits($thisdigit * 2);
  }
  return sumdigits($sum_number) % 10 == 0 ? true : false;
}

Tracking down how hackers gain access through web apps

Hackers commonly use vulnerabilities in web applications to gain access to a server. Sometimes, though, it can be difficult to track down exactly how they gained access to a server. Especially if the server hosts a bunch of websites and there are lots of potentially vulnerable scripts.

I’ve tracked down more of these than I can count, and have sortof developed a pattern for investigating. Here are some useful things to try:

1- Look in /tmp and /var/tmp for possibly malicious files. These directories are usually world-writable, and commonly used to temporarily store files. Sometimes the files are disguised with leading dot’s, or they may be named something that looks similar to other files in the directory like “. ” (dot- space), or like a session files named sess_something.

If you are able to see any files, you can use the timestamps of the files to try and look through some Apache logs to find the exact hit that it came from

2- If a rogue process is still running, look at the /proc entry for that file to determine more information about it. The files in /proc/<PID> will tell you information like the executable file that created the process, it’s working directory, environment information, and plenty more details. Usually, the rogue processes are running as the apache user (httpd, nobody, apache).

If all of the rogue processes were being run by the Apace user, then the hacker likely didn’t gain root access. If you have rogue processes that were being run by root, it is much harder to clean up after. Usually the only truly safe method is to start over with a clean installation.

3- netstat -l will help you identify processes that are listening for incoming connections. Often times, these are a perl script. Sometimes they are named things that look legitmiate like ‘httpd’, so pay close attention. netstat-n will help you to see current connections that your server has to others.

4- Look in your error logs for files being downloaded with wget. A common tactic is for hackers to run a wget command to download another file with more malicious instructions. Fortunately, wget writes to STDERR, so it’s output is usually displayed in the error logs. Something like this is evidence of a successful wget:

--20:30:40--  https://somehackedsite.com/badfile.txt
            => `Lnx.txt'
Resolving somehackedsite.com... 12.34.56.78

Connecting to somehackedsite.com[12.34.56.78]:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 12,345 [text/plain]

     0K .......... ......                                     100%  263.54 KB/s

20:30:50 (263.54 KB/s) - `badfile.txt' saved [12,345/12,345]

You can use this information to try and recreate what the hacker did. Look for the file they downloaded (badfile.txt in this case) and look at what it does. You can also used these timestamps to look through access_logs to find the vulnerable script.

Since wget is a commonly used tool for this, I like to create a .wgetrc file that contains bogus proxy information, so that even if a hacker is able to attempt a download, it won’t work. Create a .wgetrc file in Apache’s home directory with this content:

http_proxy = https://bogus.dontresolveme.com:19999/
ftp_proxy = https://bogus.dontresolveme.com:19999/

5- If you were able to identify any timestamps, you can grep through Apache logs to find requests from that time. If you have a well-structured server where you have logs in a consistent place, then you can use a command like this to search all of the log files at onces:

grep "01\\/Jun\\/2007:10:20:" /home/*/logs/access_log

I usually leave out the seconds field because requests sometimes take several seconds to execute. If you have a server name or file name that you found was used by a wget, you can try searching for those too:

grep "somehackesite.com" /home/*/logs/access_log

6 – Turn of PHP’s register_globals by default and only enable it if truly needed. If you write PHP apps, learn how to program securely, and never rely on register_globals being on.

Disabling PHP processing for an individual file

I sometimes want to post samples of PHP scripts on my website. Since the site web server is configured to parse files that end in .php, that means that simply linking to the PHP file will try to parse it instead of displaying its contents. In the past, I’ve always made a copy of the file with a .txt extension to have it displayed as text/plain. That way is kindof clumsy though. If a user wants to save the file, they download it as a .txt and have to rename it to .php.
Fortunately, Apache has a way to do about anything. To configure it to not parse a specific PHP file, you can use this in your Apache configuration:

<Files "some.file.php">
   RemoveHandler .php
   ForceType text/plain
</Files>

If you have AllowOverride FileInfo enabled, this can also be placed in a .htaccess file. It should work for other file types like .cgi or .pl files as well. You can substitute a FilesMatch directive to have it match multiple file names base on a regular expression match.

What a difference a blank line can make

I had a customer today who had problems with a PHP script that output a Microsoft Word document. The script was pretty simple and just did some authentication before sending the file to the client. But, when the document was opened in Word, it tried to convert it into a different format and would only display gibberish.

The customer had posted his problem on some forums, and was told that upgrading from PHP 5.1.4 to PHP 5.2 should fix the problem. Well it didn’t. In fact, the PHP 5.2 version had some weird bug where a PDO object would overwrite stuff in the wrong memory location. In this case, a call to fetchAll() was overwritting the username stored in the $_SESSION variable, which in turn was messing up all of the site’s authentication. After digging into it to find that out, it seemed best to revert back to PHP 5.1. Once that was completed, the we were back to the original problem with the Word document.

The headers he was sending all looked okay. Here’s the relevant code to download a document:

$file = "/path/to/some_file.doc";
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers
header("Content-Type: application/msword");
header("Content-Disposition: attachment; filename=\"".basename($file)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($file));
readfile($file);

I tried tweaking with them a little to match a known-working site, but to no avail. I finally had to download a copy of the file directly from the web server, bypassing the PHP script. I also downloaded a copy of the file through the PHP script and saved them both for comparison. After looking at them both side-by-side in vi, I noticed an extra line at the top of the bad one. I removed the extra line and downloaded the fixed copy which opened fine in Word. After that, it was just a matter of finding the included file with an extra line in it. Sure enough, one of the configuration files had an extra line after the closing ?> tag. Removed that and everything worked correctly.

Experience with eJabberd

I spent a couple hours today trying to install a jabber server called ‘ejabberd‘. The latest release was version 1.1.3, so of course I downloaded and installed that. The program came as a Linux binary installation, so I just ran that and it seemed to install okay. The program even started up just fine, and it looked like everything was working. I had a little snag when trying to login to the web interface the first time. The installation program asked for an admin password, but evidently didn’t set it. I had to set the password on my own, but then was able to log in to the admin web interface okay. Then I created a user account to log in as, and it went downhill from there

ejabberd is written in a high level language called Erlang. Evidently there is some problem in the version of Erlang that the binary installation includes. It has some problems with the cryptography functions. I spent a couple hours searching the ejabberd forums, and the posts that they referenced on the erlang development forums. After much wasted time, and serveral attempts at compiling erlang separately I was about to give up.

Then, I noticed a link for previous versions of ejabberd on their downloads page and decided to give version 1.0.0 a shot. I downloaded, installed, and had it running in under ten minutes. I guess sometimes older is better.

Stupid Advertisers

Advertisers can be dumb. I don’t read a whole lot of magazines, but a couple advertisements in eWeek have made me laugh

First of all, is the latest VeriSign ad that says ‘Introducing the biggest advancement to Internet security in the last ten years’. Turns out that this amazing new advancement is that they now sell an ‘Extended Validation SSL’ certificate. The amazing feature that they’ve manage to incorporate with this, is that modern browsers will now display a green address bar when it detects a site using one of these new certificates.

So that’s it? The big advancement of car insurance quotes in security is that the address bar turns green? You’ve gotta be kidding me. Sounds to me like just a way for VeriSign to make more money.

And my favorite, stupid-funny advertisement is a Microsoft ad that used to be inside the front cover of eWeek. You’ll notice the text that claims 5-nines uptime with a star next to it. Then read the fine print in the footnote of the start that says “Results Not Typical”. It still makes me laugh. To bad they don’t run this ad anymore.

Funny Microsoft AdThe TextThe Fine Print

Avazio.com it is

After spending far to many hours looking up possible domain names, I’ve finally settled on avazio.com. This will be a place for me to sell programs that I’ve written, and to advertise System Administration and Programming services. There is no special meaning or anything to the name. It’s just something that sounded cool and was available. I’ve spent a little time putting up a website there with a little bit of information about the products and services that I’m hoping to sell.

I’m actually quite happy with the look of the site. It’s nothing too complicated, but I have created all of the graphics for it myself using an old version of Paint Shop Pro. Considering that I know nothing about graphics, I think that it looks pretty good. I picked the colors from colorschemer.com (although I forget which one).

« Older posts Newer posts »

© 2026 Brandon Checketts

Theme by Anders NorenUp ↑