Posts Tagged ‘PHP’

Wherin Crackers Strike

Monday, October 12th, 2009

Sometimes, even the best of us can get a good lesson in security.

Last week, I found out that my website was attacked by crackers. Notice I use the word ‘crackers,’ not ‘hackers’, because hackers are not crackers, and it’s important to maintain the distinction. From what they left I can tell that they clearly fall in the black-hat camp. If I’d gotten a warning e-mail or a message on my site to tighten my security, I would take it as a reminder to batten down the hatches. But since they just left a juicy payload, I can assume that they’re up to no good.

From looking at the files they left, I can tell they wanted continuing access to the shell account on my web host, and they wanted to do so in secret. Since I work in web programming, I’ve seen my share of more-conspicuous payloads. These are usually surreptitious JavaScript files, plopped at the end of legit PHP scripts to do nasty things. Most of what I’ve seen have been little snippets of code that act as drive-by downloaders, trying to pull malicious executables onto hapless users’ computers. The only thing that my attacker’s payload did was grant PHP execution and shell access. Not damaging to anyone who happens across a compromised site, but potentially damanging to me — it essentially gave them free reign of my SHH account.

I could speculate about what they wanted to do. There are a lot of ways to do nasty things on the web. PHP is web-aware enough to allow them to do as they please and ( assuming they’ve covered their track properly) not get caught, either. But I doubt they were able to get much nastiness accomplished, because they executed their attack sloppily: they dropped their payload in the wrong directory. They put their files one level above my web root, meaning that the scripts were inaccessible over the web. At first I thought they may have found an exploit in my framework to allow access to anything on the filesystem, but after reviewing their code, I can see that this is not the case. I guess they wanted to get in, drop off the files, and get out. They may have even made a second attempt after determining that the first one didn’t work; I found two files with exactly the same code.

How did they do it? I’m not certain, but I have an idea. The only web app I use is WordPress, and I’m updated to the current version, so this is an unlikely point-of-entry. They would have to know about an exploit that’s not been reported yet, which is possible, but doubtful.

Much more likely is that they managed to guess or sniff my password. I’m the guilty one here, as I was using a simple password that I’ve been using for years, which had little variation, was dictionary-based, and was much too short. In addition to that, I’ve got a webcam at home that posts images fairly frequently (at regular intervals), and it used the same account as my main FTP/Shell account. As you may know, FTP passwords are sent in cleartext, so this was definitely a potential point of entry. Assuming that the password was the point of failure, I’m lucky that they didn’t do more damage, as I used the same password for shell access, MySQL, and even my web control panel, so they theoretically could have locked me out of everything. I’m hypothesizing here, but I’d guess such an attack would be counterproductive; I think they just wanted another remote-control node on the web to carry out any dirty business they happened to think up.

Of course, I took steps to ensure that things are more locked down, starting with changing every password associated with this site. I did this as soon as I found out, and before anything else, to sever any venues they might have had to retaliate against me. Then I checked WordPress for updates, just in case there might have been an exploit I missed. Next, I updated how my webcam saves the periodic images and created a new account specifically for it. Finally, I did a quick review of my code base, making sure they hadn’t left another way to re-gain access. Basically, I pulled down my whole site and did a global search for any of the crackers’ friend functions: eval(), the base64 functions, system() and friends, and file-related functions. I’ve still got to re-upload all the code to feel 100% safe again, but I’m pretty certain that nothing slipped by.

Stay tuned, because after I’ve further reviewed what they left and when I’ve done a bit more research, I’ll post an analysis of the code itself.

Risk Automatic Dice Roller

Monday, August 31st, 2009

I went to Missoula last weekend to play some Risk, and saw that some RTAs had made an automatic Risk dice roller. Being the inquisitive type, I decided to write one myself. Mine uses pretty dice images I made, which somehow makes it better than the other one. It also has a few options for end-of-battle strategy.

Risk Auto Dice Roller

The source code is available, too. And because I’m awesome like that, here’s a .zip of the pretty pretty dice.

You can go to the page to see all the options.

Behold the Glory that is Object-Oriented programming!

Wednesday, May 7th, 2008

So, for my final project in CS 365 (Databases), I’m designing a Wikipedia-style encyclopedia. Not very original, but it gets the job done. And it’s kind of fun to code.

Until today, however. Since this is finals week, I’ve been concentrating on other things until today. The project is due tomorrow. I already had a lot of it done (strange for me, I know, but I’m trying to get out of here), and had seen a lot of e-mails over the weekend about how the DB server we were using was going down and back up as it was fixed. I didn’t worry too much, because as of last night it was supposed to be up and strong.

Imagine my horror, then, as I logged on to the site to see what needed to be done, and got all sorts of errors, most of them involving the MySQL server’s refusal to connect. Some pages, mostly display pages, were still working. So I could browse to articles, list them, and so on, but I couldn’t create or edit them. I was understandably upset, because I also couldn’t implement the access controls or categorization features that my proposal said I would.

After some investigation, I determined that the problem arose when I requested more than one SQL connection at a time. In theory, I only needed one at a time, but my architecture was designed around a Database class, which you could have more than one of. One class for one connection. I also had some static classes for doing things like manipulating articles, categorizing them, linkifying them, and so on. All the edit pages would usually verify that the article in question exists, then call these static classes to do what they needed to do. So the calling page was creating a DB connection, then the static classes would, in order to do what they had to.

My options were looking pretty grim. Do I switch DB servers, and troubleshoot that nightmare? Do I change my whole engineering scheme with T-minus 20 hours and counting?

After some general freaking out, I realized that my pages revolved around a static call in the Database class called getConnection(), which returns a connection to the default database. The wheels in my head started turning, and I realized that since every one of my requests for a database connection go through this method, I could somehow use it to save the day.

The trick was to create a static class member called $working, which held the connection to one, and only one, database. So I changed my code. From this:

public static function getConnection ()  
   return new Database();  

To this:

public static function getConnection ()  
   if (self::$working == NULL)
    self::$working = new Database();
   return self::$working;  

Since I essentially had a factory method to get the database connections to begin with, I merely needed to change this method so that it created the first connection, but didn’t do so on subsequent connection requests. Instead, it returns the already-existing connection. Since all my pages use this method, it means that they all use one and only one server connection. I changed the code, uploaded, and… voila! It worked perfectly.

Imagine the trouble I’d be in if I hadn’t done this to begin with. This is why I love OO programming. Because if you start with well-engineered code, then a major change like this can fix everything, and break nothing. Long live Object-Oriented Programming!

Update:I would be remiss not to mention that this is the Singleton design pattern, which my buddy and classmate Dylan pointed out I had omitted from the original post.