Web Root
Checking the web root directory of the web application after gaining a foothold
While checking web root directory mostly comes down to retrieval of DB credential for further enumeration, but it is rather unnecessary in the current circumstance due to the earlier enumeration made with SQL Injection
Nonetheless, I will do so in order to better understand the web application
www-data@ubuntu:/var/www/Magic$ ll
total 52K
4.0K drwxr-xr-x 4 www-data www-data 4.0K Jul 12 2021 .
4.0K drwxr-xr-x 4 root root 4.0K Jul 6 2021 ..
4.0K drwxr-xr-x 4 www-data www-data 4.0K Jul 6 2021 images
4.0K drwxrwxr-x 6 www-data www-data 4.0K Jul 6 2021 assets
8.0K -rw-r--r-- 1 www-data www-data 4.5K Oct 22 2019 upload.php
8.0K -rw-r--r-- 1 www-data www-data 5.5K Oct 22 2019 login.php
8.0K -rw-rw-r-- 1 www-data www-data 4.5K Oct 22 2019 index.php
4.0K -rw-r--r-- 1 www-data www-data 72 Oct 18 2019 logout.php
4.0K -rwx---r-x 1 www-data www-data 162 Oct 18 2019 .htaccess
4.0K -rw-r--r-- 1 www-data www-data 881 Oct 16 2019 db.php5
While the web root directory contains the expected files, there are some surprises, such as .htaccess
and db.php5
.htaccess
www-data@ubuntu:/var/www/Magic$ cat .htaccess
<FilesMatch ".+\.ph(p([3457s]|\-s)?|t|tml)">
SetHandler application/x-httpd-php
</FilesMatch>
<Files ~ "\.(sh|sql)">
order deny,allow
deny from all
While .htaccess
file in general dictates how the Apache web server handles certain types of files within the web application, it is important to go over one by one
<FilesMatch ".+\.ph(p([3457s]|\-s)?|t|tml)">
- This section is using a regular expression pattern within
<FilesMatch>
to match file names that end with specific PHP file extensions. The regular expression is quite complex, but it essentially matches files with extensions like.php
,.php3
,.php4
,.php5
,.php7
,.php-s
,.phtml
, and.pht
.
- This section is using a regular expression pattern within
SetHandler application/x-httpd-php
- This directive sets the handler for the matched files to be
application/x-httpd-php
. In Apache, a “handler” determines how a particular file should be processed. In this case, it’s instructing Apache to treat these files as PHP scripts, so they will be executed by the PHP interpreter when accessed through the web server.
- This directive sets the handler for the matched files to be
</FilesMatch>
- This closing tag marks the end of the
<FilesMatch>
section.
- This closing tag marks the end of the
<Files ~ "\.(sh|sql)">
- This section uses another regular expression pattern within
<Files>
to match files with extensions.sh
(shell scripts) and.sql
(SQL scripts). <Files>
is used to apply directives to specific files based on a regular expression pattern.
- This section uses another regular expression pattern within
order deny,allow
- This directive sets the order of processing for access control. It specifies that the
deny
directives should be processed before theallow
directives.
- This directive sets the order of processing for access control. It specifies that the
deny from all
- This directive explicitly denies access to any files matching the pattern (i.e., files with
.sh
or.sql
extensions) for all users. It effectively blocks access to these files over the web.
- This directive explicitly denies access to any files matching the pattern (i.e., files with
In summary, this .htaccess
file is configuring the Apache web server to treat files with certain PHP-related extensions as PHP scripts and execute them using the PHP interpreter. Additionally, it explicitly denies access to any files with .sh
or .sql
extensions for all users, effectively preventing them from being accessed through the web. This can enhance the security of your web application by preventing unauthorized access to sensitive script and SQL files.
upload.php
www-data@ubuntu:/var/www/Magic$ cat upload.php
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header("location: login.php");
}
$target_dir = "images/uploads/";
$target_file = $target_dir . basename($_FILES["image"]["name"]);
$uploadOk = 1;
$allowed = array('2', '3');
// Check if image file is a actual image or fake image
if (isset($_POST["submit"])) {
// Allow certain file formats
$imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
if ($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg") {
echo "<script>alert('Sorry, only JPG, JPEG & PNG files are allowed.')</script>";
$uploadOk = 0;
}
if ($uploadOk === 1) {
// Check if image is actually png or jpg using magic bytes
$check = exif_imagetype($_FILES["image"]["tmp_name"]);
if (!in_array($check, $allowed)) {
echo "<script>alert('What are you trying to do there?')</script>";
$uploadOk = 0;
}
}
//Check file contents
/*$image = file_get_contents($_FILES["image"]["tmp_name"]);
if (strpos($image, "<?") !== FALSE) {
echo "<script>alert('Detected \"\<\?\". PHP is not allowed!')</script>";
$uploadOk = 0;
}*/
// Check if $uploadOk is set to 0 by an error
if ($uploadOk === 1) {
if (move_uploaded_file($_FILES["image"]["tmp_name"], $target_file)) {
echo "The file " . basename($_FILES["image"]["name"]) . " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
}
?>
[...REDACTED...]
As expected earlier, the upload.php
file contains a multiple security measures for the file upload feature;
- Extension
- Magic Number
- Content (Filtered with PHP’s
<?
)
index.php
www-data@ubuntu:/var/www/Magic$ cat index.php
<!DOCTYPE HTML>
<html>
[...REDACTED...]
<!-- Wrapper -->
<div id="wrapper">
<!-- Main -->
<section id="main">
<!-- Items -->
<div class="items">
<div class="item intro span-2">
<div align="center"><h1>m̴̛̫̼̟͔̼̗̒̐ȧ̷̹͍͊́̿̊̿̈́g̷̲͚̖̣̏͂̿̇̇i̴̺̻̝͍̦͎̅͋́c̴̢͙̿̒̑͂͐̔͂</h1><br/></div>
</div>
<?php
$path = "images/fulls";
$dir_handle = @opendir($path) or die("Unable to open folder");
while (false !== ($file = readdir($dir_handle))) {
if ($file != '.' && $file != '..' && $file != 'Thumbs.db') {
$span = '<article class="item thumb span-' . rand(1, 3) . '">';
echo($span);
$random = '<h2>' . dechex(rand(1, 1000000000)) . '</h2>';
echo($random);
echo("<a href='images/fulls/$file' class='image'><img src='images/fulls/$file' alt=''></a>");
echo('</article>');
}
}
echo('</div><div class="items">');
closedir($dir_handle);
$path = "images/uploads";
$dir_handle = @opendir($path) or die("Unable to open folder");
while (false !== ($file = readdir($dir_handle))) {
if ($file != '.' && $file != '..' && $file != 'Thumbs.db'
&& strpos($file, '.php') === false
&& strpos($file, '.php3') === false
&& strpos($file, '.php4') === false
&& strpos($file, '.php5') === false
&& strpos($file, '.phtml') === false) {
$span = '<article class="item thumb span-' . rand(1, 3) . '">';
echo($span);
$random = '<h2>' . dechex(rand(1, 1000000000)) . '</h2>';
echo($random);
echo("<a href='images/uploads/$file' class='image'><img src='images/uploads/$file' alt=''></a>");
echo('</article>');
} else if (strpos($file, '.php') !== false
|| strpos($file, '.php3') !== false
|| strpos($file, '.php4') !== false
|| strpos($file, '.php5') !== false
|| strpos($file, '.phtml') !== false) {
echo('<article class="item thumb span-1">');
echo('<h2>Excuse me!</h2>');
echo("<a href='images/hey.jpg' class='image'><img src='images/hey.jpg' alt=''></a>");
echo('</article>');
}
}
closedir($dir_handle);
?>
</div>
</section>
[...REDACTED...]
db.php5
</files>www-data@ubuntu:/var/www/Magic$ cat db.php5
<?php
class Database
{
private static $dbName = 'Magic' ;
private static $dbHost = 'localhost' ;
private static $dbUsername = 'theseus';
private static $dbUserPassword = 'iamkingtheseus';
private static $cont = null;
public function __construct() {
die('Init function is not allowed');
}
public static function connect()
{
// One connection through whole application
if ( null == self::$cont )
{
try
{
self::$cont = new PDO( "mysql:host=".self::$dbHost.";"."dbname=".self::$dbName, self::$dbUsername, self::$dbUserPassword);
}
catch(PDOException $e)
{
die($e->getMessage());
}
}
return self::$cont;
}
public static function disconnect()
{
self::$cont = null;
}
}
The db.php5
file defines the SQL configuration to the web application
additionally, there is also the db credential; theseus
:iamkingtheseus
Database
www-data@ubuntu:/var/www/Magic$ mysql
Command 'mysql' not found, but can be installed with:
apt install mysql-client-core-5.7
apt install mariadb-client-core-10.1
Ask your administrator to install one of them.
Attempting to connecting to the mysql
instance failed because the command line tool, mysql , does not exist within the target system
www-data@ubuntu:/var/www/Magic$ find /usr/bin -name mysql* -ls -executable -type f 2>/dev/null
32858 0 lrwxrwxrwx 1 root root 10 Jan 21 2020 /usr/bin/mysqloptimize -> mysqlcheck
32849 3788 -rwxr-xr-x 1 root root 3875176 Jan 21 2020 /usr/bin/mysqldump
32848 3712 -rwxr-xr-x 1 root root 3799752 Jan 21 2020 /usr/bin/mysqladmin
32854 3704 -rwxr-xr-x 1 root root 3790504 Jan 21 2020 /usr/bin/mysqlshow
32869 28 -rwxr-xr-x 1 root root 28448 Jan 21 2020 /usr/bin/mysqld_safe
32867 3976 -rwxr-xr-x 1 root root 4068280 Jan 21 2020 /usr/bin/mysqlbinlog
32850 8 -rwxr-xr-x 1 root root 7865 Jan 21 2020 /usr/bin/mysqldumpslow
32838 3736 -rwxr-xr-x 1 root root 3825320 Jan 21 2020 /usr/bin/mysqlcheck
32865 3568 -rwxr-xr-x 1 root root 3653288 Jan 21 2020 /usr/bin/mysql_ssl_rsa_setup
32851 3704 -rwxr-xr-x 1 root root 3791912 Jan 21 2020 /usr/bin/mysqlimport
32866 3488 -rwxr-xr-x 1 root root 3569976 Jan 21 2020 /usr/bin/mysql_tzinfo_to_sql
32876 4340 -rwxr-xr-x 1 root root 4442320 Jan 21 2020 /usr/bin/mysql_upgrade
32855 3724 -rwxr-xr-x 1 root root 3809512 Jan 21 2020 /usr/bin/mysqlslap
32864 3696 -rwxr-xr-x 1 root root 3784424 Jan 21 2020 /usr/bin/mysql_secure_installation
32860 0 lrwxrwxrwx 1 root root 10 Jan 21 2020 /usr/bin/mysqlrepair -> mysqlcheck
32856 0 lrwxrwxrwx 1 root root 10 Jan 21 2020 /usr/bin/mysqlanalyze -> mysqlcheck
32842 3544 -rwxr-xr-x 1 root root 3627200 Jan 21 2020 /usr/bin/mysql_config_editor
32868 28 -rwxr-xr-x 1 root root 26952 Jan 21 2020 /usr/bin/mysqld_multi
32863 3536 -rwxr-xr-x 1 root root 3616952 Jan 21 2020 /usr/bin/mysql_plugin
32835 22032 -rwxr-xr-x 1 root root 22558552 Jan 21 2020 /usr/bin/mysql_embedded
32875 5060 -rwxr-xr-x 1 root root 5179616 Jan 21 2020 /usr/bin/mysql_install_db
32852 4188 -rwxr-xr-x 1 root root 4286120 Jan 21 2020 /usr/bin/mysqlpump
32853 40 -rwxr-xr-x 1 root root 39016 Jan 12 2018 /usr/bin/mysqlreport
However, there is mysqldump available at /usr/bin
directory
www-data@ubuntu:/var/www/Magic$ mysqldump -utheseus -piamkingtheseus --all-databases
mysqldump: [Warning] Using a password on the command line interface can be insecure.
-- MySQL dump 10.13 Distrib 5.7.29, for Linux (x86_64)
--
-- Host: localhost Database:
-- ------------------------------------------------------
-- Server version 5.7.29-0ubuntu0.18.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Current Database: `Magic`
--
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `Magic` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `Magic`;
--
-- Table structure for table `login`
--
DROP TABLE IF EXISTS `login`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `login` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `login`
--
LOCK TABLES `login` WRITE;
/*!40000 ALTER TABLE `login` DISABLE KEYS */;
INSERT INTO `login` VALUES (1,'admin','Th3s3usW4sK1ng');
/*!40000 ALTER TABLE `login` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2023-10-01 11:03:39
There is the admin
user with the password; Th3s3usW4sK1ng
As mentioned above earlier, this has previously been enumerated via SQLi
However, checking it for password reuse has not been done yet