HackInOS: 1

Overall Summary

HackInOS 1 is a fun machine from Vulnhub that can be very easy to get a foothold for exploitation but the fun part consists in looking at a source code from an upload page to bypass an uploading restriction and to find the uploaded file as it gets renamed. Once a low privilege shell is obtained, privilege escalation consists in taking advantage of an SUID binary which would allow us to read the contents of the shadow file to then crack the hash from the root account.

Scanning and Enumeration

An nmap scan shows an SSH port and an HTTP service running on port 8000.

Browsing to the HTTP service displays what it seems to be a WordPress site.

If we try to click any links from this site attempts to redirect to a hostname of “localhost”. I’l modify my hosts file to bind the IP address to the hostname.

Once the hosts file has been edited we can use gobuster to scan for directories and files in the web server. These are the results returned by gobuster:

Several options were returned and most of the times we would try to access the administrative portal of WordPress, but this time we will browse to the upload.php file where we will see a page that allows uploading of files and if we try to upload a PHP reverse shell we don’t get an error message but a smiley face.

From the gobuster scan we can see that there is also a /uploads directory which will most likely be the folder where the files should be uploaded, however browsing to it is forbidden and adding the specific file name of the file we uploaded returns a not found error.

If we go back to the upload.php file, look at the source code and scroll all the way down, there will be a message with a link to github which seems to be a hint.

Browsing to this URL we will see the code for the upload.php file, this is the code:
<!DOCTYPE html>


<div align="center">
<form action="" method="post" enctype="multipart/form-data">

    <b>Select image : </b>
    <input type="file" name="file" id="file" style="border: solid;">
    <input type="submit" value="Submit" name="submit">

// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$rand_number = rand(1,100);
$target_dir = "uploads/";
$target_file = $target_dir . md5(basename($_FILES["file"]["name"].$rand_number));
$file_name = $target_dir . basename($_FILES["file"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($file_name,PATHINFO_EXTENSION));
$type = $_FILES["file"]["type"];
$check = getimagesize($_FILES["file"]["tmp_name"]);

if($check["mime"] == "image/png" || $check["mime"] == "image/gif"){
$uploadOk = 1;
$uploadOk = 0;
echo ":)";
  if($uploadOk == 1){
      move_uploaded_file($_FILES["file"]["tmp_name"], $target_file.".".$imageFileType);
      echo "File uploaded /uploads/?";



To take advantage of the upload page lets take a look at the code. The first to notice in the code is that the name of the file uploaded is taken and added a random number from 1 to 100 at the end and finally creating an MD5 hash with it. This is accomplished by the following variable:

$target_file = $target_dir . md5(basename($_FILES["file"]["name"].$rand_number));

From the source code we can also see that only the “mime type” is being used to check for PNG or GIF files. The mime type is basically reading the contents of the file we are trying to upload and if it sees a tag such as <?php it will make the if statement be false and we would not be able to upload the file, however if we add the signature “GIF89a” to the beginning of the a file, the mime type will recognize the file as a GIF file instead. I’ll use a PHP reverse shell from pentestmonkey and add the signature “GIF89a” at the beginning, this is how the beginning of the file will look like:

// php-reverse-shell - A Reverse Shell implementation in PHP
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  The author accepts no liability
// for damage caused by this tool.  If these terms are not acceptable to you, then
// do not use this tool.

At this point the uploading of the PHP reverse shell would be successful but we also know that the files is being renamed by an MD5 value that also contains a random number as explained before. Lets take a look at the following line of code:

$rand_number = rand(1,100);

We can see that a random number will be generated and it will be between 1 and 100, so to be able to identify the name of the PHP file that will be uploaded I’ll create a short bash script that will take the formula of taking the name of the file and adding a number at the end from 1 to 100 to then use curl and try to make a request for the file name. This is the bash script I’ll be using:


for number in {1..100}; do
        #Gets the MD5 value of the name with a number added at the end and stores it in a variable.
        temp_name=`echo -n php-reverse-shell.php$number | md5sum | cut -d "-" -f 1 | cut -d " " -f 1`
        echo "---------------------------------------------------------"
        echo "Testing http://localhost:8000/uploads/$temp_name.php"
        echo "---------------------------------------------------------"
        curl -i "http://localhost:8000/uploads/$temp_name.php"

With this script, I will now first upload the modified PHP reverse shell using. I will now execute the script and save the output to a file named “results.txt” (make sure to make the script executable).

./filename-bruteforce.sh > results.txt

Once it finishes the results.txt will have a lot of output to go through so lets use cat and grep the contents of the file to show the information that contains the code “200” which is the code for OK success status.

If we now set our netcat listener with the port we specified in the PHP reverse shell and access the URL with the 200 status code, we will be getting a reverse shell as www-data.



The first thing I usually do when getting a reverse shell is spawning a tty shell and since python is installed in the target machine I’ll use it to get a tty shell.


For privilege escalation we can look for SUID binaries, this can be done by using the following command:

find / -user root -perm -4000 -exec ls -ldb {} \;
These are the binaries that have the SUID set.

The binary that we are interested in is “tail” and if we search for it on gtfobins we will see how to take advantage of it.


Since the binary is basically allowing us to read files as root we might as well read the shadow file and the passwd file to crack the root’s password. To read the shadow file using “tail” we will first use a variable to point to the file we want to read, we will then execute the binary and use the variable to read the file. These are the commands used:
/usr/bin/tail -c1G "$LFILE"

Successfully having access to the contents of the shadow file, I will now copy the contents and save it to a file on my attacking machine, I’ll also copy the contents of the passwd file in my attacking machine and use unshadow to get a file that we can use with john the ripper to crack the root account password.

As we can see from the screenshot we were able to successfully crack the password for the root account as “john”, so now if we simply su to the root account using that password we will become the root user.

Notify of
Inline Feedbacks
View all comments