Home >> Blog >> Making your Joomla! Super Administrator secure

Thursday, 15 April 2010 11:23

Making your Joomla! Super Administrator secure

Written by  Nicholas K. Dionysopoulos
Rate this item
(2 votes)

As you all know, every new Joomla! installation comes with a Super Administrator account with a well-known user ID: 62. Nobody really knows for sure why 62 was chosen, but this can lead to your site's security being compromised. Why? It is a very well known value and potential hackers can take advantage of it in conjunction with another vulnerability to take control of your site. Known constants are a security nightmare as made clear in the case of the attack against Joomla! 1.5.5 which caused a lot of sites to be compromised as the researcher who found the vulnerability released it to the general public before the Joomla! team had a chance to fix it.

One easy workaround is to demote this well-known user account down to the Registered level and block it, hanging potential hackers to dry. However, in order to complete our security modification we do need another Super Administrator. The problem is that if you just create a new user his ID will be 63, which is not secure at all; it's a hacker's next best bet. So, we need a way to create a Super Administrator with a random ID, preferably in the 1-61 range which is otherwise unused in Joomla!. This is what we are going to do, folks, without even using phpMyAdmin for the task.

Note: You will be modifying your site's database. Even though the following procedure is well-tested, it's best to practice it on a local testing server first.

Insight on Joomla! user management, down to the database level

Joomla! 1.5 uses two tightly integrated mechanisms for authenticating users. For starters, we have the data stored in the jos_users table. It's the username, password and the group where the user belongs. There are some important pieces of information about this table. To begin with, all user ID's begin counting from 62. User IDs 1-61 are free and can't be assigned using the back-end. Then, the password is stored in the format md5:salt. Salt is a random string. The md5 part is the MD5 hash of the password and the salt. So, for a salt string "abcd" and a password "foobar", we have to calculate the MD5 hash of "foobarabcd". This calculation is easy to perform with an on-line MD5 calculation and results to 9aa618c6255a7259d747113d7e649925. So, the password field would be "9aa618c6255a7259d747113d7e649925:abcd". This means that we can create a username/password combination of our liking by assigning it a user ID less than 62.

Of course, this is not enough to log in to Joomla!. The other mechanism it uses is a cut-down version of phpGACL. In short, this mechanism allows the use of Access Control Lists which treats users as "Access Request Objects" (AROs) and what they can do as "Access Control Objects" (ACOs). This might be a bit over your head, but the overall concept is that if the user isn't marked as having access to the group he's supposed to be part of, he won't be able to login to the site. For all you need to know, each user is mapped to a single ARO and each ARO is mapped to one or more groups. If the user group assigned in the jos_users table is not in accordance to the group prescribed in the ARO-group mapping, you can't log in.

You might have guessed it, but this mechanism is not fool proof down to the database level. First off, the table which maps users to AROs (jos_core_acl_aro) has its IDs start from 10. This allows us to insert rows with IDs 1-9 without the fear of accidentally disabling another user's login ability. The other database table involved (jos_core_acl_groups_aro_map), which maps AROs to groups, is a simple glue array of a regular many-to-many relationship - it holds IDs of both ARO and group - is easy to append to.

Putting the insight to good use

Having this insight is good, but putting it to real use is even better. Let's say that we want to create a new Super Administrator user called "hacker", with a password of "hacker", using nothing but database manipulation, i.e. without using the Joomla! back-end interface. If you read the previous three paragraphs you might have figured out how: we just need to run three SQL commands. We'll first focus on what these commands are, then move on to a practical way to deliver them.

The first SQL command will create the Joomla! user and looks like this:

