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 /> ' . $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 /> ' . $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
|
nmap (thanks to comment by anonymous below) |
perl -e 'exec "/bin/bash";'
|
Perl |
Related articles:
- Online Kali Linux programs (FREE) (54.3%)
- Guide to GPS Metadata in Photos (51.5%)
- How to install Social Mapper in Kali Linux (50%)
- Best Kali Linux tools in WSL (Windows Subsystem for Linux) (Part 1) (50%)
- How to find all passwords and keys in a large number of files (42.8%)
- RDP Security Audit (RANDOM - 35.8%)
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 🙂