Naughty 2
Naughty 2
Naughty 2
Description:
This machine has been designed with the objective of demonstrating alternative ways of
enumeration and exploitation, following the principle of 'Security by Obscurity'.
To solve the machine, users must have skills in the development of Python scripts,
knowledge of protocols other than the conventional ones (SCTP) as well as knowing how
to connect to them, knowledge of advanced cryptography, use of Socket Files in order to
communicate between processes on the same machine and finally abuse of
misconfigured Kernel flags.
Difficulty:
hard
Flags:
User: 2a3d0cd5deba375d0916194f935b553b
Root: f5da7a83a519369acee489b9c727aab3
Enumeration
First of all, we start by performing a basic reconnaissance on the victim machine.
By sending an ICMP trace, we validate that the machine is active, in addition to
determining that we are dealing with a Linux machine based on its TTL (TTL=64):
Performing a first port scan with nmap, we found that no port is reported as open:
By sending an alternative scan (TCP Syn Port Scan), we validate that no open TCP port is
still reported:
At this point, since it is not possible to find any port via TCP or UDP, an alternative
scanning path is explored.
SCTP is a relatively new alternative to TCP and UDP protocols, combining most of the
features of TCP and UDP and adding new functions such as multi-homing and multi-
streaming. It is mainly used for SS7/SIGTRAN-related services, but can also be used for
other applications. The SCTP INIT scan is the SCTP equivalent of a TCP SYN scan. It can
be performed quickly, scanning thousands of ports per second on a fast network
unhindered by restrictive firewalls. Like SYN scanning, INIT scanning is relatively
unobtrusive and stealthy, as it never completes SCTP associations.
To do this, we will use the '-sY' parameter of nmap. After a while, we will be able to see 2
open ports:
At this point, we proceed to perform an exhaustive scan with nmap on this, launching a
series of basic reconnaissance scripts and trying to detect the services running on them:
The problem arises in that it will not be possible to perform a scan in this way.
Alternatively, we can use the 'socat' tool, creating the following rules:
In this way, with the nmap tool, we can point to our localhost to perform the exhaustive
reconnaissance of the ports that we have detected open:
At this point, we were able to identify the services running under the listed ports.
Foothold
At first, after logging in to the web server through the localhost, we will find a 'Forbidden':
In order to validate if Virtual Hosting is being applied, the domain 'naughty.htb' is added
in the '/etc/hosts', but it must be taken into account that it should not point to the
machine's IP, but to the IP address '127.0.0.1', due to the tunnel that we have opened with
'socat':
At this point, the web page can be viewed, displaying the following content
corresponding to a calendar:
Initially none of the clickable events are functional, except for the green labeled 'Click for
Google', which will redirect the user to a troll page:
In order to detect existing valid routes on the web server, Fuzzing will be applied with the
desired tool. In this case, the Wfuzz tool will be used:
At first, all tested routes will return a status code '302':
It is convenient to follow the redirect through the '-L' parameter of Wfuzz, so you can see
the final status code:
From the results obtained, we will get multiple responses with 1738 characters. The idea
at this point is to hide these characters in order to obtain responses from the server with
different characters for a tested path, thus being able to determine potential paths that
may host interesting content:
Although this route has an authentication panel, this panel will not be of much interest,
since it will not be possible to perform any kind of exploitation:
Applying fuzzing by html extensions, we found more interesting files:
Among them, a file 'admin.html'. After entering the URL address to this file, we will see
that we are redirected to the following resource:
It should be noted that if we try to force a 'No Redirect' from Burpsuite, it will not be
possible to access the resource, listing the following on the web server:
To facilitate the work, you can use a specific Seclists dictionary called 'burp-parameter-
names.txt', ideal for testing parameters:
The only thing to consider is that following the 'NaughtyUser' format, each of the lines
that compose the dictionary should start with the first character in upper case, since the
header is Case Sensitive.
If a valid header is found, it is possible that the size of the content will change in the
server's response, so we would already have a potential way to enumerate a possible
valid alternative header.
Once done, after entering the '/admin.html' panel, it will be possible to view the following
Dashboard:
Currently, in the upper right corner, we will see that we are logged in as a user, being able
to see the profile information:
We will also be able to view a series of emails available in our Inbox:
The first one corresponds to a conversation between ‘wh1tedrvg0n’ and ‘lrobinson’,
where a public key is exchanged:
This public key will be downloadable and will contain the following content:
Listing the rest of the existing emails in the Inbox, another of them we will see that it has
a compressed file attached, which we will be able to download:
We can see that this compressed file is password protected, so it is not possible to
extract its content:
However, reading the email, Lenore Robinson points out as a clue that the password on
the archive is usually the one used on sample ZIP files containing malware for people to
download. The password is therefore 'infected'.
It should be noted that there is a hidden file '.generator.backup' which at first will not be
visible unless you do 'ls -la'.
As we can see, we are asked to decrypt the file 'message.encrypted' using the private
key.
However, we see that the following file is shared with us, corresponding to a Backup of
the Ruby script that was used to generate the public key and the encrypted message:
As you can see, this is an implementation of OpenSSL in Ruby, we have an exponent ‘e’
and two prime numbers ‘p’ and ‘q’ of 1024 bits which is used to generate modulus, then
public key which is used to encrypt the message and generate encryption text as
‘message.encrypted’ in output.
Accordingly, this is RSA algorithm, applied to encrypt the message. In order to decrypt
the 'message.encrypted' file, we will therefore have to use RSA.
RSA encryption requires the public key, which means modulus ‘n’ and the public exponent
‘e’. We can see these values in the public key:
As we have seen, the value of 'n' is not factorizable, however, we have an interesting line
in the generator script:
q = OpenSSL::BN.new(e).mod_inverse(p)
It means that:
q = mod_inverse(p)
q = mod_inverse(p)
q = e^(-1)*mod(p)
q*e = e*(e^(-1))*mod(p)
q*e = (e/e)*mod(p)
q*e = 1*mod(p)
Following the congruence relationship, 1*mod(p) equals k*p + 1, where ‘k’ is a multiplier.
q*e = k*p+1
At this point, we can try to clear 'p'. To do this, we can subtract '1' on both sides:
q*e-1 = k*p+1-1
q*e-1 = k*p
p = ((q*e-1)/k)
At this point, we see that we have 2 unknowns, so we could not continue. However, let's
try to clear ‘q’. Let's start from the following point:
p = ((q*e-1)/k)
p*q = q*((q*e-1)/k)
p*q = (q^2*e-q)/k
k*p*q = q^2*e-q
At this point, if we pass everything to the left, we would be left with the following:
q^2*e-q-k*p*q = 0
q^2*e-q-k*p*q = 0
q = (-(-1) + square((-1)^2-4*(e)*(-k*p*q))/2e
q = (1 + square(1+4*e*k*p*q))/2e
q = (1 + square(1+4*e*k*n))/2e
And now we can calculate ‘q’ if we apply brute force on 'k', since we have the rest of the
values.
Subsequently, we can start applying brute force on the value of ‘k’ to start testing.
We will first isolate the square root part, in order to validate if for some value of ‘k’ there is
a perfect square:
After its execution, we can see the different values that are coming out:
Something to highlight is the final Boolean state, where if True, we will know that we are
in front of a perfect square.
It should be noted that in order to validate whether we are dealing with a correct value of
'p', if we look at the remainder of dividing ‘n’ by ‘q’, this should be 0. This is so because if,
for example, 16 = 2*8, then both the remainder of ‘16/2’ and the remainder of ‘16/8’
should be 0.
After executing the script it is a problem that we encounter the following problem in
Python3:
A conversion problem occurs. To fix this problem, just add an additional '/' character to
the division:
If we run the script again, we get the following values:
We have 'q', and consequently also 'p', since if 'n = p*q' then 'p = n/q':
At this point, we can try to obtain the rest of the remaining values and build the private
key.
Where 'd' is the last unknown to be calculated. The value of 'd' can be calculated using
the inverse multiplicative modular function (modinv()):
This function must receive the values of 'e' and 'm' (‘m’ is defined as ‘m = n-(p+q-1)’):
Finally, we run the script and obtain the private key:
With this private key, we try to decrypt the message:
Lateral Movement
With this password, we will be able to connect as the user 'wh1tedrvg0n' to the machine:
Immediately, we will notice that we are in a limited shell after login (lshell), which
complicates mobility at the system level.
Using the 'help' command, we will be able to see the available commands that we can
execute, obtaining the following:
If we look at the 'cat' help panel, we will see that it is not really the 'cat' command:
This is the 'ed' command, and there is a potential way to escape the Limited Shell with
this one:
At this point, we will have complete mobility through the system.
In the '/home' directory, we will also find the 's4vitar' user, which also corresponds to a
system level user:
In the user's personal directory, we will see that there is a folder 'work' with several
resources. Among them, we see a file 'notes.txt', with the following notes:
If we monitor the file 'socket_test.s' with watch, we will see that after one minute this file
disappears and is created again:
Since this has write capability, there could be a potential way to communicate with this
Socket to inject commands such as user 's4vitar'.
If we search the HackTricks website for the word 'Socket', we will see that there is a way
to inject commands using Socket Files:
As indicated on the web site, we can use 'netstat' to list if there is currently a listening
socket:
After applying the command on the victim machine, we obtain the following results:
Following the web instructions, by using the 'socat' command we can communicate with
this Socket File, injecting commands as follows:
As you can see, it has been possible to inject a command as the user 's4vitar'. In order to
gain access to the system, we would only have to inject the following command:
Thus obtaining an interactive console as this new user.
At this point, it will be possible to display the flag located on the desktop of the user
's4vitar':
Privilege Escalation
As we can see, the user 's4vitar' is in the 'sudo' group, however, we do not know its
password:
At this point, it is advisable to continue monitoring the commands that are being executed
on the system at regular intervals. To do this, we can make use of the 'pspy' tool:
En primer lugar, será necesario compilarla:
After a while, we will see the following commands executed on the system:
As can be seen, thanks to the 'UID=0', we observe that the user 'root' from a session is
migrating to the user 's4vitar'. Subsequently, in the lower area we observe a 'sudo
whoami', reported as the 'UID=0' corresponding to the user 'root'.
This suggests that being the user 's4vitar', after executing the 'sudo whoami' command,
his password had to be provided. As it is in the 'sudo' group, the command has been
executed in a privileged way and therefore it is reported with the 'UID=0'.
When a user is in the sudo group and executes a 'sudo whoami' from console (it can be
any other command, but for practical purposes we will explain it with the whoami
command), after entering the password a PRIVILEGE TOKEN is assigned that allows the
user after executing the 'sudo whoami' command again not to be required to provide the
password the following times.
This is temporary and, in case the system has the 'ptrace_scope' set to 0, it may be
possible from another console to synchronize to this privileged process to obtain a
console as root.
To do this, we must first validate that the 'ptrace_scope' is set to 0 in the following path:
This is the case, therefore a privilege escalation vulnerability could occur.
Review of this exploit shows that it is necessary for the victim machine to have 'gdb'
installed:
After validating it on the victim machine, we see that this is the case:
By way of interest, it should be noted that both Parrot OS, Kali Linux, and CentOS/RedHat
have the 'ptrace_scope' set to 0, so if a scenario like this occurs, it may be possible to
escalate privileges.
These tests can be performed on our system, for this we only need that a user is in the
'sudo' group and that from a console a privileged command has been executed starting
from that user (for example: sudo ls) to leave an active PRIVILEGE TOKEN running. Once
this is done, if we run the exploit we should get a console as root.