Make /admin variable

Good ideas? Share with us!
Post Reply
Gordon
Posts: 1339
Joined: 10 Aug 2011, 03:18

Make /admin variable

Post by Gordon » 14 Nov 2012, 05:56

I noticed in my weblogs that hackers frequently try stuff like /phpmyadmin and phppgadmin, but also /admin. While most of them restrict themselves to non-SSL http, where I have removed the /admin path, I still would like to be able to change /admin into something less obvious.

I've already attempted to change all hardcoded references to /admin in the /usr/share/webadmin files but for some reason this renders the the webadmin page useless. It works if I make /somename a proxy to /admin on 127.0.0.1 but I'm not so into these kind of "solutions". And of course I have to take into account that if I run an update that webadmin can be overwritten and I need to do it all over again. Is there any possibility therefore to make this a configurable setting?

ingo2
Posts: 81
Joined: 06 Feb 2012, 10:32

Re: Make /admin variable

Post by ingo2 » 06 Jan 2013, 10:54

At this occasion please also:

assign the user admin an UID > 1000. I know that admin is just a normal user, but for those who want to use NFS with the B3, it is essential to match UID's on the B3 with those on the (Linux)-PC's. And the majority of Linux-distributions assign UID=1000 to the first user. So if this UID is occupied by admin on the B3 it causes some configuration work to shift it to a non-conflicting value.

The same applies if you use CIFS with unix-extensions enabled. The world does not consist of only Win$-users ;-)

Regards,
Ingo

I i.e. moved admin to 999 this way:

Code: Select all

# Change 'admin' UID and GID from 1000 -> 999
usermod -u 999 admin
groupmod -g 999 admin
chown -R 999:999 /home/admin # change file permissions
passwd admin <secret> # this was necessary for the web-interface to work
UNIX is user friendly, it's just picky about who its friends are.

Gordon
Posts: 1339
Joined: 10 Aug 2011, 03:18

Re: Make /admin variable

Post by Gordon » 12 Apr 2013, 05:31

Well, it took some time but I figured it out. The issue that was causing me the most pain is that when logging on you're no longer viewing the website through the Apache driven PHP engine but are in fact using Apache to vie the result of you yourself running PHP as a CGI. In short: I forgot to add two lines to the involved Apache conf file :oops:

So here's something of a cook book for people wanting to expose the admin page as something different that is not in the default search list of hackers hitting on your website and trying to gain access. The power of obscurity if you wish...

First off some changes need to be made to the PHP code of the admin page. We want to change all the hardcoded references to "/admin" to reflect the URI we're calling. For this we'll split off the first element of the path shown in REQUEST_URI like so:

Code: Select all

preg_replace("|^(/[^/]*/).*$|","\\1",$_SERVER["REQUEST_URI"])
Note that this will return "/admin" when you access the page as "/admin/something", so this is a non-destructive change. There are three file instances that need to be changed this way:
  • /usr/share/web-admin/admin/index.php
    str_replace(SELF, '', __FILE__) => preg_replace("|^(/[^/]*/).*$|","\\1",$_SERVER["REQUEST_URI"])
  • /usr/share/web-admin/admin/config/config.php
    "/admin" => preg_replace("|^(/[^/]*/).*$|","\\1",$_SERVER["REQUEST_URI"])
  • /usr/share/web-admin/admin/legacy/defines.php
    "/admin" => preg_replace("|^(/[^/]*/).*$|","\\1",$_SERVER["REQUEST_URI"])
The next code block will perform these changes:

Code: Select all

sed -i "s/str_replace(SELF, '', __FILE__)/\"\/usr\/share\/web-admin\"\.preg_replace\(\"\|\^\(\/\[\^\/\]\*\/\)\.\*\$\|\",\"\\\\\\\\1\",\$_SERVER\[\"REQUEST_URI\"\])/" \
	/usr/share/web-admin/admin/index.php

sed -i "s/\"\/admin\/\"/preg_replace\(\"\|\^\(\/\[\^\/\]\*\/\)\.\*\$\|\",\"\\\\\\\\1\",\$_SERVER\[\"REQUEST_URI\"\])/" \
	/usr/share/web-admin/admin/config/config.php

sed -i "s/\"FORMPREFIX\",\"\/admin\"/\"FORMPREFIX\",preg_replace\(\"\|\^\(\/\[\^\/\]\*\/\)\.\*\$\|\",\"\\\\\\\\1\",\$_SERVER\[\"REQUEST_URI\"\])/" \
	/usr/share/web-admin/admin/legacy/defines.php