REPLACE INTO `jos_users` (`id`, `name`, `username`, `email`, `password`, `usertype`, `block`, `sendEmail`, `gid`, `registerDate`, `lastvisitDate`, `activation`, `params`) VALUES ('60', 'T. Hacker', 'hacker', '
 This e-mail address is being protected from spambots. You need JavaScript enabled to view it
 ', '18b42a5df78808abca92bc021a191991:abcdefghijklmnopqrstuvwxyz012345', 'Super Administrator', '0', '0', '25', '2000-01-01 00:00:00', '0000-00-00 00:00:00', '', '');

This creates a user with ID 60 and his name set to "T. Hacker". Now, we'll craft our next SQL command which creates an ARO object out of the Joomla! user:

REPLACE INTO `jos_core_acl_aro` (`id`, `section_value`, `value`, `order_value`, `name`, `hidden`) VALUES ('8', 'users', '60', '0', 'T. Hacker', '0');

This created an ARO object with ID 8. Do note that the 'name' field must match the 'name' field of the jos_users entry! Next up, we'll map this ARO object to the Super Administrator group, which goes by the group ID 25:

REPLACE INTO `jos_core_acl_groups_aro_map` (`group_id`, `section_value`, `aro_id`) VALUES ('25', '', '8');

There you go! The user is active and ready for login. If you're wondering why I use REPLACE instead of INSERT, well, it's simply because I wouldn't like the query to fail if the database record already exists.

Delivering the SQL code

This is all sweet and well, but we do have to use a database utility like phpMyAdmin to run this SQL code. Most people would find this a daunting task by any measure. Not to mention that for each and every site we are building we have to undergo the same procedure. This is far for optimal. It would be lots easier if we could just "install" this workaround on a Joomla! site just like we can install components or modules. In fact, we can!

As you might already know, the Joomla! components' installation process is able to run arbitrary SQL commands, as a means to allow component writers to create tables and pre-populate them with data. But, wait! Isn't running arbitrary SQL what we want to do? Yes. So, we'll create two files - one file for the SQL commands and one serving as the installation blueprint of our fake component - pack them in a ZIP file and deploy them. We'll name the first file install.mysql.sql and put the previous SQL commands inside it:

1
2
3
REPLACE INTO `#__users` (`id`, `name`, `username`, `email`, `password`, `usertype`, `block`, `sendEmail`, `gid`, `registerDate`, `lastvisitDate`, `activation`, `params`) VALUES ('60', 'T. Hacker', 'hacker', '
 This e-mail address is being protected from spambots. You need JavaScript enabled to view it
 ', '18b42a5df78808abca92bc021a191991:abcdefghijklmnopqrstuvwxyz012345', 'Super Administrator', '0', '0', '25', '2000-01-01 00:00:00', '0000-00-00 00:00:00', '', '');
REPLACE INTO `#__core_acl_aro` (`id`, `section_value`, `value`, `order_value`, `name`, `hidden`) VALUES ('8', 'users', '60', '0', 'T. Hacker', '0');
REPLACE INTO `#__core_acl_groups_aro_map` (`group_id`, `section_value`, `aro_id`) VALUES ('25', '', '8');

Do note that I replaced the jos_ database prefix with the generic placeholder #__. Joomla! will pick it up and replace it with the correct database prefix on-the-fly, ensuring our "hack" works on all Joomla! installations. Next up, a file named hack.xml with the following contents:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE install SYSTEM "http://dev.joomla.org/xml/1.5/component-install.dtd">
<install type="component" version="1.5.0" method="upgrade">
    <name>Hack</name><author>Nicholas K. Dionysopoulos</author>
    <creationDate>April 15th, 2010</creationDate>
    <copyright>(C) 2010 Nicholas K. Dionysopoulos</copyright>
    <license>GNU GPL 3</license><version>1.0</version>
    <description>Creates a hacker Super Administrator account</description>
    <install>
        <sql>
            <file driver="mysql" charset="utf8">install.mysql.sql</file>
            <file driver="mysqli" charset="utf8">install.mysql.sql</file>
        </sql>
    </install>
    <administration>
        <files>
            <filename>install.mysql.sql</filename>
        </files>
    </administration>
</install>

Without much ado, we simply put both files inside a ZIP file, named hack.zip. Next up, login to your site's back-end as an Administrator or Super Administrator (the Manager group can't install extensions). Go to Extensions, Install/Uninstall menu item, use Browse to locate this ZIP file and hit "Upload and Install". Ignore any error messages, log out from the site's back-end and then log-in again using "hacker" as both the username and password. Look, mom, I'm a Super Administrator!

Disabling the old Super Administrator account

This is the easiest part of the process. As you are logged in as a Super Administrator to your own site, you can go to Joomla!'s Users Manager page. First, demote him to the Registered level and click on Save. Then, edit again, set "Block" to "Yes" and save again. Your old Super Administrator user has lost his privileges and is now locked so that nobody can use it to log in to your site.

Apparently, you can write two UPDATE statements and put them in our fake component to achieve the same goal. I'll leave that as an exercise to the reader Wink

Many people would argue that we would be better off if we simply changed the user's ID instead of creating a brand new account, as demonstrated in this Bodvoc's blog post. This approach works well if you have a brand new site. But if your site already has content, doing so would leave all content items previously owned by user #62 orphans. Fixing all such records in all installed components is a might task. Ergo, it's much easier creating a new user with an unthought of user ID and disabling the old user, keeping content association and increasing your site's security in a single go.

11 comments

  • Comment Link Brian Monday, 28 February 2011 14:10 posted by Brian

    Exceptionally practical information! Much appreciated :)

  • Comment Link uggboots li Thursday, 07 October 2010 04:54 posted by uggboots li

    Ugg sale is a legendary boots, you can't understand why it has a ugly appearance when you first see her.But it has been a popular boot in the Eurasian land, now UGGs for sale popoular wind blowing all over the world today.The guide of this wind is Euramerian stars.On sale ugg boots uses only the best quality Australian sheepskin.We provide Free Shipping and discount UGG boots on sale at low price 70% discount for you.We are a professional uggs outlet ,in our ugg boots outlet store.You can choose your favorite UGGs sale cheap soon.We have a various kind of ugg boots sale collection,such as ugg classic tall ugg boots on sale,classic cardy ugg boots on sale,bailey button ugg boots on sale and so on.All boots in our UGG Collection feature a soft foam insole covered with genuine sheepskin and have a molded EVA light and flexible outsole designed for amazing comfort with every step.Cheap UGG UK ugg Boots sale online now!

  • Comment Link Nicholas K. Dionysopoulos Friday, 27 August 2010 14:47 posted by Nicholas K. Dionysopoulos

    No, I don't have a video tutorial yet, but this article together with more information and a PHP script to automatically do it for you will be published in September's issue of the Joomla! Community Magzine http://magazine.joomla.org

  • Comment Link julter Friday, 27 August 2010 01:56 posted by julter

    im firstime to upload my site i got the same problem i cnt enter my admin wrong username and password i dont know how to do it.do you have video tutorial? please say yes im new disigner please help me. i read your posted but i dont know do it. i need video tutorial please.

  • Comment Link Daren Sunday, 04 July 2010 02:34 posted by Daren

    Awesome insight! Thanks for sharing.

  • Comment Link Ahmad Alfy Sunday, 06 June 2010 03:37 posted by Ahmad Alfy

    Interesting, the part of the AROs and ACOs is new to me. This explain why when I creat superadmins from phpMyAdmin by adding values to the #__user table it never worked!
    Thanks a lot.

  • Comment Link Nicholas K. Dionysopoulos Saturday, 08 May 2010 22:19 posted by Nicholas K. Dionysopoulos

    @nishant It's funny you ask this question on this page, because it describes what you have to do :) Just follow the instructions to create a new Super Administrator. Use the new user to login to your site's backend and re-enable your old account.

    You can deliver the SQL statements using your host's database management tool, usually phpMyAdmin. Run all three of them and presto! You have a new Super Administrator use you can use to clean up your mess. As simple as that.

  • Comment Link nishant Saturday, 08 May 2010 11:53 posted by nishant

    i changed my super administrator acc. to registered and now unable to login in backend saying u dont have access to administrator area
    so plz tell me how to chnage it back to super administrator

  • Comment Link ajl Friday, 16 April 2010 17:01 posted by ajl

    Wow...thank you very much!

  • Comment Link j p cook Thursday, 15 April 2010 22:07 posted by j p cook

    Thank you!
    Thank you!
    Thank you!

«StartPrev12NextEnd»

Leave a comment

Make sure you enter the (*) required information where indicated.
Basic HTML code is allowed.
All comments are auto-published. Unless you are a spammer, violate any laws or ask me to unpublish your comment, I won't unpublish any comments. Feel free to say anything you like.