Intranet
Welcome to the intranet! - by toxicat0r
Last updated
Welcome to the intranet! - by toxicat0r
Last updated
Running a nmap scan reveals six open ports: an echo service on port 7, ftp running on port 21, ssh running on 22, a telnet service on port 23, and two web applications on ports 80 and 8080.
Visiting the web application on port 80, we are prompted with a message that the site is under construction. Further investigations via Gobuster
did not lead to any interesting material.
Next, running Gobuster
on the site on port 8080, we'll find some directories, but all are redirected to the login
page.
On the login page, we need a valid email address as a username and a password to get any further.
Looking at the source code, we are able to get two usernames:
devops@securesolacoders.no
anders@securesolacoders.no
Trying to use the user magnus
, the boss of the company, who was mentioned in the room description, we get an error message that the user is invalid.
Next, we try to log in with a random password with the two found usernames and the wild guess of admin@securesolacoders.no
. All three logins seem to be valid, like the error message states, the given password is invalid.
With the found information, it's possible to craft a users.txt,
and a password base.txt
, which will then be used to generate wordlists, to brute force the login page.
For convenience, a hostname is used for the IP of the machine in the /etc/hosts
file.
Add 10.10.211.106 securesolacoders.no
to /etc/hosts
To mangle the passwords, a simple John
rule is configured. Appending some numbers to the possible passwords and having a combination of a password with a number and a special character.
With the created rule, generate a wordlist from base.txt
Running Hydra to brute force the login page.
After several minutes, we are able to retrieve a password.
To generate a wordlist, that takes less time, the results of this generator can be used:
With the found credentials we are able to log in.
After logging in, we are able to retrieve the first flag and are immediately greeted with the next challenge. A verification code is required to enter a 2FA
code.
Looking at the source, you get confirmation that only 4 characters are needed, as indicated in the input field.
To keep it simple, we'll just use digits for now and use crunch to generate the wordilst.
To be able to reach the /sms
page with tools, the session must be possessed.
We just extract the jwt
session cookie and pass it to the tool of our choice.
For the purpose of brute forcing the 2FA code, we use Wfuzz.
To hide the incorrect responses, the tag --hl 77
is used to ignore responses with a line count of 77
Hide response with 77 lines.
And we get a 2FA Code in this case 4065.
Using the 2FA Code, we are able to log in and get the second flag.
When looking through the page, the internal page with the Update
button, which should update the news feed, stands out.
But, there is no more news.
Even logged in as one of the users, we are not able to reach the admin page. We know there is a jwt
session cookie used to stay authenticated. This might be a way to get to the admin panel in the future.
Looking further at the behavior of the update button via Burp Suite, an LFI vulnerability becomes apparent.
It is possible to retrieve the /etc/passwd
file.
The hint states, that the CMD will lead you to the source, so for the third flag, we have to get the source of the application. The CMD might be a hint on how to retrieve the file path. To check out current running processes, it's possible to read the /proc/self/stat file
. When you access /proc/self/stat
, you are reading the process status information for the current process.
From there, we are able to retrieve the PID of 669
. With /proc/pid/cmdline
it's possible to get the command line arguments passed to a specific process with the given pid
. And we get the running location of the flask application /home/devops/app.py
.
Retrieving the app.py
via the LFI
we are greeted with the thrid flag in the source code.
In the first lines of the application app.py
we are able to see how the jwt
session key is generated. It's a key containing the string secret_key_
concatenated with a random number between 100000
and 999999
. With this information we are able to generate a wordlist and crack the used password with a known jwt
session cookie using flask-unsing
.
Create the flask_base.txt
just containing secrect_key
Define a John rule to append all possible numbers in the range 1000000
to 999999
.
Create the wordlist flask_wordlist.txt
using John with the custom defined rule and the flask_base.txt
Running flask-unsign to crack the secret.
In this case we get the secret secret_key_848652
.
To create our own token first we have to check how the jwt
session token is structured.
We see that we are logged in as anders
. With this structure, we create our own token. The first try was with devops
a known user, but this did not work.
As the directory suggest it is a panel for an admin, and the admin user was also a valid user as we could see in the part of getting the first flag.
By creating and using this ticket, we are able to get to the /admin
directory with the fourth flag.
Looking at the source of the admin page, we see that there was a part of a form that did not get entirely deleted.
Again, looking at app.py
we are able to interact with the operating system in line 10 with the os.system() call. This gets its parameters from the lost form. But we are not dependent on this form and are able to send a post request with a value for debug to create a reverse shell.
Using cURL
, providing the previously created admin session cookie, we plant a basic reverse shell, where we have to url-encode the &
sign to get it to work.
While having a listener set up. We are now the user devops
and are able to retrieve the first user flag.
Looking at the processes via ps aux
, we see something odd. Instead of www-data
running apache2
, it is anders
. This Apache web server might be the web application running on port 80 and our gate to escalate to the user anders
.
To confirm our assumption, we look into /var/www/html
and find the index.html
of the web application on port 80.
Checking out the rights of /var/www/html
we are able to write in this folder.
For further confirmation we just create a test.html
site and visit it.
Next, we create a simple php-reverse shell provided by pentestmonkey.
Changing IP address and port.
To transfer our reverse shell we use nc
as follows.
File transfer via nc
on the receiving end run
nc -l -p <PORT> > <FILENAME>
to send the file
nc -w 3 <TARGET-IP> <PORT> < <FILENAME>
Setting up a listener.
After visiting the site securesolacoders.no/revshell.php
we get our reverse shell and are the user anders
.
In his home directory the second user flag is located.
While enumerating the machine, we see that we are able to restart the apache2
service with sudo permission.
In /etc/apache2
the file envvars
is writeable by the user anders.
To have a shell in which we can edit this file, we add our ssh key to the authorized_keys file to access the machine via ssh as user anders
.
Add the public key.
Connect as user anders
via ssh.
Next, add a simple reverse shell to /etc/apache2/envvars
and set up a listener.
When restarting the server with sudo permissions, envvars
is called ,and we get a reverse shell as user root.
Retrieve the final flag in /root/
.