The changes made so far will allow the webserver to fill in the blanks in the view files correctly, but not all view files are actually processed by PHP and I found that in those that are one of them didn't follow the convention of having a variable in stead of the literal "/admin". So let's fix that and replace "/admin" by it's variable "<?=FORMPREFIX?>":

Code: Select all

sed -i "s/href=\"\/admin\/filemanager\/cd/href=\"<\?=FORMPREFIX\?>\/filemanager\/cd/" \
	/usr/share/web-admin/admin/views/default/album/album_album_view.php
At this point everything still points at "/admin" if you access it through this web path, but any change to the other view files might (will) break some of the functionality. Last step therefore is to prepare the code to use an alternate view when using a different path.

Code: Select all

sed -ni '1!N; s/\/\/ Default\n\s*define(\"THEME\",\"default\")\;/if (is_dir(APPPATH.\"views\".FORMPREFIX)) {\n\t\tdefine(\"THEME\",str_replace(\"\/\",\"\",FORMPREFIX))\;\n\t} else {\n\t\t\/\/ Default theme\n\t\tdefine(\"THEME\",\"default\")\;\n\t}/; p' \
	/usr/share/web-admin/admin/legacy/defines.php
Would be nice if Excito would apply these changes in their next release of bubba-frontend.

Gordon
Posts: 1339
Joined: 10 Aug 2011, 03:18

Re: Make /admin variable

Post by Gordon » 12 Apr 2013, 06:10

Having done the preparations from the post above, it's time to create the alternate view. To do that create hard links of the default view and replace all references to "/admin" to reflect your alternate root. Do not use nano to do this, because this will actually change the one file referenced by both directory trees and you want two different files.

This script will perform all the described changes:

Code: Select all

NEWROOT="test123"

cp -al /usr/share/web-admin/admin/views/default /usr/share/web-admin/admin/views/$NEWROOT

sed -i "s/location\.assign(\"\/admin\/disk\")/location.assign(\"\/$NEWROOT\/disk\")/" \
	/usr/share/web-admin/admin/views/$NEWROOT/_js/disk_progress.js

sed -i "s/location\.assign(\"\/admin\/disk\/progress\")/location.assign(\"\/$NEWROOT\/disk\/progress\")/" \
	/usr/share/web-admin/admin/views/$NEWROOT/_js/disk_raid.js

sed -i "s/\/admin\/views\/default/\/$NEWROOT\/views\/$NEWROOT/" \
	/usr/share/web-admin/admin/views/$NEWROOT/_js/jqueryFileTree.js

sed -i "s/\/admin\/views\/default/\/$NEWROOT\/views\/$NEWROOT/" \
	/usr/share/web-admin/admin/views/$NEWROOT/_js/notify.js

sed -i "s/\"\/admin\/ajax_settings/\"\/$NEWROOT\/ajax_settings/" \
	/usr/share/web-admin/admin/views/$NEWROOT/_js/software.js

sed -i "s/\"\/admin\/ajax_notify/\"\/$NEWROOT\/ajax_notify/" \
	/usr/share/web-admin/admin/views/$NEWROOT/_js/stat.js
Obviously you should change "test123" but you got that, right?

Last thing is a little CodeIgniter (the development frame of the admin page) requirement:

Code: Select all

# NEWROOT="test123"   # Already defined

ln -s /usr/share/web-admin/admin /usr/share/web-admin/$NEWROOT
Now add the following rules to your Apache conf (either global or site dependent):

Code: Select all

        Alias /test123 /usr/share/web-admin/admin
#       ScriptAlias /fcgi-bin/php.cgi /usr/share/web-admin/admin
#       FastCgiExternalServer /usr/share/web-admin/admin/index.php -socket fcgi -idle-timeout 120 -flush
        <Location /test123>
                RewriteEngine on
                RewriteBase /test123
                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteCond %{REQUEST_FILENAME} !-d
                RewriteRule ^(.*)$ index.php?/$1 [L]
        </Location>
Again, change "test123" (3 instances) to match the NEWROOT definition above.
The two comment lines are defined in /etc/apache2/conf.d/admin.conf and I included them here for reference. Do NOT delete this admin.conf file - the definitions in there are vital for the admin page to function. Restart/reload Apache for the changes to take effect.

To block access to /admin as defined in the global apache conf, add this to your public site definition file also:

Code: Select all

        Alias /admin /home/web/errors
        <Location /admin>
                RewriteEngine on
                RewriteBase /admin
                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteRule ^(.*)$ index.php?request_uri=$1 [L]
        </Location>
:idea: If you create that path and file "/errors/index.php" you can actually do some mean stuff in there, like changing firewall rules to blacklist the offender.

Post Reply