Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

A Proper Fix for file_manager.php and define_language.php Security Holes


Rex Schrader

Recommended Posts

A few months ago my osCommerce install was hacked and converted into a Spambot. I found out when my host took down all of my hosted sites. At the time I didn't have server logs being saved and so I wasn't able to track down the cause of the bug, so I just cleaned up. The second time the site was caught by Google for having malware links everywhere. I cleaned up again and implemented a few more security precaustions. I had enabled server logs and tracked down a possible source of the exploit, but I wasn't sure I caught the security hole. After cleaning up, I installed a script which checked the entire site for modified/new files every hour. This time, when there were new/changed file, I was ready.

 

Today I saw two changed files:

/catalog/images/images.php
/catalog/includes/languages/english/cookie_usage.php

 

A quick check showed that "images.php" (which is not a proper osCommerce file) had been added and contained code to execute arbitrary PHP code passed in a cookie. "cookie_usage.php" had been modified with identical code as well as the normal defines.

 

I did a search of my apache server logs for "images.php" and found the IP of a user who had accessed it. I then searched for that IP and saw all of their activity which included, in part:

"POST //admin/file_manager.php/login.php?action=save HTTP/1.1"

"GET /cookie_setup.php?cookie=1 HTTP/1.1"

"POST /admin/define_language.php/login.php?filename=cookie_usage.php&action=save&language=english HTTP/1.1"

"GET /cookie_usage.php?language=english&cookie=1 HTTP/1.1"

"POST /admin/categories.php/login.php?action=new_product_preview HTTP/1.1"

"GET /images/images.php?cookie=1 HTTP/1.1"

I had previously removed file_manager.php, suspecting that it was a hole. What I couldn't figure out, though is why there was a login.php appended to the URL of that and the other two requests.

 

A quick look at admin/includes/application_top.php showed why:

// redirect to login page if administrator is not yet logged in

if (!tep_session_is_registered('admin')) {

$redirect = false;

 

$current_page = basename($PHP_SELF);

 

if ($current_page != FILENAME_LOGIN) {

(.. Redirect code here . .)

By using "basename", php is just returning the last full filename after the last / but before the ?. The "basename" of "admin/file_manager.php/login.php?" is "login.php" . . which of course is the default value of FILENAME_LOGIN. This completely bypasses the redirection code for non-admins and allows normal execution of ANY of the admin files. Since several of those files (file_manager.php, define_language.php, and categories.php) allow for direct uploads to the server, they allow an attacker to upload to their associated directories. You could also use this code to view and download a stored database backup, giving full access to your site and userlist. Basically, by appending "login.php" to the URL of any of the admin functions you can execute ALL of the admin functions without being logged in as an admin.

 

Since it is certainly impractical to remove categories.php (and all of the other valuable administration functions), it is much better to fix the code such that ALL non-login accesses will be redirected. Here is my simple fix -

 

admin/login.php

FROM

require('includes/application_top.php');
require('includes/functions/password_funcs.php');

TO

define("DOING_LOGIN", 1);

require('includes/application_top.php');
require('includes/functions/password_funcs.php');

 

admin/includes/application_top.php

FROM

// redirect to login page if administrator is not yet logged in
 if (!tep_session_is_registered('admin')) {
   $redirect = false;

   $current_page = basename($PHP_SELF);

   if ($current_page != FILENAME_LOGIN) {

TO

// redirect to login page if administrator is not yet logged in
 if (!tep_session_is_registered('admin')) {
   $redirect = false;

   $current_page = basename($PHP_SELF);

   if (!defined("DOING_LOGIN")) {

 

Since ONLY the login.php file will have the define directive, only it will not be redirected when the admin session variable is not set. No matter what jiggery-pokery you do on the GET line, the only way to do a 'define' is by editing a local file. With this fix in place, you should be able to leave file_manager.php, define_language.php, and categories.php all in place.

 

Of course, you are encouraged to follow all of the other security suggestions in these forums. This just cleans up a fairly egregious coding error.

 

Enjoy -

Rex Schrader

Link to comment
Share on other sites

  • 5 months later...

Tradock, you would probably get more help from MyPHPAuction at sourceforge.

- Stop Oscommerce hacks dead in their tracks with osC_Sec (see discussion here)
- Another discussion about infected files ::here::
- A discussion on file permissions ::here::
- Site hacked? Should you upgrade or not, some thoughts ::here::
- Fix the admin login bypass exploit here
- Pareto Security: New security addon I am developing, a remake of osC_Sec in PHP 5 with a number of fixes
- BTC:1LHiMXedmtyq4wcYLedk9i9gkk8A8Hk7qX

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...